当前位置: 首页 > 工具软件 > PDM Python > 使用案例 >

使用python .pcm音频文件多声道数据提取与转化(改进版本)

能翔宇
2023-12-01

有些设备采集的音频文件格式为pcm格式,其本身就为ad转化后的产物,在我的嵌入式实现中为节省计算资源,直接对其进行声道分离。

如何使用python语言将pcm音频流文件转为数值矩阵,多声道进行声道分离,便于对每个单声道进行观察,下面我写了一个函数(借用了AudioSegment)用于解决这个问题。

需提前下载的模块有AudioSegment,matplotlib,numpy

#pcm数据可以这样读取
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精度选择读取类型
    if data_type==32:
           with open(pcm_path, 'rb') as f:
            audioData = np.fromfile(f, dtype=np.uint32)
    elif data_type==16 :
            with open(pcm_path, 'rb') as f:
             audioData = np.fromfile(f, dtype=np.uint16)
    else:
            with open(pcm_path, 'rb') as f:
             audioData = np.fromfile(f, dtype=np.uint8)

    audioData.shape = -1, sound_num     #有sound_num个声道,即排成sound_num列,一行即为一帧(采样一次)
    audioData = audioData.T
    #分离每个声道
    for i in range(sound_num):#笨方法,挨个导出,方便导入
        ch_x=audioData[i,:]
        ch_x.tofile('ch_%d.pcm'%(i))


    num = len(audioData[1])
    ch_data=np.zeros((sound_num-invalid_sound,num))#减去invalid_sound个无效声道,没有抵消声道可删去
    for i in range(0,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,)
        a=voice_data.get_array_of_samples()
        ch_data[i,:] = np.array(voice_data.get_array_of_samples())
        ch_data[i,:] = ch_data[i,:]/2**(data_type-1)#转为浮点数 使其缩小到0-1的范围内

    return ch_data


测试一下:(没有无效声道invalid_sound就写0)


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=0,fs=16000,data_type=32)


 

 类似资料: