【单音MIDI音乐】两种代码解决方案-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 6383|回复: 3

【单音MIDI音乐】两种代码解决方案

[复制链接]
发表于 2016-4-27 18:07 | 显示全部楼层 |阅读模式
本帖最后由 Mitsuka 于 2016-4-29 15:28 编辑

考虑到各位对代码的复杂度,所以特意推出两种解决方案:源代码地址:http://www.arduino.cn/thread-20602-1-1.html
(1)第一种方案:和原来一样,把所有函数在程序前面都预先定义好,然后再写谱,如:

[mw_shl_code=cpp,true]const float bpm = 192; //bpm = beats per min, changable

void dura(int x)
{ int dura[] = {240000/bpm,120000/bpm,60000/bpm,30000/bpm,15000/bpm,7500/bpm,3750/bpm};
  delay(dura[x-1]);
  rest(8);
  delay(50);}

void durac(int x)
{ int durac[] = {240000/bpm,120000/bpm,60000/bpm,30000/bpm,15000/bpm,7500/bpm,3750/bpm};
  delay(durac[x-1]);}

void do_ut(int pin,int x)
{ int C[] = {33,65,131,262,523,1047,2093};
  tone(pin,C[x-1]);}

void do_up(int pin,int x)
{ int CU[] = {35,69,139,277,554,1109,2217};
  tone(pin,CU[x-1]);}

void re_dw(int pin,int x)
{ int DD[] = {35,69,139,277,554,1109,2217};
  tone(pin,DD[x-1]);}

void re(int pin,int x)
{ int D[] = {37,73,147,294,587,1175,2349};
  tone(pin,D[x-1]);}

void re_up(int pin,int x)
{ int DU[] = {39,78,156,311,622,1245,2489};
  tone(pin,DU[x-1]);}

void mi_dw(int pin,int x)
{ int ED[] = {39,78,156,311,622,1245,2489};
  tone(pin,ED[x-1]);}

void mi(int pin,int x)
{ int E[] = {41,82,165,330,659,1319,2637};
  tone(pin,E[x-1]);}

void fa(int pin,int x)
{ int F[] = {44,87,175,349,698,1397,2794};
  tone(pin,F[x-1]);}

void fa_up(int pin,int x)
{ int FU[] = {46,93,185,370,740,1480,2960};
  tone(pin,FU[x-1]);}

void sol_dw(int pin,int x)
{ int GD[] = {46,93,185,370,740,1480,2960};
  tone(pin,GD[x-1]);}

void sol(int pin,int x)
{ int G[] = {49,98,196,392,784,1568,3136};
  tone(pin,G[x-1]);}

void sol_up(int pin,int x)
{ int GU[] = {52,104,208,415,831,1661,3322};
  tone(pin,GU[x-1]);}

void la_dw(int pin,int x)
{ int AD[] = {52,104,208,415,831,1661,3322};
  tone(pin,AD[x-1]);}

void la(int pin,int x)
{ int A[] = {55,110,220,440,880,1760,3520};
  tone(pin,A[x-1]);}

void la_up(int pin,int x)
{ int AU[] = {58,117,233,466,932,1865,3729};
  tone(pin,AU[x-1]);}

void si_dw(int pin,int x)
{ int BD[] = {58,117,233,466,932,1865,3729};
  tone(pin,BD[x-1]);}

void si(int pin,int x)
{ int B[] = {62,123,247,494,988,1976,3951};
  tone(pin,B[x-1]);}

void rest(int pin)
{ tone(pin, 0);}

void setup()
{
// whole = 1;
// half = 2;
// quarter = 3;
// eighth = 4;
// sixteenth = 5;
// thirtysecond = 6;
// sixtyforth = 7;
}

void loop()
{
  do_ut(8,4); dura(3);
  do_ut(8,4); dura(3);
  sol(8,4);   dura(3);
  sol(8,4);   dura(3);  
  la(8,4);    dura(3);
  la(8,4);    dura(3);  
  sol(8,4);   dura(2);

  fa(8,4);    dura(3);
  fa(8,4);    dura(3);
  mi(8,4);    dura(3);
  mi(8,4);    dura(3);
  re(8,4);    dura(3);
  re(8,4);    dura(3);
  do_ut(8,4); dura(2);

  sol(8,4);   dura(3);
  sol(8,4);   dura(3);
  fa(8,4);    dura(3);
  fa(8,4);    dura(3);
  mi(8,4);    dura(3);
  mi(8,4);    dura(3);
  re(8,4);    dura(2);

  sol(8,4);   dura(3);
  sol(8,4);   dura(3);
  fa(8,4);    dura(3);
  fa(8,4);    dura(3);
  mi(8,4);    dura(3);
  mi(8,4);    dura(3);
  re(8,4);    dura(2);

  do_ut(8,4); dura(3);
  do_ut(8,4); dura(3);
  sol(8,4);   dura(3);
  sol(8,4);   dura(3);  
  la(8,4);    dura(3);
  la(8,4);    dura(3);  
  sol(8,4);   dura(2);

  fa(8,4);    dura(3);
  fa(8,4);    dura(3);
  mi(8,4);    dura(3);
  mi(8,4);    dura(3);
  re(8,4);    dura(3);
  re(8,4);    dura(3);
  do_ut(8,4); dura(2);
  rest(8);
  delay(50);
}[/mw_shl_code]


(2)第二种方案:做成库文件,然后自行调用:
在教程的帮助下,我把程序的所有函数都做成库文件: Scale.zip (3.91 KB, 下载次数: 29)

各位能够将该压缩包的文件解压后放入Arduino安装目录的以下路径中:
(Arduino文件夹所在路径)\Arduino\libraries
或者在Arduino IDE中选择项目->Include Library->Add .zip Library添加。
添加好库文件后,在IDE中选择项目->Include Library->Scale就可以在程序中加入了该库文件。
使用库文件后的代码如下:
[mw_shl_code=cpp,true]#include <Scale.h>

int pin = 8;
Scale scale(pin,12);

void setup()
{
/* Attention:
* whole = 1;
* half = 2;
* quarter = 3;
* eighth = 4;
* scale.scale.scale.sixteenth = 5;
* thirtysecond = 6;
* scale.scale.scale.sixtyforth = 7;
*/
}

void loop()
{
  scale.do_ut(4); scale.dura(3);
  scale.do_ut(4); scale.dura(3);
  scale.sol(4);   scale.dura(3);
  scale.sol(4);   scale.dura(3);  
  scale.la(4);    scale.dura(3);
  scale.la(4);    scale.dura(3);  
  scale.sol(4);   scale.dura(2);

  scale.fa(4);    scale.dura(3);
  scale.fa(4);    scale.dura(3);
  scale.mi(4);    scale.dura(3);
  scale.mi(4);    scale.dura(3);
  scale.re(4);    scale.dura(3);
  scale.re(4);    scale.dura(3);
  scale.do_ut(4); scale.dura(2);

  scale.sol(4);   scale.dura(3);
  scale.sol(4);   scale.dura(3);
  scale.fa(4);    scale.dura(3);
  scale.fa(4);    scale.dura(3);
  scale.mi(4);    scale.dura(3);
  scale.mi(4);    scale.dura(3);
  scale.re(4);    scale.dura(2);

  scale.sol(4);   scale.dura(3);
  scale.sol(4);   scale.dura(3);
  scale.fa(4);    scale.dura(3);
  scale.fa(4);    scale.dura(3);
  scale.mi(4);    scale.dura(3);
  scale.mi(4);    scale.dura(3);
  scale.re(4);    scale.dura(2);

  scale.do_ut(4); scale.dura(3);
  scale.do_ut(4); scale.dura(3);
  scale.sol(4);   scale.dura(3);
  scale.sol(4);   scale.dura(3);  
  scale.la(4);    scale.dura(3);
  scale.la(4);    scale.dura(3);  
  scale.sol(4);   scale.dura(2);

  scale.fa(4);    scale.dura(3);
  scale.fa(4);    scale.dura(3);
  scale.mi(4);    scale.dura(3);
  scale.mi(4);    scale.dura(3);
  scale.re(4);    scale.dura(3);
  scale.re(4);    scale.dura(3);
  scale.do_ut(4); scale.dura(2);

  scale.rest();   delay(50);
}
[/mw_shl_code]
可以看到:
第一种方案的好处是,在写谱时十分直观,do就是do,re就是re。然而最大的麻烦是要添加一大段函数定义代码。
第二种方案的好处是,将函数方法整合到库文件中,减少代码。而坏处是需要实例化,而且调用任何自定义的函数都要加“实例名.”,写谱时十分麻烦。
所以结论是:选择你喜欢的一种方式吧!反正都是复制粘贴的工作。
另外我在库文件中保存了2个利用库文件写谱的实例,大家可以看一下!
DFTBA!


发表于 2016-6-5 23:02 | 显示全部楼层
Scale scale(pin,12)和之前的tone(pin,int)有什么区别?
 楼主| 发表于 2016-6-7 06:24 | 显示全部楼层
suoma 发表于 2016-6-5 23:02
Scale scale(pin,12)和之前的tone(pin,int)有什么区别?

你好,我的朋友。
很抱歉,由于学业原因,我未能及时回复你的信息,敬请原谅。
对于你的问题的解释是这样:
库文件中的“Scale::Scale(int pin, int bpm)”的两个参数,一个是确定输出pin口,另外一个是定义整首歌曲的bpm,即每分钟的节拍数。
而tone(pin, int)的两个参数,一个是确定输出pin口,另外一个是确定输出的声音频率。
如果是这样的话可以理解吗?
(实话:由于我近期都没进行Arduino的开发,对于我之前做的这个库文件也不太清楚了,本人记性不太好,请原谅m(_ _)m)
发表于 2016-6-8 00:00 | 显示全部楼层
Mitsuka 发表于 2016-6-7 06:24
你好,我的朋友。
很抱歉,由于学业原因,我未能及时回复你的信息,敬请原谅。
对于你的问题的解释是这样 ...

感觉挺像的,理解了,谢谢
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 10:43 , Processed in 0.114349 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表