diff --git a/src/emu/sound/tms5110.c b/src/emu/sound/tms5110.c index 0b4e1362be3..2ba0e140a01 100644 --- a/src/emu/sound/tms5110.c +++ b/src/emu/sound/tms5110.c @@ -395,10 +395,12 @@ void tms5110_device::process(INT16 *buffer, unsigned int size) /* loop until the buffer is full or we've stopped speaking */ while ((size > 0) && m_speaking_now) { - /* if it is the appropriate time to update the old energy/pitch idxes, + /* if it is the appropriate time to update the old energy/pitch indices, * i.e. when IP=7, PC=12, T=17, subcycle=2, do so. Since IP=7 PC=12 T=17 * is JUST BEFORE the transition to IP=0 PC=0 T=0 sybcycle=(0 or 1), - * which happens 4 T-cycles later), we change on the latter.*/ + * which happens 4 T-cycles later), we change on the latter. + * The indices are updated here ~12 PCs before the new frame is applied. + */ if ((m_IP == 0) && (m_PC == 0) && (m_subcycle < 2)) { m_OLDE = (m_new_frame_energy_idx == 0); @@ -429,13 +431,32 @@ void tms5110_device::process(INT16 *buffer, unsigned int size) #ifdef DEBUG_GENERATION fprintf(stderr,"tms5110_process: processing frame: talk status = 0 caused by stop frame or buffer empty, halting speech.\n"); #endif - m_speaking_now = 0; // finally halt speech - goto empty; + if (m_speaking_now == 1) // we're done, set all coeffs to idle state but keep going for a bit... + { + m_new_frame_energy_idx = 0; + m_new_frame_pitch_idx = 0; + for (i = 0; i < 4; i++) + m_new_frame_k_idx[i] = 0; + for (i = 4; i < 7; i++) + m_new_frame_k_idx[i] = 0xF; + for (i = 7; i < m_coeff->num_k; i++) + m_new_frame_k_idx[i] = 0x7; + m_speaking_now = 2; // wait 8 extra interp periods before shutting down so we can interpolate everything to zero state + } + else // m_speaking_now == 2 // now we're really done. + { + m_speaking_now = 0; // finally halt speech + goto empty; + } + //m_speaking_now = 0; // finally halt speech + //goto empty; } + - /* Parse a new frame into the new_target_energy, new_target_pitch and new_target_k[] */ - parse_frame(); + /* Parse a new frame into the new_target_energy, new_target_pitch and new_target_k[], + * but only if we're not just about to end speech */ + if (m_speaking_now == 1) parse_frame(); #ifdef DEBUG_PARSE_FRAME_DUMP fprintf(stderr,"\n"); #endif diff --git a/src/emu/sound/tms5220.c b/src/emu/sound/tms5220.c index c948640972a..a78565c6a5b 100644 --- a/src/emu/sound/tms5220.c +++ b/src/emu/sound/tms5220.c @@ -749,10 +749,12 @@ void tms5220_device::process(INT16 *buffer, unsigned int size) /* loop until the buffer is full or we've stopped speaking */ while ((size > 0) && m_speaking_now) { - /* if it is the appropriate time to update the old energy/pitch idxes, + /* if it is the appropriate time to update the old energy/pitch indices, * i.e. when IP=7, PC=12, T=17, subcycle=2, do so. Since IP=7 PC=12 T=17 * is JUST BEFORE the transition to IP=0 PC=0 T=0 sybcycle=(0 or 1), - * which happens 4 T-cycles later), we change on the latter.*/ + * which happens 4 T-cycles later), we change on the latter. + * The indices are updated here ~12 PCs before the new frame is applied. + */ if ((m_IP == 0) && (m_PC == 0) && (m_subcycle < 2)) { m_OLDE = (m_new_frame_energy_idx == 0); @@ -786,13 +788,29 @@ void tms5220_device::process(INT16 *buffer, unsigned int size) #ifdef DEBUG_GENERATION fprintf(stderr,"tms5220_process: processing frame: talk status = 0 caused by stop frame or buffer empty, halting speech.\n"); #endif - m_speaking_now = 0; // finally halt speech - goto empty; + if (m_speaking_now == 1) // we're done, set all coeffs to idle state but keep going for a bit... + { + m_new_frame_energy_idx = 0; + m_new_frame_pitch_idx = 0; + for (i = 0; i < 4; i++) + m_new_frame_k_idx[i] = 0; + for (i = 4; i < 7; i++) + m_new_frame_k_idx[i] = 0xF; + for (i = 7; i < m_coeff->num_k; i++) + m_new_frame_k_idx[i] = 0x7; + m_speaking_now = 2; // wait 8 extra interp periods before shutting down so we can interpolate everything to zero state + } + else // m_speaking_now == 2 // now we're really done. + { + m_speaking_now = 0; // finally halt speech + goto empty; + } } - /* Parse a new frame into the new_target_energy, new_target_pitch and new_target_k[] */ - parse_frame(); + /* Parse a new frame into the new_target_energy, new_target_pitch and new_target_k[], + * but only if we're not just about to end speech */ + if (m_speaking_now == 1) parse_frame(); #ifdef DEBUG_PARSE_FRAME_DUMP fprintf(stderr,"\n"); #endif