代码拉取完成,页面将自动刷新
#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__
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。