hjc757 发表于 2020-10-4 17:13

来用python写一首歌

都是自带库,纯代码写一首小曲装逼无限
应该是c调,音阶频率来自网上,代码也来自网上,音阶频率和简谱有所调整,原代码输出后有一些小问题
代码中含经典世界名曲,听一听你就知道了
import wave
import math
import struct
ff=wave.open("v1.wav","w")
ff.setframerate(9000)
ff.setnchannels(1)
ff.setsampwidth(2)


def wv(t=0,f=0,v=0.5,wf=ff,sr=8000):
    '''
    t:写入时长
    f:声音频率
    v:音量
    wf:一个可以写入的音频文件
    sr:采样率
    '''
    tt=0
    dt=1.0/sr
    while tt<=t:
      s=math.sin(tt*math.pi*2*f)*v*32768 #采样,调节音量,映射到[-2^15,2^15)
      s=int(s)
      fd=struct.pack("h",s) #转换成8bit二进制数据
      wf.writeframes(fd) #写入音频文件
      tt+=dt #时间流逝

note={"1":440,"2":493.88,"3":554.37,"4":587.33,"5":659.33,"6":739.99,"7":830.61,"6-":329.63,"0":0}
n=[
    "1","2","3","1","1","2","3","1",
    "3","4","5","0","3","4","5","0",
    "5","6","5","4","3","1","5","6","5","4","3","1",
    "2","6-","1","0","2","6-","1","0"
]
tm=[
    1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,
    0.5,0.5,0.5,0.5,1,1,0.5,0.5,0.5,0.5,1,1,
    1,1,1,1,1,1,1,1,
]

for i in range(len(n)):
    wv(tm/2.0,note])

ff.close()

CuteHamster 发表于 2020-10-4 23:49

import wave
import math
import struct
ff=wave.open("v1.wav","w")
ff.setframerate(8000)
ff.setnchannels(1)
ff.setsampwidth(2)


def wv(t=0,f=0,v=0.5,wf=ff,sr=8000):
    '''
    t:写入时长
    f:声音频率
    v:音量
    wf:一个可以写入的音频文件
    sr:采样率
    '''
    tt=0
    dt=1.0/sr
    while tt<=t:
      s=math.cos(tt*math.pi*2*f)*v*32768 #采样,调节音量,映射到[-2^15,2^15)
      s=int(s)
      fd=struct.pack("h",s) #转换成8bit二进制数据
      wf.writeframes(fd) #写入音频文件
      tt+=dt #时间流逝

note={"1-":220,"2-":246.94,"3-":227.19,"4-":293.67,"5-":329.67,"6-":329.63,"7-":415.31,
      "1":440,"2":493.88,"3":554.37,"4":587.33,"5":659.33,"6":739.99,"7":830.61,
      "1+":880,"2+":987.76,"3+":1108.74,"4+":1174.66,"5+":1318.66,"6+":1479.98,"7+":1661.22,"0":0
}
n=[
      "6","0","6","0","6","0","6","3","6","7","1+","0","1+","0","1+","0",
      "1+","2+","5","4","3","0","2","0",
      "6","0","6","0","6","0","6","3","6","7","1+","0","1+","0","1+","0",
      "1+","2+","5","0","3","0","4","0","5","0","6","0","7","0",
      "1+","0","1+","0","1+","0","1+","6","1+","3+","0","4+","0","4+","0","4+","0",
      "4+","1+","3+","0","5","7","0","1+","0","2+","0","1+","0","7","0",
      "1+","0","1+","0","1+","0","1+","6","1+","3+","0","4+","0","4+","0","4+","0",
      "5+","0","4+","0","3+","1+","0","5","1+","3+","2+","0","2+","0","2+","0","3+","0","3+","0",
]

interal={
      0:0.02,1:0.1875,2:0.375,3:0.5625,4:0.75,5:0.9375,6:1.125
}
#   1拍--0.1875   2拍--0.375    3拍--0.5625   4拍--0.75
tm=[
      3,0,1,0,5,0,1,1,1,1,3,0,1,0,5,0,
      2,2,5,4,4,0,6,4,
      3,0,1,0,5,0,1,1,1,1,3,0,1,0,5,0,
      2,2,5,2,2,0,2,0,2,0,5,0,5,0,
      3,0,1,0,5,0,1,1,1,1,0,3,0,1,0,5,0,
      2,2,5,2,2,2,0,2,0,5,0,4,0,4,0,
      3,0,1,0,5,0,1,1,1,1,0,3,0,1,0,5,0,
      2,0,2,0,4,4,2,2,2,2,5,0,1,0,1,0,2,0,5,0,
]
for i in range(len(n)):
    wv(interal],note])

ff.close()
学习之后用楼主的代码扒了另一个曲子,感谢楼主分享:lol

三滑稽甲苯 发表于 2020-10-10 22:42

本帖最后由 三滑稽甲苯 于 2020-10-10 22:45 编辑

改编了一下,使代码更规范并增添了新功能。
使用方法:在同目录下新建data.txt, 按 <音阶>*<节拍> <音阶>*<节拍> <音阶>*<节拍> 的方式输入数据,运行得到music.wav。如无文件,则输出内置的一首歌。

import wave
import math
import struct
from os.path import exists
music = wave.open("music.wav","w")
music.setframerate(8000)
music.setnchannels(1)
music.setsampwidth(2)

# 音阶对应的频率
note = {"1-":220,"2-":246.94,"3-":227.19,"4-":293.67,"5-":329.67,"6-":329.63,"7-":415.31,
      "1":440,"2":493.88,"3":554.37,"4":587.33,"5":659.33,"6":739.99,"7":830.61,
      "1+":880,"2+":987.76,"3+":1108.74,"4+":1174.66,"5+":1318.66,"6+":1479.98,"7+":1661.22,"0":0
}

# 节拍对应的时长
# #   1拍--0.1875   2拍--0.375    3拍--0.5625   4拍--0.75
interal = {
      0:0.02,1:0.1875,2:0.375,3:0.5625,4:0.75,5:0.9375,6:1.125
}

# 自定义写入音乐的函数
def wv(t=0,f=0,v=0.5,wf=music,sr=8000):
    '''
    t:写入时长
    f:声音频率
    v:音量
    wf:一个可以写入的音频文件
    sr:采样率
    '''
    tt = 0
    dt = 1.0/sr
    while tt <= t:
      s = math.cos(tt*math.pi*2*f)*v*32768 #采样,调节音量,映射到[-2^15,2^15)
      s = int(s)
      fd = struct.pack("h",s) #转换成8bit二进制数据
      wf.writeframes(fd) #写入音频文件
      tt += dt #时间流逝
if exists('data.txt'):
    with open('data.txt') as f: s = f.read()
    l = s.split()
    scales = []; beats = []
    for data in l:
      tmp = data.split('*')
      scale = tmp
      beat = int(tmp)
      scales.append(scale)
      beats.append(beat)
else:
    # 简谱, 对应原来的n
    scales = [
            "6","0","6","0","6","0","6","3","6","7","1+","0","1+","0","1+","0",
            "1+","2+","5","4","3","0","2","0",
            "6","0","6","0","6","0","6","3","6","7","1+","0","1+","0","1+","0",
            "1+","2+","5","0","3","0","4","0","5","0","6","0","7","0",
            "1+","0","1+","0","1+","0","1+","6","1+","3+","0","4+","0","4+","0","4+","0",
            "4+","1+","3+","0","5","7","0","1+","0","2+","0","1+","0","7","0",
            "1+","0","1+","0","1+","0","1+","6","1+","3+","0","4+","0","4+","0","4+","0",
            "5+","0","4+","0","3+","1+","0","5","1+","3+","2+","0","2+","0","2+","0","3+","0","3+","0",
    ]

    # 与n数据相对应的节拍, 对应原来的tm
    beats = [
            3,0,1,0,5,0,1,1,1,1,3,0,1,0,5,0,
            2,2,5,4,4,0,6,4,
            3,0,1,0,5,0,1,1,1,1,3,0,1,0,5,0,
            2,2,5,2,2,0,2,0,2,0,5,0,5,0,
            3,0,1,0,5,0,1,1,1,1,0,3,0,1,0,5,0,
            2,2,5,2,2,2,0,2,0,5,0,4,0,4,0,
            3,0,1,0,5,0,1,1,1,1,0,3,0,1,0,5,0,
            2,0,2,0,4,4,2,2,2,2,5,0,1,0,1,0,2,0,5,0,
    ]

for i in range(len(scales)):
    wv(interal],note])
music.close()

呼啊哟 发表于 2020-10-4 17:29

太厉害了吧,可以的

xiaosuobjsd 发表于 2020-10-4 17:50

牛逼,学习到了

liangqz 发表于 2020-10-4 18:10

哈哈哈,可以可以

kk1212 发表于 2020-10-4 18:15

python 无所不能啊

a_xing 发表于 2020-10-4 18:19

大佬太优秀了,

error_bug 发表于 2020-10-4 18:28

带耳机听差点没给我送走了2333333

世俗难断 发表于 2020-10-4 18:54

大佬太强了

miqi1314 发表于 2020-10-4 19:01

优秀,听一听

nstar1221 发表于 2020-10-4 19:08

两只老虎,这个挺好玩
页: [1] 2 3 4
查看完整版本: 来用python写一首歌