From 4b3fad52663cbff9435e7489feba3503471e9b0c Mon Sep 17 00:00:00 2001 From: bsongis Date: Tue, 3 Jul 2012 18:33:43 +0000 Subject: [PATCH] PCM alaw codec support --- src/board_ersky9x.cpp | 3 ++ src/ersky9x/audio.cpp | 92 ++++++++++++++++++++++++++++--------------- src/ersky9x/audio.h | 3 +- 3 files changed, 64 insertions(+), 34 deletions(-) diff --git a/src/board_ersky9x.cpp b/src/board_ersky9x.cpp index 2f2dc21c4..ebff7e3a0 100644 --- a/src/board_ersky9x.cpp +++ b/src/board_ersky9x.cpp @@ -729,9 +729,12 @@ void board_init() startSound() ; + alawInit(); + eeprom_init(); init_SDcard(); + } #endif diff --git a/src/ersky9x/audio.cpp b/src/ersky9x/audio.cpp index 35a664c17..1643850f0 100644 --- a/src/ersky9x/audio.cpp +++ b/src/ersky9x/audio.cpp @@ -108,6 +108,33 @@ inline bool isAudioFileAvailable(uint8_t i, char * filename) #define isAudioFileAvailable(i, f) false #endif +uint16_t alawTable[256]; + +#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ +#define QUANT_MASK (0xf) /* Quantization field mask. */ +#define SEG_SHIFT (4) /* Left shift for segment number. */ +#define SEG_MASK (0x70) /* Segment field mask. */ + +static short alaw2linear(unsigned char a_val) +{ + int t; + int seg; + + a_val ^= 0x55; + + t = a_val & QUANT_MASK; + seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT; + if(seg) t= (t + t + 1 + 32) << (seg + 2); + else t= (t + t + 1 ) << 3; + + return (a_val & SIGN_BIT) ? t : -t; +} + +void alawInit() +{ + for (uint32_t i=0; i<256; i++) + alawTable[i] = (0x8000 + alaw2linear(i)) >> 4; +} uint8_t audioState = 0; @@ -151,6 +178,10 @@ extern uint16_t Sine_values[]; #define WAV_HEADER_SIZE 44 +#define CODEC_ID_PCM_S16LE 1 +#define CODEC_ID_PCM_ALAW 6 +uint8_t pcmCodec; + void audioTask(void* pdata) { #if defined(SDCARD) && !defined(SIMU) @@ -175,7 +206,11 @@ void audioTask(void* pdata) CoSetFlag(audioFlag); bufdata = wavSamplesArray; wavSamplesBuffer = wavSamplesArray + WAV_BUFFER_SIZE; + pcmCodec = wavSamplesArray[10]; setFrequency(wavSamplesArray[12]); + if (pcmCodec != CODEC_ID_PCM_S16LE) { + result = f_read(&wavFile, (uint8_t *)wavSamplesArray, 12, &read); + } } else { result = FR_DENIED; @@ -184,34 +219,41 @@ void audioTask(void* pdata) } read = 0; - if (result != FR_OK || f_read(&wavFile, (uint8_t *)bufdata, 2*WAV_BUFFER_SIZE, &read) != FR_OK || read != 2*WAV_BUFFER_SIZE) { - for (uint32_t i=read/2; iDACC_TNCR = read/4; toneStop(); - volumeInit(0); toneWavFile[0] = '\0'; toneWavFile[1] = 0; f_close(&wavFile); audioState = 0; } -#if 1 - { + + if (pcmCodec == CODEC_ID_PCM_S16LE) { read /= 2; - for (uint32_t i=0; i> 4; - if (toneWavFile[1]) { - toneWavFile[1] = '\0'; - register Dacc *dacptr = DACC; - dacptr->DACC_TPR = CONVERT_PTR(wavSamplesArray); - dacptr->DACC_TNPR = CONVERT_PTR(wavSamplesBuffer); - dacptr->DACC_TCR = WAV_BUFFER_SIZE/2; - dacptr->DACC_TNCR = WAV_BUFFER_SIZE/2; - volumeInit(1); - toneStart(); - } + for (; i=0; i--) + bufdata[i] = alawTable[((uint8_t *)bufdata)[i]]; + for (i=read; iDACC_TPR = CONVERT_PTR(wavSamplesArray); + dacptr->DACC_TNPR = CONVERT_PTR(wavSamplesBuffer); + dacptr->DACC_TCR = WAV_BUFFER_SIZE/2; + dacptr->DACC_TNCR = WAV_BUFFER_SIZE/2; + toneStart(); } -#endif } else #endif @@ -227,7 +269,6 @@ void audioTask(void* pdata) CoSetTmrCnt(audioTimer, toneTimeLeft*5, 0); toneTimeLeft = 0; } - volumeInit(0); toneStart(); CoStartTmr(audioTimer); } @@ -251,7 +292,6 @@ void audioTask(void* pdata) CoSetTmrCnt(audioTimer, tone2TimeLeft*5, 0); tone2TimeLeft = 0; setFrequency(tone2Freq * 6100 / 2); - volumeInit(0); toneStart(); CoStartTmr(audioTimer); } @@ -325,18 +365,6 @@ void play(uint8_t tFreq, uint8_t tLen, uint8_t tPause, } } - -void volumeInit(uint8_t boost){ - if(boost == 0){ - setVolume(g_eeGeneral.speakerVolume); //then raise it - } else { - setVolume(g_eeGeneral.speakerVolume + 10); - /* raise it by factor of 5 higher so wav and beep similar volume! - this value of 10 could potentially be a secondary menu config option in - system setup as may be different per user? */ - } -} - void playFile(const char *filename) { strcpy(toneWavFile, filename); diff --git a/src/ersky9x/audio.h b/src/ersky9x/audio.h index 59daa12b5..886314d3f 100644 --- a/src/ersky9x/audio.h +++ b/src/ersky9x/audio.h @@ -64,13 +64,12 @@ extern uint8_t queueToneLength[AUDIO_QUEUE_LENGTH]; extern uint8_t queueTonePause[AUDIO_QUEUE_LENGTH]; extern uint8_t queueToneRepeat[AUDIO_QUEUE_LENGTH]; -void initAudio(); +void alawInit(); extern "C" void retrieveAvailableAudioFiles(); void play(uint8_t tFreq, uint8_t tLen, uint8_t tPause, uint8_t tFlags=0, int8_t tFreqIncr=0); void playFile(const char *filename); void pause(uint8_t tLen); -void volumeInit(uint8_t boost); inline bool audioBusy() {