“16位整数PCM数据”是表示它是有符号还是无符号的?

18

我正在使用FMOD开发一个应用程序,其会在用户点击“下一个/上一个”按钮时,从MP3文件中立即播放包含语音(无音乐)的下一/上一句录音,并从句子开头开始播放。通过调用Sound::lock,我获取了mp3文件的PCM数据,但是Sound::getFormat只告诉我这是"16位整数PCM数据",而没有说明它是有符号还是无符号。我该如何知道它的符号?

互联网上的一些文章说,几乎所有16位整数PCM数据都是有符号的。如果我的PCM数据是有符号的,那么哪个值范围代表沉默,靠近0的值(例如-10~10),还是靠近-32768的值(例如-32768~ -32750)?如果它们是靠近0的值,这是否意味着相反的数字(如-32767和32767)没有区别?

我需要检测足够长的沉默,例如超过500毫秒,以确定每个语音句子的起始位置。

有人能给我关于如何检测句子之间的沉默的建议吗?

2个回答

27

16位音频通常是有符号的。PCM音频的每个测量值表示扬声器在某个时间点应该停留在轴线上的位置。因此,完美的静默是任何重复的值——代表扬声器不动。

0是范围的中心,并且通常是没有输入时麦克风所在的位置。-32768是扬声器尽可能靠近其轴线一端的位置,32767是它在另一端。

检测沉默的最安全方法是在相关范围内运行光谱分析,查找任何可听频率范围内没有活动的时期。

如果您正在寻找语音之间的暂停,则最简单的方法可能是转到诸如此类网站,插入适合语音的可接受频率范围(在电话中被认为是约300 Hz到约3500 Hz),以及采样率和您认为可以承担的乘法数量。复制提供的系数。例如,我假设您将在44100 Hz的输入中跨越语音范围做37次敲击,并将其转换为C数组:

double coefficients[] = {
    -0.000560, -0.001290, -0.002332, -0.003606, -0.004911, -0.005921,  -0.006201, 
    -0.005256, -0.002610, 0.002106, 0.009059, 0.018139, 0.028924, 0.040691,  0.052479, 
    0.063203, 0.071794, 0.077351, 0.079274, 0.077351, 0.071794, 0.063203,  0.052479, 
    0.040691, 0.028924, 0.018139, 0.009059, 0.002106, -0.002610, -0.005256, -0.006201, 
    -0.005921, -0.004911, -0.003606, -0.002332, -0.001290, -0.000560};

如果输入是double,对于每个输入样本c,我会计算一个采样值:

double *inputWave = ... input, an infinite array for the purposes of the example ...
double sampledValue = 0.0;
for(size_t coeff = 0; coeff < numberOfTaps; coeff++) {
    sampledValue += coefficients[coeff] * inputWave[c + coeff];
}

// (where numberOfTaps = sizeof(coefficients) / sizeof(coefficients[0]),
// i.e. the number of coefficients: 37 with the array given above)

我所得到的是一个带通滤波器。只有在频率范围为300-3500Hz的声音部分应该保留在输出值中。在现实生活中,没有这样完美的过滤器;增加系数可以提高过滤器的质量。

削减信号的无关部分后,我可以寻找持续一段时间的“采样值=[接近] 0.0”的区域。


非常感谢,汤米。我原先以为只需将PCM数据与一个数字直接比较即可找到句子间的停顿。请原谅我的无知,"taps"是什么意思?为什么应该有37个"taps"?输入数组inputWave[]是否指代像我所提到的16位整数的PCM数据?你的示例代码是否旨在确定样本inputWave[c]是否表示沉默?对于这么多问题和我的糟糕英语,感到抱歉。 - xiaokaoy
Taps是信号处理术语,用于组合多个输入样本以执行一个输出样本。它更多地来自硬件传统方面。它不需要是37,那只是该页面上的默认值。您应该根据主观性能选择——通常情况下,越多越好。至于CPU性能,请考虑使用处理器的SIMD单元进行整个过程(这可能意味着使用定点短整数而不是双精度浮点数,但无论如何)。输出是经过滤波的波形。您可以直接听取它。寻找靠近0的长时间静音期。 - Tommy

0

令人惊讶的是,如果我使用8位格式创建直接声音缓冲区,则在我的计算机上,直接声音期望样本为8位有符号数(-127至127),而当我创建16位缓冲区时,直接声音期望它们为16位无符号数(0至65535)。因此,至少在我的计算机上,标准似乎与Tommy的答案相反。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接