本帖最后由 auth 于 2015-2-2 21:04 编辑
复制代码
刚开始接触蜂鸣器音乐的时候,都是使用了库文件,或者直接录入频率来演奏,这会有比较大的局限性,效率也低。
刚开始学习数组和子程序功能,将频率存放到子程序中,然后进行调用返回相应音符频率,实现既能快速实现音乐播放功能,又能方便调用。这里以歌曲“十年”简谱为例进行介绍。
以下是程序代码:
- <p>/************************************************************
- Arduino实例学习14:蜂鸣器全能演奏【子程序版】
- 要点:带参子程序的定义,带参子程序的使用方法
- 难点:带参子程序的定义,带参子程序的使用方法
- 学习者:顾黄凯
- 本代码写于2015年01月31日晚
- ************************************************************/
-
- //低音前面加 - ,高音前面加1
-
- #define LaBa 8
- int Num; //用于存放数组元素个数
- char* YinDiao = "A"; //音调
- int PaiChang = 800; //每拍长度
-
- int PuZi[] = { //根据简谱将音符录入PuZi数组变量
- 0, 0, 1, 2,
- 3, 3, 2, 3,
- 2, 1, -7, -6, 0, -3, -6,
- -5, -6, -7, -6, -5, -6,
- 0, 1, -7, -6, -7,
- -6, 0,
- 0, -3, 1, -7, -6, -7,
- -6, 0,
- 0, 0, 1, 2,
- 3, 3, 2, 3,
- 2, 3, 5, 1, 0, 3,
- 2, 2, 2, 1, -7, 1,
- 0, 1, 1, -7, -6, -7,
- 1, -6, -6,
- 0, -3, 1, -7, -6, -5,
- -6, -7, -6,
- 0, 0,
- 0, -5, 3, 2, 1,
- 2, 3, 2, 2, -5,
- 0, 1, -6, -7, 1, 6, 5, 1,
- 3, 0, 3, 2, 3,
- 4, 0,
- 2, 3, 3, 4,
- 2, 3,
- 0, 1, 2, 5, 3,
- 3, 3, 3, 4, 5, 6,
- 2, 2, 2, 4, 3, 2,
- 1, -3, -3, 2, 1, -7,
- 1, -6, -6, 0, 1, -7, -6,
- -7, 4, 3, 2, -7, 1,
- 1, 0, 1, 2, 3,
- 6, 3, 4, 5, 2, 3,
- 3, 2, 1, 2, 5, 3,
- 3, 3, 3, 4, 5, 6,
- 2, 2, 2, 4, 3, 2,
- 1, -3, -3, 2, 1, -7,
- 1, -6, -6, 0, 1, -7, -6,
- -7, 4, 3, 2, 3, 2,
- 2, 1, 0, 1, 2, 3,
- 6, 6, 3, 1, 2,
- 2, 1, -7,
- 1,
- 0, 0, 1, 2,
- 3, 3, 2, 3,
- 2, 3, 5, 1, 0, 3,
- 2, 2, 2, 1, -7,
- 1, 1, 1, -7, -6, 1,
- -6,
- 0, -5, 3, 2, 1, 2,
- 1,
- 1
- };
-
- float JiePai[] = { //根据简谱上节拍,将每个音符相应的节拍录入JiePai数组变量,一拍记为1,半拍记为0.5……
- 1, 0.5, 0.25, 0.25,
- 0.5, 0.5, 0.5, 0.5,
- 0.25, 0.25, 0.25, 0.25, 0.5, 0.25, 0.25,
- 0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
- 1, 0.25, 0.25, 0.25, 0.25,
- 1, 1,
- 0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
- 1, 1,
- 1, 0.5, 0.25, 0.25,
- 0.5, 0.5, 0.5, 0.5,
- 0.25, 0.25, 0.25, 0.25, 0.5 + 0.25, 0.25,
- 0.5, 0.5, 0.25, 0.25, 0.25, 0.25,
- 0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
- 0.5, 0.5, 1,
- 0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
- 0.5, 0.5, 1,
- 1, 1,
- 0.5 + 0.25, 0.25, 0.5, 0.25, 0.25,
- 0.5, 0.25, 0.25, 0.5, 0.5,
- 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
- 1, 0.25, 0.25, 0.25, 0.25,
- 1, 1,
- 0.5 + 0.25, 0.25, 0.5, 0.5,
- 0.0625, 0.9375 + 1,
- 1, 0.25, 0.25, 0.25, 0.25,
- 0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
- 0.5, 0.5, 0.25, 0.25, 0.25, 0.25,
- 0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
- 0.25, 0.25, 0.5, 0.25, 0.25, 0.25, 0.25,
- 0.5, 0.25, 0.25, 0.5, 0.25, 0.25,
- 1, 0.25, 0.25, 0.25, 0.25,
- 0.5 + 0.25,0.25, 0.5, 0.25, 0.03125, 0.1875 + 0.03125,
- 0.5, 0.5, 0.25, 0.25, 0.25, 0.25,
- 0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
- 0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
- 0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
- 0.25, 0.25, 0.5, 0.25, 0.25, 0.25, 0.25,
- 0.5, 0.25, 0.25, 0.5, 0.25, 0.25,
- 0.25, 0.5 + 0.25, 0.25, 0.25, 0.25, 0.25,
- 0.5 + 0.25, 0.25, 0.5, 0.25, 0.25,
- 1 + 0.5, 0.25, 0.25,
- 2,
- 1, 0.5, 0.25, 0.25,
- 0.5, 0.5, 0.5, 0.5,
- 0.25, 0.25, 0.25, 0.25, 0.5 + 0.25, 0.25,
- 0.5, 0.5, 0.25, 0.25, 0.5,
- 0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
- 2,
- 0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
- 2,
- 1
- };
- //为了解决连音的问题,这里使用一个连音控制数组变量,需要连音的地方使用1,否则使用0
- int LianYin[]={
- 0,0,0,0,
- 0,0,0,0,
- 0,0,0,0,0,0,0,
- 0,0,0,0,0,0,
- 0,0,0,0,0,
- 0,0,
- 0,0,0,0,0,0,
- 0,0,
- 0,0,0,0,
- 0,0,0,0,
- 0,0,0,0,0,0,
- 0,0,0,0,0,0,
- 0,0,0,0,0,0,
- 0,1,0,
- 0,0,0,0,0,0,
- 0,0,0,
- 0,0,
- 0,0,0,0,0,
- 0,0,1,0,0,
- 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,
- 0,0,
- 0,1,0,0,
- 1,0,
- 0,0,0,1,0,
- 0,1,0,0,0,0,
- 0,1,0,0,0,0,
- 0,1,0,0,0,0,
- 1,0,0,0,0,0,0,
- 0,0,0,0,0,1,
- 0,0,0,0,0,
- 0,0,0,0,1,1,
- 0,0,0,0,1,0,
- 0,1,0,0,0,0,
- 0,1,0,0,0,0,
- 0,1,0,0,0,0,
- 1,0,0,0,0,0,0,
- 0,0,0,0,0,1,
- 0,0,0,0,0,0,
- 0,0,0,0,1,
- 0,1,0,
- 0,
- 0,0,0,0,
- 0,0,0,0,
- 0,0,0,0,0,0,
- 0,0,0,0,0,
- 0,0,0,0,0,0,
- 0,
- 0,0,0,0,0,0,
- 1,
- 0
- };
-
-
- void setup(){
- Num = sizeof(PuZi) / sizeof(PuZi[0]); // 通过sizeof函数,将PuZi数组的总长度/PuZi数组第一个元素的长度,获得数组元素个数。
-
- }
-
- void loop()
- {
- // 通过for循环,将音符数组中的音符逐一取出播放延时为节拍时间。
- for (int i = 0; i < Num; i++) {
- tone(LaBa, YinFu(YinDiao, PuZi[i])); //调用子程序YinFu,传递两个参数,YinDiao和音符,返回相应的频率
- delay(PaiChang * JiePai[i] );
- if (LianYin[i] == 0) {
- tone(LaBa, -1); //连音的地方不用停顿
- };
- }
- tone(LaBa, -1); // 设置喇叭静音
- delay( 3000 );
- }</p><p> </p><p>//定义一个具有返回值的带参子程序,如果你有时间,可以将B大调等进行完善,为了让大家也动动手,这里只留着A大调的相关频率数据。静音为0,-1为低音do,11为高音do
- int YinFu(char* _YinDiao, int _FuHao) {
- if (_YinDiao == "A") {
- switch (_FuHao) {
- case 0:
- return -1;
- break;
- case -1:
- return 221;
- break;
- case -2:
- return 248;
- break;
- case -3:
- return 278;
- break;
- case -4:
- return 294;
- break;
- case -5:
- return 330;
- break;
- case -6:
- return 371;
- break;
- case -7:
- return 416;
- break;
- case 1:
- return 441;
- break;
- case 2:
- return 495;
- break;
- case 3:
- return 556;
- break;
- case 4:
- return 589;
- break;
- case 5:
- return 661;
- break;
- case 6:
- return 742;
- break;
- case 7:
- return 833;
- break;
- case 11:
- return 882;
- break;
- case 12:
- return 990;
- break;
- case 13:
- return 1112;
- break;
- case 14:
- return 1178;
- break;
- case 15:
- return 1322;
- break;
- case 16:
- return 1484;
- break;
- case 17:
- return 1665;
- break;
- }
- }
- }
复制代码
使用这个方式制作蜂鸣器歌曲播放是不是很方便快捷呀?
当你拥有了完整的音调库,只要改变JianPu、JiePai等变量值,就能很快制作出一首新曲子了,赶快动手试试吧!
|