工具软件   办公软件   操作系统   网络安全   设计在线   程序开发   教程宝典   软件下载   软件论坛
您的位置:软件 > 开发者网络 > 开发工具 > 开发专栏 > VC > 正文
VC调用ACM音频编程接口压缩Wave音频
[文章信息]
作者:中国电子科技集团公司第二十二研究所青岛分所郎锐
时间:2005-02-23
出处:天极网
责任编辑:方舟
[文章导读]
本文介绍了在Microsoft Visual C++ 6.0下如何调用ACM音频压缩编程接口对原始录入的Wave音频进行数据压缩
advertisement
热点推荐
· 让你的BitComet下载得更快
· 让你的IE轻装上阵
· Word表格行列的添加与删除
· 双系统的安装和启动原理
· 趋势科技PC-cillin 2005评测报告
[正文]

上一页  1 2  

  将Wave音频转换为CODEC所支持的PCM格式

  通过CODEC将源Wave音频转换成CODEC所支持的PCM格式,可以使用任何可以做PCM间转换的驱动器。另外还有一点很重要:我们打开转换流时,要指明ACM_STREAMOPENF_NONREALTIME标志。若省略此标志,那么一些驱动程序(例如TrueSpeech CODEC)将会报告发生第512号"不可能发生的"错误。该错误指明所要求的转换不能实时进行,如果在试图播放数据的同时转换大量数据,就必须注意这点。下面是该步转换过程的简要描述:

mmr = acmStreamOpen(&hstr,
NULL, //任意驱动器
&wfSrc, //源格式
pwfPCM, //目标格式
NULL, //无过滤
NULL, //无回调
0, //初始数据
ACM_STREAMOPENF_NONREALTIME);

  根据以字节计的平均速率计算出输出缓冲区的大小,并加上一机动位(bit)如果没有此额外的空间IMA_ADPCM驱动程序将不能转换。中间的转换结果将存放在pDst1Data中:

DWORD dwSrcBytes = dwSrcSamples * wfSrc.wBitsPerSample / 8;
DWORD dwDst1Samples = dwSrcSamples * pwfPCM->nSamplesPerSec / wfSrc.nSamplesPerSec;
DWORD dwDst1Bytes = dwDst1Samples * pwfPCM->wBitsPerSample / 8;
unsigned char * pDst1Data = new unsigned char[dwDst1Bytes];
……
ACMSTREAMHEADER strhdr; //填充转换信息
memset(&strhdr, 0, sizeof(strhdr));
strhdr.cbStruct = sizeof(strhdr);
strhdr.pbSrc = cpBuf; //指定要转换的源Wave音频数据为cpBuf中的数据
strhdr.cbSrcLength = dwSrcBytes;
strhdr.pbDst = pDst1Data;
strhdr.cbDstLength = dwDst1Bytes;
mmr = acmStreamPrepareHeader(hstr, &strhdr, 0);
mmr = acmStreamConvert(hstr, &strhdr, 0); //转换数据
……
acmStreamClose(hstr, 0);

  当流打开时,第二个参数为NULL,表示接受任何驱动程序进行转换。复杂的只是计算需要给输出数据分配多大的缓冲区。PCM格式间的转换不牵扯压缩和解压缩,缓冲区大小直接就计算出来了。至于调用acmStreamPrepareHeader这个ACM API函数,是由于它可以为驱动程序安排好一切并允许驱动程序在转换前锁定内存。

  生成最终的压缩格式

  向最终压缩格式的转换过程与前面的PCM格式间转换非常相似,只不过此次转换我们提供了打开流时想要使用的驱动程序的句柄。实际上,此处仍可使用NULL,因为已预知此驱动程序存在,但提供句柄避免了系统浪费时间为我们查找此驱动程序:

mmr = acmStreamOpen(&hstr,
had, //驱动器句柄
pwfPCM, //源格式
pwfDrv, //目标格式
NULL, //无过滤
NULL, //无回调
0, //实例化数据
ACM_STREAMOPENF_NONREALTIME);

  另外,计算用于压缩数据的缓冲区的尺寸有点难办,需要凭猜测。WAVEFORMATEX结构的nAvgBytesPerSec 域表示回放期间读取字节的平均速率。我们可使用它来估计存储压缩的wave需要多大空间。一 些驱动程序给出的数据确实是平均的,而不是最差场合下的值,因此我选择多增加50%的空间。 此方法在实践中虽然有些浪费但很有效:

DWORD dwDst2Bytes = pwfDrv->nAvgBytesPerSec * dwDst1Samples / pwfPCM->nSamplesPerSec;
dwDst2Bytes = dwDst2Bytes * 3 / 2;
unsigned char * pDst2Data = new unsigned char [dwDst2Bytes];

  其中,无符号字符型指针pDst2Data用于存储压缩的最终Wave音频数据,其大小经上式估算后存到dwDst2Bytes中。一旦转换完成,ACMSTREAMHEADER的结构的cbDstLengthUsed 域指出缓冲区实际用了多少字节。可以通过它来计算出压缩比:

double result= (double) dwSrcBytes / (double) strhdr2.cbDstLengthUsed;

  当源信号为8K采样、16bits PCM编码、单声道、长度为1秒的Wave音频信号, 驱动程序采用Windows 98自带的TrueSpeech 音频CODEC,它能实现大约10:1的压缩,这样高的压缩率还是比较另人满意的。

  小结

  本文以TrueSpeech CODEC为例对使用ACM音频压缩编程接口实现Wave音频压缩的过程作了介绍。如果有自已的压缩格式,也可创建并安装自已的CODEC,实现的方法与之基本类似。在理解了上述编程思想的前提下,对代码稍加改动就可编写出相 应的解压程序。本程序在Windows 2000 Professional下,由Microsoft Visual C++ 6.0编译通过。

上一页  1 2  

发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
相关内容焦点新闻
  • VC利用控件传递自定义struct解决方案
  • MFC程序员的WTL指南之包容ActiveX
  • 用递归算法解决VC中CEdit的一个Bug
  • 木马中如何编程实现远程关机(VC版)
  • VC下利用OpenGL构造自由型曲线曲面
  • 记深圳国际物流大会:供应链让亚洲联网世界
  • 《财经》200强评选出炉 海尔夺冠TCL第五
  • 零售业:借供应链管理走出连锁经营困局
  • 海信称西门子在讹诈 拟4月在德对簿公堂
  • 高清碟机国标即将出台 张宝全不再告信产部
  • 中国企业转向全球供应链:由被动到主动
  • 宝洁中国突破供应链信息瓶颈 力推行业标准
  • 保险业:冰冷的CRM系统让客户体验深度关怀
  • Advertisement