?有些设备采集的音频文件格式为pcm格式,其本身就为ad转化后的产物,在我的嵌入式实现中为节省计算资源,直接对其进行声道分离。
如何使用python语言将pcm音频流文件转为数值矩阵,多声道进行声道分离,便于对每个单声道进行观察,下面我写了一个函数(借用了AudioSegment)用于解决这个问题。
需提前下载的模块有AudioSegment,matplotlib,numpy
有一处地方自己设置,有几声道,复制几次
函数:
from pydub import AudioSegment
import numpy as np
#import wave
#from matplotlib import pyplot
pcm_path = 'mic_demo_vvui_ori.pcm'
def voice_devide(pcm_path,sound_num,invalid_sound,fs,data_type):
'''
多声道分离转化,pcm_path为文件路径,sound_num为声道数
invalid_num为无效声道数(用于消除回声),没有则为0
fs为采样频率,data_type为数据位数(8位,16位,32位)
'''
#多声道分离,fs为采样频率,data_type为数据位数(8位,16位,32位)
#pcm_path = 'mic_demo_vvui_ori.pcm'
with open(pcm_path, 'rb') as f:
audioData = np.fromfile(f, dtype=np.uint32)
audioData.shape = -1, sound_num #有sound_num个声道,即排成sound_num列,一行即为一帧(采样一次)
#将各个声道分离,有几个声道复制几次这里,此处只列了6个通道
audioData = audioData.T
ch1 = audioData[0]
ch1.tofile("ch_0.pcm")
ch2 = audioData[1]
ch2.tofile("ch_1.pcm")
ch3 = audioData[2]
ch3.tofile("ch_2.pcm")
ch4 = audioData[3]
ch4.tofile("ch_3.pcm")
ch5 = audioData[4]
ch5.tofile("ch_4.pcm")
ch6 = audioData[5]
ch6.tofile("ch_5.pcm")
#pyplot.plot(pcm_data[1])
num = len(audioData[1])
ch_data=np.zeros((sound_num-invalid_sound,num))#减去invalid_sound个无效声道,没有抵消声道可删去
for i in range(sound_num-invalid_sound):#依次将各个声道的数据读入,转为浮点数
ch_x='ch_%d.pcm'%(i)#文件名的格式
voice_data = AudioSegment.from_file(file=ch_x,sample_width=data_type/8, frame_rate=fs,channels=1)
ch_data[i,:] = np.array(voice_data.get_array_of_samples())
ch_data[i,:] = ch_data[i,:]/2**(data_type-1)#转为浮点数
#pyplot.plot(pcm_data[1:100000])
#pyplot.plot(ch_data[i-1])
return ch_data
?此处为调用的实例:(采样频率为16k,8声道,32位数据编码,末尾2个声道为抵消回声的声道,此处称为无效声道)
# 创建时间:2021/12/25 20:43
# 版本号:1.1
# 最后修改时间:
# 作者:陈安静
import format_conversion
import matplotlib.pyplot as plt
pcm_path='mic_demo_vvui_ori.pcm'
data=format_conversion.voice_devide(pcm_path,sound_num=8,invalid_sound=2,fs=16000,data_type=32)
plt.plot(data[0,:])#随便取一个通道进行观察
实现:
总结:这个实现起来不难,就是比较麻烦,如果有什么写的不好的地方,希望各位同学多多批评指正,有问题可以留言。
|