之前借助Python利用虚拟钢琴软件弹奏了一曲东风破, 虽然是成功了, 但是终究还是要下载一个虚拟钢琴, 那么我想, 我能不能直接用电脑的蜂鸣器来弹奏一曲东风破呢? 感谢 @刘之帅 提供的创意.

不过做这个之前, 需要先普及一点乐理知识, 否则后面的代码会看不懂, 乐理这个东西, 我也是一个初学者, 可能有我理解的不对的地方, 也请各位看官指出.

预备知识

说到音乐, 那肯定离不开声音的三要素: 音调, 音色, 音量. 对于音量, 其实也就是声音的响度, 说白了就是声音的大小, 这个对于蜂鸣器来说, 是固定的, 所以我们暂时不需要考虑这个. 对于音色, 这个东西和发声器相关, 具有同样响度和音调的声音, 不同乐器发出声音听起来的感觉也是不同的, 比如我们用二胡和吉他弹奏同一首曲子, 虽然他们都是同一首曲子, 但是我们还是能够分辨是那种乐器弹奏出来的. 接下来是重点要解释的部分, 音调, 通俗解释就是人们对于声音高低的感觉, 比如男低音或者女高音, 说的就是音调, 这个主要和声波的频率有关. 对于蜂鸣器来说, 我们肯定是不能改变他的音色和音量的, 然鹅, 我们可以改变它发声的频率, 从而改变音调, 来弹奏一首曲子.

十二音律

说到音调, 我们自然不可能绕过十二音律这个东西, 我们先来看一张图.

十二音律是怎么来的呢, 就是把一定频率的音分成12份, 通常来说, 是[440, 880], 这个作为基准, 每升高一个八度, 频率翻一番, 每降低一个八度, 频率减少一半. 在钢琴中, 正好有7个白键, 5个黑键正好12个. 因为常用的键位是7个, 所以白色键位是常用键位. 黑色是不常用键位, 因此白色它比较宽, 比较大, 具体这些细节不是本文的重点, 因为我也不是学这个的, 可能我理解的也不是很到位, 这里的重点是我们如何找到钢琴中每个键位对应的频率, 如果不简单理解一下这些的话, 后面频率部分的代码, 可能是不太好理解的, 所以在这里也简单说一下. 下面先给出一个频率对应表.

这张表, 当然不可能手敲进去, 当然, 如果闲得无聊的话, 手敲也是可以的, 因为这个是有规律的, 上文说过, 这其实是把频率分成了12份, 构成一个等比数列, 公比是2^(1/12), 所以我们只需要找到上图中的O1, 然后不断做乘法就可以生成上面那张表.

def generate_piano_table():start = 27.5table = []for i in range(8):tmp = []for j in range(12):tmp.append(round(start))start *= 2 ** (1 / 12)table.append(tmp)return table

这里考虑到一个问题, 就是蜂鸣器接收频率, 只能写整数, 因此这里我们做个四舍五入, 近似一下. 再考虑到, 这个表是固定的, 因此我们生成一边之后, 复制出来就行了, 没必要每次都运行. 在这里给大家一个福利吧, 我直接把这张表贴出来. 也省的在运行了.

PIANO_TABLE = [[28, 29, 31, 33, 35, 37, 39, 41, 44, 46, 49, 52],[55, 58, 62, 65, 69, 73, 78, 82, 87, 92, 98, 104],[110, 117, 123, 131, 139, 147, 156, 165, 175, 185, 196, 208],[220, 233, 247, 262, 277, 294, 311, 330, 349, 370, 392, 415],[440, 466, 494, 523, 554, 587, 622, 659, 698, 740, 784, 831],[880, 932, 988, 1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661],[1760, 1865, 1976, 2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322],[3520, 3729, 3951, 4186, 4435, 4699, 4978, 5274, 5588, 5920, 6272, 6645]
]

但是注意一下, 这张表是从A开始的, 而DoC, 蛤, 因此看下面代码的时候需要注意到这个问题, 否则你的音会不对, 而且要注意到, 这是12音, 一般来说, 我们只需要do, re, mi, fa, sol, la, si这七个, 因此我们做一个简单的处理, 把正常的C调, 以及高八度, 低八度, 都提取出来, 其他的嘛, 我暂时也用不到, 需要的人, 自己处理一下吧.

SIMPLE_TABLE = [[33, 37, 41, 44, 49, 55, 62],[65, 73, 82, 87, 98, 110, 123],[131, 147, 165, 175, 196, 220, 247],[262, 294, 330, 349, 392, 440, 494],  # C^1[523, 587, 659, 698, 784, 880, 988],[1047, 1175, 1319, 1397, 1568, 1760, 1976],[2093, 2349, 2637, 2794, 3136, 3520, 3951]
]

得到这个频率表, 我们就可以开始尝试用蜂鸣器来弹奏了. 上面这个表中每一行代表一个八度, 然后从DoSi顺序排列. 不过, 在正式开始写代码之前, 还要补充最后一个知识点, 那就是曲速, 我们可以发现, 我们在听音乐的时候, 每个音的长短是不一样的, 因此, 我们如果想演奏出来的效果更好一些的话, 我们肯定是需要考虑一个十分重要的问题, 也就是曲速, 我们先来看一下东风破的简谱.

这里我们做一下简单化处理, 因为这些复杂的节奏, 我也把握不准, 因此我们这里按照下面的基准来区分节奏.我们按照800ms算一拍, 也就是一个四分音符, 然后八分音符是400ms暂时不考虑连音.

到这里, 我们就完成基础的乐理知识的讲解了, 当然本文的重点不在这块上面, 这些知识是便于读者理解后面的代码.

编码

之前一篇文章, 已经说过, 如何调用系统层面的东西了, 这里蜂鸣器, 我们依然通过win32api来调用. 这里因为之前我生成谱子是按照400ms做的, 但是发现间隔太短了, 后来我也没改, 然后时间直接翻倍就好了.

player = ctypes.windll.kernel32def beep(rate, _time=400):if rate == -1:time.sleep(_time/1000)player.Beep(rate, _time)

这个函数比较简单, 第一个参数是频率, 第二个参数是时间. 这里一看应该就明白了, 不需要我再多解释什么了.

接下来就是最重要的部分, 谱子了, 这个谱子, 我们需要记录音调和时间, 手动来个简单的结构表示.

{"tone": 330,"time": 400
}

第一个参数是音调, 按照上文所说的表中, 第几行第几列, 来获取对应的频率, 第二个参数是时间. 接下来就是写谱子了, 手动来吧. 如果tone = -1, 表示不发声.

有了谱子之后, 播放就非常简单了, 代码如下:

for i in music:print(i)beep(i['tone'], i['time'] * 2)

这样, 蜂鸣器版本的东风破就制作完成了, 虽然代码不是很复杂, 但是对于我这种五音不全的人来说, 难点完全不在于代码上, 哈哈, 不过这个小挑战也算是成功了.

源码和简谱图片, 以及谱子, 大家可以关注我的微信公众号(Coder小Q), 回复关键词: 东风破 获取.

谁在用Python弹奏一曲东风破 - 第二期 - 蜂鸣器版相关推荐

  1. 是谁用Python弹奏一曲东风破

    是谁在用Python弹奏一曲东风破 最近闲暇之余, 逛B站, 发现那些大神们用计算器, 用各种东西, 弹曲子, 那是弹得一个好, 作为一个手残人士, 虽然也想尝试一下, 但是吧, 我发现, 我的脑子里 ...

  2. 谁在用琵琶弹奏一曲东风破

    歌曲名称:东风破 作曲:周杰伦 作词:方文山 编曲:林迈可 歌词: 一盏离愁 孤单伫立在窗口 我在门后 假装你人还没走 旧地如重游 月圆更寂寞 夜半清醒的烛火 不忍苛责我 一壶漂泊 浪迹天涯难入喉 你 ...

  3. python获取按键状态_谁在用 python 弹奏一曲菊花台

    转自:Crossin的编程教室 想必各位在家已经闲得快发疯了吧,鄙人现在的状态如下: 但是我不想这么萎靡下去,我想做点高雅的事情,看到朋友圈有人在手机app上弹<菊花台>,简直太好听了.于 ...

  4. html入门之简单页静态面练习-东风破

    练习一个简单静态页面,在页面中展示<东风破>歌词.让歌词文字和图片居中,教程中是用的html中<center>标签,我在这里用了css样式来解决的.把想要居中的内容放在一个&l ...

  5. 听着熟悉的《东风破》,好想你~

    东风破 一盏离愁孤单伫立在窗口 我在门後假装你人还没走 旧地如重游月圆更寂寞 夜半清醒的烛火不忍苛责我 一壶漂泊浪迹天涯难入喉 你走之後酒暖回忆思念瘦 水向东流时间怎黱偷 花开就一次成熟我却错过 谁在 ...

  6. 东风破 -词:方文山 曲:周杰伦

    东风破 -词:方文山 曲:周杰伦 东风破   一盏离愁孤单伫立在窗口 我在门後假装你人还没走 旧地如重游月圆更寂寞 夜半清醒的烛火不忍苛责我 *一壶漂泊浪迹天涯难入喉 你走之後酒暖回忆思念瘦 水向东流 ...

  7. 东风破 苏轼 喜欢的词,方文山的歌词好象就是这样借过来的。

    一盏离愁 孤单窗前自鬓头 奄奄门后 人未走 月圆寂寞 旧地重游 夜半清醒泪 烛火空留 一壶漂泊浪迹天涯难入喉 君去后 酒暖思谁瘦 水向东流 三春如梦向谁偷 花开却错 谁家琵琶东风破 岁月流离 不解时候 ...

  8. HTML练习—东风破

    <!doctype html> <html><head><meta charset="utf-8" /><title>练 ...

  9. 五年IT五股东风 吹奏一曲SaaS“东风破”

    编者按:SaaS这个当今时髦的词汇到底离我们有多远,它又能够为企业信息化帮多大的忙?SaaS能否成为缺乏资金.人员.技术的中小企业进行信息化建设的捷径?本系列文章将从SaaS的模式起源开始,逐步向我们 ...

最新文章

  1. 数字证书中keytool命令使用说明
  2. Python 模块之 time datetime
  3. 【转载】Spring @Async 源码解读。
  4. Oracle通过主键id删除记录很慢
  5. Python使用os.listdir()函数来得目录内容的介绍
  6. 基于FPGA的电机控制设计(PWM)
  7. javascript学习系列(9):原数组发生变化的情况
  8. 电气工程及其自动化学不学c语言,电气工程及其自动化学什么 就业方向有哪些...
  9. 要做华为最强竞争对手,荣耀新动作曝光...
  10. mybatis与Spring整合配置文件
  11. php mysql搜索功能并分页_php实现搜索和分页效果-亲测有效
  12. JAVA日期处理(Timestamp)
  13. 自定义报表(demo1)
  14. react 小书学习笔记-state/props
  15. php集成环境安装包比较,PHP集成环境phpStudy安装包分享
  16. linux下firefox浏览器的flash版本过低解决方案
  17. 使用超级表格快速创建在线表单(如问卷调查、报名表)
  18. RNA-seq 详细教程:实验设计(2)
  19. 通信安全重重考验,阿里云通信如何打造企业级“安全感”?
  20. 【墨者学院】主机溢出提权漏洞分析

热门文章

  1. 【密集人群检测】Detection in Crowded Scenes: One Proposal, Multiple Predictions例程实现
  2. Django框架实现在线考试系统
  3. ESP8266 下载模式 GPIO 研究
  4. LVGL 字体转换与支持
  5. 【方同学】是如何高效的使用IntelliJ IDEA
  6. 响应式布局有什么优点和缺点
  7. .NET周报【10月第1期 2022-10-11】
  8. linux运行软件代码,Linux软件安装-详细源码安装过程
  9. [VQA文献阅读] FloodNet: A High Resolution Aerial Imagery Dataset for Post Flood Scene Understanding
  10. 第十二周 任务三