最近在做语音信号处理相关的项目,在Xilinx PYNQ Z2上实现SRP-PHAT算法,一起做的同学提供了算法的matlab版本,因为PYNQ是基于python的Jupyter Lab开发,所以要将SRP-PHAT用python重写,在转换时遇到了很多细节问题,花了不少时间,在此记录下来,方便大家参考。
复现期间这个官方手册给予了我不小帮助:NumPy for MATLAB users — NumPy v1.21 Manual
1.语音信号一般是一维的序列,将其读入到某一python变量时,它是没有行与列的概念的
例如:
data1,fs = read_wav_file("mic1.wav") # data1是音频数据,fs是该音频的采样频率
print(data1.shape)
>> (190208,)
这里data1并不是1行190208列的行向量,也不是190208行1列的列向量,对其转置一下,输出不变
data1,fs = read_wav_file("mic1.wav") # data1是音频数据,fs是该音频的采样频率
data1 = data1.T
print(data1.shape)
>> (190208,)
如果要获得1行190208列的data1,就要进行一次reshape了:
data1,fs = read_wav_file("mic1.wav") # data1是音频数据,fs是该音频的采样频率
data1 = data1.reshape(1,-1)
print(data1.shape)
>> (1,190208)
2.python3后,数字的除法运算默认使用浮点数运算,如果除法要得整数结果,除法的运算符号应该是 //
例如:
window_len = 256
fft_bin = window_len / 2 + 1
window_len = 256
fft_bin = window_len // 2 + 1
3.循环
matlab中"for t = 1:360",其中t从1取到360,对应python的"for t in range(1,361)"
4.数组:
定义数组时二者是一样的。
对数组进行索引时,matlab中的array(1,10)对应python中的array[0,9],因为python是从0开始索引的。
对数组进行切片时,matlab中的array(1:10,:)对应python中的array[0:10,:],都是取数组array的第1到10行及所有列,python的[0:10]是包含0不包含10的。
5.hanning窗
matlab中的hanning窗使用:
window = hanning(window_len);
这是所生成hanning窗的头部数据:
python中,numpy也有对应的hanning函数,不过生成的窗和matlab略有不同:
window = np.hanning(window_len)
hanning窗头部数据:
可见,第一行多了0,相应的尾部也多一个0:
解决办法是生成窗时多用两个点,同时去掉首位的0:
window = np.hanning(window_len+2)[1:-1]
这样就可以了!
6.快速傅里叶变换(FFT)
matlab进行FFT的方式和python是有区别的,
matlab中进行FFT: x_fft = fft(x1);
在python中用numpy实现FFT需要加上axis参数,即:
x_fft = np.fft.fft(x1,axis=0)
这样二者就一致了