2015-2-2 20:44:20 [显示全部楼层]
13124浏览
查看: 13124|回复: 10

[进阶] 我的蜂鸣器音乐实例【原创】

[复制链接]
本帖最后由 auth 于 2015-2-2 21:04 编辑
复制代码

刚开始接触蜂鸣器音乐的时候,都是使用了库文件,或者直接录入频率来演奏,这会有比较大的局限性,效率也低。

刚开始学习数组和子程序功能,将频率存放到子程序中,然后进行调用返回相应音符频率,实现既能快速实现音乐播放功能,又能方便调用。这里以歌曲“十年”简谱为例进行介绍。

我的蜂鸣器音乐实例【原创】图1
以下是程序代码:

  1. <p>/************************************************************
  2. Arduino实例学习14:蜂鸣器全能演奏【子程序版】
  3. 要点:带参子程序的定义,带参子程序的使用方法
  4. 难点:带参子程序的定义,带参子程序的使用方法
  5. 学习者:顾黄凯
  6. 本代码写于2015年01月31日晚
  7. ************************************************************/
  8. //低音前面加 - ,高音前面加1
  9. #define LaBa 8
  10. int Num;  //用于存放数组元素个数
  11. char* YinDiao = "A";  //音调
  12. int PaiChang = 800; //每拍长度
  13. int PuZi[] = {  //根据简谱将音符录入PuZi数组变量
  14.   0, 0, 1, 2,
  15.   3, 3, 2, 3,
  16.   2, 1, -7, -6, 0, -3, -6,
  17.   -5, -6, -7, -6, -5, -6,
  18.   0, 1, -7, -6, -7,
  19.   -6, 0,
  20.   0, -3, 1, -7, -6, -7,
  21.   -6, 0,
  22.   0, 0, 1, 2,
  23.   3, 3, 2, 3,
  24.   2, 3, 5, 1, 0, 3,
  25.   2, 2, 2, 1, -7, 1,
  26.   0, 1, 1, -7, -6, -7,
  27.   1, -6, -6,
  28.   0, -3, 1, -7, -6, -5,
  29.   -6, -7, -6,
  30.   0, 0,
  31.   0, -5, 3, 2, 1,
  32.   2, 3, 2, 2, -5,
  33.   0, 1, -6, -7, 1, 6, 5, 1,
  34.   3, 0, 3, 2, 3,
  35.   4, 0,
  36.   2, 3, 3, 4,
  37.   2, 3,
  38.   0, 1, 2, 5, 3,
  39.   3, 3, 3, 4, 5, 6,
  40.   2, 2, 2, 4, 3, 2,
  41.   1, -3, -3, 2, 1, -7,
  42.   1, -6, -6, 0, 1, -7, -6,
  43.   -7, 4, 3, 2, -7, 1,
  44.   1, 0, 1, 2, 3,
  45.   6, 3, 4, 5, 2, 3,
  46.   3, 2, 1, 2, 5, 3,
  47.   3, 3, 3, 4, 5, 6,
  48.   2, 2, 2, 4, 3, 2,
  49.   1, -3, -3, 2, 1, -7,
  50.   1, -6, -6, 0, 1, -7, -6,
  51.   -7, 4, 3, 2, 3, 2,
  52.   2, 1, 0, 1, 2, 3,
  53.   6, 6, 3, 1, 2,
  54.   2, 1, -7,
  55.   1,
  56.   0, 0, 1, 2,
  57.   3, 3, 2, 3,
  58.   2, 3, 5, 1, 0, 3,
  59.   2, 2, 2, 1, -7,
  60.   1, 1, 1, -7, -6, 1,
  61.   -6,
  62.   0, -5, 3, 2, 1, 2,
  63.   1,
  64.   1
  65. };
  66. float JiePai[] = {  //根据简谱上节拍,将每个音符相应的节拍录入JiePai数组变量,一拍记为1,半拍记为0.5……
  67.   1, 0.5, 0.25, 0.25,
  68.   0.5, 0.5, 0.5, 0.5,
  69.   0.25, 0.25, 0.25, 0.25, 0.5, 0.25, 0.25,
  70.   0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
  71.   1, 0.25, 0.25, 0.25, 0.25,
  72.   1, 1,
  73.   0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
  74.   1, 1,
  75.   1, 0.5, 0.25, 0.25,
  76.   0.5, 0.5, 0.5, 0.5,
  77.   0.25, 0.25, 0.25, 0.25, 0.5 + 0.25, 0.25,
  78.   0.5, 0.5, 0.25, 0.25, 0.25, 0.25,
  79.   0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
  80.   0.5, 0.5, 1,
  81.   0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
  82.   0.5, 0.5, 1,
  83.   1, 1,
  84.   0.5 + 0.25, 0.25, 0.5, 0.25, 0.25,
  85.   0.5, 0.25, 0.25, 0.5, 0.5,
  86.   0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
  87.   1, 0.25, 0.25, 0.25, 0.25,
  88.   1, 1,
  89.   0.5 + 0.25, 0.25, 0.5, 0.5,
  90.   0.0625, 0.9375 + 1,
  91.   1, 0.25, 0.25, 0.25, 0.25,
  92.   0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
  93.   0.5, 0.5, 0.25, 0.25, 0.25, 0.25,
  94.   0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
  95.   0.25, 0.25, 0.5, 0.25, 0.25, 0.25, 0.25,
  96.   0.5, 0.25, 0.25, 0.5, 0.25, 0.25,
  97.   1, 0.25, 0.25, 0.25, 0.25,
  98.   0.5 + 0.25,0.25, 0.5, 0.25, 0.03125, 0.1875 + 0.03125,
  99.   0.5, 0.5, 0.25, 0.25, 0.25, 0.25,
  100.   0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
  101.   0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
  102.   0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
  103.   0.25, 0.25, 0.5, 0.25, 0.25, 0.25, 0.25,
  104.   0.5, 0.25, 0.25, 0.5, 0.25, 0.25,
  105.   0.25, 0.5 + 0.25, 0.25, 0.25, 0.25, 0.25,
  106.   0.5 + 0.25, 0.25, 0.5, 0.25, 0.25,
  107.   1 + 0.5, 0.25, 0.25,
  108.   2,
  109.   1, 0.5, 0.25, 0.25,
  110.   0.5, 0.5, 0.5, 0.5,
  111.   0.25, 0.25, 0.25, 0.25, 0.5 + 0.25, 0.25,
  112.   0.5, 0.5, 0.25, 0.25, 0.5,
  113.   0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
  114.   2,
  115.   0.5 + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
  116.   2,
  117.   1
  118. };
  119. //为了解决连音的问题,这里使用一个连音控制数组变量,需要连音的地方使用1,否则使用0
  120. int LianYin[]={
  121.     0,0,0,0,
  122.     0,0,0,0,
  123.     0,0,0,0,0,0,0,
  124.     0,0,0,0,0,0,
  125.     0,0,0,0,0,
  126.     0,0,
  127.     0,0,0,0,0,0,
  128.     0,0,
  129.     0,0,0,0,
  130.     0,0,0,0,
  131.     0,0,0,0,0,0,
  132.     0,0,0,0,0,0,
  133.     0,0,0,0,0,0,
  134.     0,1,0,
  135.     0,0,0,0,0,0,
  136.     0,0,0,
  137.     0,0,
  138.     0,0,0,0,0,
  139.     0,0,1,0,0,
  140.     0,0,0,0,0,0,0,0,
  141.     0,0,0,0,0,
  142.     0,0,
  143.     0,1,0,0,
  144.     1,0,
  145.     0,0,0,1,0,
  146.     0,1,0,0,0,0,
  147.     0,1,0,0,0,0,
  148.     0,1,0,0,0,0,
  149.     1,0,0,0,0,0,0,
  150.     0,0,0,0,0,1,
  151.     0,0,0,0,0,
  152.     0,0,0,0,1,1,
  153.     0,0,0,0,1,0,
  154.     0,1,0,0,0,0,
  155.     0,1,0,0,0,0,
  156.     0,1,0,0,0,0,
  157.     1,0,0,0,0,0,0,
  158.     0,0,0,0,0,1,
  159.     0,0,0,0,0,0,
  160.     0,0,0,0,1,
  161.     0,1,0,
  162.     0,
  163.     0,0,0,0,
  164.     0,0,0,0,
  165.     0,0,0,0,0,0,
  166.     0,0,0,0,0,
  167.     0,0,0,0,0,0,
  168.     0,
  169.     0,0,0,0,0,0,
  170.     1,
  171.     0        
  172. };
  173. void setup(){
  174.   Num = sizeof(PuZi) / sizeof(PuZi[0]); // 通过sizeof函数,将PuZi数组的总长度/PuZi数组第一个元素的长度,获得数组元素个数。
  175.   
  176. }
  177. void loop()
  178. {
  179.    // 通过for循环,将音符数组中的音符逐一取出播放延时为节拍时间。
  180.    for (int i = 0; i < Num; i++) {     
  181.      tone(LaBa, YinFu(YinDiao, PuZi[i]));  //调用子程序YinFu,传递两个参数,YinDiao和音符,返回相应的频率
  182.      delay(PaiChang * JiePai[i] );
  183.      if (LianYin[i] == 0) {
  184.        tone(LaBa, -1);  //连音的地方不用停顿
  185.      };
  186.    }
  187.    tone(LaBa, -1);  // 设置喇叭静音
  188.    delay( 3000 );
  189. }</p><p> </p><p>//定义一个具有返回值的带参子程序,如果你有时间,可以将B大调等进行完善,为了让大家也动动手,这里只留着A大调的相关频率数据。静音为0,-1为低音do,11为高音do
  190. int YinFu(char* _YinDiao, int _FuHao) {
  191.   if (_YinDiao == "A") {
  192.     switch (_FuHao) {
  193.       case 0:
  194.         return -1;
  195.         break;
  196.       case -1:
  197.         return 221;
  198.         break;
  199.       case -2:
  200.         return 248;
  201.         break;
  202.       case -3:
  203.         return 278;
  204.         break;
  205.       case -4:
  206.         return 294;
  207.         break;
  208.       case -5:
  209.         return 330;
  210.         break;
  211.       case -6:
  212.         return 371;
  213.         break;
  214.       case -7:
  215.         return 416;
  216.         break;
  217.       case 1:
  218.         return 441;
  219.         break;
  220.       case 2:
  221.         return 495;
  222.         break;
  223.       case 3:
  224.         return 556;
  225.         break;
  226.       case 4:
  227.         return 589;
  228.         break;
  229.       case 5:
  230.         return 661;
  231.         break;
  232.       case 6:
  233.         return 742;
  234.         break;
  235.       case 7:
  236.         return 833;
  237.         break;
  238.       case 11:
  239.         return 882;
  240.         break;
  241.       case 12:
  242.         return 990;
  243.         break;
  244.       case 13:
  245.         return 1112;
  246.         break;
  247.       case 14:
  248.         return 1178;
  249.         break;
  250.       case 15:
  251.         return 1322;
  252.         break;
  253.       case 16:
  254.         return 1484;
  255.         break;
  256.       case 17:
  257.         return 1665;
  258.         break;
  259.     }
  260.   }
  261. }
复制代码
使用这个方式制作蜂鸣器歌曲播放是不是很方便快捷呀?
当你拥有了完整的音调库,只要改变JianPu、JiePai等变量值,就能很快制作出一首新曲子了,赶快动手试试吧!





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

可以,做的不错
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail