auth 发表于 2015-2-2 20:44:20

我的蜂鸣器音乐实例【原创】

本帖最后由 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:25:06

我以前玩的是葫芦娃,哈哈

hnyzcj 发表于 2015-2-2 21:25:39

本帖最后由 hnyzcj 于 2015-2-2 21:27 编辑

这个好像挺费事的,LZ辛苦了,赞一个。

heinau 发表于 2015-2-3 10:29:25

楼主的蜂鸣器演奏的好棒,音很准呢

Phoebe 发表于 2015-2-4 10:09:24

效果杠杠的,赞

auth 发表于 2015-2-4 19:35:09

hnyzcj 发表于 2015-2-2 21:25
这个好像挺费事的,LZ辛苦了,赞一个。

当你只做一首音乐的时候的确会很费事,可是如果做第二首、第N首的时候就会很方便了。

hnyzcj 发表于 2015-2-4 19:38:38

auth 发表于 2015-2-4 19:35
当你只做一首音乐的时候的确会很费事,可是如果做第二首、第N首的时候就会很方便了。 ...

哈哈,是的。

大连林海 发表于 2015-2-5 10:19:25

在你空间看的视频,弄完这首歌,lz辛苦啦

celine 发表于 2015-2-5 11:24:08

很有趣的!演奏的也很好听

李狗蛋 发表于 2020-12-25 19:47:21

复制了代码,显示expected unqualified-id before '<' token,怎么解决呀

温柔的投降 发表于 2020-12-26 13:42:50

可以,做的不错
页: [1]
查看完整版本: 我的蜂鸣器音乐实例【原创】