Python生成声音波形、模拟钢琴音色

import numpy as np
import wave
from numpy import pi
import math
import pyaudio


p=pyaudio.PyAudio()

sample_rate = 22050  #采样率
sample_width = 2 #位深
time = 1
arr = 0
#波形生成
def wave_bulid(f0,amplitude_xishu = 0.5,time=time):


    w_oumiga = 2*pi*f0
    w_oumiga1 = 2*pi*100
      #波形时间
    x = np.linspace(0,time,sample_rate*time)
    amplitude = math.pow(2, 8 * sample_width - 1) * amplitude_xishu  # 振幅
    y = amplitude*np.sin(w_oumiga*x)
    # y = amplitude*(np.sin(w_oumiga*x-pi)+np.sin(w_oumiga1*x-pi))
    return x,y,f0
    # [130.81, 138.59, 146.83, 155.56, 164.81, 174.61, 184.99, 195.99, 207.65, 220, 233.08, 246.94,
    #  261.62, 277.18, 293.67, 311.13, 329.63, 349.23, 369.99, 391.99, 415.31, 440, 466.16, 493.88,
    #  523.25, 554.36, 587.33, 622.25, 659.26, 698.46, 739.99, 783.99, 830.61, 880, 932.32, 987.76] # C3-B5,钢琴基频
for f0 in [261.62, 293.67,  329.63, 349.23,  391.99,  440,  493.88]:#C4-B4,钢琴基频
    #钢琴音频域多次谐波与基频比例关系
    Amp=[1,0.340,0.102,0.085,0.070,0.065,0.028,0.085,0.011,0.030,0.010,0.014,0.012,0.013,0.004,0.004,0.004,0.004,0.004,0.004]
    # m = int(5000/f0)
    n=len(Amp)#谐波个数
    # print(n)
    y = 0
    for i in range(0,n):
        xishu = 1 / 2* Amp[i]
        # if f0*i >5000:
        #     print(i)
        #     break
        x,tempy,fn = wave_bulid(f0*(i+1),xishu)
        y +=tempy
    #幅值变化模型
    a = sample_rate*time
    attenuation=[0 for x in range(0, a)]
    for i in range(0, int(2 / 80 * a)):
        attenuation[i] = 0.2 + i * 0.8 / int(2 / 80 * a)
    for i in range(int(2 / 80 * a), int(8 / 80 * a)):
        attenuation[i] = 1 - (i - 2 / 80 * a) * 0.6 / (int(8 / 80 * a) - int(2 / 80 * a))
    for i in range(int(8 / 80 * a), int(4 / 8 * a)):
        attenuation[i] = 0.4 - (i - int(8 / 80 * a)) * 0.2 / (int(4 / 8 * a) - int(8 / 80 * a))
    for i in range(int(4 / 8 * a), int(8 / 8 * a)):
        # attenuation[i] = 0.2
        attenuation[i] = 0.2 - (i - int(4 / 8 * a)) * 0.1 / (int(8 / 8 * a) - int(4 / 8 * a))

    # print(x,y)
    y *= attenuation
    arr = np.append(arr,y)
    zero = np.zeros(5500)#延迟
    arr = np.append(arr, zero)
# print(len(y),len(attenuation))
y_data = arr.astype(np.int16).tobytes()#转字节

wf = wave.open(r"D:\pythonProject2\wav\piano1.wav", 'wb')#保存文件地址
wf.setnchannels(1)  # 声道设置
wf.setsampwidth(2)  # 采样位数设置
wf.setframerate(sample_rate)
wf.writeframes(y_data)
print("Piano生成成功,开始播放C4-B4")
stream = p.open(format=pyaudio.paInt16,
                channels=1,
                rate=sample_rate,
                output=True,
                frames_per_buffer=1024)

stream.write(y_data)
# plt.plot(x,y)
# plt.show()

 

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值