简体   繁体   English

来自音频文件的 1/3 个八度音阶,使用 python

[英]1/3 octave from audio file with python

I am a beginner in signal processing and I would like to apply third-octave band pass filters on mp3 or wav file (yields about 30 new filtered time series) center frequencies: 39 Hz, 50 Hz, 63 Hz, 79 Hz, 99 Hz, 125 Hz, 157 Hz, 198 Hz, 250 Hz, 315 Hz, 397 Hz, 500 Hz, …我是信号处理的初学者,我想在 mp3 或 wav 文件上应用三倍频程带通滤波器(产生大约 30 个新的滤波时间序列)中心频率:39 Hz、50 Hz、63 Hz、79 Hz、99 Hz , 125 Hz, 157 Hz, 198 Hz, 250 Hz, 315 Hz, 397 Hz, 500 Hz, ...

First way...第一种方式...

After I read mp3 file, I got a stereo signal.在我阅读了 mp3 文件后,我得到了一个立体声信号。 Then I segmented 1 audio file into 4096 samples.然后我将 1 个音频文件分割成 4096 个样本。 Then I separate it to left and right channel.然后我把它分开到左右声道。 Now I have arrays of data for each channel.现在我有每个通道的数据数组。 Next, I apply Fast Fourier Transform to a sample file.接下来,我将快速傅立叶变换应用于示例文件。 The problem is I need to apply third-octave band pass filters to these samples.问题是我需要对这些样本应用三倍频程带通滤波器。 I need suggestion on how should I do since I quite not understand acoustics library.我需要关于我该怎么做的建议,因为我不太了解声学库。

Another way ...其它的办法 ...

I found some website related to my expectation but he uses octave bandpass filter.我找到了一些与我的期望相关的网站,但他使用了倍频程带通滤波器。 I use the code from Michael's reply on https://www.dsprelated.com/thread/7036/octave-bandpass-filter-on-audio-wav-files So I would like to apply this code to third-octave.我使用迈克尔在https://www.dsprelated.com/thread/7036/octave-bandpass-filter-on-audio-wav-files上的回复中的代码所以我想将此代码应用于第三个八度。

from scipy import signal
import numpy as np
import matplotlib.pyplot as plt
import math

sampleRate = 44100.0
nyquistRate = sampleRate/2.0

#center = [39, 50, 63, 79, 99, 125, 157, 198, 250, 315, 397, 500, 630, 
794, 1000, 1260, 1588, 2000, 2520, 3176, 4000, 5040, 6352, 8000, 10080, 
12704, 16000, 20160, 2508, 32000]
centerFrequency_Hz = 480.0;
lowerCutoffFrequency_Hz=centerFrequency_Hz/math.sqrt(2);
upperCutoffFrequenc_Hz=centerFrequency_Hz*math.sqrt(2);

# Determine numerator (b) and denominator (a) coefficients of the digital 
# Infinite Impulse Response (IIR) filter.
b, a = signal.butter( N=4, Wn=np.array([ lowerCutoffFrequency_Hz, 
upperCutoffFrequenc_Hz])/nyquistRate, btype='bandpass', analog=False, 
output='ba');

# Compute frequency response of the filter.
w, h = signal.freqz(b, a)

fig = plt.figure()
plt.title('Digital filter frequency response')
ax1 = fig.add_subplot(111)

plt.plot(w, 20 * np.log10(abs(h)), 'b')
plt.ylabel('Amplitude [dB]', color='b')
plt.xlabel('Frequency [rad/sample]')

ax2 = ax1.twinx()
angles = np.unwrap(np.angle(h))
plt.plot(w, angles, 'g')
plt.ylabel('Angle (radians)', color='g')
plt.grid()
plt.axis('tight')
plt.show()

fs, speech = wavfile.read(filename='segmented/atb30.wav');
speech = speech[:, 0]
fig=plt.figure()
plt.title('Speech Signal')
plt.plot(speech)

filteredSpeech=signal.filtfilt(b, a, speech)
fig=plt.figure()
plt.title('480 Hz Octave-band Filtered Speech')
plt.plot(filteredSpeech)

According to equations (5) and (6) fromANSI S1.11: Specification for Octave, Half-Octave, and Third Octave Band Filter Sets , for 1/3-octave the lower and upper frequencies of each band are given by:根据ANSI S1.11: Specification for Octave, Half-Octave, and Third Octave Band Filter Sets 中的公式 (5) 和 (6),对于 1/3 倍频程,每个频段的下限和上限频率由下式给出:

factor = np.power(G, 1.0/6.0)
lowerCutoffFrequency_Hz=centerFrequency_Hz/factor;
upperCutoffFrequency_Hz=centerFrequency_Hz*factor;

Where G is either 2 (when designing filters according to the specified base-2 rules), or np.power(10, 0.3) (when designing filters according to the specified base-10 rules).其中G是 2(根据指定的 base-2 规则设计过滤器时)或np.power(10, 0.3) (根据指定的 base-10 规则设计过滤器时)。 In your case the center frequencies you have provided are close to the values obtained using base-2 rules, so you should also G = 2 to be consistent.在您的情况下,您提供的中心频率接近使用 base-2 规则获得的值,因此您也应该G = 2以保持一致。

Note that for your given center frequency array, a few values of the upper frequencies will be greater than the Nyquist frequency (half your sampling rate).请注意,对于给定的中心频率阵列,一些上限频率值将大于奈奎斯特频率(采样率的一半)。 Those would correspondingly yield invalid upper normalized frequency inputs when trying to design the filter with scipy.signal.butter .当尝试使用scipy.signal.butter设计滤波器时,这些将相应地产生无效的上限归一化频率输入。 To avoid that you should limit your center frequency array to values less than ~19644Hz:为避免这种情况,您应该将中心频率数组限制为小于 ~19644Hz 的值:

centerFrequency_Hz = np.array([39, 50, 63, 79, 99, 125, 157, 198, 250, 315, 
397, 500, 630, 794, 1000, 1260, 1588, 2000, 2520, 3176, 4000, 5040, 6352, 8000, 10080, 
12704, 16000])

Also, scipy.signal.butter can handle one set of lower and upper frequencies at a time, so you should loop over the lower and upper frequency arrays to design each bandpass filter:此外, scipy.signal.butter可以一次处理一组低频和高频,因此您应该遍历低频和高频数组以设计每个带通滤波器:

for lower,upper in zip(lowerCutoffFrequency_Hz, upperCutoffFrequency_Hz):
    # Determine numerator (b) and denominator (a) coefficients of the digital 
    # Infinite Impulse Response (IIR) filter.
    b, a = signal.butter( N=4, Wn=np.array([ lower, 
    upper])/nyquistRate, btype='bandpass', analog=False, 
    output='ba');

    # Compute frequency response of the filter.
    w, h = signal.freqz(b, a)

    plt.plot(w, 20 * np.log10(abs(h)), 'b')

    # Filter signal
    filteredSpeech = signal.filtfilt(b, a, speech)

This should give you a plot similar to the following for the magnitude responses:这应该为您提供类似于以下幅值响应的图:

在此处输入图片说明

You may at this point notice some signs of instability in the lowest band.此时您可能会注意到最低频段的一些不稳定迹象。 To avoid this problem, you could switch to the sos representation:为了避免这个问题,你可以切换到sos表示:

for lower,upper in zip(lowerCutoffFrequency_Hz, upperCutoffFrequency_Hz):
    # Design filter
    sos = signal.butter( N=4, Wn=np.array([ lower, 
    upper])/nyquistRate, btype='bandpass', analog=False, 
    output='sos');

    # Compute frequency response of the filter.
    w, h = signal.sosfreqz(sos)

    plt.plot(w, 20 * np.log10(abs(h)), 'b')

    # Filter signal
    filteredSpeech = signal.sosfiltfilt(sos, speech)

I recently developed a function to easily perform octave and fractional octave filtering, it is available on github: PyOctaveBand我最近开发了一个函数来轻松执行八度和分数八度过滤,它可以在 github 上找到: PyOctaveBand

It uses the SOS coefficients and performs downsampling to filter correctly at low frequencies.它使用 SOS 系数并执行下采样以在低频下正确滤波。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM