• Python根据乐谱生成音乐


    --*--

    (!)有更新版本:Python音乐制作-紧急修复版v1.2_Unconquerable&Llxy的博客-CSDN博客

    --*--

    外来库:Pysynth

    PySynth — A Music Synthesizer for Pythonhttps://mdoege.github.io/PySynth/#d

    文件资源:

    Python第三方库:Pysynth-Python文档类资源-CSDN下载学习资源,解压后使用。更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/html_finder/86441665

    音色有多种,取决于不同模块。这里不过多赘述。

    上 代 码 

    文件(1)melody.py

    1. # coding:utf-8
    2. """
    3. ----------------------------------
    4. * author: Unconquerable *
    5. ----------------------------------
    6. a great tool to convert melody text to music.
    7. """
    8. class sound(object):
    9. high=4
    10. def __init__(self,high=4):
    11. self.high=high
    12. def __del__(self):
    13. del self.high
    14. def __str__(self):
    15. return ""
    16. def upLoud(self,up=1):
    17. self.high+=up
    18. def downLoud(self,down=1):
    19. self.high-=down
    20. def absoluteLoud(self,abv=0):
    21. self.high+=abv
    22. absLoud=absoluteLoud
    23. def resetLoud(self,value=4):
    24. self.high=value
    25. init=resetLoud
    26. @property
    27. def toString(self):
    28. return self.__str__()
    29. real=toString
    30. def plus(self):
    31. ...
    32. def plus_(self,num):
    33. ...
    34. def nplus(self):
    35. ...
    36. class C(sound):
    37. high = 4
    38. def __init__(self,high=4):
    39. super().__init__(high=high)
    40. def __str__(self):
    41. return "c"+str(self.high)
    42. def plus(self):
    43. return AddC(self.high)
    44. def plus_(self, num):
    45. if num == 0: return self
    46. if num < 0:
    47. return self.nplus().plus_(num + 1)
    48. if num > 0:
    49. return self.plus().plus_(num - 1)
    50. def nplus(self):
    51. return B(self.high-1)
    52. class AddC(sound):
    53. high = 4
    54. def __init__(self,high):
    55. super().__init__(high)
    56. def __str__(self):
    57. return "c#"+str(self.high)
    58. def plus(self):
    59. return D(self.high)
    60. def plus_(self, num):
    61. if num == 0: return self
    62. if num < 0:
    63. return self.nplus().plus_(num + 1)
    64. if num > 0:
    65. return self.plus().plus_(num - 1)
    66. def nplus(self):
    67. return C(self.high)
    68. class D(sound):
    69. high = 4
    70. def __init__(self,high=4):
    71. super().__init__(high=high)
    72. def __str__(self):
    73. return "d"+str(self.high)
    74. def plus(self):
    75. return AddD(self.high)
    76. def plus_(self, num):
    77. if num == 0: return self
    78. if num < 0:
    79. return self.nplus().plus_(num + 1)
    80. if num > 0:
    81. return self.plus().plus_(num - 1)
    82. def nplus(self):
    83. return AddC(self.high)
    84. class AddD(sound):
    85. high = 4
    86. def __init__(self,high=4):
    87. super().__init__(high=high)
    88. def __str__(self):
    89. return "d#"+str(self.high)
    90. def plus(self):
    91. return E(self.high)
    92. def plus_(self, num):
    93. if num == 0: return self
    94. if num < 0:
    95. return self.nplus().plus_(num + 1)
    96. if num > 0:
    97. return self.plus().plus_(num - 1)
    98. def nplus(self):
    99. return D(self.high)
    100. class E(sound):
    101. high = 4
    102. def __init__(self,high=4):
    103. super().__init__(high=high)
    104. def __str__(self):
    105. return "e"+str(self.high)
    106. def plus(self):
    107. return F(self.high)
    108. def plus_(self, num):
    109. if num == 0: return self
    110. if num < 0:
    111. return self.nplus().plus_(num + 1)
    112. if num > 0:
    113. return self.plus().plus_(num - 1)
    114. def nplus(self):
    115. return AddD(self.high)
    116. class F(sound):
    117. high = 4
    118. def __init__(self,high=4):
    119. super().__init__(high=high)
    120. def __str__(self):
    121. return "f"+str(self.high)
    122. def plus(self):
    123. return AddF(self.high)
    124. def plus_(self, num):
    125. if num == 0: return self
    126. if num < 0:
    127. return self.nplus().plus_(num + 1)
    128. if num > 0:
    129. return self.plus().plus_(num - 1)
    130. def nplus(self):
    131. return E(self.high)
    132. class AddF(sound):
    133. high = 4
    134. def __init__(self,high=4):
    135. super().__init__(high=high)
    136. def __str__(self):
    137. return "f#"+str(self.high)
    138. def plus(self):
    139. return G(self.high)
    140. def plus_(self, num):
    141. if num == 0: return self
    142. if num < 0:
    143. return self.nplus().plus_(num + 1)
    144. if num > 0:
    145. return self.plus().plus_(num - 1)
    146. def nplus(self):
    147. return F(self.high)
    148. class G(sound):
    149. high = 4
    150. def __init__(self,high=4):
    151. super().__init__(high=high)
    152. def __str__(self):
    153. return "g"+str(self.high)
    154. def plus(self):
    155. return AddG(self.high)
    156. def plus_(self, num):
    157. if num == 0: return self
    158. if num < 0:
    159. return self.nplus().plus_(num + 1)
    160. if num > 0:
    161. return self.plus().plus_(num - 1)
    162. def nplus(self):
    163. return AddF(self.high)
    164. class AddG(sound):
    165. high = 4
    166. def __init__(self,high=4):
    167. super().__init__(high=high)
    168. def __str__(self):
    169. return "g#"+str(self.high)
    170. def plus(self):
    171. return A(self.high)
    172. def plus_(self, num):
    173. if num == 0: return self
    174. if num < 0:
    175. return self.nplus().plus_(num + 1)
    176. if num > 0:
    177. return self.plus().plus_(num - 1)
    178. def nplus(self):
    179. return G(self.high)
    180. class A(sound):
    181. high = 4
    182. def __init__(self,high=4):
    183. super().__init__(high=high)
    184. def __str__(self):
    185. return "a"+str(self.high)
    186. def plus(self):
    187. return AddA(self.high)
    188. def plus_(self, num):
    189. if num == 0: return self
    190. if num < 0:
    191. return self.nplus().plus_(num + 1)
    192. if num > 0:
    193. return self.plus().plus_(num - 1)
    194. def nplus(self):
    195. return AddG(self.high)
    196. class AddA(sound):
    197. high = 4
    198. def __init__(self,high=4):
    199. super().__init__(high=high)
    200. def __str__(self):
    201. return "a#"+str(self.high)
    202. def plus(self):
    203. return B(self.high)
    204. def plus_(self, num):
    205. if num == 0: return self
    206. if num < 0:
    207. return self.nplus().plus_(num + 1)
    208. if num > 0:
    209. return self.plus().plus_(num - 1)
    210. def nplus(self):
    211. return A(self.high)
    212. class B(sound):
    213. high = 4
    214. def __init__(self,high=4):
    215. super().__init__(high=high)
    216. def __str__(self):
    217. return "b"+str(self.high)
    218. def plus(self):
    219. return C(self.high+1)
    220. def plus_(self, num):
    221. if num == 0: return self
    222. if num < 0:
    223. return self.nplus().plus_(num + 1)
    224. if num > 0:
    225. return self.plus().plus_(num - 1)
    226. def nplus(self):
    227. return AddA(self.high)
    228. class NULL(sound):
    229. def __str__(self):
    230. return "r"
    231. class time(object):
    232. real = 0
    233. def __init__(self,time=4):
    234. self.real= 4/time
    235. class note(object):
    236. sound_ = sound()
    237. time_ = time()
    238. def __init__(self,sd,t):
    239. self.soundSet(sd)
    240. self.timeSet(t)
    241. def soundSet(self,sd):
    242. if isinstance(sd,str):
    243. nd=sd[:-1].upper()
    244. dct={"C":C,"C#":AddC,"D":D,"D#":AddD,"E":E,"F":F,
    245. "F#":AddF,"G":G,"G#":AddG,"A":A,"A#":AddA,"B":B,"R":NULL}
    246. self.sound_=dct[nd](int(sd[-1]))
    247. if isinstance(sd,sound):
    248. self.sound_=sd
    249. if isinstance(sd,tuple):
    250. nd = sd[:-1].upper()
    251. dct = {"C": C, "C#": AddC, "D": D, "D#": AddD, "E": E, "F": F,
    252. "F#": AddF, "G": G, "G#": AddG, "A": A, "A#": AddA, "B": B, "R": NULL}
    253. self.sound_ = dct[nd](int(sd[-1]))
    254. def timeSet(self,t):
    255. if isinstance(t,(int,float)):
    256. self.time_=time(t)
    257. if isinstance(t,time):
    258. self.time_=t
    259. @property
    260. def out(self):
    261. return self.sound_.toString,self.time_.real
    262. class wav:
    263. melody=C(4)
    264. sound=[]
    265. staticTime=1
    266. def __init__(self,text=None,split=' '):
    267. if text:
    268. self.load(text=text,split=split)
    269. def __del__(self):
    270. pass
    271. @property
    272. def getMelody(self):
    273. return self.melody
    274. @property
    275. def getSound(self):
    276. return self.sound
    277. @property
    278. def getTime(self):
    279. return self.staticTime
    280. def setTime(self,time):
    281. self.staticTime=time
    282. def setMelody(self,melody):
    283. self.melody=melody
    284. def loadOneNote(self,n):
    285. if isinstance(n,note):
    286. self.sound.append(n.out)
    287. if isinstance(n,str):
    288. n=n.strip()
    289. if n[0]=="0":
    290. t=self.staticTime
    291. for i in n[1:]:
    292. if i == "-": # 延音符号
    293. t += self.staticTime
    294. if i == "_": # 半音符号
    295. t /= 2
    296. # (!)不要让延音符号和半音符号同时出现
    297. if i == ".": # 附点音符
    298. t += t / 2
    299. self.sound.append(("r",4/t))
    300. return
    301. #简谱
    302. t=self.staticTime
    303. dct={
    304. 1:0,
    305. 2:2,
    306. 3:4,
    307. 4:5,
    308. 5:7,
    309. 6:9,
    310. 7:11
    311. }
    312. l=self.melody.plus_(dct[int(n[0])])
    313. for i in n[1:]:
    314. if i=="#":#升音符号
    315. l.plus()
    316. if i=="&":#降音符号
    317. l.nplus()
    318. if i=="-":#延音符号
    319. t+=self.staticTime
    320. if i=="_":#半音符号
    321. t/=2
    322. # (!)不要让延音符号和半音符号同时出现
    323. if i==".":#附点音符
    324. t+=t/2
    325. if i=="+":#升音
    326. l.upLoud(1)
    327. if i=="!":#降音
    328. l.downLoud(1)
    329. mixed=note(l,t).out
    330. self.sound.append(mixed)
    331. def load(self,text,split=''):
    332. if split!='':
    333. for i in text.split(split):
    334. self.loadOneNote(i)
    335. else:
    336. tp=""
    337. for i in text:
    338. if i.isnumeric():
    339. if tp.strip() != "":
    340. self.loadOneNote(tp.strip())
    341. tp=""
    342. tp+=i
    343. def make_wav(self,module="pysynth",bpm=120,transpose=0,pause=.05,boost=1.1,
    344. repeat=0,fn="out.wav", silent=False):
    345. __import__(module.lower()).make_wav(song=self.sound,bpm=bpm,transpose=transpose,
    346. pause=pause,boost=boost,repeat=repeat,
    347. fn=fn, silent=silent)

    文件:2(可有可无,可以规定调用的规范)melody.pyi

    1. # coding:utf-8
    2. """
    3. ----------------------------------
    4. * author: Unconquerable *
    5. ----------------------------------
    6. a great tool to convert melody text to music.
    7. """
    8. from typing import Union
    9. class sound(object):
    10. high:int
    11. def __init__(self,high:int=4): ...
    12. def __del__(self): ...
    13. def __str__(self) -> str: ...
    14. def upLoud(self,up:int) -> None: ...
    15. def downLoud(self,down:int) -> None: ...
    16. def absoluteLoud(self,abv:int) -> None: ...
    17. absLoud=absoluteLoud
    18. def resetLoud(self,value:int) -> None: ...
    19. init=resetLoud
    20. @property
    21. def toString(self) -> str : ...
    22. real=toString
    23. def plus(self) -> sound : ...
    24. def plus_(self,num:int) -> sound : ...
    25. def nplus(self) -> sound: ...
    26. class C(sound):
    27. high:int
    28. def __init__(self,high:int=4):
    29. super(C,self).__init__(high=high)
    30. ...
    31. def __str__(self) -> str: ...
    32. def plus(self) -> sound : ...
    33. def plus_(self,num:int) -> sound : ...
    34. def nplus(self) -> sound: ...
    35. class AddC(sound):
    36. high:int
    37. def __init__(self,high:int=4):
    38. super(AddC,self).__init__(high=high)
    39. ...
    40. def __str__(self) -> str: ...
    41. def plus(self) -> sound : ...
    42. def plus_(self,num:int) -> sound : ...
    43. def nplus(self) -> sound: ...
    44. class D(sound):
    45. high:int
    46. def __init__(self,high:int=4):
    47. super(D,self).__init__(high=high)
    48. ...
    49. def __str__(self) -> str: ...
    50. def plus(self) -> sound : ...
    51. def plus_(self,num:int) -> sound : ...
    52. def nplus(self) -> sound: ...
    53. class AddD(sound):
    54. high:int
    55. def __init__(self,high:int=4):
    56. super(AddD,self).__init__(high=high)
    57. ...
    58. def __str__(self) -> str: ...
    59. def plus(self) -> sound : ...
    60. def plus_(self,num:int) -> sound : ...
    61. def nplus(self) -> sound: ...
    62. class E(sound):
    63. high:int
    64. def __init__(self,high:int=4):
    65. super(E,self).__init__(high=high)
    66. ...
    67. def __str__(self) -> str: ...
    68. def plus(self) -> sound : ...
    69. def plus_(self,num:int) -> sound : ...
    70. def nplus(self) -> sound: ...
    71. class F(sound):
    72. high:int
    73. def __init__(self,high:int=4):
    74. super(F,self).__init__(high=high)
    75. ...
    76. def __str__(self) -> str: ...
    77. def plus(self) -> sound : ...
    78. def plus_(self,num:int) -> sound : ...
    79. def nplus(self) -> sound: ...
    80. class AddF(sound):
    81. high:int
    82. def __init__(self,high:int=4):
    83. super(AddF,self).__init__(high=high)
    84. ...
    85. def __str__(self) -> str: ...
    86. def plus(self) -> sound : ...
    87. def plus_(self,num:int) -> sound : ...
    88. def nplus(self) -> sound: ...
    89. class G(sound):
    90. high:int
    91. def __init__(self,high:int=4):
    92. super(G,self).__init__(high=high)
    93. ...
    94. def __str__(self) -> str: ...
    95. def plus(self) -> sound : ...
    96. def plus_(self,num:int) -> sound : ...
    97. def nplus(self) -> sound: ...
    98. class AddG(sound):
    99. high:int
    100. def __init__(self,high:int=4):
    101. super(AddG,self).__init__(high=high)
    102. ...
    103. def __str__(self) -> str: ...
    104. def plus(self) -> sound : ...
    105. def plus_(self,num:int) -> sound : ...
    106. def nplus(self) -> sound: ...
    107. class A(sound):
    108. high:int
    109. def __init__(self,high:int=4):
    110. super(A,self).__init__(high=high)
    111. ...
    112. def __str__(self) -> str: ...
    113. def plus(self) -> sound : ...
    114. def plus_(self,num:int) -> sound : ...
    115. def nplus(self) -> sound: ...
    116. class AddA(sound):
    117. high:int
    118. def __init__(self,high:int=4):
    119. super(AddA,self).__init__(high=high)
    120. ...
    121. def __str__(self) -> str: ...
    122. def plus(self) -> sound : ...
    123. def plus_(self,num:int) -> sound : ...
    124. def nplus(self) -> sound: ...
    125. class B(sound):
    126. high:int
    127. def __init__(self,high:int=4):
    128. super(B,self).__init__(high=high)
    129. ...
    130. def __str__(self) -> str: ...
    131. def plus(self) -> sound : ...
    132. def plus_(self,num:int) -> sound : ...
    133. def nplus(self) -> sound: ...
    134. class NULL(sound):
    135. def __str__(self) -> str: ...
    136. class time(object):
    137. real : int
    138. def __init__(self,time:int=4): ...
    139. class note(object):
    140. sound_ : sound
    141. time_ : time
    142. def __init__(self,sd:Union[sound,str,tuple],t:Union[time,int,float]): ...
    143. def soundSet(self,sd:Union[sound,str,tuple]) -> None: ...
    144. def timeSet(self,t:Union[time,int,float]) -> None: ...
    145. @property
    146. def out(self) -> tuple[str,int]: ...
    147. class wav:
    148. melody:sound
    149. sound:list
    150. staticTime:Union[int,float]
    151. def __init__(self,text:Union[str,None]=None,split:str=' ') : ...
    152. def __del__(self) : ...
    153. @property
    154. def getMelody(self) -> str: ...
    155. @property
    156. def getSound(self) -> list: ...
    157. @property
    158. def getTime(self) -> Union[int,float]:...
    159. def setTime(self,time:Union[int,float]) -> None: ...
    160. def setMelody(self,melody:sound) -> None: ...
    161. def loadOneNote(self,n:str) -> None: ...
    162. def load(self,text:str,split:str=' ') -> None: ...
    163. def make_wav(self,module:str="pysynth",bpm:Union[int,float]=120,transpose:int=0,pause:float=.05,
    164. boost:float=1.1,repeat:int=0,fn:str="out.wav", silent:bool=False) -> None: ...

    调用(1.py,同目录,父目录名称为MELODY。):

    第三行import语句根据情况自行更改。

    open里面的文件名自定。

    1. # coding=utf-8
    2. from MELODY.melody import *
    3. a=wav()
    4. text=open(r".\1.txt").read()
    5. text=text.split("-*-")
    6. a.setMelody(note(text[1].strip(),1).sound_)
    7. a.setTime(int(text[2].strip()))
    8. a.load(
    9. str(text[3]).strip()
    10. )
    11. res=text[0].strip().split("|")
    12. a.make_wav(module=res[0],bpm=eval(res[1]),repeat=eval(res[2]),fn=res[3])

    1.txt:

    格式为:

    1. 字符串,引用模块名|整数|整数|存储文件名
    2. -*-
    3. 调式,例如:1=C则填写c,1=降B则填写a#(即升a)
    4. -*-
    5. 节拍。例如,默认为每个音四分音符,即1
    6. -*-
    7. (乐谱部分)

    注意:上面的部分基本不用更改。接下来是我写的一个模板。

    1. pysynth|120|0|file.wav
    2. -*-
    3. c
    4. -*-
    5. 1
    6. -*-

    接下来要进行介绍。

    第一行,以"|"分割。

    "pysynth"表示使用默认音色。音色列表见下:

    PySynth_A

    这种加法单声道合成器非常简单,听起来有点像长笛或风琴,结合了钢琴般的音符音量衰减。PySynth A 只需要 Python 本身。它应该在所有 Python 支持的平台上运行,例如 Windows、Unix 和 Mac。

    PySynth_B

    一个加法合成器模块,它试图用更多的谐波创建更像钢琴的声音。这个版本是复调的,因为它不会在下一个音符响起时切断前一个音符。

    PySynth_C

    PySynth C 是一种基于减法合成的简单弓弦音色。它使用锯齿波振荡器和低通滤波器,类似于 1970 年代的模拟合成器(或amsynth中的弦乐声音,或来自MOS Technology SID的声音)。与 PySynth A 一样,它只需要 Python 本身即可运行。

    PySynth_D

    PySynth D 使用与 PySynth C 类似的减法合成,但它基于方波。这种合成器主音类型的声音让人联想到木管乐器。方波也用于 1970 年代/1980 年代的计算机声音芯片,例如General Instrument AY-3-8910Atari POKEY。只需要 Python 本身。

    PySynth_E

    该模块基于 PySynth B,基于相位调制创建简单的电子钢琴声音,这是进行 FM 合成的常用方法,例如在 1980 年代 Yamaha 合成器上。这种声音当然是受到Yamaha DX7上的 Rhodes 钢琴的启发。

    PySynth_P

    PySynth P 使用与 PySynth C 和 D 类似的减法合成,但基于具有指数体积包络的白噪声。它会产生未经调音的打击乐声音。这种类型的声音在 1980 年代通常用于打击乐和游戏音效。只需要 Python 本身。

    PySynth_S

    该模块使用Karplus-Strong 算法(想想吉他或大键琴)模拟单个弹拨。由于这种合成的性质,特别是较高频率的音符可能会与 PySynth S 稍微不协调,这与谐波精确的其他变体相反。这可以通过更高的采样率来解决,但这也会使其对 Python 来说有点慢。

    PySynth_beeper

    这个贡献的合成器属于nokiacomposer2wav.py并且应该重新创建老式诺基亚功能手机的铃声。

    PySynth_samp

    此合成器使用 48 kHz、24 位Salamander 钢琴样本。请在第 50 行设置 Salamander WAV 的路径(包括尾部斜杠)。

    第二个值120表示了一分钟内演奏多少个四分音符。

    第三个值是重复次数,默认为0,即不重复。

    第四个值是文件存储路径。

    第三行,一个值,表示调式。可选的有:

    c c# d d# e f f# g g# a a# b

    第五行,一个值,表示一个数字算作几个四分音符。如果没有特殊需要,填1就可以

    乐谱部分。

    简谱表示

    升音用#

    降音用&

    半音用_

    延音用-

    附点用.

    高八度用+

    降八度用!

    (全部用英文符)

    接下来会逐渐(断断续续)发布一些相关的音乐材料(txt文件,用刚才的1.py解释一下就可以导出为wav文件了)

    OK再~见~~~

  • 相关阅读:
    Python Web 框架:你需要知道的一切
    将本地jar包手动添加到Maven仓库依赖处理
    9.DesignForManufacture\CreateArtwork...
    React SSR - 写个 Demo 一学就会
    亿某通电子文档安全管理系统任意文件上传漏洞 CNVD-2022-43886
    C++11右值引用的价值体现
    输入输出、文件读写、数据类型
    PWN入门(2)栈溢出基础
    用Unity同时开发【微信小游戏】【安卓】【IOS】游戏#6.2 WebSocket通信
    设计模式的六大原则
  • 原文地址:https://blog.csdn.net/html_finder/article/details/126499254