前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >程序员拒绝单曲循环:曲子只有5分钟,也得不重样播放450多天

程序员拒绝单曲循环:曲子只有5分钟,也得不重样播放450多天

作者头像
量子位
发布2019-04-23 09:34:22
3960
发布2019-04-23 09:34:22
举报
文章被收录于专栏:量子位量子位量子位
乾明 发自 凹非寺 量子位 报道 | 公众号 QbitAI

程序员要是喜欢上一个东西,指不定会搞出什么“疯狂”事情来。

今天要说的,是特别喜欢一首曲子的程序员贝特(Alex Bainter)。

这首曲子,名为aisatsana,来自电子乐大师Aphex Twin,只有5分多钟。

让他很苦恼的是,单曲循环听着容易腻歪,他想让这个曲子能一直不重样地播放下去。

然后,他选择了马尔可夫链……

现在这首曲子已经能够不间断播放451天不重样……(听歌地址在文末)

贝特把完成这一“壮举”的过程写成了文章,分享了出来,而且,代码已经开源

在Hacker News很快就获得了400多热度,200多条评论。

不少人评论称,这样听歌真的很爽, 实现起来很简单,但效果很好!

它到底是怎么做的呢?我们一起来看看。

从算法的角度理解一首曲子

想要曲子不重样地播放下去,首要的任务就是要理解曲子的结构。

一般情况下,播放曲子的速度可以BPM(beats per minute)来衡量。

aisatsana这首曲子很简单,共有102BPM。如果从第一个音符开始计数的,每16个节拍包含一系列音符,他称之为乐句(phrase),整首曲子中,一共有32个乐句。

想要创建一个能够不间断、不重复播放aisatsana的系统,算法需要满足以下两个要求:

  • 知道一个乐句什么时候结束。
  • 播放不重样的乐句。

第一个要求,相对来说非常简单,只是计时。第二个要求,是最棘手的部分。

让曲子一直播放下去

一种简单的策略是,编写一个程序,粗暴地把32个乐句拆分开,一个乐句之后,随机播放另一个。

这种方式,虽然相互衔接上没有问题,听起来也比单曲循环更加灵活有趣,但本质上也是重复的。

只要熟悉了这32个乐句,曲子依旧会无聊。

怎么办?答案只有一个:

创造一个系统,来生成听起很与原来乐句很相似的新乐句。

最直接的方法,就是深度学习技术了。但只有32个乐句的样本……很显然不太现实。

最后,贝特就把目光转向了马尔可夫链这个“老方法”。

马尔可夫链,能够记录一组状态中,从一个状态转移到另一个状态的概率。

举例来说,你生活中只去3个地方:家、公司和商店,也就是说,你要么在家里,要么在公司,要么在商店。

想要的知道你接下来要去哪?首先就是记录你一段时间内去这三个地方情况,根据记录数据来分析相关的可能性。

比如说,当你在家的时候,你有80%的可能性去公司,你在公司的时候,回家和去商店概率都是50%,如果你在商店,接下来回家的可能性就有95%。

以上,就是创建一个马尔可夫链的所需要的一切:状态,以及从一个状态到另一个状态的概率。

如果把它应用到音乐上,该怎么做?

马尔可夫链生成新乐句

先来看一张图:

图中展示的是两个乐句,每个有4个节拍,每个音符旁边,是音符的名字,最上面是节拍。播放这些乐句的顺序,是从左到右依次进行。

然后,把两个乐句放到马尔可夫链中,状态命名为节拍与音符的组合,比如1A就是在第一个节拍的时候演奏A音符。

除了这些,还需要有开始和结束的状态,来表示乐句的开始和结束。用箭头来表示一个状态到另一个状态的转变。

在上图中,第一个乐句就是开始→1A→2F→3A→4F→结束。第二个乐句是开始→1E→2C→3A→4C→结束。

这里面,一共有9个状态,分别是开始、1A、1E、2F、2C、3A、4F、4C和结束。从一个状态到另一个状态的概率是:

开始→1A:50% 开始→1E:50% 1A→2F:100% 1E→2C:100% 2F→3A:100% 2C→3A:100% 3A→4F:50% 3A→4C:50% 4F→结束:100% 4C→结束:100%

这样,就建立了一个马尔可夫链。从开始到结束,所有可能的路径,可以生成4个乐句:

开始→1A→2F→3A→4F→结束(原始乐句1) 开始→1A→2F→3A→4C→结束(新乐句) 开始→1E→2C→3A→4C→结束(原始乐句2) 开始→1E→2C→3A→4F→结束(新乐句)

就这样,马尔科夫链就生成了两个新的乐句!因为是通过同一个链构建的,听起来也会非常相似。

在这个例子中,只是用了2个乐句,每个乐句中4个节拍。而aisatsana中有32个乐句,每个乐句16个节拍。

按照这个逻辑,贝特最后生成了400多万个独特的乐句,可以播放超过451天,而且所有的乐句都不会重复……

整个实现代码,贝特已经开源了,项目地址: https://github.com/generative-music/pieces-alex-bainter/blob/master/packages/piece-aisatsana/src/piece.js

如果你有兴趣,可以自己上手试试~

最后,附上生成的aisatsana地址:

https://generative.fm/music/alex-bainter-aisatsana

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 量子位 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 从算法的角度理解一首曲子
  • 让曲子一直播放下去
  • 马尔可夫链生成新乐句
相关产品与服务
云直播
云直播(Cloud Streaming Services,CSS)为您提供极速、稳定、专业的云端直播处理服务,根据业务的不同直播场景需求,云直播提供了标准直播、快直播、云导播台三种服务,分别针对大规模实时观看、超低延时直播、便捷云端导播的场景,配合腾讯云视立方·直播 SDK,为您提供一站式的音视频直播解决方案。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档