



全文预览已结束
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
VC调用ACM音频压缩编程接口的方法王 琰 音频和视频数据是大多数多媒体应用程序向用户提供信息的主要方式,这些数据一般具 有较高的采样速率,如果不经过压缩的话,保存它们需要消耗大量的存贮空间,在网络上进行传输的效率也很低,因此音频视频数字压缩编码在多媒体技术中占有很重要的地位。就音频数据而言,目前常用的压缩方法有很多种,不同的方法具有不同的压缩比和还原音质,编码的格式和算法也各不相同,其中某些压缩算法相当复杂,普通程序不可能去实现其编解码算法。所幸的是,与Windows 3.x相比,Windows 95/NT 4.0为多媒体应用程序提供了更强大的支持,引入了ACM(Audio Compression Manager,音频压缩管理器)和VCM(Video Compression Manager,视频压缩管理器),它们负责管理系统中所有音频和视频编解码器(Coder-Decoder,简称CODEC,是实现音频视频数据编解码的驱动程序),应用程序可以通过ACM 或VCM提供的编程接口调用这些系统中现成的编解码器来实现音频或视频数据的压缩和解压缩。95/NT 4.0系统自带的音频CODECs支持一些早期的音频数据压缩标准,如ADPCM等,Internet Explorer 4.0等应用程序包含的音频CODECs支持一些比较新的压缩标准,如MPEG Layer 3等。在控制面板的多媒体组件中选择“高级”,打开“音频压缩的编码解码器”,就可列出系统中安装的所有音频CODECs。本文所要介绍的就是ACM音频压缩接口的编程方法,所用编程工具为VC+ 5.0。 获 取CODECs 的 信 息- ACM的API函数定义在头文件msacm.h中,除此之外,对ACM编程还必须包含头文件mmsystem.h,mmreg.h,这两个头文件定义了多媒体编程中最基本的常量和数据结构。为了避免有些高版本ACM才提供的函数和功能在较低版本的ACM中上不可用,程序中应调用acmGetVersion函数查询用户机器中ACM的版本信息。 - 前面提到,在控制面板中可以查看系统中CODECs的信息。 而在应用程序中也常常需要知道某种音频CODECs是否存在,并获取其编解码参数等信息,这一点可以通过调用下面两个函数来实现。 - MMRESULT mmr=acmMetrics(NULL, ACM_METRIC_COUNT_CODECS, &dwCodecs); - mmr = acmDriverEnum(CodecsEnumProc, 0, 0); - acmMetrics()函数可以获取许多ACM对象的有用信息,例如向其中传递ACM_METRIC_COUNT_CODECS可以查询系统中安装的音频CODECs总数。函数acmDriverEnum()的功能是枚举所有的音频CODECs,在acmDriverEnum()的参数中指定回调函数CodecsEnumProc()可以进一步查询每个CODEC的信息。Windows编程中经常要用到回调函数,下面是枚举音频CODECs的一个回调函数的示例。 BOOL CALLBACK CodecsEnumProc(HACMDRIVERID hadid, DWORD dwInstance, DWORD fdwSupport) DWORD dwSize = 0;if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC)printf(多格式转换n);ACMDRIVERDETAILS add;acmdd.cbStruct = sizeof(acmdd);MMRESULT mmr = acmDriverDetails(hadid, &acmdd, 0);if (mmr) error_msg(mmr);else printf( 全称:%sn, acmdd.szLongName); printf( 描述: %sn, acmdd.szFeatures);HACMDRIVER had = NULL;mmr = acmDriverOpen(&had, hadid, 0);/打开驱动程序if (mmr) error_msg(mmr);else mmr = acmMetrics(had, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize);WAVEFORMATEX* pwf = (WAVEFORMATEX*) malloc(dwSize);memset(pwf, 0, dwSize);pwf-cbSize = LOWORD(dwSize) - sizeof(WAVEFORMATEX);pwf-wFormatTag = WAVE_FORMAT_UNKNOWN;ACMFORMATDETAILS fd;memset(&fd, 0, sizeof(fd);fd.cbStruct = sizeof(fd);fd.pwfx = pwf;fd.cbwfx = dwSize;fd.dwFormatTag = WAVE_FORMAT_UNKNOWN;mmr = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0);if (mmr)error_msg(mmr);free(pwf);acmDriverClose(had, 0);return TRUE; - CodecsEnumProc()共有三个参数。第一个参数是驱动程序的ID值;第二个参数是实例数据,本文例子中未使用;第三个参数描述该驱动程序所支持的功能,它由一组标识进行或运算构成,例如,如果设置了标识ACMDRIVERDETAILS_SUPPORTF_CODEC,则说明该驱动程序可以将一种编码格式的音频信号转换成另一种编码格式。通过acmDriverDetails()函数可以获得对该驱动程序进一步的信息,如CODEC的名称、简单描述等。以上信息实际上是由ACM收集,并保存在ACM内部,所以查询以上信息时并未真正将驱动程序加载至内存。而要获得一种驱动程序支持的音频格式信息,则必须将驱动程序加载至内存,这是通过acmDriverOpen()完成的,在退出CodecsEnumProc()前,还要用acmDriverClose()来关闭已打开的驱动程序。在使用音频格式枚举函数前,需要先分配一块缓冲区存置格式信息,缓冲区的大小可通过调用acmMetrics()查询ACM_METRIC_MAX_SIZE_FORMAT获得,格式信息中的音频格式标识设为WAVE_FORMAT_UNKNOWN。在音频格式枚举中同样使用了回调函数,此回调函数只是列出了该音频格式的名称和标识值。 BOOL CALLBACK FormatEnumProc(HACMDRIVERID hadid, LPACMFORMATDETAILSpafd, DWORD dwInstance, DWORD fdwSupport) printf(%4.4lXH, %sn, pafd- dwFormatTag, pafd- szFormat);return TRUE; - 上面介绍了浏览系统中所有音频CODECs及每种CODEC所支持的音频格式的方法,某些典型的应用程序可能需要列出系统中所有可以选用的CODECs,并由用户来选择使用哪一种CODEC进行压缩,此时就需要利用上面的编程方法来获取CODECs的信息。音频数据的压缩- 下面说明使用某一CODEC实现音频压缩的过程,读者朋友只需稍加改动就可编写出相应的解压程序。假设源信号为8K采样、16bits PCM编码、单声道、长度为1秒的音频信号。驱动程序采用Windows 95自带的TrueSpeech音频CODEC,它能实现大约10:1的压缩。在此例中,TrueSpeech CODEC支持从源音频格式到目标格式的转换,而在实际应用中,可能某种CODEC不支持直接将源音频格式转换成目标格式,这时可以采取两步转换法,即先将源格式转换成一种中间格式,再将此中间格式转换成目标格式,因为线性PCM编码最为简单,且为绝大多数CODEC所支持,所以一般中间格式都选为线性PCM格式的一种。 - 在进行压缩之前首先需要确定TrueSpeech驱动程序的ID值。为此需要用到acmDriverEnum()函数,对枚举到的每一个驱动程序,由acmDriverEnum()指定的回调函数将检查其支持的所有音频格式,若其中包括wFormatTag值为WAVE_FORMAT_DSPGROUP_TRUESPEECH的音频格式,则此驱动程序就是要寻找的TrueSpeech CODEC,它所支持的第一种WAVE_FORMAT_DSPGROUP_TRUESPEECH音频格式即为目标音频压缩格式。查询所需的CODEC及其支持的音频格式的方法见前一小 节的介绍。- 根据查询的结果,设hadID为TrueSpeech CODEC的ID值,pwfDrv为指向目标WAVEFORMATEX结构的指针,接下来利用获得的ID值打开相应的驱动程序。HACMDRIVER had = NULL;mmr = acmDriverOpen(&had, hadID, 0);if(mmr) printf( 打开驱动程序失败n); exit(1);- 压缩和解压缩一样,都是将音频信号从一种音频格式转换成另一种格式,要完成这一过程,首先要打开转换流。在用acmStreamOpen打开转换流时,我们指定了ACM_STREAMOPENF_NONREALTIME 标 志, 它表示转换无需实时进行。因为很多压缩算法的计算量是相当大的,实时完成几乎是不可能的,例如在本例中,如果不指定此标志,TrueSpeech CODEC就会返回“无法完成”的错误。HACMSTREAM hstr = NULL;DWORD dwSrcBytes = dwSrcSamples * wfSrc.wBitsPerSample / 8;mmr = acmStreamOpen(&hstr,had, /驱动程序句柄pwfSrc, /指向源音频格式的指针pwfDrv, /指向目标音频格式的指针NULL, /无过滤器NULL, /无回调函数0,ACM_STREAMOPENF_NONREALTIME);- 在真正进行转换之前,还必须准备转换流的信息头。下面一段代码中,先利用源数据的大小以及目标格式的平均数据率估算目标数据的缓存区大小,然后调用acmStreamPrepareHeader为转换准备信息头。 - DWORD dwDstBytes=pwfDrv-nAvgBytesPerSec*dwSrcSamples/wfSrc.nSamplesPerSec; - dwDstBytes = dwDstBytes*3/2; / 计算压缩后音频数据大小,并依此适当增加输出缓冲区的大小。 BYTE* pDstData = new BYTE dwDstBytes;ACMSTREAMHEADER shdr;memset(&strhdr, 0, sizeof(shdr);shdr.cbStruct = sizeof(shdr);shdr.pbSrc = pSrcData; /源音频数据区shdr.cbSrcLength = dwSrcBytes;shdr.pbDst = pDstData; /压缩后音频数据缓冲区shdr.cbDstLength = dwDstBytes;mmr = acmStreamPrepareHeader(hstr, &shdr, 0); - 语音数据真正的压缩过程是由函数acmStreamConvert()完成的。在调用acmStreamConvert()时可以指定回调函数,以便在转换过程中显示进度信息等。在本例中,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年国际贸易专员职业素质评估考试试题及答案解析
- 2025年村级物流安全员笔试冲刺题
- 课件专业评审表评价
- 课件与乐器的融合
- 2025年建筑设计师专业面试模拟题与案例分析
- 2025年竞聘笔试县公司电力电商解析题
- 2025年香材鉴别师初级笔试模拟试卷
- 2025年供销社考试模拟试卷及答案
- 应用写作孙秀秋教学课件
- 2025年安全生产法规考试十套题及答案
- 2025-2026秋学期学校主题升旗仪式安排表+主题班会安排表
- 提高住院病历完成及时性持续改进(PDCA)
- 《矿业权评估指南》
- 广东省地质灾害危险性评估报告
- 整套教学课件《现代心理与教育统计学》研究生
- 手机拍照技巧大全课件
- RBA(原EICC)ERT应急准备与响应培训课件
- 工业建筑钢筋工程监理实施细则
- 河西走廊课件
- 2023版北京协和医院重症医学科诊疗常规
- 人工膝关节置换术护理查房
评论
0/150
提交评论