録音したオーディオとディスクから読み取ったオーディオを一貫した方法で比較したいのですが、音量の正規化で問題が発生しています (そうしないと、スペクトログラムの振幅が異なります)。
また、これまで信号、FFT、または WAV 形式を扱ったことがないので、これは私にとって未知の領域です。両方から 44100 Hz でサンプリングされた符号付き 16 ビット整数のリストとしてチャンネルを取得します
- ディスク上の .wav ファイル
- 私のラップトップから再生される録音された音楽
次に、一定量のオーバーラップを持つウィンドウ (2^k) でそれぞれを処理します。ウィンドウごとに次のようにします。
# calculate window variables
window_step_size = int(self.window_size * (1.0 - self.window_overlap_ratio)) + 1
last_frame = nframes - window_step_size # nframes is total number of frames from audio source
num_windows, i = 0, 0 # calculate number of windows
while i <= last_frame:
num_windows += 1
i += window_step_size
# allocate memory and initialize counter
wi = 0 # index
nfft = 2 ** self.nextpowof2(self.window_size) # size of FFT in 2^k
fft2D = np.zeros((nfft/2 + 1, num_windows), dtype='c16') # 2d array for storing results
# for each window
count = 0
times = np.zeros((1, num_windows)) # num_windows was calculated
while wi <= last_frame:
# channel_samples is simply list of signed ints
window_samples = channel_samples[ wi : (wi + self.window_size)]
window_samples = np.hamming(len(window_samples)) * window_samples
# calculate and reformat [[[[ THIS IS WHERE I'M UNSURE ]]]]
fft = 2 * np.fft.rfft(window_samples, n=nfft) / nfft
fft[0] = 0 # apparently these are completely real and should not be used
fft[nfft/2] = 0
fft = np.sqrt(np.square(fft) / np.mean(fft)) # use RMS of data
fft2D[:, count] = 10 * np.log10(np.absolute(fft))
# sec / frame * frames = secs
# get midpt
times[0, count] = self.dt * wi
wi += window_step_size
count += 1
# remove NaNs, infs
whereAreNaNs = np.isnan(fft2D);
fft2D[whereAreNaNs] = 0;
whereAreInfs = np.isinf(fft2D);
fft2D[whereAreInfs] = 0;
# find the spectorgram peaks
fft2D = fft2D.astype(np.float32)
# the get_2D_peaks() method discretizes the fft2D periodogram array and then
# finds peaks and filters out those peaks below the threshold supplied
#
# the `amp_xxxx` variables are used for discretizing amplitude and the
# times array above is used to discretize the time into buckets
local_maxima = self.get_2D_peaks(fft2D, self.amp_threshold, self.amp_max, self.amp_min, self.amp_step_size, times, self.dt)
特に、私のコメント [[[[ THIS IS WHERE I'M UNSURE ]]]] の行で (少なくとも私にとっては) クレイジーなことが起こります。
誰かが私を正しい方向に向けたり、音量を正しく正規化しながらこのオーディオスペクトログラムを生成するのを手伝ってくれたりできますか?