diff --git a/audio.c b/audio.c index e865fdc95..07e3d48b6 100644 --- a/audio.c +++ b/audio.c @@ -31,50 +31,11 @@ #include "settings.h" #include "ui/ui.h" -#ifdef ENABLE_VOICE - - static const uint8_t VoiceClipLengthChinese[58] = - { - 0x32, 0x32, 0x32, 0x37, 0x37, 0x32, 0x32, 0x32, - 0x32, 0x37, 0x37, 0x32, 0x64, 0x64, 0x64, 0x64, - 0x64, 0x69, 0x64, 0x69, 0x5A, 0x5F, 0x5F, 0x64, - 0x64, 0x69, 0x64, 0x64, 0x69, 0x69, 0x69, 0x64, - 0x64, 0x6E, 0x69, 0x5F, 0x64, 0x64, 0x64, 0x69, - 0x69, 0x69, 0x64, 0x69, 0x64, 0x64, 0x55, 0x5F, - 0x5A, 0x4B, 0x4B, 0x46, 0x46, 0x69, 0x64, 0x6E, - 0x5A, 0x64, - }; - - static const uint8_t VoiceClipLengthEnglish[76] = - { - 0x50, 0x32, 0x2D, 0x2D, 0x2D, 0x37, 0x37, 0x37, - 0x32, 0x32, 0x3C, 0x37, 0x46, 0x46, 0x4B, 0x82, - 0x82, 0x6E, 0x82, 0x46, 0x96, 0x64, 0x46, 0x6E, - 0x78, 0x6E, 0x87, 0x64, 0x96, 0x96, 0x46, 0x9B, - 0x91, 0x82, 0x82, 0x73, 0x78, 0x64, 0x82, 0x6E, - 0x78, 0x82, 0x87, 0x6E, 0x55, 0x78, 0x64, 0x69, - 0x9B, 0x5A, 0x50, 0x3C, 0x32, 0x55, 0x64, 0x64, - 0x50, 0x46, 0x46, 0x46, 0x4B, 0x4B, 0x50, 0x50, - 0x55, 0x4B, 0x4B, 0x32, 0x32, 0x32, 0x32, 0x37, - 0x41, 0x32, 0x3C, 0x37, - }; - - VOICE_ID_t gVoiceID[8]; - uint8_t gVoiceReadIndex; - uint8_t gVoiceWriteIndex; - volatile uint16_t gCountdownToPlayNextVoice_10ms; - volatile bool gFlagPlayQueuedVoice; - VOICE_ID_t gAnotherVoiceID = VOICE_ID_INVALID; - -#endif BEEP_Type_t gBeepToPlay = BEEP_NONE; void AUDIO_PlayBeep(BEEP_Type_t Beep) { - uint16_t ToneConfig; - uint16_t ToneFrequency; - uint16_t Duration; if (Beep != BEEP_880HZ_60MS_TRIPLE_BEEP && Beep != BEEP_500HZ_60MS_DOUBLE_BEEP && @@ -84,31 +45,32 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep) !gEeprom.BEEP_CONTROL) return; - #ifdef ENABLE_AIRCOPY - if (gScreenToDisplay == DISPLAY_AIRCOPY) - return; - #endif - +#ifdef ENABLE_AIRCOPY + if (gScreenToDisplay == DISPLAY_AIRCOPY) + return; +#endif + if (gCurrentFunction == FUNCTION_RECEIVE) return; if (gCurrentFunction == FUNCTION_MONITOR) return; - ToneConfig = BK4819_ReadRegister(BK4819_REG_71); +#ifdef ENABLE_FMRADIO + if (gFmRadioMode) + BK1080_Mute(true); +#endif AUDIO_AudioPathOff(); if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode) BK4819_RX_TurnOn(); - #ifdef ENABLE_FMRADIO - if (gFmRadioMode) - BK1080_Mute(true); - #endif - SYSTEM_DelayMs(20); + uint16_t ToneConfig = BK4819_ReadRegister(BK4819_REG_71); + + uint16_t ToneFrequency; switch (Beep) { default: @@ -133,7 +95,7 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep) ToneFrequency = 880; break; } - + BK4819_PlayTone(ToneFrequency, true); SYSTEM_DelayMs(2); @@ -142,6 +104,7 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep) SYSTEM_DelayMs(60); + uint16_t Duration; switch (Beep) { case BEEP_880HZ_60MS_TRIPLE_BEEP: @@ -161,18 +124,15 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep) BK4819_ExitTxMute(); Duration = 60; break; - case BEEP_880HZ_40MS_OPTIONAL: case BEEP_440HZ_40MS_OPTIONAL: BK4819_ExitTxMute(); Duration = 40; break; - case BEEP_880HZ_200MS: BK4819_ExitTxMute(); Duration = 200; break; - case BEEP_440HZ_500MS: case BEEP_880HZ_500MS: default: @@ -187,10 +147,6 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep) AUDIO_AudioPathOff(); - #ifdef ENABLE_VOX - gVoxResumeCountdown = 80; - #endif - SYSTEM_DelayMs(5); BK4819_TurnsOffTones_TurnsOnRX(); SYSTEM_DelayMs(5); @@ -199,254 +155,294 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep) if (gEnableSpeaker) AUDIO_AudioPathOn(); - #ifdef ENABLE_FMRADIO - if (gFmRadioMode) - BK1080_Mute(false); - #endif - +#ifdef ENABLE_FMRADIO + if (gFmRadioMode) + BK1080_Mute(false); +#endif + if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode) BK4819_Sleep(); + +#ifdef ENABLE_VOX + gVoxResumeCountdown = 80; +#endif + } #ifdef ENABLE_VOICE - void AUDIO_PlayVoice(uint8_t VoiceID) +static const uint8_t VoiceClipLengthChinese[58] = +{ + 0x32, 0x32, 0x32, 0x37, 0x37, 0x32, 0x32, 0x32, + 0x32, 0x37, 0x37, 0x32, 0x64, 0x64, 0x64, 0x64, + 0x64, 0x69, 0x64, 0x69, 0x5A, 0x5F, 0x5F, 0x64, + 0x64, 0x69, 0x64, 0x64, 0x69, 0x69, 0x69, 0x64, + 0x64, 0x6E, 0x69, 0x5F, 0x64, 0x64, 0x64, 0x69, + 0x69, 0x69, 0x64, 0x69, 0x64, 0x64, 0x55, 0x5F, + 0x5A, 0x4B, 0x4B, 0x46, 0x46, 0x69, 0x64, 0x6E, + 0x5A, 0x64, +}; + +static const uint8_t VoiceClipLengthEnglish[76] = +{ + 0x50, 0x32, 0x2D, 0x2D, 0x2D, 0x37, 0x37, 0x37, + 0x32, 0x32, 0x3C, 0x37, 0x46, 0x46, 0x4B, 0x82, + 0x82, 0x6E, 0x82, 0x46, 0x96, 0x64, 0x46, 0x6E, + 0x78, 0x6E, 0x87, 0x64, 0x96, 0x96, 0x46, 0x9B, + 0x91, 0x82, 0x82, 0x73, 0x78, 0x64, 0x82, 0x6E, + 0x78, 0x82, 0x87, 0x6E, 0x55, 0x78, 0x64, 0x69, + 0x9B, 0x5A, 0x50, 0x3C, 0x32, 0x55, 0x64, 0x64, + 0x50, 0x46, 0x46, 0x46, 0x4B, 0x4B, 0x50, 0x50, + 0x55, 0x4B, 0x4B, 0x32, 0x32, 0x32, 0x32, 0x37, + 0x41, 0x32, 0x3C, 0x37, +}; + +VOICE_ID_t gVoiceID[8]; +uint8_t gVoiceReadIndex; +uint8_t gVoiceWriteIndex; +volatile uint16_t gCountdownToPlayNextVoice_10ms; +volatile bool gFlagPlayQueuedVoice; +VOICE_ID_t gAnotherVoiceID = VOICE_ID_INVALID; + + +void AUDIO_PlayVoice(uint8_t VoiceID) +{ + unsigned int i; + + GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); + SYSTEM_DelayMs(20); + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); + + for (i = 0; i < 8; i++) { - unsigned int i; - + if ((VoiceID & 0x80U) == 0) + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1); + else + GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1); + + SYSTICK_DelayUs(1000); GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); - SYSTEM_DelayMs(20); + SYSTICK_DelayUs(1200); GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); - - for (i = 0; i < 8; i++) - { - if ((VoiceID & 0x80U) == 0) - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1); - else - GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1); - - SYSTICK_DelayUs(1000); - GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); - SYSTICK_DelayUs(1200); - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); - VoiceID <<= 1; - SYSTICK_DelayUs(200); - } + VoiceID <<= 1; + SYSTICK_DelayUs(200); } - - void AUDIO_PlaySingleVoice(bool bFlag) +} + +void AUDIO_PlaySingleVoice(bool bFlag) +{ + uint8_t VoiceID; + uint8_t Delay; + + VoiceID = gVoiceID[0]; + + if (gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF && gVoiceWriteIndex > 0) { - uint8_t VoiceID; - uint8_t Delay; - - VoiceID = gVoiceID[0]; - - if (gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF && gVoiceWriteIndex > 0) + if (gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE) + { // Chinese + if (VoiceID >= ARRAY_SIZE(VoiceClipLengthChinese)) + goto Bailout; + + Delay = VoiceClipLengthChinese[VoiceID]; + VoiceID += VOICE_ID_CHI_BASE; + } + else + { // English + if (VoiceID >= ARRAY_SIZE(VoiceClipLengthEnglish)) + goto Bailout; + + Delay = VoiceClipLengthEnglish[VoiceID]; + VoiceID += VOICE_ID_ENG_BASE; + } + + if (gCurrentFunction == FUNCTION_RECEIVE || + gCurrentFunction == FUNCTION_MONITOR || + gCurrentFunction == FUNCTION_INCOMING) // 1of11 + BK4819_SetAF(BK4819_AF_MUTE); + + #ifdef ENABLE_FMRADIO + if (gFmRadioMode) + BK1080_Mute(true); + #endif + + AUDIO_AudioPathOn(); + + #ifdef ENABLE_VOX + gVoxResumeCountdown = 2000; + #endif + + SYSTEM_DelayMs(5); + AUDIO_PlayVoice(VoiceID); + + if (gVoiceWriteIndex == 1) + Delay += 3; + + if (bFlag) { - if (gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE) - { // Chinese - if (VoiceID >= ARRAY_SIZE(VoiceClipLengthChinese)) - goto Bailout; - - Delay = VoiceClipLengthChinese[VoiceID]; - VoiceID += VOICE_ID_CHI_BASE; - } - else - { // English - if (VoiceID >= ARRAY_SIZE(VoiceClipLengthEnglish)) - goto Bailout; - - Delay = VoiceClipLengthEnglish[VoiceID]; - VoiceID += VOICE_ID_ENG_BASE; - } - + SYSTEM_DelayMs(Delay * 10); + if (gCurrentFunction == FUNCTION_RECEIVE || gCurrentFunction == FUNCTION_MONITOR || - gCurrentFunction == FUNCTION_INCOMING) // 1of11 - BK4819_SetAF(BK4819_AF_MUTE); - + gCurrentFunction == FUNCTION_INCOMING) // 1of11 + RADIO_SetModulation(gRxVfo->Modulation); + #ifdef ENABLE_FMRADIO if (gFmRadioMode) - BK1080_Mute(true); + BK1080_Mute(false); #endif - - AUDIO_AudioPathOn(); + + if (!gEnableSpeaker) + AUDIO_AudioPathOff(); + + gVoiceWriteIndex = 0; + gVoiceReadIndex = 0; #ifdef ENABLE_VOX - gVoxResumeCountdown = 2000; + gVoxResumeCountdown = 80; #endif - - SYSTEM_DelayMs(5); - AUDIO_PlayVoice(VoiceID); - - if (gVoiceWriteIndex == 1) - Delay += 3; - - if (bFlag) - { - SYSTEM_DelayMs(Delay * 10); - - if (gCurrentFunction == FUNCTION_RECEIVE || - gCurrentFunction == FUNCTION_MONITOR || - gCurrentFunction == FUNCTION_INCOMING) // 1of11 - RADIO_SetModulation(gRxVfo->Modulation); - - #ifdef ENABLE_FMRADIO - if (gFmRadioMode) - BK1080_Mute(false); - #endif - - if (!gEnableSpeaker) - AUDIO_AudioPathOff(); - - gVoiceWriteIndex = 0; - gVoiceReadIndex = 0; - - #ifdef ENABLE_VOX - gVoxResumeCountdown = 80; - #endif - - return; - } - - gVoiceReadIndex = 1; - gCountdownToPlayNextVoice_10ms = Delay; - gFlagPlayQueuedVoice = false; - + return; } - - Bailout: + + gVoiceReadIndex = 1; + gCountdownToPlayNextVoice_10ms = Delay; + gFlagPlayQueuedVoice = false; + + return; + } + +Bailout: + gVoiceReadIndex = 0; + gVoiceWriteIndex = 0; +} + +void AUDIO_SetVoiceID(uint8_t Index, VOICE_ID_t VoiceID) +{ + if (Index >= ARRAY_SIZE(gVoiceID)) + return; + + if (Index == 0) + { + gVoiceWriteIndex = 0; gVoiceReadIndex = 0; + } + + gVoiceID[Index] = VoiceID; + + gVoiceWriteIndex++; +} + +uint8_t AUDIO_SetDigitVoice(uint8_t Index, uint16_t Value) +{ + uint16_t Remainder; + uint8_t Result; + uint8_t Count; + + if (Index == 0) + { gVoiceWriteIndex = 0; + gVoiceReadIndex = 0; } - - void AUDIO_SetVoiceID(uint8_t Index, VOICE_ID_t VoiceID) + + Count = 0; + Result = Value / 1000U; + Remainder = Value % 1000U; + if (Remainder < 100U) { - if (Index >= ARRAY_SIZE(gVoiceID)) - return; - - if (Index == 0) - { - gVoiceWriteIndex = 0; - gVoiceReadIndex = 0; - } - - gVoiceID[Index] = VoiceID; - - gVoiceWriteIndex++; + if (Remainder < 10U) + goto Skip; } - - uint8_t AUDIO_SetDigitVoice(uint8_t Index, uint16_t Value) + else { - uint16_t Remainder; - uint8_t Result; - uint8_t Count; - - if (Index == 0) - { - gVoiceWriteIndex = 0; - gVoiceReadIndex = 0; - } - - Count = 0; - Result = Value / 1000U; - Remainder = Value % 1000U; - if (Remainder < 100U) - { - if (Remainder < 10U) - goto Skip; - } - else - { - Result = Remainder / 100U; - gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Result; - Count++; - Remainder -= Result * 100U; - } - Result = Remainder / 10U; + Result = Remainder / 100U; gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Result; Count++; - Remainder -= Result * 10U; - - Skip: - gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Remainder; - - return Count + 1U; + Remainder -= Result * 100U; } - - void AUDIO_PlayQueuedVoice(void) + Result = Remainder / 10U; + gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Result; + Count++; + Remainder -= Result * 10U; + +Skip: + gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Remainder; + + return Count + 1U; +} + +void AUDIO_PlayQueuedVoice(void) +{ + uint8_t VoiceID; + uint8_t Delay; + bool Skip; + + Skip = false; + + if (gVoiceReadIndex != gVoiceWriteIndex && gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF) { - uint8_t VoiceID; - uint8_t Delay; - bool Skip; - - Skip = false; - - if (gVoiceReadIndex != gVoiceWriteIndex && gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF) + VoiceID = gVoiceID[gVoiceReadIndex]; + if (gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE) { - VoiceID = gVoiceID[gVoiceReadIndex]; - if (gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE) + if (VoiceID < ARRAY_SIZE(VoiceClipLengthChinese)) { - if (VoiceID < ARRAY_SIZE(VoiceClipLengthChinese)) - { - Delay = VoiceClipLengthChinese[VoiceID]; - VoiceID += VOICE_ID_CHI_BASE; - } - else - Skip = true; + Delay = VoiceClipLengthChinese[VoiceID]; + VoiceID += VOICE_ID_CHI_BASE; } else + Skip = true; + } + else + { + if (VoiceID < ARRAY_SIZE(VoiceClipLengthEnglish)) { - if (VoiceID < ARRAY_SIZE(VoiceClipLengthEnglish)) - { - Delay = VoiceClipLengthEnglish[VoiceID]; - VoiceID += VOICE_ID_ENG_BASE; - } - else - Skip = true; - } - - gVoiceReadIndex++; - - if (!Skip) - { - if (gVoiceReadIndex == gVoiceWriteIndex) - Delay += 3; - - AUDIO_PlayVoice(VoiceID); - - gCountdownToPlayNextVoice_10ms = Delay; - gFlagPlayQueuedVoice = false; - - #ifdef ENABLE_VOX - gVoxResumeCountdown = 2000; - #endif - - return; + Delay = VoiceClipLengthEnglish[VoiceID]; + VoiceID += VOICE_ID_ENG_BASE; } + else + Skip = true; + } + + gVoiceReadIndex++; + + if (!Skip) + { + if (gVoiceReadIndex == gVoiceWriteIndex) + Delay += 3; + + AUDIO_PlayVoice(VoiceID); + + gCountdownToPlayNextVoice_10ms = Delay; + gFlagPlayQueuedVoice = false; + + #ifdef ENABLE_VOX + gVoxResumeCountdown = 2000; + #endif + + return; } - - if (gCurrentFunction == FUNCTION_RECEIVE || - gCurrentFunction == FUNCTION_MONITOR || - gCurrentFunction == FUNCTION_INCOMING) // 1of11 - RADIO_SetModulation(gRxVfo->Modulation); - - #ifdef ENABLE_FMRADIO - if (gFmRadioMode) - BK1080_Mute(false); - #endif - - if (!gEnableSpeaker) - AUDIO_AudioPathOff(); - - #ifdef ENABLE_VOX - gVoxResumeCountdown = 80; - #endif - - gVoiceWriteIndex = 0; - gVoiceReadIndex = 0; } -#endif + if (gCurrentFunction == FUNCTION_RECEIVE || + gCurrentFunction == FUNCTION_MONITOR || + gCurrentFunction == FUNCTION_INCOMING) + { + RADIO_SetModulation(gRxVfo->Modulation); // 1of11 + } + + #ifdef ENABLE_FMRADIO + if (gFmRadioMode) + BK1080_Mute(false); + #endif + if (!gEnableSpeaker) + AUDIO_AudioPathOff(); + + #ifdef ENABLE_VOX + gVoxResumeCountdown = 80; + #endif + + gVoiceWriteIndex = 0; + gVoiceReadIndex = 0; +} + +#endif