如何将原始WAV字节转为uint数组?如何读取文件字节用于webrtcvad库?
嘿,我来帮你把这两个需求落地,结合webrtcvad的要求,咱们把代码补全并讲清楚细节:
需求实现方案
1. 原始WAV字节转uint数组
WAV文件里的16位PCM数据是有符号整数(范围-32768到32767),要转成uint数组(0到65535),只需要给每个值加上32768即可。我们可以用struct模块解析字节,或者用numpy提升处理大数据量的效率。
2. 适配webrtcvad的文件读取
webrtcvad对输入有严格要求:单声道、16位有符号PCM、采样率必须是8000/16000/32000/48000。你的代码已经做了基础校验,我把它补全并加上uint数组转换的逻辑:
import contextlib import wave import struct import numpy as np def read_wave(path): """Reads a .wav file. Returns: (PCM字节数据, 采样率, uint16数组) """ with contextlib.closing(wave.open(path, 'rb')) as wf: # 校验声道数:必须单声道 num_channels = wf.getnchannels() assert num_channels == 1, "webrtcvad只支持单声道WAV文件" # 校验采样宽度:必须16位 sample_width = wf.getsampwidth() assert sample_width == 2, "webrtcvad只支持16位采样的WAV文件" # 校验采样率:必须是指定值 sample_rate = wf.getframerate() assert sample_rate in (8000, 16000, 32000, 48000), "采样率必须是8000/16000/32000/48000" # 读取所有PCM原始字节 pcm_data = wf.readframes(wf.getnframes()) # 解析为int16数组(16位有符号) int16_array = struct.unpack(f"{len(pcm_data)//2}h", pcm_data) # 转换为uint16数组:int16 + 32768 得到0~65535的无符号值 # 方式1:用numpy(适合大数据量) uint16_array = np.array(int16_array, dtype=np.int16) + 32768 uint16_array = uint16_array.astype(np.uint16) # 方式2:纯Python列表(小数据量够用) # uint16_array = [sample + 32768 for sample in int16_array] return pcm_data, sample_rate, uint16_array
3. 用webrtcvad处理的示例
拿到pcm_data后,就可以直接传给webrtcvad做语音检测了,这里给个简单的示例:
import webrtcvad def detect_speech(pcm_data, sample_rate, aggressiveness=3): """用webrtcvad检测语音片段 aggressiveness:0~3,值越大检测越敏感 """ vad = webrtcvad.Vad(aggressiveness) # 帧时长必须是10/20/30ms,这里选10ms frame_duration_ms = 10 # 计算每个帧的字节数:采样率*时长/1000 * 2(16位采样每个样本占2字节) frame_size = int(sample_rate * frame_duration_ms / 1000) * 2 speech_frames = [] for i in range(0, len(pcm_data), frame_size): frame = pcm_data[i:i+frame_size] # 忽略长度不足的末尾帧 if len(frame) < frame_size: break # 判断当前帧是否为语音 is_speech = vad.is_speech(frame, sample_rate) speech_frames.append(is_speech) return speech_frames
关键注意点
- webrtcvad的
is_speech方法必须传入完整的帧数据,所以要严格计算帧大小,不能缺字节。 - 如果不需要numpy依赖,直接用列表推导式转uint数组就行,适合小文件场景。
内容的提问来源于stack exchange,提问作者Isaac
相关产品推荐
相关产品推荐

