首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

史上特例:Python 写音乐

方法1,去GitHub上找到这个库下载即可

(https://mdoege.github.io/PySynth/#m)

方法2

直接pip install pysynth 即可

但注意,这个不是一个确切的库,是不可以被引入的。

安装后,他是多个文件

在site-package目录下

C:\Users\CC>pip install PySynth

Requirement already satisfied: PySynth in c:\users\cc\appdata\local\programs\python\python37\lib\site-packages (2.3)

进到这个目录看,关于pysynth的文件有这些

可以直接拿出来用

直接import会报错

import PySynth

Traceback (most recent call last):

File "", line 1, in

ModuleNotFoundError: No module named 'PySynth'

那就正式开始介绍了

闲来无事,就去查了查网上关于Python音乐的资料,但是都是英文的资料,但照样弄过来玩玩8.顺便锻炼一下英语水平(在看得懂的情况下)

开始8

基本知识

打开主文件pysynth。py

源文件里有这样的解释

# 'song' is a Python list (or tuple) in which the song is defined,

# the format is [['note', value]]

# Notes are 'a' through 'g' of course,

# optionally with '#' or 'b' appended for sharps or flats.

# Finally the octave number (defaults to octave 4 if not given).

# An asterisk at the end makes the note a little louder (useful for the beat).

# 'r' is a rest.

# Note value is a number:

# 1=Whole Note; 2=Half Note; 4=Quarter Note, etc.

# Dotted notes can be written in two ways:

# 1.33 = -2 = dotted half

# 2.66 = -4 = dotted quarter

# 5.33 = -8 = dotted eighth

在这里说明,song对象是一个列表或者元祖定义的

音调是从a到g调。

可以选择#升半调或者b降半调

最后的什么octave什么,如果不指定默认以4octave结尾(octave音符)

一个什么,asterisk在最后会是重音

r是一个休止符?

音符长度用数字表示

1是全音符,2是二分音符,4是4分衣服

浮点音符可以写成这样

1.33 = -2 = 二分浮点音符

2.66 = -4 = 四分浮点音符

5.33 = -8 = 八分浮点音符

# Some parameters:

# Beats (quarters) per minute

# e.g. bpm = 95

# Octave shift (neg. integer -> lower; pos. integer -> higher)

# e.g. transpose = 0

# Pause between notes as a fraction (0. = legato and e.g., 0.5 = staccato)

# e.g. pause = 0.05

# Volume boost for asterisk notes (1. = no boost)

# e.g. boost = 1.2

# Output file name

#fn = 'pysynth_output.wav'

# Other parameters:

# Influences the decay of harmonics over frequency. Lowering the

# value eliminates even more harmonics at high frequencies.

# Suggested range: between 3. and 5., depending on the frequency response

# of speakers/headphones used

。。。。。

一些参数。

节奏:每分钟节拍数; bpm = 95

八度转变 (neg. 降八度; pos. 升八度);

transpose = 0 音符间停顿 (0. = 连音 ; 0.5 = 断音);

pause = 0.05

Volume boost:音量变高 (1. = 音量无变化);

boost = 1.2

Output file name 输出文件名;fn = 'pysynth_output.wav'

我不懂嗷,专业名词就拉谷歌了

1.

尝试分析

在上面引入了这个

from demosongs import *

from mkfreq import getfreq

pitchhz, keynum = getfreq(pr = True)

demosongs是一个音乐的例子,等等再去看

这个getfreq,得到频率?

是一个函数,去看看

def getfreq(pr = False):

if pr:

print("Piano key frequencies (for equal temperament):")

print("Key number\tScientific name\tFrequency (Hz)")

for k in range(88):

freq = 27.5 * 2.**(k/12.)

oct = (k + 9) // 12

note = '%s%u' % (keys_s[k%12], oct)

if pr:

print("%10u\t%15s\t%14.2f" % (k+1, note.upper(), freq))

pitchhz[note] = freq

keynum[note] = k

note = '%s%u' % (keys_f[k%12], oct)

pitchhz[note] = freq

keynum[note] = k

note = '%s%u' % (keys_e[k%12], oct)

pitchhz[note] = freq

keynum[note] = k

return pitchhz, keynum

做着说了,这个是piano,的音调频率

我不懂乐理,看不懂他在弄什么

翻译成中文就是

频率=。。

音阶=。。

音长=。。

去网上查了一下。

频率原来是定义piano第一个音到最后一个的频率(88键)

音阶的话,8个音一个音阶,所以就变成那样了(//是整除)

音调的话。这个note = '%s%u' % (keys_f[k%12], oct)

oct是音阶,这个keys——f是?

keys_s = ('a', 'a#', 'b', 'c', 'c#', 'd', 'd#', 'e', 'f', 'f#', 'g', 'g#')

keys_f = ('a', 'bb', 'b', 'c', 'db', 'd', 'eb', 'e', 'f', 'gb', 'g', 'ab')

keys_e = ('a', 'bb', 'cb', 'b#', 'db', 'd', 'eb', 'fb', 'e#', 'gb', 'g', 'ab')

上面给了这个三个东东

所以那就是,note就是一个代表音调和音阶的变量

去把那个打印出来

print(pitchhz)

print (keynum)

其实就是两个字典对应音调和频率嗷

综上所述,这个引入的函数是用来生成钢琴对应的参数的

2.

里里面的栗子

看看里面的例子

if __name__ == '__main__':

print("Creating Demo Songs... (this might take about a minute)")

# SONG 1

make_wav(song1, fn = "pysynth_scale.wav")

这里用了一个make——wav函数,再去看看这个函数是什么

def make_wav(song,bpm=120,transpose=0,pause=.05,boost=1.1,repeat=0,fn="out.wav", silent=False):

f=wave.open(fn,'w')

f.setnchannels(1)

f.setsampwidth(2)

f.setframerate(44100)

f.setcomptype('NONE','Not Compressed')

bpmfac = 120./bpm

def length(l):

return 88200./l*bpmfac

def waves2(hz,l):

a=44100./hz

b=float(l)/44100.*hz

return [a,round(b)]

def sixteenbit(x):

return struct.pack('h', round(32000*x))

def asin(x):

return math.sin(2.*math.pi*x)

def render2(a,b,vol):

b2 = (1.-pause)*b

l=waves2(a,b2)

ow=b''

q=int(l[0]*l[1])

# harmonics are frequency-dependent:

lf = math.log(a)

lf_fac = (lf-3.) / harm_max

if lf_fac > 1: harm = 0

else: harm = 2. * (1-lf_fac)

decay = 2. / lf

t = (lf-3.) / (8.5-3.)

volfac = 1. + .8 * t * math.cos(math.pi/5.3*(lf-3.))

for x in range(q):

fac=1.

if x

if 100

if x>q-400: fac=1.-((x-q+400)/400.)

s = float(x)/float(q)

dfac = 1. - s + s * decay

ow=ow+sixteenbit((asin(float(x)/l[0])

+harm*asin(float(x)/(l[0]/2.))

+.5*harm*asin(float(x)/(l[0]/4.)))/4.*fac*vol*dfac*volfac)

fill = max(int(ex_pos - curpos - q), 0)

f.writeframesraw((ow)+(sixteenbit(0)*fill))

return q + fill

##########################################################################

# Write to output file (in WAV format)

##########################################################################

if silent == False:

print("Writing to file", fn)

curpos = 0

ex_pos = 0.

for rp in range(repeat+1):

for nn, x in enumerate(song):

if not nn % 4 and silent == False:

print("[%u/%u]\t" % (nn+1,len(song)))

if x[0]!='r':

if x[0][-1] == '*':

vol = boost

note = x[0][:-1]

else:

vol = 1.

note = x[0]

try:

a=pitchhz[note]

except:

a=pitchhz[note + '4'] # default to fourth octave

a = a * 2**transpose

if x[1]

b=length(-2.*x[1]/3.)

else:

b=length(x[1])

ex_pos = ex_pos + b

curpos = curpos + render2(a,b,vol)

if x[0]=='r':

b=length(x[1])

ex_pos = ex_pos + b

f.writeframesraw(sixteenbit(0)*int(b))

curpos = curpos + int(b)

f.writeframes(b'')

f.close()

print()

很长,而且很复杂,我看不懂,不理他

因为声音是一个多个三角函数,是一个数学模型,很复杂,不搞了,气死我

能弄就行,看不懂就算了

3.

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190211A0I31Y00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券