diff --git a/src/FatFs/ffconf.h b/src/FatFs/ffconf.h index 2e13e3420..643b8b980 100644 --- a/src/FatFs/ffconf.h +++ b/src/FatFs/ffconf.h @@ -14,7 +14,7 @@ / Functions and Buffer Configurations /----------------------------------------------------------------------------*/ -#define _FS_TINY 1 /* 0:Normal or 1:Tiny */ +#define _FS_TINY 0 /* 0:Normal or 1:Tiny */ /* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system / object instead of the sector buffer in the individual file object for file / data transfer. This reduces memory consumption 512 bytes each file object. */ diff --git a/src/ersky9x/audio.cpp b/src/ersky9x/audio.cpp index cb6279bd8..5f1e6499f 100644 --- a/src/ersky9x/audio.cpp +++ b/src/ersky9x/audio.cpp @@ -136,36 +136,11 @@ void alawInit() alawTable[i] = (0x8000 + alaw2linear(i)) >> 4; } -uint8_t audioState = 0; +AudioQueue audioQueue; -uint8_t t_queueRidx; -uint8_t t_queueWidx; - -uint8_t toneFreq; -int8_t toneFreqIncr; -uint8_t toneTimeLeft; -uint8_t tonePause; - -uint8_t tone2Freq; -uint8_t tone2TimeLeft; -uint8_t tone2Pause; - -char toneWavFile[32+1] = ""; - -// queue arrays -uint8_t queueToneFreq[AUDIO_QUEUE_LENGTH]; -int8_t queueToneFreqIncr[AUDIO_QUEUE_LENGTH]; -uint8_t queueToneLength[AUDIO_QUEUE_LENGTH]; -uint8_t queueTonePause[AUDIO_QUEUE_LENGTH]; -uint8_t queueToneRepeat[AUDIO_QUEUE_LENGTH]; - -void audioInit() +AudioQueue::AudioQueue() { - toneTimeLeft = 0; - tonePause = 0; - - t_queueRidx = 0; - t_queueWidx = 0; + memset(this, 0, sizeof(AudioQueue)); } void audioTimerHandle(void) @@ -183,122 +158,129 @@ extern uint16_t Sine_values[]; uint8_t pcmCodec; void audioTask(void* pdata) +{ + while (1) { + + CoWaitForSingleFlag(audioFlag, 0); + + audioQueue.wakeup(); + + } +} + +void AudioQueue::wakeup() { #if defined(SDCARD) && !defined(SIMU) static FIL wavFile; #endif - while (1) { - CoWaitForSingleFlag(audioFlag, 0); - - audioState = 1; // TODO #define - #if defined(SDCARD) && !defined(SIMU) - if (toneWavFile[0]) { - FRESULT result = FR_OK; - UINT read = 0; - uint16_t * bufdata = wavSamplesBuffer; - if (toneWavFile[1]) { - result = f_open(&wavFile, toneWavFile, FA_OPEN_EXISTING | FA_READ); - if (result == FR_OK) { - result = f_read(&wavFile, (uint8_t *)wavSamplesArray, WAV_HEADER_SIZE, &read); - if (result == FR_OK && read == WAV_HEADER_SIZE && !memcmp(wavSamplesArray, "RIFF", 4)) { - 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; + if (current.file[0]) { + FRESULT result = FR_OK; + UINT read = 0; + uint16_t * bufdata = wavSamplesBuffer; + if (current.file[1]) { + result = f_open(&wavFile, current.file, FA_OPEN_EXISTING | FA_READ); + if (result == FR_OK) { + result = f_read(&wavFile, (uint8_t *)wavSamplesArray, WAV_HEADER_SIZE, &read); + if (result == FR_OK && read == WAV_HEADER_SIZE && !memcmp(wavSamplesArray, "RIFF", 4)) { + 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); } } - } - - read = 0; - uint16_t bufsize = (pcmCodec == CODEC_ID_PCM_S16LE ? 2*WAV_BUFFER_SIZE : WAV_BUFFER_SIZE); - if (result != FR_OK || f_read(&wavFile, (uint8_t *)bufdata, bufsize, &read) != FR_OK || read != bufsize) { - DACC->DACC_TNCR = read/4; - toneStop(); - toneWavFile[0] = '\0'; - toneWavFile[1] = '\0'; - f_close(&wavFile); - audioState = 0; - } - - if (pcmCodec == CODEC_ID_PCM_S16LE) { - read /= 2; - uint32_t i = 0; - for (; i> 4; - 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(); + else { + result = FR_DENIED; + } } } - else -#endif - if (toneTimeLeft > 0) { - // TODO function for that ... - setFrequency(toneFreq * 6100 / 2); - if (toneFreqIncr) { - CoSetTmrCnt(audioTimer, 5/*10ms*/, 0); - toneFreq += toneFreqIncr; - toneTimeLeft--; + + read = 0; + uint16_t bufsize = (pcmCodec == CODEC_ID_PCM_S16LE ? 2*WAV_BUFFER_SIZE : WAV_BUFFER_SIZE); + if (result != FR_OK || f_read(&wavFile, (uint8_t *)bufdata, bufsize, &read) != FR_OK || read != bufsize) { + current.file[0] = 0; + current.file[1] = 0; + if (pcmCodec == CODEC_ID_PCM_S16LE) { + DACC->DACC_TNCR = read/4; } else { - CoSetTmrCnt(audioTimer, toneTimeLeft*5, 0); - toneTimeLeft = 0; + DACC->DACC_TNCR = read/2; } - toneStart(); - CoStartTmr(audioTimer); - } - else if (tonePause > 0) { - CoSetTmrCnt(audioTimer, tonePause*5, 0); - tonePause = 0; toneStop(); - CoStartTmr(audioTimer); - } - else if (t_queueRidx != t_queueWidx) { - toneFreq = queueToneFreq[t_queueRidx]; - toneTimeLeft = queueToneLength[t_queueRidx]; - toneFreqIncr = queueToneFreqIncr[t_queueRidx]; - tonePause = queueTonePause[t_queueRidx]; - if (!queueToneRepeat[t_queueRidx]--) { - t_queueRidx = (t_queueRidx + 1) % AUDIO_QUEUE_LENGTH; - } + f_close(&wavFile); CoSetFlag(audioFlag); } - else if (tone2TimeLeft > 0) { - CoSetTmrCnt(audioTimer, tone2TimeLeft*5, 0); - tone2TimeLeft = 0; - setFrequency(tone2Freq * 6100 / 2); + + if (pcmCodec == CODEC_ID_PCM_S16LE) { + read /= 2; + uint32_t i = 0; + for (; i> 4; + 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(); - CoStartTmr(audioTimer); + } + } + else +#endif + if (current.duration > 0) { + // TODO function for that ... + setFrequency(current.freq * 6100 / 2); + if (current.freqIncr) { + CoSetTmrCnt(audioTimer, 5/*10ms*/, 0); + current.freq += current.freqIncr; + current.duration--; } else { - audioState = 0; - toneStop(); + CoSetTmrCnt(audioTimer, current.duration*5, 0); + current.duration = 0; } + toneStart(); + CoStartTmr(audioTimer); + } + else if (current.pause > 0) { + CoSetTmrCnt(audioTimer, current.pause*5, 0); + current.pause = 0; + toneStop(); + CoStartTmr(audioTimer); + } + else if (ridx != widx) { + memcpy(¤t, &fragments[ridx], sizeof(current)); + if (!fragments[ridx].repeat--) { + ridx = (ridx + 1) % AUDIO_QUEUE_LENGTH; + } + CoSetFlag(audioFlag); + } + else if (background.duration > 0) { + CoSetTmrCnt(audioTimer, background.duration*5, 0); + background.duration = 0; + setFrequency(background.freq * 6100 / 2); + toneStart(); + CoStartTmr(audioTimer); + } + else { + state = 0; + toneStop(); } } @@ -314,24 +296,23 @@ inline uint8_t getToneLength(uint8_t tLen) return result; } -void pause(uint8_t tLen) +void AudioQueue::pause(uint8_t tLen) { play(0, 0, tLen); // a pause } extern OS_MutexID audioMutex; -void play(uint8_t tFreq, uint8_t tLen, uint8_t tPause, - uint8_t tFlags, int8_t tFreqIncr) +void AudioQueue::play(uint8_t tFreq, uint8_t tLen, uint8_t tPause, uint8_t tFlags, int8_t tFreqIncr) { CoEnterMutexSection(audioMutex); if (tFlags & PLAY_SOUND_VARIO) { - tone2Freq = tFreq; - tone2TimeLeft = tLen; - tone2Pause = tPause; - if (audioState == 0) { - audioState = 1; + background.freq = tFreq; + background.duration = tLen; + background.pause = tPause; + if (state == 0) { + state = 1; CoSetFlag(audioFlag); } } @@ -340,14 +321,14 @@ void play(uint8_t tFreq, uint8_t tLen, uint8_t tPause, tFreq += g_eeGeneral.speakerPitch + BEEP_OFFSET; // add pitch compensator } tLen = getToneLength(tLen); - if ((tFlags & PLAY_NOW) || !audioBusy()) { - toneWavFile[0] = '\0'; - toneFreq = tFreq; - toneTimeLeft = tLen; - tonePause = tPause; - toneFreqIncr = tFreqIncr; - t_queueWidx = t_queueRidx; - audioState = 1; + if ((tFlags & PLAY_NOW) || !busy()) { + state = 1; + current.file[0] = '\0'; + current.freq = tFreq; + current.duration = tLen; + current.pause = tPause; + current.freqIncr = tFreqIncr; + widx = ridx; CoSetFlag(audioFlag); } else { @@ -356,14 +337,16 @@ void play(uint8_t tFreq, uint8_t tLen, uint8_t tPause, tFlags &= 0x0f; if (tFlags) { - uint8_t next_queueWidx = (t_queueWidx + 1) % AUDIO_QUEUE_LENGTH; - if (next_queueWidx != t_queueRidx) { - queueToneFreq[t_queueWidx] = tFreq; - queueToneLength[t_queueWidx] = tLen; - queueTonePause[t_queueWidx] = tPause; - queueToneRepeat[t_queueWidx] = tFlags - 1; - queueToneFreqIncr[t_queueWidx] = tFreqIncr; - t_queueWidx = next_queueWidx; + uint8_t next_widx = (widx + 1) % AUDIO_QUEUE_LENGTH; + if (next_widx != ridx) { + AudioFragment & fragment = fragments[widx]; + memset(&fragment, 0, sizeof(fragment)); + fragment.freq = tFreq; + fragment.duration = tLen; + fragment.pause = tPause; + fragment.repeat = tFlags - 1; + fragment.freqIncr = tFreqIncr; + widx = next_widx; } } } @@ -371,10 +354,32 @@ void play(uint8_t tFreq, uint8_t tLen, uint8_t tPause, CoLeaveMutexSection(audioMutex); } -void playFile(const char *filename) +void AudioQueue::playFile(const char *filename, uint8_t flags) { CoEnterMutexSection(audioMutex); - strcpy(toneWavFile, filename); + + if ((flags & PLAY_NOW) || !busy()) { + state = 1; + memset(¤t, 0, sizeof(current)); + strcpy(current.file, filename); + widx = ridx; + CoSetFlag(audioFlag); + } + else { + flags++; + } + + flags &= 0x0f; + if (flags) { + uint8_t next_widx = (widx + 1) % AUDIO_QUEUE_LENGTH; + if (next_widx != ridx) { + AudioFragment & fragment = fragments[widx]; + memset(&fragment, 0, sizeof(fragment)); + strcpy(current.file, filename); + fragment.repeat = flags - 1; + widx = next_widx; + } + } CoSetFlag(audioFlag); CoLeaveMutexSection(audioMutex); } @@ -394,163 +399,163 @@ void audioEvent(uint8_t e, uint8_t f) if (g_eeGeneral.beeperMode>0 || (g_eeGeneral.beeperMode==0 && e>=AU_TRIM_MOVE) || (g_eeGeneral.beeperMode>=-1 && e<=AU_ERROR)) { if (e < AU_FRSKY_FIRST && isAudioFileAvailable(e, filename)) { - playFile(filename); + audioQueue.playFile(filename); } - else if (e < AU_FRSKY_FIRST || !audioBusy()) { + else if (e < AU_FRSKY_FIRST || !audioQueue.busy()) { switch (e) { // inactivity timer alert case AU_INACTIVITY: - play(70, 20, 4, 2|PLAY_NOW); + audioQueue.play(70, 20, 4, 2|PLAY_NOW); break; // low battery in tx case AU_TX_BATTERY_LOW: - if (!audioBusy()) { - play(60, 40, 6, 2, 1); - play(80, 40, 6, 2, -1); + if (!audioQueue.busy()) { + audioQueue.play(60, 40, 6, 2, 1); + audioQueue.play(80, 40, 6, 2, -1); } break; // error case AU_ERROR: - play(BEEP_DEFAULT_FREQ, 50, 2, PLAY_NOW); + audioQueue.play(BEEP_DEFAULT_FREQ, 50, 2, PLAY_NOW); break; // keypad up (seems to be used when going left/right through system menu options. 0-100 scales etc) case AU_KEYPAD_UP: - play(BEEP_KEY_UP_FREQ, 20, 2, PLAY_NOW); + audioQueue.play(BEEP_KEY_UP_FREQ, 20, 2, PLAY_NOW); break; // keypad down (seems to be used when going left/right through system menu options. 0-100 scales etc) case AU_KEYPAD_DOWN: - play(BEEP_KEY_DOWN_FREQ, 20, 2, PLAY_NOW); + audioQueue.play(BEEP_KEY_DOWN_FREQ, 20, 2, PLAY_NOW); break; // menu display (also used by a few generic beeps) case AU_MENUS: - play(BEEP_DEFAULT_FREQ, 20, 4, PLAY_NOW); + audioQueue.play(BEEP_DEFAULT_FREQ, 20, 4, PLAY_NOW); break; // trim move case AU_TRIM_MOVE: - play(f, 12, 2, PLAY_NOW); + audioQueue.play(f, 12, 2, PLAY_NOW); break; // trim center case AU_TRIM_MIDDLE: - play(f, 20, 4, PLAY_NOW); + audioQueue.play(f, 20, 4, PLAY_NOW); break; // trim center case AU_TRIM_END: - play(f, 20, 4, PLAY_NOW); + audioQueue.play(f, 20, 4, PLAY_NOW); break; // warning one case AU_WARNING1: - play(BEEP_DEFAULT_FREQ, 20, 2, PLAY_NOW); + audioQueue.play(BEEP_DEFAULT_FREQ, 20, 2, PLAY_NOW); break; // warning two case AU_WARNING2: - play(BEEP_DEFAULT_FREQ, 40, 2, PLAY_NOW); + audioQueue.play(BEEP_DEFAULT_FREQ, 40, 2, PLAY_NOW); break; // warning three case AU_WARNING3: - play(BEEP_DEFAULT_FREQ, 50, 2, PLAY_NOW); + audioQueue.play(BEEP_DEFAULT_FREQ, 50, 2, PLAY_NOW); break; // startup tune case AU_TADA: - play(50, 20, 10); - play(90, 20, 10); - play(110, 10, 8, 2); + audioQueue.play(50, 20, 10); + audioQueue.play(90, 20, 10); + audioQueue.play(110, 10, 8, 2); break; // pot/stick center case AU_POT_STICK_MIDDLE: - play(BEEP_DEFAULT_FREQ + 50, 20, 2, PLAY_NOW); + audioQueue.play(BEEP_DEFAULT_FREQ + 50, 20, 2, PLAY_NOW); break; // mix warning 1 case AU_MIX_WARNING_1: - play(BEEP_DEFAULT_FREQ + 50, 12, 0, PLAY_NOW); + audioQueue.play(BEEP_DEFAULT_FREQ + 50, 12, 0, PLAY_NOW); break; // mix warning 2 case AU_MIX_WARNING_2: - play(BEEP_DEFAULT_FREQ + 52, 12, 0, PLAY_NOW); + audioQueue.play(BEEP_DEFAULT_FREQ + 52, 12, 0, PLAY_NOW); break; // mix warning 3 case AU_MIX_WARNING_3: - play(BEEP_DEFAULT_FREQ + 54, 12, 0, PLAY_NOW); + audioQueue.play(BEEP_DEFAULT_FREQ + 54, 12, 0, PLAY_NOW); break; // time 30 seconds left case AU_TIMER_30: - play(BEEP_DEFAULT_FREQ + 50, 30, 6, 2|PLAY_NOW); + audioQueue.play(BEEP_DEFAULT_FREQ + 50, 30, 6, 2|PLAY_NOW); break; // time 20 seconds left case AU_TIMER_20: - play(BEEP_DEFAULT_FREQ + 50, 30, 6, 1|PLAY_NOW); + audioQueue.play(BEEP_DEFAULT_FREQ + 50, 30, 6, 1|PLAY_NOW); break; // time 10 seconds left case AU_TIMER_10: - play(BEEP_DEFAULT_FREQ + 50, 30, 6, PLAY_NOW); + audioQueue.play(BEEP_DEFAULT_FREQ + 50, 30, 6, PLAY_NOW); break; // time <3 seconds left case AU_TIMER_LT3: - play(BEEP_DEFAULT_FREQ + 50, 30, 6, PLAY_NOW); + audioQueue.play(BEEP_DEFAULT_FREQ + 50, 30, 6, PLAY_NOW); break; case AU_FRSKY_WARN1: - play(BEEP_DEFAULT_FREQ+20,30,10,2); - pause(200); + audioQueue.play(BEEP_DEFAULT_FREQ+20,30,10,2); + audioQueue.pause(200); break; case AU_FRSKY_WARN2: - play(BEEP_DEFAULT_FREQ+30,30,10,2); - pause(200); + audioQueue.play(BEEP_DEFAULT_FREQ+30,30,10,2); + audioQueue.pause(200); break; case AU_FRSKY_CHEEP: - play(BEEP_DEFAULT_FREQ+30,20,4,2,2); - pause(200); + audioQueue.play(BEEP_DEFAULT_FREQ+30,20,4,2,2); + audioQueue.pause(200); break; case AU_FRSKY_RING: - play(BEEP_DEFAULT_FREQ+25,10,4,10); - play(BEEP_DEFAULT_FREQ+25,10,20,1); - play(BEEP_DEFAULT_FREQ+25,10,4,10); - pause(200); + audioQueue.play(BEEP_DEFAULT_FREQ+25,10,4,10); + audioQueue.play(BEEP_DEFAULT_FREQ+25,10,20,1); + audioQueue.play(BEEP_DEFAULT_FREQ+25,10,4,10); + audioQueue.pause(200); break; case AU_FRSKY_SCIFI: - play(80,20,6,2,-1); - play(60,20,6,2,1); - play(70,20,2,0); - pause(200); + audioQueue.play(80,20,6,2,-1); + audioQueue.play(60,20,6,2,1); + audioQueue.play(70,20,2,0); + audioQueue.pause(200); break; case AU_FRSKY_ROBOT: - play(70,10,2,1); - play(50,30,4,1); - play(80,30,4,1); - pause(200); + audioQueue.play(70,10,2,1); + audioQueue.play(50,30,4,1); + audioQueue.play(80,30,4,1); + audioQueue.pause(200); break; case AU_FRSKY_CHIRP: - play(BEEP_DEFAULT_FREQ+40,10,2,2); - play(BEEP_DEFAULT_FREQ+54,10,2,3); - pause(200); + audioQueue.play(BEEP_DEFAULT_FREQ+40,10,2,2); + audioQueue.play(BEEP_DEFAULT_FREQ+54,10,2,3); + audioQueue.pause(200); break; case AU_FRSKY_TADA: - play(50,10,10); - play(90,10,10); - play(110,6,8,2); - pause(200); + audioQueue.play(50,10,10); + audioQueue.play(90,10,10); + audioQueue.play(110,6,8,2); + audioQueue.pause(200); break; case AU_FRSKY_CRICKET: - play(80,10,20,3); - play(80,10,40,1); - play(80,10,20,3); - pause(200); + audioQueue.play(80,10,20,3); + audioQueue.play(80,10,40,1); + audioQueue.play(80,10,20,3); + audioQueue.pause(200); break; case AU_FRSKY_SIREN: - play(10,40,10,2,1); - pause(200); + audioQueue.play(10,40,10,2,1); + audioQueue.pause(200); break; case AU_FRSKY_ALARMC: - play(50,8,20,2); - play(70,16,40,1); - play(50,16,20,2); - play(70,8,40,1); - pause(200); + audioQueue.play(50,8,20,2); + audioQueue.play(70,16,40,1); + audioQueue.play(50,16,20,2); + audioQueue.play(70,8,40,1); + audioQueue.pause(200); break; case AU_FRSKY_RATATA: - play(BEEP_DEFAULT_FREQ+50,10,20,10); + audioQueue.play(BEEP_DEFAULT_FREQ+50,10,20,10); break; case AU_FRSKY_TICK: - play(BEEP_DEFAULT_FREQ+50,10,100,2); - pause(200); + audioQueue.play(BEEP_DEFAULT_FREQ+50,10,100,2); + audioQueue.pause(200); break; default: break; diff --git a/src/ersky9x/audio.h b/src/ersky9x/audio.h index 886314d3f..08f921b64 100644 --- a/src/ersky9x/audio.h +++ b/src/ersky9x/audio.h @@ -31,7 +31,6 @@ * */ - #ifndef audio_h #define audio_h @@ -41,41 +40,61 @@ #define BEEP_KEY_UP_FREQ (BEEP_DEFAULT_FREQ+5) #define BEEP_KEY_DOWN_FREQ (BEEP_DEFAULT_FREQ-5) -extern uint8_t audioState; +class ToneFragment { + public: + uint8_t freq; + uint8_t duration; + uint8_t pause; + uint8_t repeat; + int8_t freqIncr; +}; -extern uint8_t t_queueRidx; -extern uint8_t t_queueWidx; +class AudioFragment : public ToneFragment { + public: + char file[32+1]; +}; -extern uint8_t toneFreq; -extern uint8_t toneTimeLeft; -extern uint8_t tonePause; +extern "C" void DAC_IRQHandler(); -extern char toneWavFile[32+1]; +class AudioQueue { -// vario -extern uint8_t tone2Freq; -extern uint8_t tone2TimeLeft; -extern uint8_t tone2Pause; + friend void audioTask(void* pdata); + friend void DAC_IRQHandler(); -// queue arrays -extern uint8_t queueToneFreq[AUDIO_QUEUE_LENGTH]; -// int8_t queueToneFreqIncr[AUDIO_QUEUE_LENGTH]; -extern uint8_t queueToneLength[AUDIO_QUEUE_LENGTH]; -extern uint8_t queueTonePause[AUDIO_QUEUE_LENGTH]; -extern uint8_t queueToneRepeat[AUDIO_QUEUE_LENGTH]; + public: + + AudioQueue(); + + void play(uint8_t tFreq, uint8_t tLen, uint8_t tPause, uint8_t tFlags=0, int8_t tFreqIncr=0); + + void playFile(const char *filename, uint8_t tFlags=0); + + void pause(uint8_t tLen); + + bool busy() + { + return (state != 0); + } + + protected: + + void wakeup(); + + uint8_t state; + uint8_t ridx; + uint8_t widx; + AudioFragment fragments[AUDIO_QUEUE_LENGTH]; + ToneFragment background; // for vario + + AudioFragment current; + +}; + +extern AudioQueue audioQueue; 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); - -inline bool audioBusy() -{ - return (audioState != 0); -} - void audioEvent(uint8_t e, uint8_t f=BEEP_DEFAULT_FREQ); #define AUDIO_KEYPAD_UP() audioEvent(AU_KEYPAD_UP) @@ -101,7 +120,7 @@ void audioEvent(uint8_t e, uint8_t f=BEEP_DEFAULT_FREQ); #define AUDIO_TRIM_END(f) audioEvent(AU_TRIM_END, f) #define AUDIO_TRIM(event, f) audioEvent(AU_TRIM_MOVE, f) #define AUDIO_PLAY(p) audioEvent(p) -#define AUDIO_VARIO(f, t) play(f, t, 0, PLAY_SOUND_VARIO) +#define AUDIO_VARIO(f, t) audioQueue.play(f, t, 0, PLAY_SOUND_VARIO) #define AUDIO_HEARTBEAT() diff --git a/src/ersky9x/sound_driver.cpp b/src/ersky9x/sound_driver.cpp index 1deb7a693..28fcd6af8 100644 --- a/src/ersky9x/sound_driver.cpp +++ b/src/ersky9x/sound_driver.cpp @@ -177,7 +177,7 @@ uint16_t *wavSamplesBuffer; extern "C" void DAC_IRQHandler() { // Data for PDC must NOT be in flash, PDC needs a RAM source. - if (toneWavFile[0]) { + if (audioQueue.current.file[0]) { CoEnterISR(); // Enter the interrupt CoSetFlag(audioFlag); CoExitISR(); // Exit the interrupt diff --git a/src/general_menus.cpp b/src/general_menus.cpp index 8c0250d43..0576e92fd 100644 --- a/src/general_menus.cpp +++ b/src/general_menus.cpp @@ -645,7 +645,7 @@ void menuProcSd(uint8_t event) f_getcwd(lfn, SD_SCREEN_FILE_LENGTH); strcat_P(lfn, PSTR("/")); strcat(lfn, reusableBuffer.sd.lines[index]); - playFile(lfn); + audioQueue.playFile(lfn); } #endif } diff --git a/src/open9x.cpp b/src/open9x.cpp index 919a7bcee..72b8936ae 100644 --- a/src/open9x.cpp +++ b/src/open9x.cpp @@ -1701,12 +1701,12 @@ void evalFunctions() #if defined(PCBARM) && defined(SDCARD) else if (sd->func == FUNC_PLAY_TRACK) { - if (!audioBusy()) { + if (!audioQueue.busy()) { char lfn[32] = SOUNDS_PATH "/"; strncpy(lfn+sizeof(SOUNDS_PATH), sd->param, sizeof(sd->param)); lfn[sizeof(SOUNDS_PATH)+sizeof(sd->param)] = '\0'; strcat(lfn+sizeof(SOUNDS_PATH), SOUNDS_EXT); - playFile(lfn); + audioQueue.playFile(lfn); } } else if (sd->func == FUNC_VOLUME) {