功能思路
功能:
- 合并多个单通道的pcm成一个多通道pcm文件
- 长度短的声道,末尾自动补零,与最长声道长度对齐
思路:
- 先了解pcm数据保存格式,见文末参考资料1
- 遍历所有要合并的单声道文件,将每个声道数据追加到列表中
- 同时,保存每个声道的数据长度进入对应列表,单位是
Byte
- 根据位深,确定单个声道每块数据的大小,如bit为16位,则一个数据占2个
Byte
,作为步长 - 在长度列表中找到最大长度的数据,以此作为循环终止条件
- 若某个文件已到末尾,则补零
实现代码
## -*- coding: utf-8 -*-
import os
if __name__ == '__main__':
input_dir = r"D:\seq\pcm"
output_dir = input_dir + r"\combin"
pcm_data = []
pcm_len = []
file_num = 3
for i in range(file_num) :
with open(os.path.join(input_dir, "file%d.pcm" %(i + 1)), 'rb') as pcmfile:
## pcm_data[i] = pcmfile.read()
## pcm_len[i] = len(pcm_data[i])
pcm_data.append(pcmfile.read())
pcm_len.append(len(pcm_data[i]))
print("i={0}, len={1}".format(i, len(pcm_data[i])))
max_len = max(pcm_len)
ch = file_num
sr = 48000
bit = 16
## output_pcm = "" ## 初始化为字符串
output_pcm = [] ## 初始化为列表
frame_len = bit / 8;
start = 0
step = int(frame_len)
fill_zero = b"" ## 声明一个bytes类型的字符串
for i in range(step) :
fill_zero += b"\x00"
for i in range(start, max_len, step) :
## output_pcm += pcm_data1[i:i+2] + pcm_data2[i:i+2] #字符串追加的方法
for file in range(file_num) :
if i + step < pcm_len[file]:
output_pcm.append(pcm_data[file][i:i+step])
else : ## 超过对应声道的长度
output_pcm.append(fill_zero)
with open(os.path.join(output_dir, 'combine_out_ch{0}_bit{1}_sr{2}.pcm'.format(file_num, bit, sr)), 'wb') as outpcm_file:
outpcm_file.write(b''.join(output_pcm)) ## b"",表示用byte方式写入,而非str