|
本帖最后由 Mitsuka 于 2016-4-27 18:43 编辑
《Arduino Projects Book》上有一个小项目叫“Keyboard Instrument”,是利用四个开关控制蜂鸣器发出四个不同音阶。然后我对这个项目做了两次魔改,结果就是我的这个项目:在网上我找到有很多前辈做的和我类似的项目,都总结得很好,但是我认为在写谱这方面,他们的程序不够直观,而我就是希望能让写谱人在用本程序写谱时,觉得更加的直观和方便;
连接方式(就是这么简单):
奉上我的代码:
[mw_shl_code=cpp,true]
const float bpm = 296; // bpm = 每分钟节拍,可更改
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); // rest(pin)是自定义的休止符函数,之后有讲
delay(50); // 这里加一个50ms的短暂休止是模仿钢琴弹奏时音符与音符切换时的间隙
}
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 withdot(int x) // 附点音符函数,我是把音阶和时值分由两种不同的函数控制
{
durac[x]; // 附点音符的时值是原时值 * 1.5;
dura[x+1];
}
// 接下来就是音阶部分,七个全音阶,五个半音阶,从C1到B7,总计84个音,全在听觉范围内
// 其实音阶就是声音频率,不同频率产生不同的音阶,根据网上的音阶频率表设计
// 目前仅有部分音符记号函数,如连音和附点,重音等暂无法实现 // 循环的话,目前就只靠复制代码解决(0 w 0 )~
void do_ut(int pin,int x) // 音名C(或B#),唱名do,用“do_ut"表示(由于do为保留字),音阶分别为C1,C2,C3,C4,C5,C6,C7
{ int C[] = {33,65,131,262,523,1047,2093};
tone(pin,C[x-1]);} // tone()函数,是pin口发出特定频率的声音信号,以下略
void do_up(int pin,int x) // 音名C#,音阶分别为C#1,C#2,C#3,C#4,C#5,C#6,C#7
{ int CU[] = {35,69,139,277,554,1109,2217};
tone(pin,CU[x-1]);}
void re_dw(int pin,int x) // 音名Db,音阶分别为Db1,Db2,Db3,Db4,Db5,Db6,Db7
{ int DD[] = {35,69,139,277,554,1109,2217};
tone(pin,DD[x-1]);}
void re(int pin,int x) // 音名D,唱名re,音阶分别为D1,D2,D3,D4,D5,D6,D7
{ int D[] = {37,73,147,294,587,1175,2349};
tone(pin,D[x-1]);}
void re_up(int pin,int x) // 音名D#,音阶分别为D#1,CD#2,D#3,D#4,D#5,D#6,D#7
{ int DU[] = {39,78,156,311,622,1245,2489};
tone(pin,DU[x-1]);}
void mi_dw(int pin,int x) // 音名Eb,音阶分别为Eb1,Eb2,Eb3,Eb4,Eb5,Eb6,Eb7
{ int ED[] = {39,78,156,311,622,1245,2489};
tone(pin,ED[x-1]);}
void mi(int pin,int x) // 音名E,唱名mi,音阶分别为E1,E2,E3,E4,E5,E6,E7
{ int E[] = {41,82,165,330,659,1319,2637};
tone(pin,E[x-1]);}
void fa(int pin,int x) // 音名F,唱名fa,音阶分别为F1,F2,F3,F4,F5,F6,F7
{ int F[] = {44,87,175,349,698,1397,2794};
tone(pin,F[x-1]);}
void fa_up(int pin,int x) // 音名F#,音阶分别为F#1,F#2,F#3,F#4,F#5,F#6,F#7
{ int FU[] = {46,93,185,370,740,1480,2960};
tone(pin,FU[x-1]);}
void sol_dw(int pin,int x) // 音名Gb,音阶分别为Gb1,Gb2,Gb3,Gb4,Gb5,Gb6,Gb7
{ int GD[] = {46,93,185,370,740,1480,2960};
tone(pin,GD[x-1]);}
void sol(int pin,int x) // 音名G,唱名sol,音阶分别为G1,G2,G3,G4,G5,G6,G7
{ int G[] = {49,98,196,392,784,1568,3136};
tone(pin,G[x-1]);}
void sol_up(int pin,int x) // 音名G#,音阶分别为G#1,G#2,G#3,G#4,G#5,G#6,G#7
{ int GU[] = {52,104,208,415,831,1661,3322};
tone(pin,GU[x-1]);}
void la_dw(int pin,int x) // 音名Ab,音阶分别为Ab1,Ab2,Ab3,Ab4,Ab5,Ab6,Ab7
{ int AD[] = {52,104,208,415,831,1661,3322};
tone(pin,AD[x-1]);}
void la(int pin,int x) // 音名A,唱名do,音阶分别为A1,A2,A3,A4,A5,A6,A7
{ int A[] = {55,110,220,440,880,1760,3520};
tone(pin,A[x-1]);}
void la_up(int pin,int x) // 音名A#,唱名do,音阶分别为A#1,A#2,A#3,A#4,A#5,A#6,A#7
{ int AU[] = {58,117,233,466,932,1865,3729};
tone(pin,AU[x-1]);}
void si_dw(int pin,int x) // 音名Bb,唱名do,音阶分别为Bb1,Bb2,Bb3,Bb4,Bb5,Bb6,Bb7
{ int BD[] = {58,117,233,466,932,1865,3729};
tone(pin,BD[x-1]);}
void si(int pin,int x) // 音名B,唱名do,音阶分别为B1,B2,B3,B4,B5,B6,B7
{ int B[] = {62,123,247,494,988,1976,3951};
tone(pin,B[x-1]);}
void rest(int pin) // 休止符,tone()的频率设为零就行了
{ tone(pin, 0);}
void setup()
{
/* Attention: // 这里再次对时值的表示方法做解释
* whole = 1; // 全音符
* half = 2; // 二分音符
* quarter = 3; // 四分音符
* eighth = 4; // 八分音符
* sixteenth = 5; // 十六分音符
* thirtysecond = 6; // 三十二分音符
* sixtyforth = 7; // 六十四分音符
*/
}
void loop()
{
/* Here's an example: // 自己写的一个例子:小星星
* 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);
* rest(8);
* delay(50);
*/
}
[/mw_shl_code]
按照例子中的格式,在loop()函数中写谱:
音阶名(输出pin口,音阶频率); dura(时值);
要是有附点音符的话就是:
音阶名(输出pin口,音阶频率); withdot(时值);
两个音符之间有连音号的话:
音阶名1(输出pin口,音阶频率); durac(时值);
音阶名2(输出pin口,音阶频率); dura(时值);
目前,我用这个程序编了几首歌曲:
aLIEz(未完成)
九九八十一(前奏和间奏未完成)
铃儿响叮当(完成)
小星星(完成)
最炫民族风(完成)
热情欢迎各位对我的程序提出任何建议,同时如果有人想让我编写某一首曲子的话,可以私信我,十分感谢! 另外,我希望有前辈帮忙解决我一个问题,就是怎么实现同时发出多个不同频率的声音,目前我编的音乐都是一次只能发出一个音的,所以还无法添加和弦之类的背景音,麻烦又热心的前辈教我应该怎么做,谢谢!
最后在这里奉上我的其中一个作品,铃儿响叮当:
[mw_shl_code=cpp,true]
const float bpm = 182; //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()
{
/* Attention:
* whole = 1;
* half = 2;
* quarter = 3;
* eighth = 4;
* sixteenth = 5;
* thirtysecond = 6;
* sixtyforth = 7;
*/
}
void loop()
{
sol(8,3); dura(5);
sol(8,3); dura(5);
sol(8,3); dura(4);
mi(8,4); dura(4);
re(8,4); dura(4);
do_ut(8,4); dura(4);
sol(8,3); durac(3); dura(4);
sol(8,3); dura(5);
sol(8,3); dura(5);
sol(8,3); dura(4);
mi(8,4); dura(4);
re(8,4); dura(4);
do_ut(8,4); dura(4);
la(8,3); durac(3); dura(4);
la(8,3); dura(4);
la(8,3); dura(4);
fa(8,4); dura(4);
mi(8,4); dura(4);
re(8,4); dura(4);
si(8,3); durac(3); dura(4);
si(8,3); dura(4);
sol(8,4); dura(4);
sol(8,4); dura(4);
fa(8,4); dura(4);
re(8,4); dura(4);
mi(8,4); durac(4); durac(5);
do_ut(8,4); dura(3);
sol(8,3); dura(5);
sol(8,3); dura(5);
sol(8,3); dura(4);
mi(8,4); dura(4);
re(8,4); dura(4);
do_ut(8,4); dura(4);
sol(8,3); durac(3); dura(4);
sol(8,3); dura(5);
sol(8,3); dura(5);
sol(8,3); dura(4);
mi(8,4); dura(4);
re(8,4); dura(4);
do_ut(8,4); dura(4);
la(8,3); durac(3); dura(4);
la(8,3); dura(4);
la(8,3); dura(4);
fa(8,4); dura(4);
mi(8,4); dura(4);
re(8,4); dura(4);
sol(8,4); dura(4);
sol(8,4); dura(4);
sol(8,4); dura(4);
sol(8,4); dura(4);
la(8,4); dura(4);
sol(8,4); dura(4);
fa(8,4); dura(4);
re(8,4); dura(4);
do_ut(8,4); durac(3);dura(4);
rest(8); dura(4);
mi(8,4); dura(4);
mi(8,4); dura(4);
mi(8,4); dura(3);
mi(8,4); dura(4);
mi(8,4); dura(4);
mi(8,4); dura(3);
mi(8,4); dura(4);
sol(8,4); dura(4);
do_ut(8,4); dura(4);
re(8,4); dura(4);
mi(8,4); dura(2);
fa(8,4); dura(4);
fa(8,4); dura(4);
fa(8,4); durac(4);dura(5);
fa(8,4); dura(5);
fa(8,4); dura(4);
mi(8,4); dura(4);
mi(8,4); dura(4);
mi(8,4); dura(5);
mi(8,4); dura(5);
mi(8,4); dura(4);
re(8,4); dura(4);
re(8,4); dura(4);
do_ut(8,4); dura(4);
re(8,4); durac(3);
sol(8,4); dura(3);
mi(8,4); dura(4);
mi(8,4); dura(4);
mi(8,4); dura(3);
mi(8,4); dura(4);
mi(8,4); dura(4);
mi(8,4); dura(3);
mi(8,4); dura(4);
sol(8,4); dura(4);
do_ut(8,4); dura(4);
re(8,4); dura(4);
mi(8,4); dura(2);
fa(8,4); dura(4);
fa(8,4); dura(4);
fa(8,4); durac(4);dura(5);
fa(8,4); dura(5);
fa(8,4); dura(4);
mi(8,4); dura(4);
mi(8,4); dura(4);
mi(8,4); dura(5);
mi(8,4); dura(5);
sol(8,4); dura(4);
sol(8,4); dura(4);
fa(8,4); dura(4);
re(8,4); dura(4);
do_ut(8,4); durac(3);dura(4);
rest(8); delay(50);
}[/mw_shl_code]
2016-04-27 另一首作品 - 九九八十一:http://www.arduino.cn/thread-20605-1-1.html
2016-04-27 withdot()函数好像不好用,如果乐谱中有附点音符的话请使用以下格式:
唱名(pin, 音阶); durac(时值); dura(时值+1);
2016-04-27 将程序整合成了库文件,详细用法看帖:http://www.arduino.cn/thread-20632-1-1.html
|
|