在Ardunio代码中编曲,让你的蜂鸣器奏出动听音乐

本人蒟蒻,初学 Ardunio ,如有错误,请指正,感谢各路大佬。

最近上“早期工程实践”的时候,从老师那拿到了一块蜂鸣器,还有几页教人怎么用蜂鸣器的PPT。在PPT的结尾,老师布置了一个简单的实践任务:用蜂鸣器,演奏一首时长较短、旋律简单的儿歌。

这首歌很短,代码长度还好,难度不高,但是完成这个任务后,我有所思考

先给出一张PPT的截图

按照老师所教的方法,每次发出蜂鸣,都要调用一遍 tone() 和 delay() 。想要让蜂鸣器准确发出音调,还要查这个音调对应的频率

当要播放的乐谱变长之后,将会非常痛苦

所以我在想,能不能写一个函数,只需要输入乐谱,就能按照乐谱播放音乐

说干就干,于是乎有了下面这段代码

int pinMusic = 0; // 定义蜂鸣器占用的针脚,这里默认0号

// 定义三维整型数组,用于存乐谱
// 第一维度存放音调,第二维度用于提升或降低8度,第三维度存放一个音的持续时间
int music[][3] = {{1,1,4}}; // 像这样定义一个乐谱

int S, T;
void playMusic(int music[][3], int length) // 用于演奏的函数
{
  for (int i=0; i<length; i++)
  {
    int note[3] = {music[i][0], music[i][1], music[i][2]};
    if (note[0] == 0) // 休止符
    {
      T = 2500 / note[2];
      delay(T);
    }
    else // 音符
    {
      readNotes(note[0],note[1],note[2]);
      tone(pinMusic,S);
      delay(T);
      noTone(pinMusic);
    }
    delay(100); // 两个音之间的短暂间隔
  }
}

// 把 1 - 7 映射到 音调频率表
int noteTable[7][3] = {{262,523,1046},{294,587,1175},{330,659,1318},{349,698,1397},
{392,784,1568},{440,880,1760},{494,988,1967}};

void readNotes(int sound, int jump, int time) // 用于读谱的函数
{
  S = noteTable[sound-1][jump+1]; // 解析当前音符的音调,转换成蜂鸣器对应的频率
  T = 2500 / time; // 解析当前音符的持续时间
}

// 示例:两只老虎
int twoTiggers[][3] = {{1,1,4},{2,1,4},{3,1,4},{1,1,4},{1,1,4},{2,1,4},{3,1,4},
                     {1,1,4},{3,1,4},{4,1,4},{5,1,2},{3,1,4},{4,1,4},{5,1,2},
                     {5,1,8},{6,1,8},{5,1,8},{4,1,8},{3,1,4},{1,1,4},{5,1,8},
                     {6,1,8},{5,1,8},{4,1,8},{3,1,4},{1,1,4},{2,1,4},{5,-1,4},
                     {1,1,3},{0,1,4},{2,1,4},{5,-1,4},{1,1,3}};
void setup()
{
  Serial.begin(9600);
  Serial.println("start");
  delay(1000); // 开机缓冲1s
  // 演奏方法:
  // 先定义 int num = sizeof(乐谱名)/sizeof(乐谱名[0]);
  // 然后调用 playMusic(乐谱名, num);
  int num = sizeof(twoTiggers)/sizeof(twoTiggers[0]);
  playMusic(twoTiggers, num); // 演奏 两只老虎
}

void loop() // 用不上loop,但是没有它会报错
{

}

在这段程序中,只需要以三维数组的形式,编写想要演奏的乐谱,即可调用 playMusic() 函数为您演奏。其中,编写的乐谱要遵守如下规则:

一个音符包含三个维度,以 {1,1,4} 为例

第一维:

do - si 用 1 - 7 表示

0 为休止符, 其他符号均非法

第二维:

0 不改变音域

1 = 升8度; -1 = 降8度

第三维:

8表示8分音符的持续时间

4表示4分音符的持续时间

其余同理

要制作不同时间的休止符,请用{0,1,time}

改变 time 的值以制作不同的休止符

程序中音调与频率的对应关系,来自老师给出的一个表格

不知道准不准确,本人乐理知识欠缺。(如果代码中有一些音乐术语的错误,请原谅)

接下来,就开始愉快地编曲吧!这里给出一段简单的示范

// 示例:两只老虎
int twoTiggers[][3] = {{1,1,4},{2,1,4},{3,1,4},{1,1,4},{1,1,4},{2,1,4},{3,1,4},
                     {1,1,4},{3,1,4},{4,1,4},{5,1,2},{3,1,4},{4,1,4},{5,1,2},
                     {5,1,8},{6,1,8},{5,1,8},{4,1,8},{3,1,4},{1,1,4},{5,1,8},
                     {6,1,8},{5,1,8},{4,1,8},{3,1,4},{1,1,4},{2,1,4},{5,-1,4},
                     {1,1,3},{0,1,4},{2,1,4},{5,-1,4},{1,1,3}};

由于我的编程能力欠缺,本人的代码还有很多欠完善的地方,希望多多谅解,也欢迎大神改进!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值