生成正弦波
import numpy as np
import random
import IPython.display as ipd
import matplotlib.pyplot as plt
import math
%matplotlib inline
def create_sinusoid(amp, freq, duration, sample_rate):
t = np.arange(0, duration, 1.0 / sample_rate)
return amp * np.sin(2 * np.pi * freq * t)
# complete the function seven_harmonics according
# to the specification above
def seven_harmonics(amp, freq, duration, sample_rate):
if sample_rate<10*freq:
return
signal=[]
for i in range(7):
d=duration
f=(i+1)*freq
hnum=np.random.randint(0,7)
a=amp / (1+hnum)
sig=list(create_sinusoid(a, f, duration, sample_rate))
signal+=sig
return np.array(signal)
# use the code in this cell to plot/listen to the resulting
# signal of the seven_harmonics function
f0 = 220
sr = 8000
amp = 0.8257463
duration = 1
signal = seven_harmonics(amp, f0, duration, sr)
assert(np.isclose(np.max(signal), 0.8257463))
plt.plot(np.abs(signal))
ipd.Audio(signal, rate=sr)
三角波信号
可以用奇数次谐波累加合成三角波、矩形波等等,其思想也比较简单
def midi_to_freq(pitch):
return 440*(2**((pitch-69)/12.0))
def generate_triangle(pitch, nharmonics, dur=1.0, amp=1.0, sr=44100):
freq=midi_to_freq(nharmonics)
t = np.arange(0, dur, 1.0 / sr)
triangle_signal= np.zeros_like(t)
for i in range(nharmonics):
n=2*i+1
A1=(-1)**i
A2=n**(-2)
si=np.array((8/(math.pi **2)*A1*A2*amp * np.sin(2 * np.pi * freq *n* t)))
triangle_signal += si
return list(triangle_signal)
# code to check how your function works
signal = generate_triangle(48, 25)
ipd.Audio(signal, rate=44100)
x1 = generate_triangle(48, 1, 0.02)
x2 = generate_triangle(48, 2, 0.02)
x3 = generate_triangle(48, 3, 0.02)
x4 = generate_triangle(48,40, 0.02)
#x4 = generate_triangle(48,40, 0.02)
fig, axs = plt.subplots(2,2, dpi=150)
axs[0,0].plot(x1)
axs[0,0].set_title('1 Sinusoid')
axs[0,1].plot(x2)
axs[0,1].set_title('2 Sinusoids')
axs[1,0].plot(x3)
axs[1,0].set_title('3 Sinusoids')
axs[1,1].plot(x4)
axs[1,1].set_title('4 Sinusoids')
fig.tight_layout()