使用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采样参数中转换而来),包括dwSamplesPerSec、dwAvgBytesPerSec、wBlockAlign、 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步来释放资源。