用 Python 进行音乐创作

文/世界上的霸主  图片来源于网络

投稿邮箱:pythonpost@163.com

前言

上期留了尾,卖了关子。接着上回用 Python 播放多声轨 MIDI 文件音乐继续为您说。

如今,许多人尝试用计算机创作乐器,普遍方法是随机生成一段音乐,和现有曲子的相似度进行打分,一个分值范围内算通过。我也这么做?不,这样做效率低下,随机生成几千首只有一首通过,计算速度也十分低下(超级电脑不说),筛选出的曲子也不一定好听。

我用什么方法呢?今天,我们要了解许多令人发指的乐理,以及计算令人发指的乐理公式。准备好笔纸了么?今天,就让我,带您进入美妙复杂的音乐殿堂吧!

乐理的代码:

废话不多说,先来讲讲“音程”:

音程及其算法:

看着玄乎,其实是最简单,它表示两音之间的“距离其基本单位称为度。在mido中,以“半音”为基本单位,接下来,我都采用半音计数

1:小二度
2:大二度/减三度
3:小三度/增二度
4:大三度/减四度
5:纯四度/增三度
6:增四度/减五度
7:纯五度/减六度
8:小六度/增五度
9:大六度/减七度
10:小七度/增六度
11:大七度
单位:半音

除了四度和五度(八度不算)度按减小大增来计算没有基准。但,一般“大度”为最佳选择。不信可以尝试下,是大三度好听,还是小三度好听。除四度以外,只有理论上的增减,不会说增三度,只说纯四度。因此,只需做11个函数就行了。比如说小二度:

1.def sd_two(low=None,high=None):         #小二度  
2.    if type(low) == str:  
3.     ···#就是转换,前面的代码都写过  
4.    yin = []  
5.    if low and high == None:  
6.        high = low + 1  
7.    if high and low == None:  
8.        low = high - 1  
9.     yin.append(low)  
10.    yin.append(high)  
11.    return yin  

我花了整天肝枯燥的做简单计算 的代码,想看去我的Github:

https://github.com/duoduo666/mido-Barock/blob/master/turn%20note/yin_cheng.py

记得star哦。

三和弦:

三和弦有四类,大三和弦,小三和弦,增三和弦,减三和弦。七和弦较复杂,有兴趣读者可自己搜搜。

大三和弦结构是:大三度+小三度。小三和弦结构是:小三度+大三度。增三和弦结构是:大三度+大三度,减三和弦结构是:小三度+小三度。最舒服的和弦是大三和弦,最恶心的和弦是减三和弦。

因此,我们只要知道一个音,就可以求出其他的音。我在这贴大三和弦代码:

1.def b_three(geng=None,zhong=None,wu=None):  
2.        yin = []  
3.        if geng and zhong == None and wu == None:    #知道根音  
4.            zhong = geng + 4  
5.            wu = zhong + 3  
6.             yin.append(geng)
7.             yin.append(zhong)
8.             yin.append(wu)
9.             return yin
10.        if zhong and geng == None and wu == None:      #知道中音  
11.            geng = zhong - 4  
12.            wu = zhong + 3  
13.             ····#同上
14.        if wu and geng == None and zhong == None:      #知道五音  
15.            zhong = wu - 3  
16.            geng = zhong - 4  
17.            ····#同上

转位

三和弦有四类,每类都有3种“形态”,称为“转位”,分别是:第一转位(原位),第二转位(4转位),第三转位(46转位)

每次转位把最低音(根音)提八度(12半音)。为大家理解,我画了大三和弦转位图(单位:半音)。

X代表根音(最低音),Y代表三音(中间音),Z代表五音(最高音)。清楚多了吧,其余三个皆如此。

脑筋都不用动了,直接出转换代码。(转换位大4和弦)

·····  #前面有
2.    yin = []  
3.    if geng and zhong and wu:                        #若是三个都有  
4.        if zhong - geng == 4 and wu - zhong == 3:    #若是第一转为(三和弦)  
5.            geng += 12  
6.            yin.append(zhong)  
7.            yin.append(wu)  
8.            yin.append(geng)  
9.            return yin  
10.        if zhong - geng == 5 and wu - zhong == 4:    #若是第三转为(46和弦)  
11.            wu -= 12  
12.            yin.append(wu)  
13.            yin.append(geng)  
14.            yin.append(zhong)  
15.            return yin  
16.         if zhong - geng == 3 and wu - zhong == 5:  
17.            return True  

但是,种类太多我花了10天夸张) 完成,这不贴了,有兴趣的到我的GitHub

https://github.com/duoduo666/mido-Barock/tree/master/turn%20note

配上和弦(音程):

哇!可以求和弦和、音程了!鼓掌!。动动脑筋,在myin基础上,更改下,给曲子配上和弦:

1.    def myin(fu,pai,time=120,du=None,chord=None,high=64,note="low",yue=2):  
2.        #和声版  
3.        pig = int(beat(time))    #int取整,time要求整数
4.        for i in range(len(pai)):  
5.            if type(pai[i]) == list:  
6.                ···   #上篇文章有,看看
7.            else:
8.                if chord == None and du == None:
9.                    ···  #上篇文章有,看看
10.                else:  
11.                    #和弦  
12.                    if chord == "dasan":            #大三和弦  
13.                        if note == "low":  
14.                            fu[i] = b_three(fu[i])  
15.                        elif note == "zhong":  
16.                            fu[i] = b_three(zhong=fu[i])  
17.                        elif note == "wu":  
18.                            fu[i] = b_three(wu=fu[i])  
19.                    ····· #此处省略一千行  
20.    
21.                    #音程(度)
22.                    if du == "xiaoer":                   #小二度  
23.                        if note == "low":  
24.                            fu[i] = sd_two(fu[i])  
25.                        if note == "high":  
26.                            fu[i] = sd_two(high=fu[i])  
27.                    ····#此处省略一千行  
28.    
29.                    #循环  
30.                    for x in range(len(fu[i])):  
31.                        yin(fu[i][x],pai[i]*pig,liang=high,unit=tra[x],qi=yue)  

有太多的“音程”、“和弦”,这不可能全贴,看完整代码?去:

https://github.com/duoduo666/mido-Barock/blob/master/play%20note/play%20note(basic).py

庆祝一下,我用这函数,给《玛丽有只小山羊》配了和弦和音程,只有你没想到,没有我做不出,去这里(https://github.com/duoduo666/mido-Barock/tree/master/mary)听听。

巴洛克曲子算法及实现:

巴洛克时期有许多不同的种类曲子,二部曲,三部曲,四部曲,宾格,赋格……数不过来,不同种类的曲子有不同形式。今天我们实现二部曲。二部曲有很多形式,单开式,双起式,加厚式……我们挑个简单的,“单开式”。

《巴赫二部创意曲》第一首就是讲这个。讲之前,要贴几段代码:

倒影:

打个比方:[3,4,5]的倒影就是[3,2,1]。这形式在巴洛克时期全都是,实现函数:

def dao(yin):                 #计算倒影a = yin[0] * 2daoyin = []for i in yin:b = a - idaoyin.append(b)return daoyin 

首音乘2,以此减接下来的数,得出数组(list)

倒影难道音高不变了?总要变吧。动动脑经,得出答案:

def getdao(xuanlu,base):for i in range(len(xuanlu)):if type(xuanlu[i]) == str:xuanlu[i] = num(xuanlu[i])if type(base) == str:base = num(base)xuanlu = dao(xuanlu)high = base - xuanlu[0]for i in range(len(xuanlu)):xuanlu[i] += highreturn xuanlu

以base位基音,得出xuanlu倒影。

分拆和弦、时间:

在巴洛克时期,总会把主题(主旋律)拆开来,分成个主题。但你不知道用户会输入怎样的节奏型。再动动脑筋,就可以把旋律按节拍的不同拆开。

1.    def getlu(first,second,ind):  
2.        s = 0  
3.        c = 0  
4.        for i in range(1,len(second)):  
5.            if second[i] != second[s]:  
6.                c += 1  
7.                if c == ind:  
8.                    return first[s:i]  
9.                else:  
10.                    s = i  
11.        return first[s:]  

同理,分拆时间:

1.    def gettime(paizi,ind):  
2.        s = 0  
3.        c = 0  
4.        for i in range(1,len(paizi)):  
5.            if paizi[i] != paizi[s]:  
6.                c += 1  
7.                if c == ind:  
8.                    return paizi[s:i]  
9.                else:  
10.                    s = i  
11.        return paizi[s:]  

这样你就可以获取任意一段的代码和时间了。

计算机计算乐曲实现:

有小白生气了,算法还不讲!别急,算法这不就来了?那最经典的BWV772举例:

此图版权为作者所有!我们用蓝色框匡主题,绿色框匡副题和配旋律。用黄色代表倒影。我们用数学的语言总结下:(我画的)

有个特别的。所有的曲子都要“解决”,“解决”是较复杂,有兴趣的可以搜搜。这我自己做了个个性化 解决,大家可以拿来用。

lastyin = [b_three(".do"),b_three(".mi"),b_three(".so"),b_three("do"),b_three("mi"),b_three("so"),'so','mi','do',"do","si"]  
lastpai = [xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,0.5,0.5,1.5,5]  
myin(lastyin,lastpai,track=track4)  
myin(["do"],[10],high=120)  

此解决方法严禁抄袭。到这,相信只要智商>100,就可以写出来。但,许多的小白还是不会写。为了照顾小白,我原来想在这里贴,但是实在太长,放不下。请去我的barok文件下载(https://github.com/duoduo666/mido-Barock/tree/master/barok)。

结语

如今,您可以通过计算机计算出巴洛克时期的二部曲的开场事了,只要有个好旋律,就可以出个好曲子。但其他的种类呢?可以买本《巴赫创意曲集》,一共30首曲子,每首曲子都很经典。可以自己挨个分析写代码哦。

如果有问题,请到我的github的issue模块哦:

https://github.com/duoduo666

赞 赏 作 者

Python中文社区作为一个去中心化的全球技术社区,以成为全球20万Python中文开发者的精神部落为愿景,目前覆盖各大主流媒体和协作平台,与阿里、腾讯、百度、微软、亚马逊、开源中国、CSDN等业界知名公司和技术社区建立了广泛的联系,拥有来自十多个国家和地区数万名登记会员,会员来自以工信部、清华大学、北京大学、北京邮电大学、中国人民银行、中科院、中金、华为、BAT、谷歌、微软等为代表的政府机关、科研单位、金融机构以及海内外知名公司,全平台近20万开发者关注。

投稿邮箱:pythonpost@163.com

投稿点击阅读原文   喜欢文章,点个在看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/40443.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Github ChatGPT-Web:了解最新AI技术的前沿应用!

近年来OpenAI的ChatGPT模型在自然语言处理领域取得了很大的进展,并且已经在全球范围内得到了广泛的应用和普及。ChatGPT不仅可以用于生成对话和文本摘要等任务,还可以用于机器翻译、问答系统、情感分析等多个领域。ChatGPT已经成为自然语言处理领域的一个…

chatgpt赋能python:Python怎么将界面和程序交互

Python怎么将界面和程序交互 随着互联网技术的不断发展和普及,越来越多的人开始关注于网站的设计和开发。在Web应用程序的开发过程中,与用户进行交互是至关重要的一个方面,而Python作为一种强大的开发语言,可以很好地帮助我们实现…

汇正财经骗局?大盘午后有修复,科创50大涨2.69%

盘面回顾: 沪深创集体调整,收盘沪指跌0.09%,深成指跌0.37%,创业板指跌1.2%,科创50全天占优,收盘涨2.69%。板块个股,早上6G概念股开盘大涨,业绩增长股大受追捧,算力、CPO…

汇正财经骗局?大小指数分化,主板偏强

盘面回顾: 今日大小指数全天分化,沪指保持红盘,创业板一度跌近1%,黄白二线大幅背离,截止收盘沪指涨0.41%,深成指涨0.05%,创业板指跌0.41%。早盘,ChatGPT概念反弹AI应用端持续发力&a…

马斯克又任性了!将推特“蓝鸟”换成“狗头”,意欲何为?

整理 | 朱珂欣 出品 | CSDN程序人生(ID:coder_life) 自从去年 10 月 27 日马斯克收购 Twitter 、担任 CEO 后,以一己之力凭借“灭霸式”裁员、精确到代码行数的“周报”等职场“骚操作”,让他进阶为互联网流量密码。…

世界杯小组赛频繁爆冷?这或许是强队的谋略 一分钟带你了解2022卡塔尔世界杯赛制

今年的世界杯你赚到钱了吗? 我们这里所说的世界杯是指世界杯决赛圈,也被叫做世界杯正赛。参赛队伍是已经通过世界杯预选赛选拔出的的32支队伍(除了东道主卡塔尔自动晋级)。 世界杯中没有皇马、巴萨、曼联,这些都是俱…

2018世界杯数据清单:真球迷看球必备,伪球迷速成指南(附完整赛程)

导读:每隔4年都有那么1个月,无论是线上还是线下,不管是真球迷还是真球盲,你的社交圈子都会被世界杯话题攻占。每到这个时候,真球迷一言不合就面红耳赤,伪球迷尬聊不超过3句就暴露“球商”…… 用段子缓解尴…

2022年卡塔尔世界杯,分析之前的比赛计算出谁是冠军

2022 年卡塔尔国际足联世界杯即将开始,让我们来玩个游戏吧。 我研究了世界杯上每支球队之前所有比赛的历史数据,以预测从小组赛阶段到决赛以及第三名获胜者的过往球队。 我们将遵循的规则: 查看两支球队之前的比赛,并根据胜负或平…

Python预测卡塔尔世界杯身价最高的英格兰要夺冠?!

文章目录 🏳️‍🌈 1. 数据🏳️‍🌈 2. 绘图2.1 绘制表头2.2 绘制排名、球队以及国旗2.3 绘制身价柱状图2.4 绘制FIFA排名散点图2.5 设置背景2.6 设置标题 🏳️‍🌈 3. 更多可视化项目源码数据:…

神了,用 Python 预测世界杯决赛,发现准确率还挺高

那么四年一度的世界杯即将要在卡塔尔开幕了,对于不少热爱足球运动的球迷来说,这可是十分难得的盛宴,而对于最后大力神杯的归属,相信很多人都满怀着期待,每个人心中都有不同的答案。 今天我就通过Python数据分析以及机…

太硬核!用大数据技术预测足球胜率

点个关注👆跟腾讯工程师学技术 引言| 足球作为世界第一运动,充满了速度和力量的结果,团队与谋略的对抗。人们也说,足球是圆的,恰恰也表明了足球比赛的不可预知性,一切结果都皆有可能。强如巴萨,…

chatgpt赋能python:Python如何处理两个表的关联-实现数据的整合与分析

Python如何处理两个表的关联 - 实现数据的整合与分析 在日常的数据处理与分析中,有时我们需要将两个表格进行关联,以实现数据的整合与分析。Python作为一门常用的数据分析工具,提供了多种方式来实现不同表格之间的关联。 什么是表格关联&am…

Android 14 的首个开发者预览版,推出四大安全增强功能

【CSDN 编者按】2 月 8 日,谷歌正式发布了 Android 14 首个开发者预览版,该版本将继续致力于提高开发者效率,同时推出四大安全功能。该版本将支持跨/多设备登录、应用双开、基于自己的需求定制增强的辅助功能等。 原文链接:https:…

薅!无魔法无限量GPT-4安卓App安装包;Notion AI从入门到精通;最全大模型进展汇总;雇AI给我打零工 | ShowMeAI日报

👀日报&周刊合集 | 🎡生产力工具与行业应用大全 | 🧡 点赞关注评论拜托啦! 🤖 『大模型进展汇总 (持续更新至4月17日)』应该是最全总结了吧 ShowMeAI资料编号 No.T001 (进入社群获取高清PDF文件&#x…

微信链接经常被秒封、被屏蔽、被拦截的最新微信防封方案

很多商家团队经常会需要通过微信推广一些线下举办的活动或者产品的广告网页(如QP、BC、CP等)。 因为现阶段,微信推广是传播信息速度最快的方法,见的最多的就是通过广告页或产品介绍,里面经常会嵌入产品的网站二维码&a…

当GPT-4化身主考官:与ChatGPT处于同水平的有这些

魏亦豪 投稿量子位 | 公众号 QbitAI GPT-4太强,甚至已经化身“主考官”了! 给其他市面上主流的大模型打分,结果自己给了自己最高分: 95.5。(好,给自己留点努力的空间) 不过随后就没有上90的选手…

教师ChatGPT的23种用法

火爆全网的ChatGPT,作为教师应该如何正确使用?本文梳理了教师ChatGPT的23种用法,一起来看看吧! 1、回答问题 ChatGPT可用于实时回答问题,使其成为需要快速获取信息的学生的有用工具。 从这个意义上说,Cha…

“此电话号码无法用于进行验证” 注册gmail邮箱手机号码不能验证的解决方法(已解决)

如果网页注册Google账号时出现 此电话号码无法用于进行验证 1.手机上安装gmail app(华军软件园下载), 2 安装后,从手机的添加账号里面创建就行。 3、 然后电脑上就能登录了 4.参考链接 https://baiyunju.cc/5391

注册谷歌广告联盟提示“此电话号码无法用于进行验证”解决办法

今天给网站注册谷歌联盟账号的时候到了验证手机号的时候一直提示“此电话号码无法用于进行验证”,我以为是我195的号还没被兼容,于是换了好几个手机号都是这样,经过一番百度之后终于是解决了问题。 其实要做的就是将我们的浏览器语言改成英文…

谷歌账号注册时中国大陆手机号无法验证,“此电话号码无法用于进行验证”快速解决。2023年新方法

谷歌注册无法验证?不要紧——解决方法在这里! 相信大部分人注册谷歌都遇到一个问题,那就是手机号无法用于验证。今天这篇文章,讲讲如何解决这种问题。如下图: 大部分人都是出现无法验证,说白了就是谷歌防止批量恶意…