有问题的代码如下
https://github.com/k2-fsa/sherpa-onnx/blob/master/java-api-examples/VadFromMic.java#L65-L70
问题说明:
Java 的 byte 是有符号的(-128~127),buffer[2 * i] 强转成 short 会做符号扩展;
对于负数样本(高、低字节经常是 0xFF 之类),(high << 8) + low 算出来的值就不再是正确的 16-bit PCM 了,导致整个波形严重畸变。
建议修复代码如下:
for (int i = 0; i != windowSize; ++i) {
int low = buffer[2 * i] & 0xFF; // 低字节按无符号处理
int high = buffer[2 * i + 1]; // 高字节保留符号位(会在左移时扩展)
int s = (high << 8) | low; // 组合成 16-bit 整数
short sample = (short) s; // 截断到 16-bit(保证范围正确)
samples[i] = sample / 32768.0f; // 转成 [-1, 1) 的 float
}
或者更简洁点
for (int i = 0; i != windowSize; ++i) {
int s = (buffer[2 * i + 1] << 8) | (buffer[2 * i] & 0xFF);
short sample = (short) s;
samples[i] = sample / 32768.0f;
}
修复效果:音频切割后为录制原声,播放无波形畸变