voice: allow rendering actor to be specified as by 'renderer/name'.
authorKrisztian Litkey <kli@iki.fi>
Fri, 18 Apr 2014 20:52:58 +0000 (23:52 +0300)
committerKrisztian Litkey <kli@iki.fi>
Fri, 18 Apr 2014 20:52:58 +0000 (23:52 +0300)
We'll need a better approach for selecting actors than a brute
force linear search. Some renderers (eg. the soon to be committed
espeak-based one) provide a huge number of voices. A linear search
over such a number for every render request is not a good idea...

src/daemon/voice.c

index 5622500..58a9589 100644 (file)
@@ -283,6 +283,27 @@ static void unregister_actors(renderer_t *r)
 }
 
 
+static actor_t *find_actor(state_t *state, const char *r, const char *v)
+{
+    mrp_list_hook_t *lp, *ln, *ap, *an;
+    language_t      *l;
+    actor_t         *a;
+
+    mrp_list_foreach(&state->languages, lp, ln) {
+        l = mrp_list_entry(lp, typeof(*l), hook);
+
+        mrp_list_foreach(&l->actors, ap, an) {
+            a = mrp_list_entry(ap, typeof(*a), hook);
+
+            if (!strcmp(a->r->name, r) && !strcmp(a->voice, v))
+                return a;
+        }
+    }
+
+    return NULL;
+}
+
+
 static void free_renderer(renderer_t *r)
 {
     if (r != NULL) {
@@ -432,7 +453,7 @@ static renderer_t *find_renderer(state_t *state, const char *voice,
     language_t      *l;
     actor_t         *a, *fallback;
     mrp_list_hook_t *ap, *an;
-    char             lang[128], *e;
+    char             lang[128], renderer[128], *e;
     int              n;
 
     if (state == NULL) {
@@ -441,6 +462,23 @@ static renderer_t *find_renderer(state_t *state, const char *voice,
         return NULL;
     }
 
+    if ((e = strchr(voice, '/')) != NULL) {
+        n = e - voice;
+
+        if (n >= sizeof(renderer) - 1)
+            return NULL;
+
+        strncpy(renderer, voice, n);
+        renderer[n] = '\0';
+
+        if ((a = find_actor(state, renderer, e + 1)) != NULL) {
+            *actor = a->id;
+            return a->r;
+        }
+        else
+            return NULL;
+    }
+
     if ((e = strchr(voice, '-')) == NULL)
         l = find_language(state, voice, FALSE);
     else {