CURRENT ISSUE
Contests
Feature Article
|
|
Issue #207 October 2007
Embedded Speech
Speech Synthesis for Small Applications
by Nicusor Birsan & Ionut Tarsa
Start | Embedding Speech | Speech Synthesis Techniques | Open-Source Project | System Building Blocks | Sound From Luminary Micro | First Big Porting Problem | Synthesizer | Translator | The LM3S811 Speaks | More Speech Applications | Sources & PDF
Listing 1—While playback is done from one half of the buffer, the other half is filled with data.
//internal driver buffer
#define MAXIM_BUF 1024
unsigned char* MCU_out_ptr;
unsigned char* MCU_out_end;
unsigned char MCU_outbuf[MAXIM_BUF];
//=================================================================
// Sound Handler
// Output samples to PWM1
// if max_ix is reached the generation is stoped
//=================================================================
void IntSoundHdl(void) {
unsigned short m_ind = snd_ix;
//use a register as apointer to SFRs
unsigned long* p_gen = (unsigned long*) TIMER0_BASE;
p_gen[((TIMER_O_ICR)/4)] = TIMER_TIMA_TIMEOUT;
if(m_ind != max_ix){
unsigned long c = MCU_outbuf[m_ind++]+5;
snd_ix = m_ind & (MAXIM_BUF -1);
p_gen = (unsigned long*) (PWM_BASE + PWM_GEN_1);
p_gen[((PWM_O_X_CMPA)/4)] = c;
p_gen[((PWM_O_X_CMPB)/4)] = c;
}else{
//stop generation (disable timer interrupt)
HWREG(NVIC_DIS0) = 1 << (INT_TIMER0A - INT_GPIOA);
sound_stopped = 1;
}
}
void task_sound_driver(void){
static unsigned short prev_ix=0;
unsigned short curr_ix = snd_ix & (MAXIM_BUF/2);
if( (curr_ix != prev_ix) ){
// driver is playing, fill next half buffer only
MCU_out_ptr = MCU_outbuf + prev_ix;
MCU_out_end = MCU_out_ptr + (MAXIM_BUF/2-1);
filled = MCU_WavegenFill(0);
}
}
|