我的蜂鸣器音乐实例【原创】
本帖最后由 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); // 通过sizeof函数,将PuZi数组的总长度/PuZi数组第一个元素的长度,获得数组元素个数。
}
void loop()
{
// 通过for循环,将音符数组中的音符逐一取出播放延时为节拍时间。
for (int i = 0; i < Num; i++) {
tone(LaBa, YinFu(YinDiao, PuZi));//调用子程序YinFu,传递两个参数,YinDiao和音符,返回相应的频率
delay(PaiChang * JiePai );
if (LianYin == 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等变量值,就能很快制作出一首新曲子了,赶快动手试试吧!
http://player.youku.com/player.php/sid/XODg1MTQ4NDcy/v.swf
我以前玩的是葫芦娃,哈哈 本帖最后由 hnyzcj 于 2015-2-2 21:27 编辑
这个好像挺费事的,LZ辛苦了,赞一个。 楼主的蜂鸣器演奏的好棒,音很准呢 效果杠杠的,赞 hnyzcj 发表于 2015-2-2 21:25
这个好像挺费事的,LZ辛苦了,赞一个。
当你只做一首音乐的时候的确会很费事,可是如果做第二首、第N首的时候就会很方便了。 auth 发表于 2015-2-4 19:35
当你只做一首音乐的时候的确会很费事,可是如果做第二首、第N首的时候就会很方便了。 ...
哈哈,是的。 在你空间看的视频,弄完这首歌,lz辛苦啦 很有趣的!演奏的也很好听 复制了代码,显示expected unqualified-id before '<' token,怎么解决呀 可以,做的不错
页:
[1]