| // control = 1, less shortening at fast speeds | // control = 1, less shortening at fast speeds | ||||
| unsigned int len; | unsigned int len; | ||||
| int srate2; | |||||
| if (length == 0) | if (length == 0) | ||||
| len = 0; | len = 0; | ||||
| if (len < 90000) | if (len < 90000) | ||||
| len = (len * samplerate) / 1000; // convert from mS to number of samples | len = (len * samplerate) / 1000; // convert from mS to number of samples | ||||
| else { | else { | ||||
| srate2 = samplerate / 25; // avoid overflow | |||||
| int srate2 = samplerate / 25; // avoid overflow | |||||
| len = (len * srate2) / 40; | len = (len * srate2) / 40; | ||||
| } | } | ||||
| } | } | ||||
| // RMS just adjust the formant amplitudes by the appropriate ratio | // RMS just adjust the formant amplitudes by the appropriate ratio | ||||
| int x; | int x; | ||||
| int h; | |||||
| int ix; | int ix; | ||||
| static const short sqrt_tab[200] = { | static const short sqrt_tab[200] = { | ||||
| x = sqrt_tab[x]; // sqrt(new_rms/fr->rms)*0x200; | x = sqrt_tab[x]; // sqrt(new_rms/fr->rms)*0x200; | ||||
| for (ix = 0; ix < 8; ix++) { | for (ix = 0; ix < 8; ix++) { | ||||
| int h; | |||||
| h = fr->fheight[ix] * x; | h = fr->fheight[ix] * x; | ||||
| fr->fheight[ix] = h/0x200; | fr->fheight[ix] = h/0x200; | ||||
| } | } | ||||
| static void formants_reduce_hf(frame_t *fr, int level) | static void formants_reduce_hf(frame_t *fr, int level) | ||||
| { | { | ||||
| // change height of peaks 2 to 8, percentage | // change height of peaks 2 to 8, percentage | ||||
| int ix; | |||||
| int x; | |||||
| if (voice->klattv[0]) | if (voice->klattv[0]) | ||||
| return; | return; | ||||
| for (ix = 2; ix < 8; ix++) { | |||||
| for (int ix = 2; ix < 8; ix++) { | |||||
| int x; | |||||
| x = fr->fheight[ix] * level; | x = fr->fheight[ix] * level; | ||||
| fr->fheight[ix] = x/100; | fr->fheight[ix] = x/100; | ||||
| } | } | ||||
| int FormantTransition2(frameref_t *seq, int *n_frames, unsigned int data1, unsigned int data2, PHONEME_TAB *other_ph, int which) | int FormantTransition2(frameref_t *seq, int *n_frames, unsigned int data1, unsigned int data2, PHONEME_TAB *other_ph, int which) | ||||
| { | { | ||||
| int ix; | |||||
| int formant; | |||||
| int next_rms; | |||||
| int len; | int len; | ||||
| int rms; | int rms; | ||||
| int f1; | int f1; | ||||
| seq[0].frflags |= FRFLAG_LEN_MOD2; // reduce length modification | seq[0].frflags |= FRFLAG_LEN_MOD2; // reduce length modification | ||||
| fr->frflags |= FRFLAG_LEN_MOD2; | fr->frflags |= FRFLAG_LEN_MOD2; | ||||
| next_rms = seq[1].frame->rms; | |||||
| int next_rms = seq[1].frame->rms; | |||||
| if (voice->klattv[0]) | if (voice->klattv[0]) | ||||
| fr->klattp[KLATT_AV] = seq[1].frame->klattp[KLATT_AV] - 4; | fr->klattp[KLATT_AV] = seq[1].frame->klattp[KLATT_AV] - 4; | ||||
| set_frame_rms(fr, rms); | set_frame_rms(fr, rms); | ||||
| if ((vcolour > 0) && (vcolour <= N_VCOLOUR)) { | if ((vcolour > 0) && (vcolour <= N_VCOLOUR)) { | ||||
| for (ix = 0; ix < *n_frames; ix++) { | |||||
| for (int ix = 0; ix < *n_frames; ix++) { | |||||
| fr = CopyFrame(seq[ix].frame, 0); | fr = CopyFrame(seq[ix].frame, 0); | ||||
| seq[ix].frame = fr; | seq[ix].frame = fr; | ||||
| for (formant = 1; formant <= 5; formant++) { | |||||
| for (int formant = 1; formant <= 5; formant++) { | |||||
| int x; | int x; | ||||
| x = fr->ffreq[formant] * vcolouring[vcolour-1][formant-1]; | x = fr->ffreq[formant] * vcolouring[vcolour-1][formant-1]; | ||||
| fr->ffreq[formant] = x / 256; | fr->ffreq[formant] = x / 256; | ||||
| int frameix; | int frameix; | ||||
| frame_t *frame1; | frame_t *frame1; | ||||
| frame_t *frame2; | frame_t *frame2; | ||||
| frame_t *fr; | |||||
| int ix; | |||||
| intptr_t *q; | intptr_t *q; | ||||
| int len; | int len; | ||||
| int frame_length; | |||||
| int length_factor; | |||||
| int length_mod; | int length_mod; | ||||
| int length_sum; | int length_sum; | ||||
| int length_min; | int length_min; | ||||
| if (last_frame->frflags & FRFLAG_BREAK_LF) { | if (last_frame->frflags & FRFLAG_BREAK_LF) { | ||||
| // but flag indicates keep HF peaks in last segment | // but flag indicates keep HF peaks in last segment | ||||
| frame_t *fr; | |||||
| fr = CopyFrame(frame1, 1); | fr = CopyFrame(frame1, 1); | ||||
| for (ix = 3; ix < 8; ix++) { | |||||
| for (int ix = 3; ix < 8; ix++) { | |||||
| if (ix < 7) | if (ix < 7) | ||||
| fr->ffreq[ix] = last_frame->ffreq[ix]; | fr->ffreq[ix] = last_frame->ffreq[ix]; | ||||
| fr->fheight[ix] = last_frame->fheight[ix]; | fr->fheight[ix] = last_frame->fheight[ix]; | ||||
| length_sum = 0; | length_sum = 0; | ||||
| for (frameix = 1; frameix < n_frames; frameix++) { | for (frameix = 1; frameix < n_frames; frameix++) { | ||||
| length_factor = length_mod; | |||||
| int length_factor = length_mod; | |||||
| if (frames[frameix-1].frflags & FRFLAG_LEN_MOD) // reduce effect of length mod | if (frames[frameix-1].frflags & FRFLAG_LEN_MOD) // reduce effect of length mod | ||||
| length_factor = (length_mod*(256-speed.lenmod_factor) + 256*speed.lenmod_factor)/256; | length_factor = (length_mod*(256-speed.lenmod_factor) + 256*speed.lenmod_factor)/256; | ||||
| else if (frames[frameix-1].frflags & FRFLAG_LEN_MOD2) // reduce effect of length mod, used for the start of a vowel | else if (frames[frameix-1].frflags & FRFLAG_LEN_MOD2) // reduce effect of length mod, used for the start of a vowel | ||||
| length_factor = (length_mod*(256-speed.lenmod2_factor) + 256*speed.lenmod2_factor)/256; | length_factor = (length_mod*(256-speed.lenmod2_factor) + 256*speed.lenmod2_factor)/256; | ||||
| frame_length = frames[frameix-1].length; | |||||
| int frame_length = frames[frameix-1].length; | |||||
| len = (frame_length * samplerate)/1000; | len = (frame_length * samplerate)/1000; | ||||
| len = (len * length_factor)/256; | len = (len * length_factor)/256; | ||||
| length_sum += len; | length_sum += len; | ||||
| { | { | ||||
| // There were embedded commands in the text at this point | // There were embedded commands in the text at this point | ||||
| unsigned int word; // bit 7=last command for this word, bits 5,6 sign, bits 0-4 command | unsigned int word; // bit 7=last command for this word, bits 5,6 sign, bits 0-4 command | ||||
| unsigned int value; | |||||
| int command; | |||||
| do { | do { | ||||
| unsigned int value; | |||||
| int command; | |||||
| word = embedded_list[*embix]; | word = embedded_list[*embix]; | ||||
| value = word >> 8; | value = word >> 8; | ||||
| command = word & 0x7f; | command = word & 0x7f; | ||||
| static int ix; | static int ix; | ||||
| static int embedded_ix; | static int embedded_ix; | ||||
| static int word_count; | static int word_count; | ||||
| PHONEME_LIST *prev; | |||||
| PHONEME_LIST *next; | |||||
| PHONEME_LIST *next2; | |||||
| PHONEME_LIST *p; | PHONEME_LIST *p; | ||||
| bool released; | bool released; | ||||
| int stress; | int stress; | ||||
| unsigned char *amp_env; | unsigned char *amp_env; | ||||
| PHONEME_TAB *ph; | PHONEME_TAB *ph; | ||||
| int use_ipa = 0; | int use_ipa = 0; | ||||
| bool done_phoneme_marker; | |||||
| int vowelstart_prev; | int vowelstart_prev; | ||||
| char phoneme_name[16]; | char phoneme_name[16]; | ||||
| static int sourceix = 0; | static int sourceix = 0; | ||||
| if (WcmdqFree() <= free_min) | if (WcmdqFree() <= free_min) | ||||
| return 1; // wait | return 1; // wait | ||||
| PHONEME_LIST *prev; | |||||
| PHONEME_LIST *next; | |||||
| PHONEME_LIST *next2; | |||||
| prev = &phoneme_list[ix-1]; | prev = &phoneme_list[ix-1]; | ||||
| next = &phoneme_list[ix+1]; | next = &phoneme_list[ix+1]; | ||||
| next2 = &phoneme_list[ix+2]; | next2 = &phoneme_list[ix+2]; | ||||
| if ((p->prepause > 0) && !(p->ph->phflags & phPREVOICE)) | if ((p->prepause > 0) && !(p->ph->phflags & phPREVOICE)) | ||||
| DoPause(p->prepause, 1); | DoPause(p->prepause, 1); | ||||
| done_phoneme_marker = false; | |||||
| bool done_phoneme_marker = false; | |||||
| if (option_phoneme_events && (p->ph->code != phonEND_WORD)) { | if (option_phoneme_events && (p->ph->code != phonEND_WORD)) { | ||||
| if ((p->type == phVOWEL) && (prev->type == phLIQUID || prev->type == phNASAL)) { | if ((p->type == phVOWEL) && (prev->type == phLIQUID || prev->type == phNASAL)) { | ||||
| // For vowels following a liquid or nasal, do the phoneme event after the vowel-start | // For vowels following a liquid or nasal, do the phoneme event after the vowel-start | ||||
| int clause_tone; | int clause_tone; | ||||
| char *voice_change; | char *voice_change; | ||||
| const char *phon_out; | |||||
| if (control == 2) { | if (control == 2) { | ||||
| // stop speaking | // stop speaking | ||||
| CalcLengths(translator); | CalcLengths(translator); | ||||
| if ((option_phonemes & 0xf) || (phoneme_callback != NULL)) { | if ((option_phonemes & 0xf) || (phoneme_callback != NULL)) { | ||||
| const char *phon_out; | |||||
| phon_out = GetTranslatedPhonemeString(option_phonemes); | phon_out = GetTranslatedPhonemeString(option_phonemes); | ||||
| if (option_phonemes & 0xf) | if (option_phonemes & 0xf) | ||||
| fprintf(f_trans, "%s\n", phon_out); | fprintf(f_trans, "%s\n", phon_out); |