如何在PCM音频中使用IMediaSample检测静音

时间:2012-07-31 09:39:21

标签: c++ audio directshow pcm

我需要使用IMediaSample检测PCM音频流中的静音。信号由电视提供,并通过光缆与PC连接到Prodigy 7.1 HiFi声卡。到目前为止,我有这个:

bool detectSound(IMediaSample *pSamples)
{
    BYTE *pData;
    pSamples->GetPointer(&pData);
    long size = pSamples->GetActualDataLength();

    long nulls = 0;
    for(long i = 0; i < size; ++i) {
        if(pData[i] == 0)
            ++nulls;
    }

    /* 0.9 to eliminate interference */
    long max_nulls = (long) (0.9 * size);
    if(nulls > max_nulls) {                 /* STOP */
        /* no audio */
        return false;
    }
    else {
        /* audio available */
        return true;
    }
}

问题在于,如果我将断点放在标记为“STOP”的行上,则nulls几乎总是相同的值,并且小于max_nulls,无论我是否将电视静音。我注意到pData [i]值总是0或255.(奇怪,不是?)

可能我不明白这个“数据”究竟是什么以及如何解释它。我所确定的是,如果没有音频,那么波形的所有采样值都应该几乎为0。

你能验证一下我的思维方式吗?提前谢谢。

编辑:

问题出在驱动程序和AC3滤波器设置的某处,因为在“SPDIF测试”中我得到了DirectSound不支持的44.1 kHz,48 kHz和32 kHz。罗曼的想法是正确的,当我解决这个问题时它会起作用。

1 个答案:

答案 0 :(得分:2)

更好的方法是找出PCM数据是什么,并且发布的问题的答案将是微不足道的。

更快捷的方法是:

  • 将这些音频数据字节视为SHORT值(您没有提及,但我认为您的音频是16位)
  • 最好分成频道并单独处理
  • 计算standard deviation
  • 沉默是指/如果计算值低于某个小的thresold