Voice driver

This commit is contained in:
muzkr committed 2025-10-29 03:23:03 +08:00
1 parent 554315bab5
commit bf31740faa
7 files changed
+296 -102

No files matched your search

+97 -44
View File
@@ -1,4 +1,5 @@
/* Copyright 2023 Dual Tachyon
/* Copyright 2025 muzkr https://github.com/muzkr
* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,6 +26,8 @@
#include "driver/gpio.h"
#include "driver/system.h"
#include "driver/systick.h"
#include "driver/voice.h"
#include "driver/py25q16.h"
#include "functions.h"
#include "misc.h"
#include "settings.h"
@@ -198,31 +201,10 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
#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,
};
uint16_t gVoiceBuf[VOICE_BUF_CAP][VOICE_BUF_LEN];
uint8_t gVoiceBufReadIndex = 0;
uint8_t gVoiceBufWriteIndex = 0;
uint8_t gVoiceBufLen = 0;
VOICE_ID_t gVoiceID[8];
uint8_t gVoiceReadIndex;
@@ -231,29 +213,100 @@ volatile uint16_t gCountdownToPlayNextVoice_10ms;
volatile bool gFlagPlayQueuedVoice;
VOICE_ID_t gAnotherVoiceID = VOICE_ID_INVALID;
static void AUDIO_PlayVoice(uint8_t VoiceID)
static const uint16_t VOICE_SAMPLES[256] =
{
unsigned int i;
0x06a8, 0x06b8, 0x0688, 0x0698, 0x06e8, 0x06f8, 0x06c8, 0x06d8, //
0x0628, 0x0638, 0x0608, 0x0618, 0x0668, 0x0678, 0x0648, 0x0658, //
0x0754, 0x075c, 0x0744, 0x074c, 0x0774, 0x077c, 0x0764, 0x076c, //
0x0714, 0x071c, 0x0704, 0x070c, 0x0734, 0x073c, 0x0724, 0x072c, //
0x02a0, 0x02e0, 0x0220, 0x0260, 0x03a0, 0x03e0, 0x0320, 0x0360, //
0x00a0, 0x00e0, 0x0020, 0x0060, 0x01a0, 0x01e0, 0x0120, 0x0160, //
0x0550, 0x0570, 0x0510, 0x0530, 0x05d0, 0x05f0, 0x0590, 0x05b0, //
0x0450, 0x0470, 0x0410, 0x0430, 0x04d0, 0x04f0, 0x0490, 0x04b0, //
0x07ea, 0x07eb, 0x07e8, 0x07e9, 0x07ee, 0x07ef, 0x07ec, 0x07ed, //
0x07e2, 0x07e3, 0x07e0, 0x07e1, 0x07e6, 0x07e7, 0x07e4, 0x07e5, //
0x07fa, 0x07fb, 0x07f8, 0x07f9, 0x07fe, 0x07ff, 0x07fc, 0x07fd, //
0x07f2, 0x07f3, 0x07f0, 0x07f1, 0x07f6, 0x07f7, 0x07f4, 0x07f5, //
0x07aa, 0x07ae, 0x07a2, 0x07a6, 0x07ba, 0x07be, 0x07b2, 0x07b6, //
0x078a, 0x078e, 0x0782, 0x0786, 0x079a, 0x079e, 0x0792, 0x0796, //
0x07d5, 0x07d7, 0x07d1, 0x07d3, 0x07dd, 0x07df, 0x07d9, 0x07db, //
0x07c5, 0x07c7, 0x07c1, 0x07c3, 0x07cd, 0x07cf, 0x07c9, 0x07cb, //
0x0958, 0x0948, 0x0978, 0x0968, 0x0918, 0x0908, 0x0938, 0x0928, //
0x09d8, 0x09c8, 0x09f8, 0x09e8, 0x0998, 0x0988, 0x09b8, 0x09a8, //
0x08ac, 0x08a4, 0x08bc, 0x08b4, 0x088c, 0x0884, 0x089c, 0x0894, //
0x08ec, 0x08e4, 0x08fc, 0x08f4, 0x08cc, 0x08c4, 0x08dc, 0x08d4, //
0x0d60, 0x0d20, 0x0de0, 0x0da0, 0x0c60, 0x0c20, 0x0ce0, 0x0ca0, //
0x0f60, 0x0f20, 0x0fe0, 0x0fa0, 0x0e60, 0x0e20, 0x0ee0, 0x0ea0, //
0x0ab0, 0x0a90, 0x0af0, 0x0ad0, 0x0a30, 0x0a10, 0x0a70, 0x0a50, //
0x0bb0, 0x0b90, 0x0bf0, 0x0bd0, 0x0b30, 0x0b10, 0x0b70, 0x0b50, //
0x0815, 0x0814, 0x0817, 0x0816, 0x0811, 0x0810, 0x0813, 0x0812, //
0x081d, 0x081c, 0x081f, 0x081e, 0x0819, 0x0818, 0x081b, 0x081a, //
0x0805, 0x0804, 0x0807, 0x0806, 0x0801, 0x0800, 0x0803, 0x0802, //
0x080d, 0x080c, 0x080f, 0x080e, 0x0809, 0x0808, 0x080b, 0x080a, //
0x0856, 0x0852, 0x085e, 0x085a, 0x0846, 0x0842, 0x084e, 0x084a, //
0x0876, 0x0872, 0x087e, 0x087a, 0x0866, 0x0862, 0x086e, 0x086a, //
0x082b, 0x0829, 0x082f, 0x082d, 0x0823, 0x0821, 0x0827, 0x0825, //
0x083b, 0x0839, 0x083f, 0x083d, 0x0833, 0x0831, 0x0837, 0x0835 //
};
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
SYSTEM_DelayMs(20);
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
static struct
{
uint32_t Addr;
uint32_t Size;
} VoiceClipState = {0};
for (i = 0; i < 8; i++)
static bool LoadVoiceClip(uint8_t VoiceID)
{
if (VoiceID >= VOICE_ID_END)
{
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);
return false;
}
uint32_t Addr = gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE ? 0x14c000 : 0x14c800;
struct
{
uint32_t Offset;
uint32_t Size;
} Info;
PY25Q16_ReadBuffer(Addr + 8 * VoiceID, &Info, 8);
if (Info.Offset > 0x0b0000 || Info.Size > 0x019000)
{
return false;
}
VoiceClipState.Addr = 0x14d000 + Info.Offset;
VoiceClipState.Size = Info.Size;
return true;
}
static inline uint32_t CalcDelay(uint32_t Size)
{
return 2 * Size; // in ms!!
}
static void LoadVoiceSamples() {
if (0 == VoiceClipState.Addr || 0 == VoiceClipState.Size)
{
return;
}
if (gVoiceBufLen >= VOICE_BUF_CAP)
{
return;
}
extern uint8_t **gFrameBuffer;
uint8_t *Buf = (uint8_t *)gFrameBuffer;
PY25Q16_ReadBuffer(VoiceClipState.Addr, Buf, VOICE_BUF_LEN);
VoiceClipState.Addr += VOICE_BUF_LEN;
VoiceClipState.Size -= VOICE_BUF_LEN;
for (uint32_t i = 0; i < VOICE_BUF_LEN; i++)
{
gVoiceBuf[gVoiceBufWriteIndex][i] = VOICE_SAMPLES[Buf[i]];
}
VOCIE_BUF_ForwardWriteIndex();
gVoiceBufLen++;
}
void AUDIO_PlaySingleVoice(bool bFlag)