voice, festival, client, native-client, dbus-client: add API support for rate and...
authorKrisztian Litkey <krisztian.litkey@intel.com>
Tue, 11 Mar 2014 12:03:13 +0000 (14:03 +0200)
committerKrisztian Litkey <krisztian.litkey@intel.com>
Tue, 11 Mar 2014 12:03:13 +0000 (14:03 +0200)
13 files changed:
src/daemon/client.c
src/daemon/client.h
src/daemon/voice.c
src/daemon/voice.h
src/plugins/client-api/dbus/dbus-client.c
src/plugins/client-api/native/native-client.c
src/plugins/client-api/native/native-client.h
src/plugins/client-api/native/native-messages.c
src/plugins/client-api/native/native-messages.h
src/plugins/client-api/native/native-server.c
src/plugins/client-api/native/test-client.c
src/plugins/client-api/wrt-media-client/wrt-media-client.c
src/plugins/text-to-speech/festival/festival-voice.c

index 26fa74e..35695a2 100644 (file)
@@ -371,7 +371,8 @@ static void client_voice_event(srs_voice_event_t *event, void *notify_data)
 
 
 uint32_t client_render_voice(srs_client_t *c, const char *msg,
-                             const char *voice, int timeout, int notify_events)
+                             const char *voice, double rate, double pitch,
+                             int timeout, int notify_events)
 {
     srs_context_t *srs    = c->srs;
     const char    *tags[] = { "media.role=speech", NULL };
@@ -385,9 +386,14 @@ uint32_t client_render_voice(srs_client_t *c, const char *msg,
     req->c             = c;
     req->notify_events = notify_events;
 
-    req->id = srs_render_voice(srs, msg, (char **)tags, voice, timeout,
-                               notify_events | forced, client_voice_event,
-                               req);
+    if (rate == 0)
+        rate = 1;
+    if (pitch == 0)
+        pitch = 1;
+
+    req->id = srs_render_voice(srs, msg, (char **)tags, voice, rate, pitch,
+                               timeout, notify_events | forced,
+                               client_voice_event, req);
 
     if (req->id != SRS_VOICE_INVALID) {
         mrp_list_append(&c->voices, &req->hook);
index 2b79bd3..3de0043 100644 (file)
@@ -132,7 +132,8 @@ void client_notify_command(srs_client_t *c, int idx, int ntoken,
 
 /** Request synthesizing a message. */
 uint32_t client_render_voice(srs_client_t *c, const char *msg,
-                             const char *voice, int timeout, int notify_events);
+                             const char *voice, double rate, double pitch,
+                             int timeout, int notify_events);
 
 /** Cancel/stop a synthesizing request. */
 void client_cancel_voice(srs_client_t *c, uint32_t id);
index bb829d8..b26e270 100644 (file)
@@ -106,6 +106,8 @@ typedef struct {
     char               *msg;             /* message to render */
     char              **tags;            /* stream tags */
     uint32_t            actor;           /* actor id */
+    double              rate;            /* synthesis rate (1 = normal) */
+    double              pitch;           /* synthesis pitch (1 = default) */
     int                 timeout;         /* timeout */
 } queued_t;
 
@@ -606,9 +608,9 @@ static void request_timer_cb(mrp_timer_t *t, void *user_data)
 
 
 static request_t *enqueue_request(state_t *state, const char *msg, char **tags,
-                                  renderer_t *r, uint32_t actor, int timeout,
-                                  int notify_mask, srs_voice_notify_t notify,
-                                  void *notify_data)
+                                  renderer_t *r, uint32_t actor, double rate,
+                                  double pitch, int timeout, int notify_mask,
+                                  srs_voice_notify_t notify, void *notify_data)
 {
     queued_t *qr;
 
@@ -673,8 +675,8 @@ static request_t *activate_next(state_t *state)
     qr->req.timer = NULL;
 
     r = qr->req.r;
-    qr->req.vid = r->api.render(qr->msg, qr->tags, qr->actor,
-                                qr->req.notify_mask, r->api_data);
+    qr->req.vid = r->api.render(qr->msg, qr->tags, qr->actor, qr->rate,
+                                qr->pitch, qr->req.notify_mask, r->api_data);
 
     mrp_free(qr->msg);
     qr->msg = NULL;
@@ -706,9 +708,9 @@ static request_t *activate_next(state_t *state)
 
 
 request_t *render_request(state_t *state, const char *msg, char **tags,
-                          renderer_t *r, uint32_t actor, int timeout,
-                          int notify_mask, srs_voice_notify_t notify,
-                          void *notify_data)
+                          renderer_t *r, uint32_t actor, double rate,
+                          double pitch, int timeout, int notify_mask,
+                          srs_voice_notify_t notify, void *notify_data)
 {
     request_t *req;
 
@@ -720,7 +722,8 @@ request_t *render_request(state_t *state, const char *msg, char **tags,
     mrp_list_init(&req->hook);
     req->id  = state->nextid++;
     req->r   = r;
-    req->vid = r->api.render(msg, tags, actor, notify_mask, r->api_data);
+    req->vid = r->api.render(msg, tags, actor, rate, pitch,
+                             notify_mask, r->api_data);
 
     if (req->vid == SRS_VOICE_INVALID) {
         mrp_free(req);
@@ -738,9 +741,9 @@ request_t *render_request(state_t *state, const char *msg, char **tags,
 
 
 uint32_t srs_render_voice(srs_context_t *srs, const char *msg,
-                          char **tags, const char *voice, int timeout,
-                          int notify_mask, srs_voice_notify_t notify,
-                          void *user_data)
+                          char **tags, const char *voice, double rate,
+                          double pitch, int timeout, int notify_mask,
+                          srs_voice_notify_t notify, void *user_data)
 {
     state_t    *state = (state_t *)srs->synthesizer;
     renderer_t *r;
@@ -762,7 +765,7 @@ uint32_t srs_render_voice(srs_context_t *srs, const char *msg,
     }
 
     if (state->active == NULL)
-        req = render_request(state, msg, tags, r, actid, timeout,
+        req = render_request(state, msg, tags, r, actid, rate, pitch, timeout,
                              notify_mask, notify, user_data);
     else {
         if (timeout == SRS_VOICE_IMMEDIATE) {
@@ -770,8 +773,8 @@ uint32_t srs_render_voice(srs_context_t *srs, const char *msg,
             req   = NULL;
         }
         else
-            req = enqueue_request(state, msg, tags, r, actid, timeout,
-                                  notify_mask, notify, user_data);
+            req = enqueue_request(state, msg, tags, r, actid, rate, pitch,
+                                  timeout, notify_mask, notify, user_data);
     }
 
     if (req != NULL)
index 35f3add..8b16c0d 100644 (file)
@@ -45,8 +45,8 @@ typedef void (*srs_voice_notify_t)(srs_voice_event_t *event, void *notify_data);
  */
 typedef struct {
     /** Render the given message. */
-    uint32_t (*render)(const char *msg, char **tags, int actor,
-                       int notify_events, void *api_data);
+    uint32_t (*render)(const char *msg, char **tags, int actor, double rate,
+                       double pitch, int notify_events, void *api_data);
     /** Cancel the given rendering, notify cancellation if asked for. */
     void (*cancel)(uint32_t id, void *api_data);
 } srs_voice_api_t;
@@ -63,9 +63,9 @@ void srs_unregister_voice(srs_context_t *srs, const char *name);
 
 /** Render the given message using the given parameters. */
 uint32_t srs_render_voice(srs_context_t *srs, const char *msg,
-                          char **tags, const char *voice, int timeout,
-                          int notify_events, srs_voice_notify_t notify,
-                          void *user_data);
+                          char **tags, const char *voice, double rate,
+                          double pitch, int timeout, int notify_events,
+                          srs_voice_notify_t notify, void *user_data);
 
 /** Cancel the given voice rendering. */
 void srs_cancel_voice(srs_context_t *srs, uint32_t id, int notify);
index 95f471a..dad9fc8 100644 (file)
@@ -625,8 +625,8 @@ static int voice_notify(srs_client_t *c, srs_voice_event_t *event)
 
 static int parse_render_voice(mrp_dbus_msg_t *req, const char **id,
                               const char **msg, const char **voice,
-                              int *timeout, int *notify_events,
-                              const char **errmsg)
+                              double *rate, double *pitch, int *timeout,
+                              int *notify_events, const char **errmsg)
 {
     char    **events, *e;
     int       i;
@@ -638,8 +638,13 @@ static int parse_render_voice(mrp_dbus_msg_t *req, const char **id,
     if (*id == NULL)
         return EINVAL;
 
+    *rate = *pitch = 1;
+
     if (!mrp_dbus_msg_read_basic(req, MRP_DBUS_TYPE_STRING, msg) ||
         !mrp_dbus_msg_read_basic(req, MRP_DBUS_TYPE_STRING, voice) ||
+        (mrp_dbus_msg_arg_type(req, NULL) != MRP_DBUS_TYPE_DOUBLE ||
+         !(mrp_dbus_msg_read_basic(req, MRP_DBUS_TYPE_DOUBLE, &rate) &&
+           mrp_dbus_msg_read_basic(req, MRP_DBUS_TYPE_DOUBLE, &pitch))) ||
         !mrp_dbus_msg_read_basic(req, MRP_DBUS_TYPE_INT32 , &to) ||
         !mrp_dbus_msg_read_array(req, MRP_DBUS_TYPE_STRING,
                                  (void **)&events, &nevent)) {
@@ -681,12 +686,13 @@ static int render_voice_req(mrp_dbus_t *dbus, mrp_dbus_msg_t *req,
     dbusif_t      *bus = (dbusif_t *)user_data;
     srs_context_t *srs = bus->self->srs;
     const char    *id, *msg, *voice, *errmsg;
+    double         rate, pitch;
     int            timeout, events, err;
     uint32_t       reqid;
     srs_client_t  *c;
 
-    err = parse_render_voice(req, &id, &msg, &voice, &timeout, &events,
-                             &errmsg);
+    err = parse_render_voice(req, &id, &msg, &voice, &rate, &pitch, &timeout,
+                             &events, &errmsg);
 
     if (err != 0) {
         reply_error(dbus, req, err, errmsg);
@@ -702,7 +708,7 @@ static int render_voice_req(mrp_dbus_t *dbus, mrp_dbus_msg_t *req,
         return TRUE;
     }
 
-    reqid = client_render_voice(c, msg, voice, timeout, events);
+    reqid = client_render_voice(c, msg, voice, rate, pitch, timeout, events);
 
     if (reqid != SRS_VOICE_INVALID)
         reply_render(dbus, req, reqid);
index 2f39e4a..63d9d5e 100644 (file)
@@ -538,8 +538,8 @@ int srs_request_focus(srs_t *srs, srs_voice_focus_t focus)
 
 
 uint32_t srs_render_voice(srs_t *srs, const char *msg, const char *voice,
-                          int timeout, int events, srs_render_notify_t cb,
-                          void *cb_data)
+                          double rate, double pitch, int timeout, int events,
+                          srs_render_notify_t cb, void *cb_data)
 {
     srs_req_voice_t req;
     request_data_t  data;
@@ -550,6 +550,8 @@ uint32_t srs_render_voice(srs_t *srs, const char *msg, const char *voice,
     req.type    = SRS_REQUEST_RENDERVOICE;
     req.msg     = (char *)msg;
     req.voice   = (char *)voice;
+    req.rate    = rate;
+    req.pitch   = pitch;
     req.timeout = timeout;
     req.events  = events;
 
index 8088969..8a32bc1 100644 (file)
@@ -88,8 +88,8 @@ int srs_request_focus(srs_t *srs, srs_voice_focus_t focus);
 
 /** Request rendering the given message, subscribing for the given events. */
 uint32_t srs_render_voice(srs_t *srs, const char *msg, const char *voice,
-                          int timeout, int events, srs_render_notify_t cb,
-                          void *cb_data);
+                          double rate, double pitch, int timeout,
+                          int events, srs_render_notify_t cb, void *cb_data);
 
 /** Cancel an ongoing voice render request. */
 int srs_cancel_voice(srs_t *srs, uint32_t id);
index c9db5de..060c8e7 100644 (file)
@@ -89,6 +89,8 @@ mrp_typemap_t *register_message_types(void)
                     MRP_UINT32(srs_req_voice_t, reqno   , DEFAULT),
                     MRP_STRING(srs_req_voice_t, msg     , DEFAULT),
                     MRP_STRING(srs_req_voice_t, voice   , DEFAULT),
+                    MRP_DOUBLE(srs_req_voice_t, rate    , DEFAULT),
+                    MRP_DOUBLE(srs_req_voice_t, pitch   , DEFAULT),
                     MRP_UINT32(srs_req_voice_t, timeout , DEFAULT),
                     MRP_UINT32(srs_req_voice_t, events  , DEFAULT));
 
index 159ff8a..2d3056d 100644 (file)
@@ -140,6 +140,8 @@ typedef struct {
     uint32_t  reqno;                     /* request number */
     char     *msg;                       /* message to render */
     char     *voice;                     /* voice to use */
+    double    rate;                      /* voice pitch (0 or 1 = default) */
+    double    pitch;                     /* voice pitch (0 or 1 = default) */
     uint32_t  timeout;                   /* message timeout */
     uint32_t  events;                    /* mask of events to notify about */
 } srs_req_voice_t;
index 2f3d069..b9e0c06 100644 (file)
@@ -188,13 +188,15 @@ static void request_voice(client_t *c, srs_req_voice_t *req)
 {
     const char *msg     = req->msg;
     const char *voice   = req->voice;
+    double      rate    = req->rate;
+    double      pitch   = req->pitch;
     int         timeout = req->timeout;
     int         events  = req->events;
     uint32_t    reqid;
 
     mrp_debug("received voice render request from native client #%d", c->id);
 
-    reqid = client_render_voice(c->c, msg, voice, timeout, events);
+    reqid = client_render_voice(c->c, msg, voice, rate, pitch, timeout, events);
 
     if (reqid != SRS_VOICE_INVALID)
         reply_render(c, req->reqno, reqid);
index b327492..fe82a09 100644 (file)
@@ -753,7 +753,7 @@ static void request_tts(client_t *c, int ntoken, char **tokens)
 
     print(c, "Requesting TTS for message: '%s'.", msg);
 
-    c->vreq = srs_render_voice(c->srs, msg, voice, timeout,
+    c->vreq = srs_render_voice(c->srs, msg, voice, 0, 0, timeout,
                                events ? SRS_VOICE_MASK_ALL:SRS_VOICE_MASK_NONE,
                                render_notify, NULL);
 }
index 1119cf1..2344a8f 100644 (file)
@@ -227,7 +227,7 @@ static void tts_request_cb(GDBusConnection *c, const gchar *sender,
     mrp_log_info("WRT media client: relaying TTS request '%s' in '%s' from %s.",
                  msg, voice, sender);
 
-    id = client_render_voice(wrtc->c, msg, voice, timeout, events);
+    id = client_render_voice(wrtc->c, msg, voice, 0, 0, timeout, events);
 
     g_dbus_method_invocation_return_value(inv, g_variant_new("(u)", id));
 }
index 4970d31..fd2d0fb 100644 (file)
@@ -58,13 +58,17 @@ static void stream_event_cb(festival_t *f, srs_voice_event_t *event,
 
 
 static uint32_t festival_render(const char *msg, char **tags, int actor,
-                                int notify_events, void *api_data)
+                                double rate, double pitch, int notify_events,
+                                void *api_data)
 {
     festival_t *f = (festival_t *)api_data;
     void       *samples;
     uint32_t    nsample, id;
     int         srate, nchannel;
 
+    MRP_UNUSED(rate);
+    MRP_UNUSED(pitch);
+
     if (0 <= actor && actor < f->nactor)
         carnival_select_voice(f->actors[actor].name);
     else