TonePlayer音调播放器开发

音调播放器

           根据蜂鸣器的声音频率、播放长短和声音大小,来产生设备需要的音频:比如设备启动声音、设备关机音、故障音、连接成功音、断开连接音、信号不稳定提示音、充电启动提示音、充电关闭提示音、设备插入提示音、设备拔出提示音、无操作提示音以及需要的音乐(八音盒播放的那种声音);

参考:[11-2] 蜂鸣器播放提示音&音乐_哔哩哔哩_bilibili
补充:

#表示右侧的符号转化为字符串
##表示将左右的符号拼接在一起。例如拼接变量名MUSIC_DEF(name)等同MUSIC_DEF_name 

eg. 
#define ADD_MUSIC(mc) {Music_##mc,(sizeof(Music_##mc) / sizeof(Music_##mc[0])), #mc}
               ADD_MUSIC(Startup), // 等价 {ADD_MUSIC_Startup , 3 , "Startup" },
现在定义相关的设备启动声音、设备关机音、故障音、连接成功音、断开连接音、信号不稳定提示音、充电启动提示音、充电关闭提示音、设备插入提示音、设备拔出提示音、无操作提示音,音乐表如下:
 

#include "ToneMap.h"
//##表示将左右的符号拼接在一起。例如拼接变量名MUSIC_DEF(name)等同MUSIC_DEF_name
#define MUSIC_DEF(name) static const TonePlayer::MusicNode_t Music_##name[] =/*开机音 MUSIC_DEF_Startup[]={}; */
MUSIC_DEF(Startup)
{{M1, 80},{M6, 80},{M3, 80},
};/*关机音*/
MUSIC_DEF(Shutdown)
{{M3, 80},{M6, 80},{M1, 80},
};/*错误提示音*/
MUSIC_DEF(Error)
{{100, 80},{0,   80},{100, 80},
};/*连接成功音*/
MUSIC_DEF(Connect)
{{H1, 80},{H2, 80},{H3, 80},
};/*断开连接音*/
MUSIC_DEF(Disconnect)
{{H3, 80},{H2, 80},{H1, 80},
};/*信号不稳定提示音*/
MUSIC_DEF(UnstableConnect)
{{H1, 80},{0, 80},{H1, 80},
};/*充电启动提示音*/
MUSIC_DEF(BattChargeStart)
{{L1, 80},{L3, 80},
};/*充电关闭提示音*/
MUSIC_DEF(BattChargeEnd)
{{L3, 80},{L1, 80},
};/*设备插入提示音*/
MUSIC_DEF(DeviceInsert)
{/*C4,A3,F3,F4*/{M1, 180},{L6, 80},{L4, 80},{M4, 160},
};/*设备拔出提示音*/
MUSIC_DEF(DevicePullout)
{/*A4,F4,E4*/{L6, 80},{L4, 80},{L3, 80},
};/*无操作提示音*/
MUSIC_DEF(NoOperationWarning) 
{{4000, 40},{0, 80},{4000, 40},{0, 80},{4000, 40},
};/*列表数据类型定义*/
typedef struct
{const TonePlayer::MusicNode_t* mc;uint16_t length;const char* name;
} MusicList_t;
//#表示右侧的符号转化为字符串
//ADD_MUSIC(mc) {ADD_MUSIC_mc , 成员数 ,"mc" } 
#define ADD_MUSIC(mc) {Music_##mc,(sizeof(Music_##mc) / sizeof(Music_##mc[0])), #mc}/*提示音地址储存列表*/
static const MusicList_t MusicList[] =
{ADD_MUSIC(Startup), // 等价 {ADD_MUSIC_Startup , 3 , "Startup" },ADD_MUSIC(Shutdown),ADD_MUSIC(Error),ADD_MUSIC(Connect),ADD_MUSIC(Disconnect),ADD_MUSIC(UnstableConnect),ADD_MUSIC(BattChargeStart),ADD_MUSIC(BattChargeEnd),ADD_MUSIC(DeviceInsert),ADD_MUSIC(DevicePullout),ADD_MUSIC(NoOperationWarning),
};

音符频率列表

/*音符频率对应表*/
enum ToneMap
{L1 = 262,L1h = 277,L2 = 294,L2h = 311,L3 = 330,L4 = 349,L4h = 370,L5 = 392,L5h = 415,L6 = 440,L6h = 466,L7 = 494,M1 = 523,M1h = 554,M2 = 587,M2h = 622,M3 = 659,M4 = 698,M4h = 740,M5 = 784,M5h = 831,M6 = 880,M6h = 932,M7 = 988,H1 = 1046,H1h = 1109,H2 = 1175,H2h = 1245,H3 = 1318,H4 = 1397,H4h = 1480,H5 = 1568,H5h = 1661,H6 = 1760,H6h = 1865,H7 = 1976,
};

TonePlayer.cpp 

#include "TonePlayer.h"TonePlayer::TonePlayer()
{CallbackFunction = nullptr;CurrentMusic = nullptr;Speed = SPEED_NORMAL;
}void TonePlayer::SetMusic(const MusicNode_t* music, uint16_t length)
{if (music == CurrentMusic){return;}CurrentMusic = music;Length = length;CurrentPos = length;
}void TonePlayer::SetSpeed(uint16_t speed)
{Speed = speed;
}void TonePlayer::Play()
{CurrentPos = 0;
}void TonePlayer::Stop()
{CurrentPos = Length;
}bool TonePlayer::Update(uint32_t tick)
{if (CallbackFunction == nullptr){return false;}if(CurrentPos < Length){if(tick > NextTime){CallbackFunction(CurrentMusic[CurrentPos].Freq, CurrentMusic[CurrentPos].Volume);NextTime = tick + CurrentMusic[CurrentPos].Time * Speed / SPEED_NORMAL;CurrentPos++;}return true;}else if(CurrentPos == Length && tick > NextTime){CallbackFunction(0, 0);CurrentPos++;}return false;
}

TonePlayer.h

#include <stdint.h>class TonePlayer
{typedef void(*CallbackFunction_t)(uint32_t, uint16_t);
public://音乐链表typedef struct{uint16_t Freq;//频率uint16_t Time;//时长uint16_t Volume;//音量} MusicNode_t;//速度enum Speed{SPEED_HALF = 512,SPEED_NORMAL = 256,SPEED_DOUBLE = 128};TonePlayer();~TonePlayer() {}void SetMusic(const MusicNode_t* music, uint16_t length);void SetCallback(CallbackFunction_t func){CallbackFunction = func;}void Play();void Play(const MusicNode_t* music, uint16_t length){SetMusic(music, length);Play();}void Stop();void SetSpeed(uint16_t speed);bool Update(uint32_t tick);
private:uint16_t Length;uint16_t CurrentPos;uint32_t NextTime;uint16_t Speed;const MusicNode_t* CurrentMusic;CallbackFunction_t CallbackFunction;
};

回调函数定义

 沦陷更新控制蜂鸣器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/501140.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows系统搭建VisualSVN并结合内网穿透实现远程访问本地服务

文章目录 前言1. VisualSVN安装与配置2. VisualSVN Server管理界面配置3. 安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4. 固定公网地址访问 前言 SVN 是 subversion 的缩写&#xff0c;是一个开放源代码的版本控制系统…

Vue.js+SpringBoot开发音乐偏好度推荐系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、系统设计2.1 功能模块设计2.1.1 音乐档案模块2.1.2 我的喜好模块2.1.3 每日推荐模块2.1.4 通知公告模块 2.2 用例图设计2.3 实体类设计2.4 数据库设计 三、系统展示3.1 登录注册3.2 音乐档案模块3.3 音乐每日推荐模块3.4 通知公告模…

C++ //练习 10.15 编写一个lambda,捕获它所在函数的int,并接受一个int参数。lambda应该返回捕获的int和int参数的和。

C Primer&#xff08;第5版&#xff09; 练习 10.15 练习 10.15 编写一个lambda&#xff0c;捕获它所在函数的int&#xff0c;并接受一个int参数。lambda应该返回捕获的int和int参数的和。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;v…

PID闭环控制算法的学习与简单使用

平台&#xff1a;matlab2021b&#xff0c;Vivado2018 应用场景和理解 一个早餐店&#xff0c;假如一天都有生意&#xff0c;生意有的时间很火爆&#xff0c;有时候又一般&#xff0c;老板又是个实在人&#xff0c;只知道在后厨蒸包子。由于包子蒸熟需要一定的时间&#xff0c;老…

vscode更新至1.86版本后,ssh远程连接服务器出现异常

问题 you are connected to an OS version that is unsupported by Visual Studio Code 你已连接到不受Visual Studio Code支持的OS 版本 原因是vscode更新到1.86版本后要求远程连接服务器的内核版本和库版本需要符合下面条件。 解决方法 因此有两种方法解决 1.更新服务器…

Transformer之Residuals Decoder

The Residuals 我们需要提到的编码器架构中的一个细节是&#xff0c;每个编码器中的每个子层(self-attention,&#xff0c;ffnn)周围都有一个残余连接&#xff0c;然后是 layer-normalization 步骤。 如果我们要可视化向量和与 self attention 相关的 layer-norm 运算&#x…

记一次dockerfile无法构建问题追溯

我有一个dockerfile如下&#xff1a; ENTRYPOINT ["/sbin/tini"&#xff0c;"-g", "--"] CMD /home/scrapy/start.sh 我原本的用意是先启动tini&#xff0c;再执行下面的cmd命令启动start.sh。 为啥要用tini&#xff1f; 因为我的这个docker…

C语言的数据存储详解

C语言数据存储 文章目录 C语言数据存储类型的基本归类类型的意义 数据在内存中的存储整形在内存中的存储大小端整形提升和截断 浮点型在内存中的存储浮点型的存储规则E的不同情况 运用 类型的基本归类 有无符号的意义&#xff1a;生活中有写数据是没有符号之分的&#xff0c;将…

线程安全的队列

学习一下别人写的&#xff0c;线程安全的队列代码。https://github.com/markparticle/WebServer/blob/master/code/log/blockqueue.hhttps://github.com/markparticle/WebServer/blob/master/code/log/blockqueue.h /** Author : mark* Date : 2020-06-16* copy…

2024 2.24~3.1 周报

目录 一、本周计划 二、DD-Net整体介绍 三、DDNet的体系结构 四、损失函数 五、课程学习 六、实验环境 A. SEG盐数据集 B. OpenFWI数据集 C. 训练和前沿设置&#xff08;未完&#xff09; 七、结论 八、跑代码——对比试验结果&#xff08;CBAM&#xff09; 1. In…

el-table实现日期表头+二级表头+嵌套echarts

先上效果图 表头的时间首个是搜索项的endTime&#xff0c;后面的时间则是startTime到endTime-1的正序排列&#xff0c;折线图则是时间的正序排列 1、先实现月份表头&#xff0c;用的是项目封装后的el-table&#xff0c;但是跟直接在页面上实现没有啥区别 //数据结构 {"…

css背景图片属性

基础代码&#xff1a; div {width: 200px;height: 200px;background: url(./css-logo.png); }<div></div> 1、background-repeat&#xff1a;默认是repeat 设置背景图片在容器内是否平铺。 background-repeat: repeat-y; background-repeat: repeat-x; background…