谁在用Python弹奏一曲东风破 - 第二期 - 蜂鸣器版
之前借助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开始的, 而Do
是C
, 蛤, 因此看下面代码的时候需要注意到这个问题, 否则你的音会不对, 而且要注意到, 这是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]
]
得到这个频率表, 我们就可以开始尝试用蜂鸣器来弹奏了. 上面这个表中每一行代表一个八度, 然后从Do
到Si
顺序排列. 不过, 在正式开始写代码之前, 还要补充最后一个知识点, 那就是曲速, 我们可以发现, 我们在听音乐的时候, 每个音的长短是不一样的, 因此, 我们如果想演奏出来的效果更好一些的话, 我们肯定是需要考虑一个十分重要的问题, 也就是曲速, 我们先来看一下东风破的简谱.
这里我们做一下简单化处理, 因为这些复杂的节奏, 我也把握不准, 因此我们这里按照下面的基准来区分节奏.我们按照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弹奏一曲东风破 - 第二期 - 蜂鸣器版相关推荐
- 是谁用Python弹奏一曲东风破
是谁在用Python弹奏一曲东风破 最近闲暇之余, 逛B站, 发现那些大神们用计算器, 用各种东西, 弹曲子, 那是弹得一个好, 作为一个手残人士, 虽然也想尝试一下, 但是吧, 我发现, 我的脑子里 ...
- 谁在用琵琶弹奏一曲东风破
歌曲名称:东风破 作曲:周杰伦 作词:方文山 编曲:林迈可 歌词: 一盏离愁 孤单伫立在窗口 我在门后 假装你人还没走 旧地如重游 月圆更寂寞 夜半清醒的烛火 不忍苛责我 一壶漂泊 浪迹天涯难入喉 你 ...
- python获取按键状态_谁在用 python 弹奏一曲菊花台
转自:Crossin的编程教室 想必各位在家已经闲得快发疯了吧,鄙人现在的状态如下: 但是我不想这么萎靡下去,我想做点高雅的事情,看到朋友圈有人在手机app上弹<菊花台>,简直太好听了.于 ...
- html入门之简单页静态面练习-东风破
练习一个简单静态页面,在页面中展示<东风破>歌词.让歌词文字和图片居中,教程中是用的html中<center>标签,我在这里用了css样式来解决的.把想要居中的内容放在一个&l ...
- 听着熟悉的《东风破》,好想你~
东风破 一盏离愁孤单伫立在窗口 我在门後假装你人还没走 旧地如重游月圆更寂寞 夜半清醒的烛火不忍苛责我 一壶漂泊浪迹天涯难入喉 你走之後酒暖回忆思念瘦 水向东流时间怎黱偷 花开就一次成熟我却错过 谁在 ...
- 东风破 -词:方文山 曲:周杰伦
东风破 -词:方文山 曲:周杰伦 东风破 一盏离愁孤单伫立在窗口 我在门後假装你人还没走 旧地如重游月圆更寂寞 夜半清醒的烛火不忍苛责我 *一壶漂泊浪迹天涯难入喉 你走之後酒暖回忆思念瘦 水向东流 ...
- 东风破 苏轼 喜欢的词,方文山的歌词好象就是这样借过来的。
一盏离愁 孤单窗前自鬓头 奄奄门后 人未走 月圆寂寞 旧地重游 夜半清醒泪 烛火空留 一壶漂泊浪迹天涯难入喉 君去后 酒暖思谁瘦 水向东流 三春如梦向谁偷 花开却错 谁家琵琶东风破 岁月流离 不解时候 ...
- HTML练习—东风破
<!doctype html> <html><head><meta charset="utf-8" /><title>练 ...
- 五年IT五股东风 吹奏一曲SaaS“东风破”
编者按:SaaS这个当今时髦的词汇到底离我们有多远,它又能够为企业信息化帮多大的忙?SaaS能否成为缺乏资金.人员.技术的中小企业进行信息化建设的捷径?本系列文章将从SaaS的模式起源开始,逐步向我们 ...
最新文章
- 数字证书中keytool命令使用说明
- Python 模块之 time datetime
- 【转载】Spring @Async 源码解读。
- Oracle通过主键id删除记录很慢
- Python使用os.listdir()函数来得目录内容的介绍
- 基于FPGA的电机控制设计(PWM)
- javascript学习系列(9):原数组发生变化的情况
- 电气工程及其自动化学不学c语言,电气工程及其自动化学什么 就业方向有哪些...
- 要做华为最强竞争对手,荣耀新动作曝光...
- mybatis与Spring整合配置文件
- php mysql搜索功能并分页_php实现搜索和分页效果-亲测有效
- JAVA日期处理(Timestamp)
- 自定义报表(demo1)
- react 小书学习笔记-state/props
- php集成环境安装包比较,PHP集成环境phpStudy安装包分享
- linux下firefox浏览器的flash版本过低解决方案
- 使用超级表格快速创建在线表单(如问卷调查、报名表)
- RNA-seq 详细教程:实验设计(2)
- 通信安全重重考验,阿里云通信如何打造企业级“安全感”?
- 【墨者学院】主机溢出提权漏洞分析
热门文章
- 【密集人群检测】Detection in Crowded Scenes: One Proposal, Multiple Predictions例程实现
- Django框架实现在线考试系统
- ESP8266 下载模式 GPIO 研究
- LVGL 字体转换与支持
- 【方同学】是如何高效的使用IntelliJ IDEA
- 响应式布局有什么优点和缺点
- .NET周报【10月第1期 2022-10-11】
- linux运行软件代码,Linux软件安装-详细源码安装过程
- [VQA文献阅读] FloodNet: A High Resolution Aerial Imagery Dataset for Post Flood Scene Understanding
- 第十二周 任务三