static int linear_container_darray_find(LinearContainer* thiz, DataCompareFunc cmp, void* ctx) { PrivInfo* priv = (PrivInfo*)thiz->priv; return darray_find(priv->darray, cmp, ctx); }
void rsynth_phones(rsynth_t * rsynth, char *phone, int len) { darray_t elm; darray_t f0; unsigned frames; darray_init(&elm, sizeof(char), len); darray_init(&f0, sizeof(float), len); if ((frames = phone_to_elm(rsynth, len, phone, &elm, &f0))) { if (rsynth_verbose(rsynth)) fprintf(stderr, "[%.*s]\n", len, phone); rsynth_flush(rsynth, rsynth_interpolate(rsynth, (unsigned char *) darray_find(&elm, 0),elm.items, (float *) darray_find(&f0,0), f0.items)); } darray_free(&f0); darray_free(&elm); }
void rsynth_pho(rsynth_t * rsynth, const char *path, int dodur, char *trans) { int verbose = rsynth_verbose(rsynth); FILE *f = fopen(path, "r"); trie_ptr table; if (!phtoelm) enter_phonemes(); if (trans && *trans && strcmp(trans, "sampa")) table = enter_trans(trans, verbose); else table = phtoelm; if (f) { char buffer[1024]; char *s; darray_t elm; unsigned t = 0; float f0a[1024] = { rsynth->speaker->F0Hz }; unsigned nf0 = 0; /* index of last f0 value */ unsigned f0t = 0; /* time of last f0 value */ darray_init(&elm, sizeof(char), 1024); if (verbose) { fprintf(stderr, "Frame is %.3gms\n", rsynth->samples_frame * 1000.0 / rsynth->sr); } while ((s = fgets(buffer, sizeof(buffer), f))) { /* skip leading space - should not be any but ... */ while (isspace((unsigned) *s)) s++; if (*s && *s != ';') { /* Not a comment */ char *ps = s; char *e = (char *) trie_lookup(&table, &s); if (*s == ':') s++; if (e && isspace((unsigned) *s)) { char *pe = s; unsigned pt = 0; int n = *e++; int i; double ms = strtod(s, &s); float frames = ms * (rsynth->sr / rsynth->samples_frame) / 1000; float edur = 0; float estp = 0; int nstp = 0; float delta = 0; for (i = 0; i < n; i++) { int x = e[i]; Elm_ptr p = &Elements[x]; if (!p->du || p->feat & stp) estp += p->ud; else { edur += p->ud; nstp++; } } /* Stops don't change length */ frames -= estp; delta = frames - edur; #if 0 /* FIXME - revisit the rounding process */ if (verbose) fprintf(stderr, "'%.*s' %gms %d elem %g frames vs %g nat d=%g) %d stops\n", (pe - ps), ps, ms, n, frames, edur, delta, n - nstp); #endif for (i = 0; i < n; i++) { int x = e[i]; Elm_ptr p = &Elements[x]; darray_append(&elm, x); if (!p->du || p->feat & stp) pt += darray_append(&elm, p->ud); else { if (dodur) { float share = (nstp > 1) ? rint(delta * (p->ud - 1) / (edur - nstp)) : delta; #if 0 fprintf(stderr, "%s d=%d vs nstp=%g delta=%g take=%g\n", p->name, p->ud, edur, delta, share); #endif edur -= p->ud; delta -= share; nstp--; pt += darray_append(&elm, (int) (p->ud + share)); } else pt += darray_append(&elm, p->du); } } /* Now have elements entered and duration of phone computed */ if (verbose && dodur) { float got = 1.0 * pt * rsynth->samples_frame / rsynth->sr * 1000; if (fabs(got - ms) > 0.5) { fprintf(stderr, "'%.*s' want=%gms got=%.3g (%+3.0f%%)\n", (pe - ps), ps, ms, got, 100 * (got - ms) / ms); } } while (isspace((unsigned) *s)) s++; while (*s) { float percent = strtod(s, &s); float f0 = strtod(s, &s); unsigned nt = (unsigned) (t + (percent * pt / 100)); if (nt > f0t) { /* time has advanced */ f0a[++nf0] = (nt - f0t); f0a[++nf0] = f0; f0t = nt; } else { /* same time - change target inplace */ f0a[nf0] = f0; } while (isspace((unsigned) *s)) s++; } t += pt; } else { fputs(buffer, stderr); fprintf(stderr, "Unknown phone:%s", ps); } } } fclose(f); if (t) { float f0 = f0a[nf0++]; if (f0t < t) { f0a[nf0++] = t - f0t; f0a[nf0++] = f0; } rsynth_flush(rsynth, rsynth_interpolate(rsynth, (unsigned char *) darray_find(&elm, 0), elm.items, f0a, nf0)); } } else { perror(path); } }