音频特征学习记录

音频特征提取介绍:

音频通常是把一个实际信号看作是根据时间变化的电压值。 这是从时域的角度来观察信号。 而傅立叶定律指出,任意波形在时域中都可以由若干个正弦波和余弦波的加权和来表示。 例如,有两个正弦波,其中一个的频率是另一个的3倍。 将两个正弦波相加,就得到了一个不同的信号。

较常见的音频读取方式为librosa.core.load()

一众博客上都点明该方法是通过采样率对音频进行采样,默认采样率为22050,对于采样率较高的音频会被下采样,而采样率低于该值的将会上采样,所以要保留原有采样频率则sr=None实现。

参数信息:

  • path:音频文件路径
  • sr:采样率,值为None时保留原本采样率
  • mono: bool,是否将信号转为单声道
  • offset: float,在该值对应时间后开始阅读(秒为计量单位)
  • duration: float,持续时间,仅计算该长度的音频(秒为计量单位)

返回值:

  • y:音频时间序列
  • sr:音频的采样率

从音频文件中读取出来的原始语音信号是一个一维数组,长度是由音频长度和采样率决定,值的大小通常表示的是振幅。

通过傅立叶定理(将每个信号分解成正弦波和余弦波,使之相加与原始信号相等)可以将信号分解为单个频率和频率幅度(简言之,将时域转换至频域)。

频域信号显示了不同频率对应的电压。 频域可以看成是另一种观察信号的角度。上述函数将音频采样转换为离散的值。 因为发生了转换,傅立叶转换在这些数据上无法进行。 可使用离散傅立叶变换(DFT),其结果是离散形式的频域信号。 FFT是DFT的一种优化实现,计算量较少,但是本质上是对信号的分解。

STFT短时傅里叶变换是另一种对音频特征的提取方式,实际上是对一系列加窗数据做FFT。对原始信号进行分帧加窗后,可以得到很多帧,对每一帧做FFT(快速傅里叶变换),傅里叶变换的作用是把时域信号转为频域信号,把每一帧FFT后的频域信号(频谱图)在时间上堆叠起来就可以得到声谱图。

离散傅里叶变换(Discrete Fourier Transform)

离散傅里叶变换(Discrete Fourier Transform)是对一个向量进行变换,可将该向量看做一个n-1次多项式,并在每个单位根处求值,得出向量y(离散傅里叶变换后的结果,记为 D F T n ( a ) DFT_{n}(a) DFTn(a)
A ( x ) = ∑ i = 0 n − 1 a i x i  在  ω n 0 , ω n 1 , ⋯   , ω n n − 1  处的值  y 0 , y 1 , ⋯   , y n − 1 A(x)=\sum_{i=0}^{n-1} a_{i} x^{i} \text { 在 } \omega_{n}^{0}, \omega_{n}^{1}, \cdots, \omega_{n}^{n-1} \text { 处的值 } y_{0}, y_{1}, \cdots, y_{n-1} A(x)=i=0n1aixi  ωn0,ωn1,,ωnn1 处的值 y0,y1,,yn1
在每个单位根处求值,得到向量y。
y i = A ( ω n i ) = ∑ j = 0 n − 1 ω n i j a j y_{i}=A\left(\omega_{n}^{i}\right)=\sum_{j=0}^{n-1} \omega_{n}^{i j} a_{j} yi=A(ωni)=j=0n1ωnijaj

y = DFT ⁡ n ( a ) y=\operatorname{DFT}_{n}(a) y=DFTn(a)

快速傅里叶变换(Fast Fourier Transform)

快速傅里叶变换(Fast Fourier Transform),对此n-1次多项式,其系数向量为a

A ( x ) → a = [ a 0 , a 1 , a 2 , ⋯   , a n − 1 ] ⊤ A(x) \rightarrow a=\left[a_{0}, a_{1}, a_{2}, \cdots, a_{n-1}\right]^{\top} A(x)a=[a0,a1,a2,,an1]

将其分为偶数项和奇数项两个向量,对应为 a [ 0 ] a^{[0]} a[0] a [ 1 ] a^{[1]} a[1],对应的两个多项式为 A [ 0 ] A^{[0]} A[0] A [ 1 ] A^{[1]} A[1],
a [ 0 ] = [ a 0 , a 2 , ⋯   , a n − 2 ] ⊤ → A [ 0 ] ( x ) a [ 1 ] = [ a 1 , a 3 , ⋯   , a n − 1 ] ⊤ → A [ 1 ] ( x ) a^{[0]}=\left[a_{0}, a_{2}, \cdots, a_{n-2}\right]^{\top} \rightarrow A^{[0]}(x) \\ a^{[1]}=\left[a_{1}, a_{3}, \cdots, a_{n-1}\right]^{\top} \rightarrow A^{[1]}(x) \\ a[0]=[a0,a2,,an2]A[0](x)a[1]=[a1,a3,,an1]A[1](x)
则对应多项式为:
A ( x ) = a 0 + a 1 x + a 2 x 2 + ⋯ + a n − 1 x n − 1 A [ 0 ] ( x ) = a 0 + a 2 x + a 4 x 2 + ⋯ + a n − 2 x n 2 − 1 A [ 1 ] ( x ) = a 1 + a 3 x + a 5 x 2 + ⋯ + a n − 1 x n 2 − 1 A(x)=a_{0}+a_{1} x+a_{2} x^{2}+\cdots+a_{n-1} x^{n-1} \\ A^{[0]}(x)=a_{0}+a_{2} x+a_{4} x^{2}+\cdots+a_{n-2} x^{\frac{n}{2}-1} \\ A^{[1]}(x)=a_{1}+a_{3} x+a_{5} x^{2}+\cdots+a_{n-1} x^{\frac{n}{2}-1} A(x)=a0+a1x+a2x2++an1xn1A[0](x)=a0+a2x+a4x2++an2x2n1A[1](x)=a1+a3x+a5x2++an1x2n1
x x x替换成 x 2 x^{2} x2:
A [ 0 ] ( x 2 ) = a 0 + a 2 x 2 + a 4 x 4 + ⋯ + a n − 2 x n − 2 A [ 1 ] ( x 2 ) = a 1 + a 3 x 2 + a 5 x 4 + ⋯ + a n − 1 x n − 2 A^{[0]}(x^{2})=a_{0}+a_{2} x^{2}+a_{4} x^{4}+\cdots+a_{n-2} x^{{n}-2} \\ A^{[1]}(x^{2})=a_{1}+a_{3} x^{2}+a_{5} x^{4}+\cdots+a_{n-1} x^{{n}-2} A[0](x2)=a0+a2x2+a4x4++an2xn2A[1](x2)=a1+a3x2+a5x4++an1xn2
将奇数项对应多项式乘以 x x x:
x A [ 1 ] ( x 2 ) = a 1 + a 3 x 3 + a 5 x 5 + ⋯ + a n − 1 x n − 1 xA^{[1]}(x^{2})=a_{1}+a_{3} x^{3}+a_{5} x^{5}+\cdots+a_{n-1} x^{{n}-1} xA[1](x2)=a1+a3x3+a5x5++an1xn1
最终可以得到:
A ( x ) = A [ 0 ] ( x 2 ) + x A [ 1 ] ( x 2 ) A(x)=A^{[0]}(x^{2})+xA^{[1]}(x^{2}) A(x)=A[0](x2)+xA[1](x2)
结合消去引理与折半引理(参见附录)​
ω d n d k = ω n k ( ω n k + n 2 ) 2 = ( ω n k ) 2 = ω n 2 k \omega_{dn}^{dk}=\omega_{n}^{k}\\\left(\omega_{n}^{k+\frac{n}{2}}\right)^{2}=\left(\omega_{n}^{k}\right)^{2}=\omega_{\frac{n}{2}}^{k} ωdndk=ωnk(ωnk+2n)2=(ωnk)2=ω2nk
可进行如下推导:
{ A ( ω n k ) = A [ 0 ] ( ( ω n k ) 2 ) + ω n k A [ 1 ] ( ( ω n k ) 2 ) A ( ω n k + n 2 ) = A [ 0 ] ( ( ω n k + n 2 ) 2 ) + ω n k + n 2 A [ 1 ] ( ( ω n k + n 2 ) 2 ) ∵ ( ω n k + n 2 ) 2 = ( ω n k ) 2 = ω n 2 k ∴ { A ( ω n k ) = A [ 0 ] ( ω n 2 k ) + ω n k A [ 1 ] ( ω n 2 k ) A ( ω n k + n 2 ) = A [ 0 ] ( ω n 2 k ) + ω n k + n 2 A [ 1 ] ( ω n 2 k ) 又 ∵ ω n k + n 2 = − ω n k ∴ { A ( ω n k ) = A [ 0 ] ( ω n 2 k ) + ω n k A [ 1 ] ( ω n 2 k ) A ( ω n k + n 2 ) = A [ 0 ] ( ω n 2 k ) − ω n k A [ 1 ] ( ω n 2 k ) \left\{\begin{array}{l} A\left(\omega_{n}^{k}\right)=A^{[0]}\left(\left(\omega_{n}^{k}\right)^{2}\right)+\omega_{n}^{k} A^{[1]}\left(\left(\omega_{n}^{k}\right)^{2}\right) \\ A\left(\omega_{n}^{k+\frac{n}{2}}\right)=A^{[0]}\left(\left(\omega_{n}^{k+\frac{n}{2}}\right)^{2}\right)+\omega_{n}^{k+\frac{n}{2}} A^{[1]}\left(\left(\omega_{n}^{k+\frac{n}{2}}\right)^{2}\right) \\ \end{array}\right.\\ \because\left(\omega_{n}^{k+\frac{n}{2}}\right)^{2}=\left(\omega_{n}^{k}\right)^{2}=\omega_{\frac{n}{2}}^{k}\\ \therefore\left\{\begin{array}{l} A\left(\omega_{n}^{k}\right)=A^{[0]}\left(\omega_{\frac{n}{2}}^{k}\right)+\omega_{n}^{k} A^{[1]}\left(\omega_{\frac{n}{2}}^{k}\right) \\ A\left(\omega_{n}^{k+\frac{n}{2}}\right)=A^{[0]}\left(\omega_{\frac{n}{2}}^{k}\right)+\omega_{n}^{k+\frac{n}{2}} A^{[1]}\left(\omega_{\frac{n}{2}}^{k}\right) \end{array}\right.\\ 又\because\omega_{n}^{k+\frac{n}{2}}=-\omega_{n}^{k}\\ \therefore\left\{\begin{array}{l} A\left(\omega_{n}^{k}\right)=A^{[0]}\left(\omega_{\frac{n}{2}}^{k}\right)+\omega_{n}^{k} A^{[1]}\left(\omega_{\frac{n}{2}}^{k}\right) \\ A\left(\omega_{n}^{k+\frac{n}{2}}\right)=A^{[0]}\left(\omega_{\frac{n}{2}}^{k}\right)-\omega_{n}^{k} A^{[1]}\left(\omega_{\frac{n}{2}}^{k}\right) \end{array}\right. A(ωnk)=A[0]((ωnk)2)+ωnkA[1]((ωnk)2)A(ωnk+2n)=A[0]((ωnk+2n)2)+ωnk+2nA[1]((ωnk+2n)2)(ωnk+2n)2=(ωnk)2=ω2nkA(ωnk)=A[0](ω2nk)+ωnkA[1](ω2nk)A(ωnk+2n)=A[0](ω2nk)+ωnk+2nA[1](ω2nk)ωnk+2n=ωnkA(ωnk)=A[0](ω2nk)+ωnkA[1](ω2nk)A(ωnk+2n)=A[0](ω2nk)ωnkA[1](ω2nk)
则问题转化为了求次数界为n/2的多项式 A 0 A^{0} A0 A 1 A^{1} A1在各个n/2次单位根上的值,
D E F n ( a ) 分 解 为 D E F n 2 ( a [ 0 ] ) 与 D E F n 2 ( a [ 1 ] ) DEF_{n}(a)分解为DEF_{\frac{n}{2}}(a^{[0]})与DEF_{\frac{n}{2}}(a^{[1]}) DEFn(a)DEF2n(a[0])DEF2n(a[1])
至此我们可以将该问题化为递归问题,也由此可以看出该多项式需为2的幂次项

则递归式FFT其伪代码如下:


FFT ⁡ ( a , lim ⁡ ) \operatorname{FFT}(a, \lim ) FFT(a,lim)


1 : i f lim ⁡ = = 1 r e t u r n 1: if\quad \lim ==1 \quad return 1:iflim==1return

2 : a [ 0 ] = ( a 0 , a 2 , ⋯   , a n − 2 ) 2: a^{[0]}=\left(a_{0}, a_{2}, \cdots, a_{n-2}\right) 2:a[0]=(a0,a2,,an2)

3 : a [ 1 ] = ( a 1 , a 3 , ⋯   , a n − 1 ) 3: a^{[1]}=\left(a_{1}, a_{3}, \cdots, a_{n-1}\right) 3:a[1]=(a1,a3,,an1)

4 : FFT ⁡ ( a [ 0 ] , lim ⁡ > > 1 ) 4: \operatorname{FFT}\left(a^{[0]}, \lim >>1\right) 4:FFT(a[0],lim>>1)

5 : FFT ⁡ ( a [ 1 ] , lim ⁡ > > 1 ) 5: \operatorname{FFT}\left(a^{[1]}, \lim >>1\right) 5:FFT(a[1],lim>>1)

6 : ω n = e 2 π n i = cos ⁡ ( 2 π / n ) + i sin ⁡ ( 2 π / n ) 6: \omega_{n}=e^{\frac{2 \pi}{n} i}=\cos (2 \pi / n)+i \sin (2 \pi / n) 6:ωn=en2πi=cos(2π/n)+isin(2π/n)

7 : ω = 1 7: \omega=1 7:ω=1

8 : f o r k = 0 … n / 2 − 1 8: for\quad k=0 \ldots n / 2-1 8:fork=0n/21

9 : a k = a k [ 0 ] + ω a k [ 1 ] 9:\quad\quad a_{k}=a_{k}^{[0]}+\omega a_{k}^{[1]} 9:ak=ak[0]+ωak[1]

10 : a k + n 2 = a k [ 0 ] − ω a k [ 1 ] 10:\quad\quad a_{k+\frac{n}{2}}=a_{k}^{[0]}-\omega a_{k}^{[1]} 10:ak+2n=ak[0]ωak[1]
11 : ω = ω ω n 11:\quad\quad \omega=\omega \omega_{n} 11:ω=ωωn


当输入向量长度为1时,不进行处理,将其值直接返回,

若非,则将原向量按下标分为奇偶两个向量,再对其执行递归FFT,

而次数界(lim)则需要除以2,

第k组需要n次单位根的k次方(旋转因子)来乘奇数项的值,

设一个常量 ω n \omega_{n} ωn作为n次单位根,设一个变量 ω \omega ω为旋转因子,且当k为0时,其值为1,

根据先前推导的公式执行合并,共n/2次

最后需要将旋转因子乘以 ω n \omega_{n} ωn,保证k次执行时, ω = ω n k \omega=\omega_{n}^{k} ω=ωnk


F F T ( a ) \mathrm{FFT}(a) FFT(a)


1 : B i t R e v e r s e a 1: BitReverse \quad a \quad 1:BitReversea

$ 2: for \quad dep=1 \ldots \log _{2} n$

3 : m = 2 d e p 3: \quad m=2^{d e p} 3:m=2dep

4 : ω m = e 2 π m i = cos ⁡ ( 2 π / m ) + i sin ⁡ ( 2 π / m ) 4: \quad \omega_{m}=e^{\frac{2 \pi}{m} i}=\cos (2 \pi / m)+i \sin (2 \pi / m) 4ωm=em2πi=cos(2π/m)+isin(2π/m)
5 : f o r k = 0 … n − 1 b y m 5: \quad for \quad k=0 \ldots n-1 by \quad m 5:fork=0n1bym
6 : ω = 1 6: \quad\quad \omega=1 6:ω=1
7 :  for  j = 0 … m / 2 − 1 7: \quad\quad \text { for }\quad j=0 \ldots m / 2-1 7: for j=0m/21
8 : t = ω a k + j + m / 2 8:\quad\quad\quad\quad t=\omega a_{k+j+m / 2} 8:t=ωak+j+m/2
9 : u = a k : + j 9:\quad\quad\quad\quad u=a_{k:+j} 9:u=ak:+j
10 : a k + j = u + t 10:\quad\quad\quad\quad a_{k+j}=u+t 10:ak+j=u+t

11 : a k + j + m / 2 = u − t 11:\quad\quad\quad\quad a_{k+j+m/2}=u-t 11:ak+j+m/2=ut

12 : ω = ω ω m 12:\quad\quad\quad\quad \omega=\omega \omega_{m} 12:ω=ωωm


对原数组重新排列,

从1到次数界的对数,

定义两个常量,表示合并后序列的长度m与m次单位根

再通过一个循环对每隔m的一组执行蝴蝶操作,

定义一个变量为旋转因子,

再通过一个循环体对每组内对应的数进行蝶形操作,

最后需要将旋转因子乘以 ω m \omega_{m} ωm,保证k次执行时, ω = ω m k \omega=\omega_{m}^{k} ω=ωmk

最终需要的数据顺序由位逆序置换(BitReverse)可得到,下标数据与排序数据的二进制互为倒数。
r e v [ i ] = ( r e v [ i > > 1 ] > > 1 ) ∣ ( ( i & 1 ) < < (  len  − 1 ) ) r e v[i]=(r e v[i>>1]>>1) \quad \mid((i \& 1)<<(\text { len }-1)) rev[i]=(rev[i>>1]>>1)((i&1)<<( len 1))

音频特征学习记录

短时傅里叶变换(Short Time Fourier Transform)

短时傅里叶变换可以看成是将语音数据按照固定帧长进行切割,并且帧长移动时的步长会小于每一帧的长度,目的是保留语音的前后关系,每帧frame通过FFT得到一个向量,对应的是各频点的大小。之后将每帧进行结合形成矩阵向量(声谱图)


附录:

复数:

  • 加法法则: ( a + b i ) + ( c + d i ) = ( a + c ) + ( b + d ) i (a+bi)+(c+di)=(a+c)+(b+d)i (a+bi)+(c+di)=(a+c)+(b+d)i
  • 乘法法则: ( a + b i ) ( c + d i ) = ( a c − b d ) + ( a d + b c ) i (a+bi)(c+di)=(ac-bd)+(ad+bc)i (a+bi)(c+di)=(acbd)+(ad+bc)i
  • 除法法则: a + b i c + d i = a c + b d c 2 + d 2 + b c − a d c 2 + d 2 i \frac{a+bi}{c+di}=\frac{ac+bd}{c^{2}+d^{2}}+\frac{bc-ad}{c^{2}+d^{2}}i c+dia+bi=c2+d2ac+bd+c2+d2bcadi
  • 欧拉定理: e i θ = c o s θ + i s i n θ e^{i\theta}=cos\theta+isin\theta eiθ=cosθ+isinθ

每个复数都可以表示为 r ∗ e i θ r*e^{i\theta} reiθ, z = x + y i = r ( c o s θ + i s i n θ ) = r e i θ z=x+yi=r(cos\theta+isin\theta)=re^{i\theta} z=x+yi=r(cosθ+isinθ)=reiθ,则两复数相乘的结果为两复数模相乘再乘以 e i θ e^{i\theta} eiθ 「棣莫弗定理」

单位根是 z n = r n e n θ i = 1 z^{n}=r^{n}e^{n\theta i}=1 zn=rnenθi=1在复数方位内的n个根,由于单位根的n次方为1,则单位根的模一定为1,因此单位根乘其自身就相当于辐角增加一倍,由于每个单位根的n次方都落在复平面上(1,0)所以每个单位根的辐角的n倍都是 2 π 2\pi 2π的倍数,并使用欧拉定理将其写成复数的形式。

z n = r n e n θ i = 1 ⇒ { r = 1 n θ = 2 k π ∴ ω n = 1 的 n 个 根 为 : ω n k = e i 2 k π n = c o s 2 k π n + i s i n 2 k π n ( k = 0 , 1 , 2 , … , n − 1 ) z^{n}=r^{n}e^{n\theta i}=1\\\Rightarrow \left \{ \begin {array}{l}r=1\\n\theta=2k\pi\end{array}\right.\\ \therefore \omega^{n}=1的n个根为:\\ \omega_{n}^{k}=e^{i\frac{2k\pi}{n}}=cos\frac{2k\pi}{n}+isin\frac{2k\pi}{n}\quad (k=0,1,2,…,n-1) zn=rnenθi=1{r=1nθ=2kπωn=1nωnk=ein2kπ=cosn2kπ+isinn2kπ(k=0,1,2,,n1)

单位根:

  • ​ 消去引理:

ω d n d k = ω n k ω n n 2 = ω 2 = − 1 p r o o f . ω d k d n = ( e 2 π d n i ) d k = ( e 2 π n i ) k = ω n k \omega_{dn}^{dk}=\omega_{n}^{k}\\ \omega_{n}^{\frac{n}{2}}=\omega_{2}=-1\\ proof.\omega_{dk}^{dn}=(e^{\frac{2\pi}{dn}i})^{dk}=(e^{\frac{2\pi}{n}i})^{k}=\omega_{n}^{k} ωdndk=ωnkωn2n=ω2=1proof.ωdkdn=(edn2πi)dk=(en2πi)k=ωnk

  • 折半引理:

( ω n k + n 2 ) 2 = ( ω n k ) 2 = ω n 2 k ∵ ω n n 2 = ω 2 = − 1 ∴ p r o o f . ω n k + n 2 = ω n k ω n n 2 = − ω n k ( ω n k ) 2 = ω n 2 k = ω n 2 k (\omega_{n}^{k+\frac{n}{2}})^{2}=(\omega_{n}^{k})^{2}=\omega_{\frac{n}{2}}^{k}\\ \because\omega_{n}^{\frac{n}{2}}=\omega_{2}=-1\\ \therefore proof.\omega_{n}^{k+\frac{n}{2}}=\omega_{n}^{k}\omega_{n}^{\frac{n}{2}}=-\omega_{n}^{k}\\ (\omega_{n}^{k})^{2}=\omega_{n}^{2k}=\omega_{\frac{n}{2}}^{k} (ωnk+2n)2=(ωnk)2=ω2nkωn2n=ω2=1proof.ωnk+2n=ωnkωn2n=ωnk(ωnk)2=ωn2k=ω2nk

  • 求和引理:

∑ i = 0 n − 1 ( ω n k ) i = 0 p r o o f . ∑ i = 0 n − 1 ( ω n k ) i = ( ω n k ) n − 1 ω n k − 1 = ( ω n n ) k − 1 ω n k − 1 = 1 k − 1 ω n k − 1 = 0 \begin{matrix} \sum_{i=0}^{n-1} (\omega_{n}^{k})^{i}=0 \end{matrix}\\ proof.\sum_{i=0}^{n-1}(\omega_{n}^{k})^{i}=\frac{(\omega_{n}^{k})^{n}-1}{\omega_{n}^{k}-1}=\frac{(\omega_{n}^{n})^{k}-1}{\omega_{n}^{k}-1}=\frac{1^{k}-1}{\omega_{n}^{k}-1}=0 i=0n1(ωnk)i=0proof.i=0n1(ωnk)i=ωnk1(ωnk)n1=ωnk1(ωnn)k1=ωnk11k1=0

多项式:

  • 多项式加法:

A ( x ) = ∑ i = 0 n a i x i B ( x ) = ∑ i = 0 n b i x i C ( x ) = ∑ i = 0 n c i x i c ( x ) = A ( x ) + B ( x ) c i = a i + b i A(x)=\sum_{i=0}^{n}a_{i}x^{i}\\ B(x)=\sum_{i=0}^{n}b_{i}x^{i}\\ C(x)=\sum_{i=0}^{n}c_{i}x^{i}\\ c(x)=A(x)+B(x) \quad c_{i}=a_{i}+b_{i} A(x)=i=0naixiB(x)=i=0nbixiC(x)=i=0ncixic(x)=A(x)+B(x)ci=ai+bi

  • 多项式乘法:

A ( x ) = ∑ i = 0 n a i x i B ( x ) = ∑ i = 0 n b i x i C ( x ) = ∑ i = 0 2 n c i x i c i = ∑ j = 0 i a j b i − j c = a ⊗ b A(x)=\sum_{i=0}^{n}a_{i}x^{i}\\ B(x)=\sum_{i=0}^{n}b_{i}x^{i}\\ C(x)=\sum_{i=0}^{2n}c_{i}x^{i}\\ c_{i}=\sum_{j=0}^{i}a_{j}b_{i-j} \quad c=a\otimes b A(x)=i=0naixiB(x)=i=0nbixiC(x)=i=02ncixici=j=0iajbijc=ab