diff --git a/src/audio.cpp b/src/audio.cpp index c627da68e..0ff3146ae 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -22,20 +22,13 @@ audioQueue::audioQueue() void audioQueue::aqinit() { //make sure haptic off by default - HAPTIC_OFF; - //initialize all arrays - flushqueue(0); - - //set key vars to 0 to ensure no garbage - toneFreq = 0; - toneFreqEnd = 0; - toneRepeat = 0; toneTimeLeft = 0; - queueState = 0; - toneRepeatCnt = 0; - inToneRepeat = 0; + tonePause = 0; + + t_queueRidx = 0; + t_queueRidx = 0; #ifdef HAPTIC hapticTick = 0; @@ -45,196 +38,70 @@ void audioQueue::aqinit() frskySample = 0; #endif - heartbeatTimer = 0; - flushTemp(); } bool audioQueue::busy() { - if (toneTimeLeft > 0) { - return true; - } - else { - return false; - } + return (toneTimeLeft > 0); } +/* TODO to be added when needed bool audioQueue::freeslots(uint8_t slots) { - //find out if enough queue space exists to add the requested routine! - for (uint8_t i = AUDIO_QUEUE_LENGTH; i--;) { - slots--; - if (slots == 0) { - break; - } //only loop for the number of items indicated in slots - if (queueToneStart[i] != 0) { - return false; - break; - } - } - return true; -} - -void audioQueue::commit(uint8_t toneInterupt) -{ - - if (toneInterupt == 0) { - //queued events - if (freeslots(3)) { //do not insert into the queue if less than 3 spare slots! this stops sound collitions from occuring - for (uint8_t i = 0; i < AUDIO_QUEUE_LENGTH; i++) { - if (queueToneStart[i] == 0) { //add to the first entry that has a start tone of zero (no sound) - queueToneStart[i] = t_queueToneStart; - queueToneEnd[i] = t_queueToneEnd; - queueToneLength[i] = t_queueToneLength; - queueTonePause[i] = t_queueTonePause; - queueToneRepeat[i] = t_queueToneRepeat; -#ifdef HAPTIC - queueToneHaptic[i] = t_queueToneHaptic; -#endif - flushTemp(); - break; - } - } - } - } - else { - //interrupt events - queueToneStart[0] = t_queueToneStart; - queueToneEnd[0] = t_queueToneEnd; - queueToneLength[0] = t_queueToneLength; - queueTonePause[0] = t_queueTonePause; - queueToneRepeat[0] = t_queueToneRepeat; -#ifdef HAPTIC - queueToneHaptic[0] = t_queueToneHaptic; -#endif - - flushqueue(1); //purge queue on interrupt events to stop broken audio - flushTemp(); - } - -} - -void audioQueue::flushqueue(uint8_t startpos) -{ - for (; startpos < AUDIO_QUEUE_LENGTH; startpos++) { - queueToneStart[startpos] = 0; - queueToneEnd[startpos] = 0; - queueToneLength[startpos] = 0; - queueTonePause[startpos] = 0; - queueToneRepeat[startpos] = 0; -#ifdef HAPTIC - queueToneHaptic[startpos] = 0; -#endif - } -} - -//set all temporary buffers to default -void audioQueue::flushTemp() -{ - t_queueToneStart = 0; - t_queueToneEnd = 0; - t_queueToneLength = 0; - t_queueTonePause = 0; - t_queueToneRepeat = 0; -#ifdef HAPTIC - t_queueToneHaptic = 0; -#endif - rateOfChange = 0; -#ifdef HAPTIC - toneHaptic = 0; -#endif -} - -void audioQueue::restack() -{ - for (uint8_t i = 0; i < AUDIO_QUEUE_LENGTH - 1; i++) { - queueToneStart[i] = queueToneStart[i + 1]; - queueToneEnd[i] = queueToneEnd[i + 1]; - queueToneLength[i] = queueToneLength[i + 1]; - queueTonePause[i] = queueTonePause[i + 1]; - queueToneRepeat[i] = queueToneRepeat[i + 1]; -#ifdef HAPTIC - queueToneHaptic[i] = queueToneHaptic[i + 1]; -#endif - } - flushqueue(AUDIO_QUEUE_LENGTH - 1); //set the last entry to 0 as nothing in stack to add too! + return AUDIO_QUEUE_LENGTH - ((t_queueWidx + AUDIO_QUEUE_LENGTH - t_queueRidx) % AUDIO_QUEUE_LENGTH) >= slots; } +*/ //heartbeat is responsibile for issueing the audio tones and general square waves // it is essentially the life of the class. void audioQueue::heartbeat() { +#if defined(PCBSTD) + if (toneTimeLeft > 0) { + //square wave generator use for speaker mod + //simply generates a square wave for toneFreq for + //as long as the toneTimeLeft is more than 0 + static uint8_t toneCounter; + toneCounter += toneFreq; + if ((toneCounter & 0x80) == 0x80) + PORTE |= (1 << OUT_E_BUZZER); // speaker output 'high' + else + PORTE &= ~(1 << OUT_E_BUZZER); // speaker output 'low' + } - uint8_t z; //direction calulations - uint8_t hTimer; //heartbeat timer + static uint8_t cnt10ms = 77; // execute 10ms code once every 78 ISRs + if (cnt10ms-- == 0) // every 10ms ... + cnt10ms = 77; + else + return; +#endif - if (queueState == 1) { - - if (g_eeGeneral.beeperVal > 0) { - //never do sounds if we are set to go quiet -#if 0 - switch (g_eeGeneral.speakerMode) { - - case 0: - //stock beeper. simply turn port on for x time! - if (toneTimeLeft > 0) { + if (toneTimeLeft > 0) { #if defined(PCBV4) - TCCR0A |= (0b01< 0) { - toneCounter += toneFreq; - if ((toneCounter & 0x80) == 0x80) { -#if defined(PCBV4) - TCCR0A |= (0b01< 0 -#ifdef HAPTIC - || queueToneHaptic[0] == 1 -#endif - ) && toneTimeLeft <= 0 - && queueState == 0) { - if (queueToneEnd[0] > 0 && queueToneEnd[0] != queueToneStart[0]) { - if (queueToneStart[0] > queueToneEnd[0]) { //tone going down - z = queueToneStart[0] - queueToneEnd[0]; - rateOfChange = -2; - } - else { //tone going up - z = queueToneEnd[0] - queueToneStart[0]; - rateOfChange = 2; - } - if (queueToneStart[0] > 0) { - toneFreq = queueToneStart[0] + g_eeGeneral.speakerPitch + BEEP_OFFSET; // add pitch compensator - } - else { - toneFreq = queueToneStart[0]; // done so hapticOnly option can work - } - toneFreqEnd = queueToneEnd[0] + g_eeGeneral.speakerPitch + BEEP_OFFSET; - toneTimeLeft = z; - tonePause = queueTonePause[0]; - toneRepeat = queueToneRepeat[0]; -#ifdef HAPTIC - toneHaptic = queueToneHaptic[0]; -#endif - } - else { - //simple tone handler - if (queueToneStart[0] > 0) { - toneFreq = (queueToneStart[0] + g_eeGeneral.speakerPitch) + BEEP_OFFSET; // add pitch compensator - } - else { - toneFreq = queueToneStart[0]; - } - rateOfChange = 0; - toneFreqEnd = 0; - toneTimeLeft = queueToneLength[0]; - tonePause = queueTonePause[0]; - toneRepeat = queueToneRepeat[0]; -#ifdef HAPTIC - toneHaptic = queueToneHaptic[0]; -#endif - } - queueState = 1; - if (toneRepeat != 0 && inToneRepeat == 0) { - inToneRepeat = 1; - toneRepeatCnt = toneRepeat; - } - - if (inToneRepeat == 1) { - toneRepeatCnt--; - if (toneRepeatCnt <= 0) { - inToneRepeat = 0; - restack(); - } - } - else { - restack(); - } - - } - - hTimer = AUDIO_QUEUE_HEARTBEAT_NORM; // default +inline uint8_t audioQueue::getToneLength(uint8_t tLen) +{ + uint8_t result = tLen; // default if (g_eeGeneral.beeperVal == 2) { - //xshort - hTimer = AUDIO_QUEUE_HEARTBEAT_XSHORT; + result /= 2; } else if (g_eeGeneral.beeperVal == 3) { - //short - hTimer = AUDIO_QUEUE_HEARTBEAT_SHORT; + result = (result * 3) / 2; } else if (g_eeGeneral.beeperVal == 5) { //long - hTimer = AUDIO_QUEUE_HEARTBEAT_LONG; + result *= 2; } else if (g_eeGeneral.beeperVal == 6) { //xlong - hTimer = AUDIO_QUEUE_HEARTBEAT_XLONG; + result *= 3; } + return result; +} - heartbeatTimer++; - if (heartbeatTimer >= hTimer) { +void audioQueue::playNow(uint8_t tFreq, uint8_t tLen, uint8_t tPause, + uint8_t tRepeat, uint8_t tHaptic, int8_t tFreqIncr) +{ + if (g_eeGeneral.beeperVal) { + toneFreq = tFreq + g_eeGeneral.speakerPitch + BEEP_OFFSET; // add pitch compensator + toneTimeLeft = getToneLength(tLen); + tonePause = tPause; + #ifdef HAPTIC + t_queueToneHaptic = tHaptic; + #endif + toneFreqIncr = tFreqIncr; + t_queueWidx = t_queueRidx; - heartbeatTimer = 0; - - if (queueState == 1) { - if (toneTimeLeft > 0) { - toneFreq += rateOfChange; // -2, 0 or 2 - toneTimeLeft--; //time gets counted down - } - if (toneTimeLeft <= 0) { - if (tonePause-- <= 0) { - queueState = 0; - } - } + if (tRepeat) { + playASAP(tFreq, tLen, tPause, tRepeat-1, tHaptic, tFreqIncr); } - } - } -void audioQueue::playNow(uint8_t tStart, uint8_t tLen, uint8_t tPause, - uint8_t tRepeat, uint8_t tHaptic, uint8_t tEnd) +void audioQueue::playASAP(uint8_t tFreq, uint8_t tLen, uint8_t tPause, + uint8_t tRepeat, uint8_t tHaptic, int8_t tFreqIncr) { - t_queueToneStart = tStart; - t_queueToneLength = tLen; - t_queueTonePause = tPause; + if (g_eeGeneral.beeperVal) { + queueToneFreq[t_queueWidx] = tFreq + g_eeGeneral.speakerPitch + BEEP_OFFSET; // add pitch compensator + queueToneLength[t_queueWidx] = getToneLength(tLen); + queueTonePause[t_queueWidx] = tPause; #ifdef HAPTIC - t_queueToneHaptic = tHaptic; + queueToneHaptic[t_queueWidx] = tHaptic; #endif - t_queueToneRepeat = tRepeat; - t_queueToneEnd = tEnd; - commit(1); -} + queueToneRepeat[t_queueWidx] = tRepeat; + queueToneFreqIncr[t_queueWidx] = tFreqIncr; -void audioQueue::playASAP(uint8_t tStart, uint8_t tLen, uint8_t tPause, - uint8_t tRepeat, uint8_t tHaptic, uint8_t tEnd) -{ - t_queueToneStart = tStart; - t_queueToneLength = tLen; - t_queueTonePause = tPause; -#ifdef HAPTIC - t_queueToneHaptic = tHaptic; -#endif - t_queueToneRepeat = tRepeat; - t_queueToneEnd = tEnd; - commit(0); + t_queueWidx = (t_queueWidx + 1) % AUDIO_QUEUE_LENGTH; + } } #ifdef FRSKY //this is done so the menu selections only plays tone once! -void audioQueue::frskyeventSample(uint8_t e) { +void audioQueue::frskyeventSample(uint8_t e) +{ if(frskySample != e) { aqinit(); //flush the queue frskyevent(e); @@ -408,7 +188,8 @@ void audioQueue::frskyeventSample(uint8_t e) { } } -void audioQueue::frskyevent(uint8_t e) { +void audioQueue::frskyevent(uint8_t e) +{ // example playASAP(tStart,tLen,tPause,tRepeat,tHaptic,tEnd); switch(e) { case AU_FRSKY_WARN1: @@ -615,15 +396,13 @@ void audioQueue::event(uint8_t e, uint8_t f) { //low battery in tx //case 19: case AU_TX_BATTERY_LOW: - playASAP(60, 4, 3, 2, 1, 70); - playASAP(80, 4, 3, 2, 1, 70); + playASAP(60, 4, 3, 2, 1, 2); + playASAP(80, 4, 3, 2, 1, -2); break; default: break; - } - } void audioDefevent(uint8_t e) { diff --git a/src/audio.h b/src/audio.h index 4712cc96a..74bc85fc6 100644 --- a/src/audio.h +++ b/src/audio.h @@ -22,11 +22,11 @@ #define BEEP_KEY_UP_FREQ (BEEP_DEFAULT_FREQ+5) #define BEEP_KEY_DOWN_FREQ (BEEP_DEFAULT_FREQ-5) -#define AUDIO_QUEUE_HEARTBEAT_XSHORT (30) //speaker timing [Norm] -#define AUDIO_QUEUE_HEARTBEAT_SHORT (50) //speaker timing [Norm] -#define AUDIO_QUEUE_HEARTBEAT_NORM (77) //speaker timing [Norm] -#define AUDIO_QUEUE_HEARTBEAT_LONG (130) //speaker timing [Long] -#define AUDIO_QUEUE_HEARTBEAT_XLONG (200) //speaker timing [xLong] +// #define AUDIO_QUEUE_HEARTBEAT_XSHORT (30) //speaker timing [Norm] +// #define AUDIO_QUEUE_HEARTBEAT_SHORT (50) //speaker timing [Norm] +// #define AUDIO_QUEUE_HEARTBEAT_NORM (77) //speaker timing [Norm] +// #define AUDIO_QUEUE_HEARTBEAT_LONG (130) //speaker timing [Long] +// #define AUDIO_QUEUE_HEARTBEAT_XLONG (200) //speaker timing [xLong] #ifdef HAPTIC #define HAPTIC_ON PORTG |= (1<<2) #define HAPTIC_OFF PORTG &= ~(1<<2) @@ -85,41 +85,29 @@ #define BEEP_LONG (5) #define BEEP_XLONG (6) -struct audioQueue { - - //queue temporaries - uint8_t t_queueToneStart; - uint8_t t_queueToneEnd; - uint8_t t_queueToneLength; - uint8_t t_queueTonePause; - uint8_t t_queueToneRepeat; -#ifdef HAPTIC - uint8_t t_queueToneHaptic; -#endif +struct audioQueue +{ + uint8_t t_queueRidx; + uint8_t t_queueWidx; //queue general vars uint8_t toneFreq; - uint8_t toneFreqEnd; + int8_t toneFreqIncr; uint8_t toneTimeLeft; - int8_t rateOfChange; uint8_t tonePause; - uint8_t queueState; - uint8_t toneRepeat; - uint8_t toneRepeatCnt; - uint8_t inToneRepeat; + #ifdef HAPTIC uint8_t toneHaptic; uint8_t hapticTick; #endif - uint8_t heartbeatTimer; #ifdef FRSKY uint8_t frskySample; #endif - //queue arrays - uint8_t queueToneStart[AUDIO_QUEUE_LENGTH]; - uint8_t queueToneEnd[AUDIO_QUEUE_LENGTH]; + // 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]; @@ -127,17 +115,16 @@ struct audioQueue { uint8_t queueToneHaptic[AUDIO_QUEUE_LENGTH]; #endif - //beep length table - // uint8_t beepLenTable[10]; - audioQueue(); void aqinit(); // To stop constructor being compiled twice + inline uint8_t getToneLength(uint8_t tLen); + //only difference between these two functions is that one does the //interupt queue (Now) and the other queues for playing ASAP. - void playNow(uint8_t tStart,uint8_t tLen,uint8_t tPause,uint8_t tRepeat=0,uint8_t tHaptic=0,uint8_t tEnd=0); - void playASAP(uint8_t tStart,uint8_t tLen,uint8_t tPause,uint8_t tRepeat=0,uint8_t tHaptic=0,uint8_t tEnd=0); + void playNow(uint8_t tFreq,uint8_t tLen,uint8_t tPause,uint8_t tRepeat=0,uint8_t tHaptic=0,int8_t tFreqIncr=0); + void playASAP(uint8_t tFreq,uint8_t tLen,uint8_t tPause,uint8_t tRepeat=0,uint8_t tHaptic=0,int8_t tFreqIncr=0); bool busy(); @@ -148,26 +135,19 @@ struct audioQueue { void frskyeventSample(uint8_t e); #endif - void commit(uint8_t toneInterupt); - - //set all temporary buffers to default - void flushTemp(); - void flushqueue(uint8_t startpos); - - void restack(); //heartbeat is responsibile for issueing the audio tones and general square waves // it is essentially the life of the class. void heartbeat(); - bool freeslots(uint8_t slots); + + // TODO bool freeslots(uint8_t slots); }; //wrapper function - dirty but results in a space saving!!! extern audioQueue audio; + //void audioevent(uint8_t e,uint8_t f=BEEP_DEFAULT_FREQ); void audioDefevent(uint8_t e); -void audioError(); - #define AUDIO_KEYPAD_UP() audioDefevent(AU_KEYPAD_UP) #define AUDIO_KEYPAD_DOWN() audioDefevent(AU_KEYPAD_DOWN) #define AUDIO_MENUS() audioDefevent(AU_MENUS) diff --git a/src/beeper.h b/src/beeper.h index 3e7a316a8..88d1180a4 100644 --- a/src/beeper.h +++ b/src/beeper.h @@ -79,30 +79,14 @@ inline void AUDIO_HEARTBEAT() if (beepOn) { static bool warbleC; warbleC = warble && !warbleC; - if (warbleC) { -#if defined(PCBV4) - TCCR0A &= ~( 1 << COM0A0); -#else + if (warbleC) PORTE &= ~(1 << OUT_E_BUZZER); // speaker output 'low' -#endif - } - else { -#if defined(PCBV4) - TCCR0A |= (1 << COM0A0); // tone on -#else + else PORTE |= (1 << OUT_E_BUZZER); // speaker output 'high' -#endif - } } else { -#if defined(PCBV4) - TCCR0A &= ~(1 << COM0A0); -#else PORTE &= ~(1 << OUT_E_BUZZER); // speaker output 'low' -#endif } } - - #endif diff --git a/src/s9xsplash.xcf b/src/s9xsplash.xcf deleted file mode 100644 index 580636ef9..000000000 Binary files a/src/s9xsplash.xcf and /dev/null differ