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

时间:2015-02-20 15:38:43

标签: audio signal-processing pcm fmod

我正在使用FMOD开发一个应用程序,当用户单击Next / Prev按钮时,该应用程序将立即开始播放下一个/上一个句子的录音,该录音完全从包含语音的MP3文件开始,而不包含音乐。我通过调用 Sound :: lock 获得了mp3文件的PCM数据,但 Sound :: getFormat 只告诉我它是“16位整数PCM数据”,不知道是否它是签名未签名。我怎么知道的?

互联网上的一些文章称几乎所有16位整数PCM数据都是签名。如果我的PCM数据是签名,则什么范围的值表示静音,这些值接近0(例如-10~10),或接近-32768(例如-32768~-32750)?如果它们是接近0的值,这是否意味着相对数字之间的含义没有区别,如-32767和32767?

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

有人可以就如何检测句子之间的沉默给我任何建议吗?

2 个答案:

答案 0 :(得分:19)

按照惯例,16位音频通常是签名的。

考虑一下PCM音频是什么:每个测量指的是扬声器在那个时刻在物理上休息的轴线的距离。因此,完美的沉默绝对是任何重复的价值 - 代表说话者不动。

然后

0是范围的中心,通常是麦克风没有输入的地方。 -32768是扬声器尽可能接近其轴的一端,32767是另一端。

检测静音的最安全方法是在相关范围内进行频谱分析,并查找在任何可听频率范围内没有活动的时段。

如果您正在寻找语音之间的暂停,那么最简单的事情可能就是去this之类的地方,插入可接受的语音频率范围(在电话中它被认为是大约300Hz到3500Hz左右) ),您的采样率,以及您认为可以承受的多次乘法。复制提供的系数。例如。我假设你用44100Hz输入在语音范围内进行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的声音的那部分信号应保留在输出值中。在现实生活中,这种过滤器并不完美;增加系数的数量,以提高过滤器的质量。

在剪掉信号的不相关部分之后,我可以寻找sampledValue = [close to] 0.0的长时间。

答案 1 :(得分:-1)

令人惊讶的是,如果我创建8Bit格式的directsound声音缓冲区,directsound期望在我的机器上采样为8Bit SIGNED(-127-127),而当我创建16Bit缓冲区时,directsound期望它们为16Bit UNSIGNED(0-65535)。因此,至少在我的机器上,该标准似乎与汤米的答案相反。