Browse Source

Pass syllable_tab by parameter instead of a static global to avoid setting a stack value to a global [clang scan-build].

master
Reece H. Dunn 9 years ago
parent
commit
902d610a70
1 changed files with 28 additions and 32 deletions
  1. 28
    32
      src/libespeak-ng/intonation.c

+ 28
- 32
src/libespeak-ng/intonation.c View File

unsigned char pitch2; unsigned char pitch2;
} SYLLABLE; } SYLLABLE;


static SYLLABLE *syllable_tab;

static int tone_pitch_env; // used to return pitch envelope static int tone_pitch_env; // used to return pitch envelope


/* Pitch data for tone types */ /* Pitch data for tone types */
static int tone_posn2; static int tone_posn2;
static int no_tonic; static int no_tonic;


static void count_pitch_vowels(int start, int end, int clause_end)
static void count_pitch_vowels(SYLLABLE *syllable_tab, int start, int end, int clause_end)
{ {
int ix; int ix;
int stress; int stress;
} }


// Count number of primary stresses up to tonic syllable or body_reset // Count number of primary stresses up to tonic syllable or body_reset
static int count_increments(int ix, int end_ix, int min_stress)
static int count_increments(SYLLABLE *syllable_tab, int ix, int end_ix, int min_stress)
{ {
int count = 0; int count = 0;
int stress; int stress;
syl->flags |= flags; syl->flags |= flags;
} }


static int CountUnstressed(int start, int end, int limit)
static int CountUnstressed(SYLLABLE *syllable_tab, int start, int end, int limit)
{ {
int ix; int ix;


return ix - start; return ix - start;
} }


static int SetHeadIntonation(TUNE *tune, int syl_ix, int end_ix)
static int SetHeadIntonation(SYLLABLE *syllable_tab, TUNE *tune, int syl_ix, int end_ix)
{ {
int stress; int stress;
SYLLABLE *syl; SYLLABLE *syl;
overflow_ix = 0; overflow_ix = 0;


if (tune->onset == 255) { if (tune->onset == 255) {
n_steps = count_increments(syl_ix, head_final, 4);
n_steps = count_increments(syllable_tab, syl_ix, head_final, 4);
pitch = tune->head_start << 8; pitch = tune->head_start << 8;
} else { } else {
// a pitch has been specified for the onset syllable, don't include it in the pitch incrementing // a pitch has been specified for the onset syllable, don't include it in the pitch incrementing
n_steps = count_increments(syl_ix+1, head_final, 4);
n_steps = count_increments(syllable_tab, syl_ix+1, head_final, 4);
pitch = tune->onset << 8; pitch = tune->onset << 8;
used_onset = 1; used_onset = 1;
} }
} }


if (stress >= PRIMARY) { if (stress >= PRIMARY) {
n_unstressed = CountUnstressed(syl_ix+1, end_ix, secondary);
n_unstressed = CountUnstressed(syllable_tab, syl_ix+1, end_ix, secondary);
unstressed_ix = 0; unstressed_ix = 0;
syl->stress = PRIMARY_STRESSED; syl->stress = PRIMARY_STRESSED;
syl->env = tune->stressed_env; syl->env = tune->stressed_env;
set_pitch(syl, (pitch >> 8), tune->stressed_drop); set_pitch(syl, (pitch >> 8), tune->stressed_drop);
} else if (stress >= secondary) { } else if (stress >= secondary) {
n_unstressed = CountUnstressed(syl_ix+1, end_ix, secondary);
n_unstressed = CountUnstressed(syllable_tab, syl_ix+1, end_ix, secondary);
unstressed_ix = 0; unstressed_ix = 0;
set_pitch(syl, (pitch >> 8), drops[stress]); set_pitch(syl, (pitch >> 8), drops[stress]);
} else { } else {
/* Calculate pitches until next RESET or tonic syllable, or end. /* Calculate pitches until next RESET or tonic syllable, or end.
Increment pitch if stress is >= min_stress. Increment pitch if stress is >= min_stress.
Used for tonic segment */ Used for tonic segment */
static int calc_pitch_segment(int ix, int end_ix, TONE_HEAD *th, TONE_NUCLEUS *tn, int min_stress, int continuing)
static int calc_pitch_segment(SYLLABLE *syllable_tab, int ix, int end_ix, TONE_HEAD *th, TONE_NUCLEUS *tn, int min_stress, int continuing)
{ {
int stress; int stress;
int pitch = 0; int pitch = 0;
if ((initial) || (stress == 5)) { if ((initial) || (stress == 5)) {
initial = 0; initial = 0;
overflow = 0; overflow = 0;
n_steps = n_primary = count_increments(ix, end_ix, min_stress);
n_steps = n_primary = count_increments(syllable_tab, ix, end_ix, min_stress);


if (n_steps > th->body_max_steps) if (n_steps > th->body_max_steps)
n_steps = th->body_max_steps; n_steps = th->body_max_steps;
return ix; return ix;
} }


static void SetPitchGradient(int start_ix, int end_ix, int start_pitch, int end_pitch)
static void SetPitchGradient(SYLLABLE *syllable_tab, int start_ix, int end_ix, int start_pitch, int end_pitch)
{ {
// Set a linear pitch change over a number of syllables. // Set a linear pitch change over a number of syllables.
// Used for pre-head, unstressed syllables in the body, and the tail // Used for pre-head, unstressed syllables in the body, and the tail
} }


// Calculate pitch values for the vowels in this tone group // Calculate pitch values for the vowels in this tone group
static int calc_pitches2(int start, int end, int tune_number)
static int calc_pitches2(SYLLABLE *syllable_tab, int start, int end, int tune_number)
{ {
int ix; int ix;
TUNE *tune; TUNE *tune;


// vowels before the first primary stress // vowels before the first primary stress


SetPitchGradient(ix, ix+number_pre, tune->prehead_start, tune->prehead_end);
SetPitchGradient(syllable_tab, ix, ix+number_pre, tune->prehead_start, tune->prehead_end);
ix += number_pre; ix += number_pre;


// body of tonic segment // body of tonic segment


if (option_tone_flags & OPTION_EMPHASIZE_PENULTIMATE) if (option_tone_flags & OPTION_EMPHASIZE_PENULTIMATE)
tone_posn = tone_posn2; // put tone on the penultimate stressed word tone_posn = tone_posn2; // put tone on the penultimate stressed word
ix = SetHeadIntonation(tune, ix, tone_posn);
ix = SetHeadIntonation(syllable_tab, tune, ix, tone_posn);


if (no_tonic) if (no_tonic)
return 0; return 0;


// tail, after the tonic syllable // tail, after the tonic syllable


SetPitchGradient(ix, end, tune->tail_start, tune->tail_end);
SetPitchGradient(syllable_tab, ix, end, tune->tail_start, tune->tail_end);


return tone_pitch_env; return tone_pitch_env;
} }


// Calculate pitch values for the vowels in this tone group // Calculate pitch values for the vowels in this tone group
static int calc_pitches(int control, int start, int end, int tune_number)
static int calc_pitches(SYLLABLE *syllable_tab, int control, int start, int end, int tune_number)
{ {
int ix; int ix;
TONE_HEAD *th; TONE_HEAD *th;
int continuing = 0; int continuing = 0;


if (control == 0) if (control == 0)
return calc_pitches2(start, end, tune_number);
return calc_pitches2(syllable_tab, start, end, tune_number);


if (start > 0) if (start > 0)
continuing = 1; continuing = 1;


// vowels before the first primary stress // vowels before the first primary stress


SetPitchGradient(ix, ix+number_pre, th->pre_start, th->pre_end);
SetPitchGradient(syllable_tab, ix, ix+number_pre, th->pre_start, th->pre_end);
ix += number_pre; ix += number_pre;


// body of tonic segment // body of tonic segment


if (option_tone_flags & OPTION_EMPHASIZE_PENULTIMATE) if (option_tone_flags & OPTION_EMPHASIZE_PENULTIMATE)
tone_posn = tone_posn2; // put tone on the penultimate stressed word tone_posn = tone_posn2; // put tone on the penultimate stressed word
ix = calc_pitch_segment(ix, tone_posn, th, tn, PRIMARY, continuing);
ix = calc_pitch_segment(syllable_tab, ix, tone_posn, th, tn, PRIMARY, continuing);


if (no_tonic) if (no_tonic)
return 0; return 0;


// tail, after the tonic syllable // tail, after the tonic syllable


SetPitchGradient(ix, end, tn->tail_start, tn->tail_end);
SetPitchGradient(syllable_tab, ix, end, tn->tail_start, tn->tail_end);


return tone_pitch_env; return tone_pitch_env;
} }
PHONEME_TAB *ph; PHONEME_TAB *ph;
int ph_end = n_phoneme_list; int ph_end = n_phoneme_list;


SYLLABLE syllable_tab2[N_PHONEME_LIST];

syllable_tab = syllable_tab2; // don't use permanent storage. it's only needed during the call of CalcPitches()
SYLLABLE syllable_tab[N_PHONEME_LIST];
n_st = 0; n_st = 0;
n_primary = 0; n_primary = 0;
for (ix = 0; ix < (n_phoneme_list-1); ix++) { for (ix = 0; ix < (n_phoneme_list-1); ix++) {
} }
} }


count_pitch_vowels(st_start, ix, n_st);
count_pitch_vowels(syllable_tab, st_start, ix, n_st);
if ((ix < n_st) || (clause_type == 0)) { if ((ix < n_st) || (clause_type == 0)) {
calc_pitches(option, st_start, ix, group_tone); // split into > 1 tone groups
calc_pitches(syllable_tab, option, st_start, ix, group_tone); // split into > 1 tone groups


if ((clause_type == 1) || (clause_type == 2)) if ((clause_type == 1) || (clause_type == 2))
group_tone = tr->langopts.tunes[1]; // , or ? remainder has comma-tone group_tone = tr->langopts.tunes[1]; // , or ? remainder has comma-tone
else else
group_tone = tr->langopts.tunes[0]; // . or ! remainder has statement tone group_tone = tr->langopts.tunes[0]; // . or ! remainder has statement tone
} else } else
calc_pitches(option, st_start, ix, group_tone);
calc_pitches(syllable_tab, option, st_start, ix, group_tone);


st_start = ix; st_start = ix;
} }
if ((st_start < st_ix) && (syl->flags & SYL_END_CLAUSE)) { if ((st_start < st_ix) && (syl->flags & SYL_END_CLAUSE)) {
// end of clause after this syllable, indicated by a phonPAUSE_CLAUSE phoneme // end of clause after this syllable, indicated by a phonPAUSE_CLAUSE phoneme
st_clause_end = st_ix+1; st_clause_end = st_ix+1;
count_pitch_vowels(st_start, st_clause_end, st_clause_end);
calc_pitches(option, st_start, st_clause_end, group_tone_comma);
count_pitch_vowels(syllable_tab, st_start, st_clause_end, st_clause_end);
calc_pitches(syllable_tab, option, st_start, st_clause_end, group_tone_comma);
st_start = st_clause_end; st_start = st_clause_end;
} }
} }


if (st_start < st_ix) { if (st_start < st_ix) {
count_pitch_vowels(st_start, st_ix, n_st);
calc_pitches(option, st_start, st_ix, group_tone);
count_pitch_vowels(syllable_tab, st_start, st_ix, n_st);
calc_pitches(syllable_tab, option, st_start, st_ix, group_tone);
} }


// unpack pitch data // unpack pitch data

Loading…
Cancel
Save