1 Star 4 Fork 8

vtor3478/vtor_elec_module

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
vtor_string_player.c 3.65 KB
一键复制 编辑 原始数据 按行查看 历史
#include "vtor_string_player.h"
#ifdef __VTOR_STRING_PLAYER__
//https://zhidao.baidu.com/question/1929397911420653787.html
const short VtorStringPlayer_toneArray[] = {0, // 0静音
262, 294, 330, 349, 392, 440, 494, // 1~7低音
523, 587, 659, 698, 784, 880, 988, // 8~14中音
1047, 1175, 1319, 1397, 1568, 1760, 1967 // 15~21高音
};
// 塞入音调下标和长度,自动整理成字符串
uint8_t* VtorStringPlayer_PushTone(uint8_t* str, uint8_t toneIdx, uint16_t toneLen)
{
// 先计算长度,如果0,就是0
if(toneIdx < 1)
{
*str++ = '0';
}
else if(toneIdx < 1 + 7)
{
*str++ = '-';
*str++ = (toneIdx - 1) + '1';
}
else if(toneIdx < 1 + 7 + 7)
{
*str++ = (toneIdx - 1 - 7) + '1';
}
else if(toneIdx < 1 + 7 + 7 + 7)
{
*str++ = '+';
*str++ = (toneIdx - 1 - 7 - 7) + '1';
}
uint8_t toneLenArray[] = {".,:;!=#@"};
int i = 7;
for( ; i > 0; i--)
{
if(toneLen & (1 << i))
{
*str++ = toneLenArray[i];
}
}
*str = '\0';
return str;
}
// 获取音调频率下标
uint8_t VtorStringPlayer_GetToneIdx(VtorStringPlayer* player)
{
uint8_t toneIdx = 1 + 7; // 中音1下标
while(*(player->curMusicChar))
{
uint8_t curChar = *(player->curMusicChar);
// 如果已有音调,且此时为数字,
// 得知音调“6”“+1”“++5”“-5”等,
// 由“+-”或数字开头
if('0' == curChar)
{
toneIdx = 0;
break;
// 0做特殊处理,直接结束,不再判断
}
// 调整低音和高音
toneIdx -= ('-' == curChar) ? 7 : 0;
toneIdx += ('+' == curChar) ? 7 : 0;
// 0代表静音,1~7代表不同音调
if('1' <= curChar && curChar <= '7')
{
toneIdx += (curChar - '1');
break;
}
// while内每次循环只处理1个字符
player->curMusicChar++;
}
// 返回之前,调整,使其指向下一个音符
player->curMusicChar++;
// 如果数组越界,回到静音状态
if(toneIdx > (1 + 3 * 7 - 1))
{
toneIdx = 0;
}
return toneIdx;
}
// 获取音调长度
uint16_t VtorStringPlayer_GetToneLen(VtorStringPlayer* player)
{
uint16_t toneLen = 0; // 基本长度
while(*(player->curMusicChar))
{
uint8_t curChar = *(player->curMusicChar);
// 长度分别为 1 2 4 8 16 32 64 128
// 默认是 = ,长度为32,后续调整长度
uint8_t toneLenArray[] = {".,:;!=#@"};
int i = 0;
for(i = 0; toneLenArray[i] != '\0'; i++)
{
if(curChar == toneLenArray[i])
{
toneLen += 1 << i;
break;
}
}
if('\0' == toneLenArray[i])
{
// 如果出现了不匹配,那么结束
break;
}
// 指向下一个说明符
player->curMusicChar++;
}
// 如果没有长度描述符,恢复成默认长度
if(0 == toneLen)
{
toneLen = player->presetToneLen;
// 如果静音,将长度默认为最短的1
if(0 == player->toneIdx)
{
toneLen = 1;
}
}
else
{
// 如果有长度描述符,以32作为基数,调整对应长度
toneLen = toneLen * player->presetToneLen / 32;
}
// 长度描述符后面一定是频率描述符,所以不用移动
return toneLen;
}
void VtorStringPlayer_Run(VtorStringPlayer* player)
{
// 当前音调,当前音调长度,当前频率
if (player->toneLen <= 0)
{
if('\0' == *(player->curMusicChar))
{
VtorStringPlayer_SwitchMusicCallback(player);
player->curMusicChar = player->curMusic[0];
}
player->toneIdx = VtorStringPlayer_GetToneIdx(player);
player->toneLen = VtorStringPlayer_GetToneLen(player);
player->freq = VtorStringPlayer_toneArray[player->toneIdx];
VtorStringPlayer_PlayFreq(player);
/*
VtorChanPrintf("tone %d %d %d [%s]\r\n",
player->tone, player->freq, player->toneLen,
*player->curMusicChar);
*/
}
player->toneLen--;
}
#endif // __VTOR_STRING_PLAYER__
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/vtor3478/vtor_elec_module.git
git@gitee.com:vtor3478/vtor_elec_module.git
vtor3478
vtor_elec_module
vtor_elec_module
main

搜索帮助

0d507c66 1850385 C8b1a773 1850385