【问题标题】:Compressing PCM data压缩 PCM 数据
【发布时间】:2014-03-16 00:56:13
【问题描述】:

我正在使用 WinAPI - Wave 函数创建一个录制程序,用于录制麦克风 X 秒。网上搜了一下,发现PCM数据太大了,通过socket发送会有问题……

我怎样才能把它压缩成更小的东西?任何简单/“便宜”的方式?

我还注意到,当我使用 Wave API 函数声明格式时,我使用的是以下代码:

WAVEFORMATEX pFormat;
pFormat.wFormatTag= WAVE_FORMAT_PCM;     // simple, uncompressed format
pFormat.nChannels=1;                    //  1=mono, 2=stereo
pFormat.nSamplesPerSec=sampleRate;      // 44100
pFormat.nAvgBytesPerSec=sampleRate*2;   // = nSamplesPerSec * n.Channels * wBitsPerSample/8
pFormat.nBlockAlign=2;                  // = n.Channels * wBitsPerSample/8
pFormat.wBitsPerSample=16;              //  16 for high quality, 8 for telephone-grade
pFormat.cbSize=0;

如您所见,pFormat.wFormatTag= WAVE_FORMAT_PCM; 也许我可以插入而不是 WAVE_FORMAT_PCM 其他东西,所以它会立即被压缩? 我已经检查了 MSDN 的其他值,尽管它们在我的 Visual Studio 中都不适合我......

那我该怎么办?

谢谢!

【问题讨论】:

  • wFormat 标签描述数据。更改它不会更改数据,只会导致它解释错误。您需要的是一个编码器,它将采用 PCM 并输出压缩格式,如 ADPCM 或 Vorbis。
  • 您需要一个编解码器。你需要什么编解码器?这取决于你的约束。您是在录制语音、音乐还是其他东西?您是对可以无损下载的文件进行编码还是对实时流进行编码?如果是实时的,你的带宽是多少?回答完这些问题后,您或许可以选择编解码器。
  • @arx 我正在尝试编写一个小的 IP 语音程序

标签: c++ c winapi voip voice-recording


【解决方案1】:

最简单的方法是将采样率从 44100 降低到更易于管理的值,例如 22050、16000、11025 甚至 8000。大多数语音编解码器无论如何都不会高于 16000 赫兹。而旧的则针对 8khz 进行了优化。

下一步是寻找编解码器。 Windows Audio Compression Manager 可以使用一些编解码器,但几乎所有编解码器都可以追溯到 Windows 95 并且在解压缩后按照现代标准听起来很糟糕。

您始终可以使用 Format SDK 或 Media Foundation API 实时转换为 WMA。或者只是去获取一个开源 MP3 库,例如 LAME

【讨论】:

  • 既然数组现在是24000的长度,压缩它还重要吗?
  • @Amit - 这实际上是你的电话。您从未提及您的音频数据块有多大、性能要求或既定目标。因此,如果您对性能感到满意,那么您就一切就绪。否则,请继续探索更多选择。
【解决方案2】:

GSM 具有良好的压缩性。您可以使用acmStreamConvert() 将一块 PCM 数据转换为 GSM(或您安装的任何其他编解码器)。有关详细信息,请参阅 MSDN:

Converting Data from One Format to Another

【讨论】:

    【解决方案3】:

    对于电话质量的语音,您可以更改为每个样本 8 位和 8000 的采样率。这将大大减少数据量。

    【讨论】:

    • 谢谢!数组大小现在是 24,000。 VOIP 的速度是否足够小?还是我应该压缩它?
    • @Amit:VOIP 面临的挑战不是您的平均数据速率;而是您的平均数据速率。它确保您在丢包同时保持低延迟时得到合理的结果。
    • @MSalters 我可以用线程做到这一点,24/7 接收数据,并通过线程播放数据..这就是你的意思,不是吗?
    • @Amit:不,一点也不。当(不是如果)你丢了一个包时你会怎么做?您不能将 TCP 用于 VoIP,这会引入口吃。重新发送不是一种选择。你需要一种叫做前向纠错的东西。
    • @MSalters 我明白了。你的意思是,如果我发送例如音频声音的数组,而数组已损坏,或者类似的东西会发生什么?谢谢!我会检查主题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多