Exemplo n.º 1
0
/// Append Holmes-elements for phones in (phonestr) to (eltq).
/// Returns ps->t.
unsigned phone_to_elm(phtoelm_state_t *ps, char *phonestr, dsqueue_t *eltq) {

#ifdef PHOLMES_DEBUG
  post("phone_to_elm(): called with phonestr='%s'", phonestr);
#endif

  ps->s = phonestr;
  while (ps->s && *ps->s) {
    pte_eltseq_str es = trie_lookup(&phtoelm, &(ps->s));
    if (es) {
     int n = *es++;
     while (n-- > 0) {
       int eid = *es++;             // -- index of sequence-element in Elements[]
       holmes_qelt_t he;            // -- encoded Holmes-triple for output-queue
       Elm_ptr ep = &Elements[eid]; // -- pointer to actual current element
       int dur;                     // -- placeholder for element duration

       //
       // This works because only vowels have ud != du,
       //  and we set stress just before a vowel
       //
       if (!(ep->feat & vwl)) ps->stress = 0;
       dur = StressDur(ep,ps->stress);
       he = hqeNew(eid,dur,ps->stress);

       // append the encoded element to the output queue
       dsqueue_append(eltq, (void *)he);

#ifdef PHOLMES_DEBUG
       post("phone_to_elm(): enqueued Holmes-triple %s,%d,%d", ep->name,dur,ps->stress);
#endif
     }
    }
    else {
     char ch = *(ps->s++);
     switch (ch) {
     case '\'':                // Primary stress
       ps->stress = 3;
       break;
     case ',':                 // Secondary stress
       ps->stress = 2;
       break;
     case '+':                 // Tertiary stress
       ps->stress = 1;
       break;
     case '-':                 // hyphen in input
       break;
     case '.':                 // literal dot indicates end-of-utterance
       dsqueue_append(eltq, (void *)hqeNew(0,0,0));
       break;
     default:
       {
	 fprintf(stderr,
		 "phone_to_elm(): ignoring unknown character '%c'\n",
		 ch);
	 break;
       }
     }
    }
  }
  return ps->t;
}
Exemplo n.º 2
0
static unsigned
phone_to_elm(rsynth_t * rsynth, int n, char *phone, darray_ptr elm,
	     darray_ptr f0)
{
    float F0Hz = rsynth->speaker->F0Hz;
    float speed = rsynth->speed;
    int stress = 0;
    int seen_vowel = 0;
    int islong = 0;
    char *s = phone;
    unsigned t = 0;
    unsigned f0t = 0;
    char *limit = s + n;
    float f = darray_float(f0, F0Hz * 1.1F);
    if (!phtoelm)
	enter_phonemes();
    while (s < limit && *s) {
	char *e = (char *) trie_lookup(&phtoelm, &s);
	if (e) {
	    int n = *e++;
	    while (n-- > 0) {
		int x = *e++;
		Elm_ptr p = &Elements[x];
		darray_append(elm, x);
		/* StressDur works because only vowels have ud != du,
		   and we set stress just before a vowel
		 */
		t += darray_append(elm,
				   (int) (StressDur(p, stress, islong)));
		if (p->feat & vwl) {
		    seen_vowel = 1;
		}
		else if (seen_vowel) {
		    stress = 0;
		}
	    }
	}
	else {
	    char ch = *s++;
	    switch (ch) {
	    case '\'':		/* Primary stress */
		stress++;
	    case ',':		/* Secondary stress */
		stress++;
	    case '+':		/* Tertiary stress */
		stress++;
		if (stress > 3)
		    stress = 3;
		seen_vowel = 0;
		/* f0 has been declining since f0t */
		f = decline_f0(F0Hz, f0, f, t - f0t);
		f0t = t;
		/* Now stress pulse pushes f0 up "instantly" */
		darray_float(f0, 0);
		darray_float(f0, f + F0Hz * stress * 0.02);
		break;
	    case '-':		/* hyphen in input */
		break;
	    case ':':		/* Length mark */
		islong = 1;
		break;
	    default:
		fprintf(stderr, "Ignoring %c in '%.*s'\n", ch, n, phone);
		break;
	    }
	}
    }
    /* Add final decline to f0 contour */
    decline_f0(F0Hz, f0, f, t - f0t);
    return t;
}