×

Arduino音乐

消耗积分:0 | 格式:zip | 大小:0.06 MB | 2022-10-19

李莉

分享资料个

描述

让我们在坚果壳中制作音乐

如果您喜欢 Arduino 并且对音乐有基本的了解,那么为什么不与Let's Make Music一起玩乐呢?

使用非常基本的套件列表并使用非常少、非常短和基本的功能,可以制作非常详细的乐谱,以便在简单配置的 Arduino 和扬声器上播放。结果可能非常惊人和有益!

能力

为了让您了解“让我们制作音乐”的草图功能,我制作了一些非常复杂的乐谱,由一些传奇的流行艺术家创作,所有这些乐曲都忠实地演奏。不幸的是,由于版权原因,我无法发布这些内容。不过,我已经包含了其他开箱即用的示例 (OOTB),它们提供了有用的能力演示和指导,以帮助您开始自己的分数。

硬件

再简单不过了——你只需要一个 Arduino 微控制器(任何一个都可以)、一个 100 欧姆的电阻、一个小面包板、一些电线,最好是一个 8 欧姆 0.25 瓦的扬声器(如果你不这样做,还需要一个蜂鸣器手头没有扬声器)。

接线图如下图所示,但它是一个非常简单的威廉希尔官方网站 。草图使用数字输出引脚 11 来驱动扬声器,但如果您希望使用另一个引脚,请选择合适的替代引脚并#define speaker根据需要更改草图中的定义 ' '。

我应该建议微控制器不应该直接连接到除了扬声器/蜂鸣器之外的任何东西,否则你可能会损坏你的微控制器。

让我们做音乐

该草图包括使用基本和标准音乐术语和概念将您自己的乐谱和作品组合在一起所需的一切。例如,草图包括一套全面的标准速度、涵盖多个八度音阶的预设音符以及基于所选速度的常见音符/休息时间值。

该草图提供了五个可用于创建和播放音乐的功能。这些是:

set_tempo - 以每分钟节拍数(即每分钟四分音符)为单位设置乐曲的节奏(节奏),例如set_tempo(allegro),set_tempo(144)等。四分音符的值计算为 60/节奏秒。然后根据该计算值确定所有其他音符持续时间。在草图启动时,速度设置为default_tempo( animato),或每分钟 120 拍(四分音符)。速度将保持在此设置,直到被用户代码更改。
play - 将在给定的持续时间内播放给定的音符,例如,将在最小的持续时间内播放中 C,在四分音符+ 八分音符的持续时间内播放 F2 升号,等等。当然,这些播放的速度取决于节奏设置。play(note_C4, minim)play(note_FS2, crot + quav)
休息- 在给定的持续时间内休息,在此期间保持沉默,例如rest(quav)rest(0.5)等。请记住,休息也适用于当前速度。
颤音- 用给定的两个音符在给定的持续时间一个接一个地连续执行颤音,例如trill(note_C4, note_CS4, minim)trill(note_F3, note_E3, crot)等。默认情况下和 OOTB,颤音在每个四分音符或其中一部分执行八个音符变化,具体取决于在给出的颤音持续时间它的函数调用,与速度设置无关。如果每个 crotchet 需要更少或更多的音符更改,则重置定义“ ”。请记住,颤音也适用于当前速度。#define trills_per_crotchet
等待- 等待给定的持续时间(秒或其一部分),例如wait(5.5)等待 5.5 秒,wait(minim)等待最小持续时间等。此功能由播放和休息功能使用,但也可用于最终用户代码。

让我们看一个熟悉的曲子(生日快乐)的例子:

 // Happy_Birthday
 set_tempo(default_tempo);
 // bar 1
 play(note_G3, quav);
 play(note_G3, quav);
 play(note_A3, crot);
 play(note_G3, crot);
 // bar 2
 play(note_C4, crot);
 play(note_B3, minim);
 // bar 3
 play(note_G3, quav);
 play(note_G3, quav);
 play(note_A3, crot);
 play(note_G3, crot);
 // bar 4
 play(note_D4, crot);
 play(note_C4, minim);
 // bar 5
 play(note_G3, quav);
 play(note_G3, quav);
 play(note_G4, crot);
 play(note_E4, crot);
 // bar 6
 play(note_C4, crot);
 play(note_B3, crot);
 play(note_A3, crot);
 // bar 7
 play(note_F4, quav);
 play(note_F4, quav);
 play(note_E4, crot);
 play(note_C4, crot);
 // bar 8
 play(note_D4, crot);
 play(note_C4, minim);

要注意上面的例子是:

  • 乐谱的节奏已设置为default_tempo (每分钟 120 拍)
  • 乐谱以条形排列。在这个例子中,小节有 3 个节拍(3/4 拍)。当您输入自己的乐谱时,这是一种有用的方法,因为它可以让您跟随音乐并轻松挑选出您无疑会错误引入的错误音符和/或持续时间!
  • 音符一个接一个地播放(单通道设计),参考草图的音符定义中的音符值(请参阅婴儿床表以获取这些和其他有用的点点滴滴的易于访问的列表)
  • 使用标准乐谱,例如crot(chet)、minimquav(er) 等,在指定的时间/持续时间内演奏每个音符。同样,使用Crib Sheet可以轻松访问这些音符。

让我们看另一个简短的例子,当你玩它时你就会知道:

 set_tempo(default_tempo * 2); // lively pace
 // 3/4 time
 // bar 1
 play(note_C4, minim);
 play(note_G3, crot);
 // bar 2
 play(note_G3, crot);
 play(note_GS3, minim);
 // bar 3
 play(note_G3, minim);
 rest(note_crot);
 // bar 4
 play(note_B3, minim);
 play(note_C4, crot);
 set_tempo(default_tempo); // reset tempo 

要注意上面的例子是:

  • 我们将速度提高到默认值的两倍 - 每分钟 240 拍
  • rest 我们在第 3 小节的中间引入了一个空头crot(切)
  • 当乐曲完成时,我们将速度重置为默认值。

最后,在本节中,让我们回顾一下生日快乐,这次我们将在每个奇数小节的开头添加一个颤音:

 //_Happy_trill_Birthday
 set_tempo(default_tempo);
 // 3/4 time
 // bar 1
 trill(note_G3, note_GS3, quav);
 play(note_G3, quav);
 play(note_A3, crot);
 play(note_G3, crot);
 // bar 2
 play(note_C4, crot);
 play(note_B3, minim);
 // bar 3
 trill(note_G3, note_GS3, quav);
 play(note_note_G3, quav);
 play(note_A3, crot);
 play(note_G3, crot);
 // bar 4
 play(note_D4, crot);
 play(note_C4, minim);
 // bar 5
 trill(note_G3, 
 play(note_G3, quav);
 play(note_G4, crot);
 play(note_E4, crot);
 // bar 6
 play(note_C4, crot);
 play(note_B3, crot);
 play(note_A3, crot);
 // bar 7
 trill(note_F4, note_FS4, quav);
 play(note_F4, quav);
 play(note_E4, crot);
 play(note_C4, crot);
 // bar 8
 play(note_D4, crot);
 play(note_C4, minim);

这是我们习惯的旋律,但有一点曲折。颤音功能是音乐颤音的简单实现,但应该对您的乐谱产生一些兴趣。

希望到此为止,您了解所应用的原则吗?

一些有用的指针和技巧...

三胞胎

三连音是一个单独的节拍,分为三个等时的音符,通常在三连音音符上方用“3”表示。这很容易建模,例如,如果我们将以下三个音符定义为三连音 - A3、AS3 和 B3 并且值得一个四分音符,那么我们可以简单地将其转录为:

// crotchet triplet
play(note_A3, crot/3);
play(note_AS3, crot/3); 
play(note_B3, crot/3);

同样的想法适用于任何部门。

领带

并列音符是由连接两个相同音高音符的曲线表示的乐谱。在平局中,不播放第二个音符,但将其持续时间值添加到第一个音符。因此,例如,如果乐谱显示两个并列的音符,比如note_AF3都带有四分音符的持续时间,那么我们会将其表示为play(note_AF3, crot + crot), 或play(note_AF3, minim)第一个表示更好,因为它推断我们正在演奏一个并列的音符。请注意,捆绑的音符通常可以从一个小节的末尾延伸到下一个小节。在这些情况下,它有助于在您包含描述条形图的任何评论中标记这一点。

另一个例子可能是两个音符,比如说note_F4第一个音符的持续时间值是四分音符,第二个音符的持续时间值是八分音符。我们将其表示为play(note_F4, crot + quav)等等。

复合音符和休息时间

我们在上面的技术中看到了我们如何能够复合和操纵音符持续时间以满足表示三连音和连音的乐谱的精确需求。同样的技术同样适用于需要音符时长的rest 和函数。trill 事实上,只要有意义,任何算术组合都是允许的,例如play(note_D5, minim + crot + quav), rest(crot + quav),trill(note_G2, note_GS2, dot_minim + quav/2)等。

节奏

虽然草图提供了标准速度定义的列表,但该函数可以指定任何值set_tempo 因此,如果您需要一个不在标准列表中的速度,那么只需指定您自己的速度。例如set_tempo(95),介于maestroso (每分钟 88 次)和moderato (每分钟 100 次)之间,依此类推。

重复

乐谱的一部分经常重复。与其复制相同的一组和一系列的音符/休止符,使用标签和(可怕的)goto 语句会很有帮助。为此,有必要检测乐谱的一部分是否已经重复。这可以使用具有两种状态之一的简单变量来管理 -false如果重复部分尚未重复,则为“ true”,否则为“ ”。例如:

...
bool repeated = false;
...
repeat_1:
play(note_B3, crot);
rest(quav);
play(note_C4, quav);
play(note_D4, crot+quav);  // dotted crotchet
play(note_C4, quav);
...
If (repeated == false){
repeated = true;  
play(note_A3, crot);  
rest(crot);  
play(note_C4, crot);  
play(note_D4, crot);  
goto repeat;
}
// continue with the rest of the score...

我向你们中间的纯粹主义者道歉,但在这种情况下,a 的使用goto 简单、清晰且易于实施,即使乐谱具有多个重复部分。如果它们更适合您的需求,请随意使用 do/while 或 while 构造。

转录乐谱

在将乐谱编码为音乐命令时,它有助于有序和结构化。根据乐谱的拍号逐个小节工作,用小节编号评论每个小节,并添加任何其他可能有帮助的评论。这种方法有助于调试您的代码,因为我可以保证您将引入不正确的音符和/或音符/休息时间。在逐条阅读代码的同时聆听乐谱以确保准确性,很快就会发现哪里出了问题。

盒子外面

Let's Make Music 草图包含了整理您自己的乐谱所需的所有音乐数据和功能。还包括许多乐谱示例,因此您可以了解如何使用各种草图功能,也可以立即在 Arduino 上播放音乐。

为方便起见,示例分数作为函数提供,并且可以以任何顺序直接从主 void 循环引用。如果一个接一个地组装多个得分函数,然后wait(..)在每个函数之间添加一个函数调用,以便在一个结束和下一个开始之间获得短暂的休息,例如wait(3)等待三秒钟。

OOTB 提供的乐谱函数有:

  • middle_C
  • twinkle_twinkle(小星星)
  • silent_night
  • jingle_bells
  • happy_birthday
  • ditty_1
  • door_bell_1
  • door_bell_2
  • ode_to_joy (贝多芬)
  • canon_in_D(帕赫贝尔)
  • scarborough_fair

最后

Let's Make Music 小品是关于用 Arduino 制作音乐的乐趣。它并不过分复杂,但提供了一些简单而基本的命令,可以产生非常好的结果。下载并打印婴儿床表,作为对所有草图的音乐数据定义和功能的方便和快速参考。

最重要的是,享受在 Arduino 上制作音乐并玩得开心!

延伸阅读

您可能还会发现同一作者的这些贡献有趣且有用:

  • 为您的草图添加心跳- 包括一种可见的方法来查看您的代码在您的微控制器上运行,而无需任何额外的组件或接线!
  • 音乐和灯光工作台- 旨在将计算机编程新手介绍给该主题,使用具有酷炫效果的简单命令。方法是导师和学生之一
  • 了解和使用按钮开关,基本知识- 按钮开关,一个简单但通常很棘手的工具包。本教程提供了实现简单按钮开关的来龙去脉,灵活地探索威廉希尔官方网站 设计的差异、不同的读取方法和去抖动。
  • 外部中断- 支持并发异步多个中断的通用框架。配置多个不同特性的外部中断,并添加代码提供中断后异步处理。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.obk20.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'Arduino音乐',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.obk20.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);