我想分析我的音乐收藏,这是所有CD音频数据(立体声16位PCM,44.1kHz)。我想要做的是以编程方式确定低音是否仅混合(平移)到一个通道。理想情况下,我希望能够运行这样的程序
mono-bass-checker music.wav
并输出类似“低音未平移”或“低音主要与通道0混合”的内容。
我对此有一个初步的开头,伪代码看起来像这样:
binsize = 2^N # define a window or FFT bin as a power of 2
while not end of audio file:
read binsize samples from audio file
de-interleave channels into two separate arrays
chan0_fft_result = fft on channel 0 array
chan1_fft_result = fft on channel 1 array
for each index i in (number of items in chanX_fft_result/2):
freqency_bin = i * 44100 / binsize
# define bass as below 150 Hz (and above 30 Hz, since I can't hear it)
if frequency_bin > 150 or frequency_bin < 30 ignore
magnitude = sqrt(chanX_fft_result[i].real^2 + chanX_fft_result[i].complex^2)
我不确定从哪里开始。我读过的一些概念但对我来说仍然过于模糊:
我可以像这样使用sox生成“单声道低音歌曲”:
sox -t null /dev/null --encoding signed-integer --bits 16 --rate 44100 --channels 1 sine40hz_mono.wav synth 5.0 sine 40.0
sox -t null /dev/null --encoding signed-integer --bits 16 --rate 44100 --channels 1 sine329hz_mono.wav synth 5.0 sine 329.6
sox -M sine40hz_mono.wav sine329hz_mono.wav sine_merged.wav
在生成的“sine_merged.wav”文件中,一个通道是纯低音(40Hz),一个是非低音(329Hz)。当我计算该文件的每个通道的低音频率的大小时,我确实看到了显着的差异。但令人好奇的是329Hz通道具有非零亚150Hz的幅度。我希望它是零。
即便如此,使用这个简单的sox生成的文件,我真的不知道如何解释我正在生成的数据。显然,我不知道如何概括我的实际音乐收藏。
FWIW,我试图用C中的libsndfile和fftw3来做这个,基于这些其他帖子的帮助:
答案 0 :(得分:0)
不使用窗口函数(与使用矩形窗口相同)会将一些高频内容(FFT长度中不完全周期性的内容)溅入FFT结果的所有其他频率区间,包括低频区间。 (有时这被称为光谱“泄漏”。)
为了最大限度地减少这种情况,请尝试在FFT之前应用窗函数(von Hann等),并期望必须使用某个阈值级别,而不是期望任何区间中的零内容。
另请注意,来自许多乐器的低音音符可以产生一些非常强大的高频泛音或谐波,这些泛音或谐波将出现在FFT的上部音箱中,因此您不能排除强大的低音混音。很多高频内容。