立体声音频文件的程序化混音分析 - 低音平移到一个声道?

时间:2014-02-13 17:48:59

标签: audio signal-processing fft

我想分析我的音乐收藏,这是所有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)

我不确定从哪里开始。我读过的一些概念但对我来说仍然过于模糊:

  • 窗口功能。我目前没有使用它,只是天真地读取音频文件0到1024,1025到2048等(例如binsize = 1024)。这件事对我有用吗?如果是这样,它如何融入该计划?
  • 规模化和/或缩放幅度。很多人这样做是为了制作漂亮的光谱图,但在我的情况下我是否需要这样做?我理解人类听觉大致在对数范围内工作,所以我可能需要以某种方式按摩量级结果来过滤掉我无法听到的内容? A-weighting在这里是否相关?
  • binsize。我知道一个更大的binsize让我有更多的频率箱...但在这种情况下我无法确定这是否有帮助或伤害。

我可以像这样使用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来做这个,基于这些其他帖子的帮助:

1 个答案:

答案 0 :(得分:0)

不使用窗口函数(与使用矩形窗口相同)会将一些高频内容(FFT长度中不完全周期性的内容)溅入FFT结果的所有其他频率区间,包括低频区间。 (有时这被称为光谱“泄漏”。)

为了最大限度地减少这种情况,请尝试在FFT之前应用窗函数(von Hann等),并期望必须使用某个阈值级别,而不是期望任何区间中的零内容。

另请注意,来自许多乐器的低音音符可以产生一些非常强大的高频泛音或谐波,这些泛音或谐波将出现在FFT的上部音箱中,因此您不能排除强大的低音混音。很多高频内容。