PCM原始音频采样数据压缩为GSM6.10格式的大致流程

时间:2022-02-22 19:46:45

使用ACM来进行音频格式压缩的大致步骤:

1、使用 acmDriverEnum 函数来枚举操作系统的所有音频格式驱动,把GSM6.10格式的驱动取出来。

GSM6.10格式驱动的名称为:Microsoft GSM 6.10 Audio CODEC

2、使用 acmDriverOpen 函数将上面取得的驱动ID打开。

3、通过 acmMetrics 函数来获取GSM6.10格式Format Chunk的附加数据长度,为4个字节。大致调用如下:

acmMetrics((HACMOBJ)m_hDriverCmp, ACM_METRIC_MAX_SIZE_FORMAT, &nSize);

4、使用 acmFormatSuggest 函数来获取GSM6.10的各个参数值(从PCM采样参数中转换而来),包括dwSamplesPerSecdwAvgBytesPerSecwBlockAlign、 wBitsPerSample以及附加数据。大致调用如下:

acmFormatSuggest(m_hDriverCmp, pPCMFmt, pGSMFmt, nSize, ACM_FORMATSUGGESTF_WFORMATTAG);

5、使用 acmStreamOpen 函数来打开格式转换流,必须确保 acmFormatSugges 函数调用成功。 大致调用如下:

 

acmStreamOpen(&m_hStreamCmp/*格式转换流*/, m_hDriverCmp/*压缩驱动程序句柄*/, 

        pPCMFmt, pGSMFmt, NULL/*无过滤器*/, 0/*无回调函数*/, 0/*无回调参数*/, CM_STREAMOPENF_NONREALTIME);

6、使用 acmStreamSize 函数来获取从源数据压缩后的GSM6.10格式数据的长度。

7、声明一个 ACMSTREAMHEADER(数据流格式转换头)的对象,将PCM音频数据和GSM6.10音频数据的内存地址赋到该对象中。然后调用 acmStreamPrepareHeader 来为格式转换流准备好转换头(及转换所需的相关参数)。

8、调用 acmStreamConvert 函数来完成格式转换。

9、调用 acmStreamClose 来关闭转换流。

10、调用 acmDriverClose 来关闭GSM6.10驱动。

 

注意:每次转换的源数据长度必须为65何320的整数倍,否则转换后的音频数据听起来会断断续续(这大概是其内部自动补零为65和320的整数据所致吧)。

如果循环压缩,每次压缩一部分采样数据, 1~5步可以用来做初始化,每次压缩为6~8步,压缩完成之后,9和10步来释放资源。