使用PyAudio录制多声道音频:拆分单声道文件及Float32格式保存问题
多声道音频拆分与Float32格式处理方案
声道交错规则
PyAudio录制的多声道数据采用交错存储:每个采样周期内,按声道顺序依次存储单个采样值。比如6声道时,数据顺序为:声道1采样1 → 声道2采样1 → ... → 声道6采样1 → 声道1采样2 → 声道2采样2 → ...
1. 当前Int24格式拆分方案
利用numpy处理字节数据,步骤如下:
步骤1:导入依赖库
import numpy as np import wave import pyaudio
步骤2:处理录制的frames数据
# 拼接所有录制的字节数据 raw_data = b''.join(frames) channels_in = 6 # 你的输入声道数 sample_width = 3 # Int24占3字节 # 将字节数据转换为numpy数组(Int24需转为Int32处理,补高位) # PyAudio的Int24是小端字节序 int24_data = np.frombuffer(raw_data, dtype=np.uint8).reshape(-1, 3) int32_data = np.zeros((int24_data.shape[0], 4), dtype=np.uint8) int32_data[:, :3] = int24_data # 处理符号位:最高位为1时说明是负数,补全高位为0xFF int32_data[int24_data[:, 2] >= 128, 3] = 0xFF audio_array = int32_data.view(np.int32) / 2**24 # 可选:归一化到[-1.0, 1.0] # 重塑为(总采样数, 声道数)的二维数组 audio_array = audio_array.reshape(-1, channels_in) # 拆分并保存每个声道 for idx in range(channels_in): # 提取单声道数据 mono_data = audio_array[:, idx] # 转回Int24字节格式 int32_mono = (mono_data * 2**24).astype(np.int32) int24_mono = int32_mono.view(np.uint8).reshape(-1, 4)[:, :3].flatten() # 保存单声道WAV文件 with wave.open(f'mono_channel_{idx+1}.wav', 'wb') as wf: wf.setnchannels(1) wf.setsampwidth(sample_width) wf.setframerate(fs) wf.writeframes(int24_mono.tobytes())
2. 后续Float32格式处理方案
改用soundfile处理更简洁,无需手动处理字节转换:
步骤1:修改录制格式
sample_format = pyaudio.paFloat32 # 切换为Float32格式 fs = 48000 chunk = 1024 channels_in = 6 # 初始化录制流 rec_stream = p.open(format=sample_format, channels=channels_in, rate=fs, frames_per_buffer=chunk, input=True, input_device_index=recdevice)
步骤2:录制后拆分并保存
import soundfile as sf # 拼接字节数据并转换为Float32数组 raw_data = b''.join(frames) audio_array = np.frombuffer(raw_data, dtype=np.float32).reshape(-1, channels_in) # 拆分每个声道并保存 for idx in range(channels_in): mono_data = audio_array[:, idx] sf.write(f'mono_channel_{idx+1}_float32.wav', mono_data, fs, format='WAV', subtype='FLOAT')
关键说明
- 两种格式的拆分逻辑核心一致:都是将一维数组重塑为
(总采样数, 声道数),然后按列提取单声道数据。 - Float32格式下,soundfile直接支持读写,无需手动处理字节转换,比wave模块更高效。
- 原录制+播放的循环逻辑无需修改,仅需调整录制后的处理代码即可。
内容的提问来源于stack exchange,提问作者anton
相关产品推荐
相关产品推荐

