/*-------------------------------------------------------------------- * FLOAT : guess phones for a float */ void number2text_float(t_number2text *x, t_floatarg f) { long l = (long)f; char *b, *e; if ((float)l == (float)f) { // -- do integer conversion xlate_cardinal(l, &x->text); } else { // -- do floating-point conversion sprintf(x->fbuf, "%g", (float)f); xlate_float_string(x->fbuf, &x->text); } // -- output the text phone_append(&x->text, 0); for (b = e = x->text.data; *e; e++) { if (*e == ' ' || !*e) { *e = 0; outlet_symbol(x->txt_out, gensym(b)); e++; b = e; } } if (b != e) outlet_symbol(x->txt_out, gensym(b)); x->text.items = 0; }
/* ** Translate a number to phonemes. This version is for ORDINAL numbers. ** Note: this is recursive. */ static int xlate_ordinal(int value, darray *phone) { int nph = 0; if (value < 0) { nph += xlate_string("minus", phone); value = (-value); if (value < 0) /* Overflow! -32768 */ { nph += xlate_string("a lot", phone); return nph; } } if (value >= 1000000000L) /* Billions */ { nph += xlate_cardinal(value / 1000000000L, phone); value = value % 1000000000; if (value == 0) { nph += xlate_string("billionth", phone); return nph; /* Even billion */ } nph += xlate_string("billion", phone); if (value < 100) nph += xlate_string("and", phone); /* as in THREE BILLION AND FIVE */ } if (value >= 1000000L) /* Millions */ { nph += xlate_cardinal(value / 1000000L, phone); value = value % 1000000L; if (value == 0) { nph += xlate_string("millionth", phone); return nph; /* Even million */ } nph += xlate_string("million", phone); if (value < 100) nph += xlate_string("and", phone); /* as in THREE MILLION AND FIVE */ } /* Thousands 1000..1099 2000..99999 */ /* 1100 to 1999 is eleven-hunderd to ninteen-hunderd */ if ((value >= 1000L && value <= 1099L) || value >= 2000L) { nph += xlate_cardinal(value / 1000L, phone); value = value % 1000L; if (value == 0) { nph += xlate_string("thousandth", phone); return nph; /* Even thousand */ } nph += xlate_string("thousand", phone); if (value < 100) nph += xlate_string("and", phone); /* as in THREE THOUSAND AND FIVE */ } if (value >= 100L) { nph += xlate_string(Cardinals[value / 100], phone); value = value % 100; if (value == 0) { nph += xlate_string("hundredth", phone); return nph; /* Even hundred */ } nph += xlate_string("hundred", phone); } if (value >= 20) { if ((value % 10) == 0) { nph += xlate_string(Ord_twenties[(value - 20) / 10], phone); return nph; /* Even ten */ } nph += xlate_string(Twenties[(value - 20) / 10], phone); value = value % 10; } nph += xlate_string(Ordinals[value], phone); return nph; }
int xlate_string(const char *string, darray *phone) { int nph = 0; const char *s = string; char ch; while (isspace(ch = *s)) s++; while ((ch = *s)) { const char *word = s; if (isalpha(ch)) { while (isalpha(ch = *s) || ((ch == '\'' || ch == '-' || ch == '.') && isalpha(s[1]))) s++; if (!ch || isspace(ch) || ispunct(ch) || (isdigit(ch) && !suspect_word(word, (int)(s - word)))) nph += xlate_word(word, (int)(s - word), phone); else { while ((ch = *s) && !isspace(ch) && !ispunct(ch)) s++; nph += spell_out(word, (int)(s - word), phone); } } else if (isdigit(ch) || (ch == '-' && isdigit(s[1]))) { int sign = (ch == '-') ? -1 : 1; int value = 0; if (sign < 0) ch = *++s; while (isdigit(ch = *s)) { value = value * 10 + ch - '0'; s++; } if (ch == '.' && isdigit(s[1])) { word = ++s; nph += xlate_cardinal(value * sign, phone); nph += xlate_string("point", phone); while (isdigit(ch = *s)) s++; nph += spell_out(word, (int)(s - word), phone); } else { /* check for ordinals, date, time etc. can go in here */ nph += xlate_cardinal(value * sign, phone); } } else if (ch == '[' && strchr(s, ']')) { const char *word = s; while (*s && *s++ != ']') /* nothing */ ; nph += xlate_word(word, (int)(s - word), phone); } else if (ispunct(ch)) { switch (ch) { case '!': case '?': case '.': s++; phone->put(' '); break; case '"': /* change pitch ? */ case ':': case '-': case ';': case ',': case '(': case ')': s++; phone->put(' '); break; case '[': { const char *e = strchr(s, ']'); if (e) { s++; while (s < e) phone->put(*s++); s = e + 1; break; } } default: nph += spell_out(word, 1, phone); s++; break; } } else { while ((ch = *s) && !isspace(ch)) s++; nph += spell_out(word, (int)(s - word), phone); } while (isspace(ch = *s)) s++; } return nph; }