我试图测量和计算音频设备的频率响应,只需生成输入信号,然后用扫频测量输出.
以下是我试图在伪代码中实现的:
for each frequency f in (10-20k):
generate reference signal s with frequency f
async play s and record result r
determine amplitude a of r using FFT
add tuple (f,a) to result
在Python中:
import numpy as np
from matplotlib import pyplot as plt
import sounddevice as sd
import wave
from math import log10, ceil
from scipy.fft import fft, rfft, rfftfreq, fftfreq
SAMPLE_RATE = 44100 # Hertz
DURATION = 3 # Seconds
def generate_sine_wave(freq, sample_rate, duration):
x = np.linspace(0, duration, int(sample_rate * duration), endpoint=False)
frequencies = x * freq
y = np.sin((2 * np.pi) * frequencies)
return x, y
def main():
# info about our device
print(sd.query_devices(device="Studio 24c"))
# default device settings
sd.default.device = 'Studio 24c'
sd.default.samplerate = SAMPLE_RATE
f_start = 10
f_end = 20000
samples_per_decade = 10
ndecades = ceil(log10(f_end) - log10(f_start))
npoints = ndecades * samples_per_decade
freqs = np.logspace(log10(f_start), log10(f_end), num=npoints, endpoint=True, base=10)
measure_duration = 0.25 # seconds
peaks = []
for f in freqs:
_, y = generate_sine_wave(f, SAMPLE_RATE, measure_duration)
rec = sd.playrec(y, SAMPLE_RATE, input_mapping=[2], output_mapping=[2])
sd.wait()
yf = np.fft.rfft(rec, axis=0)
yf_abs = 1 / rec.size * np.abs(yf)
xf = np.fft.rfftfreq(rec.size, d=1./SAMPLE_RATE)
peaks.append(np.max(yf_abs))
plt.xscale("log")
plt.scatter(freqs,peaks)
plt.grid()
plt.show()
if __name__ == "__main__":
main()
在测量实际设备之前,我简单地将输出信号循环到音频接口的输入端,以基本上"校准"我正在做的事情.我以为振幅在所有频率上都是相等的.然而,这就是我得到的:
为什么所有的振幅都是到处都是,即使产生的正弦波是相同的?在扫描测量阶段,我没有改变音频接口上的任何东西.