问题描述
我有一个带有频率值的数组,并且想要生成带有在给定值之间扫描的音调的 wav 文件。说
freqs = [100,100,200,400,1000,50]
duration = 7
我想要持续时间为 7 秒的 WAV。所以从 T=0 到 T=1s 音调应该是 100Hz,从 T=1 到 T=2 扫描从 100Hz 到 200Hz,依此类推。
如何生成传递给 scipy.io.wavfile.write 的波形?
解决方法
以下是对两个任意频率执行此操作的方法:
import numpy as np
from scipy.signal import chirp
from scipy.io.wavfile import write
interval_length = 1 # in seconds
fs = 16000 # sampling of your signal
f0 = 100 # frequency 1
f1 = 200 # frequency 2
t = np.linspace(0,interval_length,int(fs * interval_length))
w = chirp(t,f0=f0,f1=f0,t1=interval_length,method='linear') # check also other methods
write('test.wav',fs,w)
作为练习,您可以针对您拥有的一组频率在循环中执行此操作。
,作为 Lukasz Tracewski said 这可以通过 np.chirp() 来完成:
import numpy as np
from scipy.signal import chirp
from scipy.io.wavfile import write
duration = 30
Fs = 16000
freqs = [100,100,300,600,100]
segment = int(Fs * duration / (len(freqs)-1))
f = np.array(freqs) / Fs
wav = np.array(1)
for f0,f1 in zip(f[:-1],f[1:]):
wav = np.append(wav,chirp(np.arange(segment),t1=segment,f1=f1))
write('test.wav',Fs,wav)
这给出了很好的频谱图: 听这里:https://soundcloud.com/dcoder_mm/npchip/s-Kx8L2vN0nfv
它有效,但您会注意到(在光谱上和聆听时)一些咔哒声。
让我们尝试使用较低的频率:
freqs = [100,100]
听这里:https://soundcloud.com/dcoder_mm/dj-npchirp-feat-low-frequencies/s-fNsA61bJ0Wk
事情变得更糟了。为什么?
为了摆脱这种情况,我们需要计算相位校正。根据最后一点的 wiki 相位(对于线性啁啾!)将是:
phi = T*(f1+f0)/2
这样就可以了:
import numpy as np
from scipy.signal import chirp
from scipy.io.wavfile import write
duration = 30
Fs = 16000
freqs = [100,100.5,99,99.3,100.1,100]
segment = int(Fs * duration / (len(freqs)-1))
f = np.array(freqs) / Fs
wav = np.array(1)
phase = 0
for f0,f1=f1,phi=phase))
phase = phase + 360*(segment*(f0+f1)/2)
write('test3.wav',wav)
听:https://soundcloud.com/dcoder_mm/dj-npchirp-feat-low-frequencies-phase-c/s-XneSWRlojLD
注意 phi = T*(f1+f0)/2 仅适用于线性啁啾。对于其他方法,您需要不同的相位公式。另见this question