ImageVerifierCode 换一换
格式:DOCX , 页数:12 ,大小:22.97KB ,
资源ID:6762927      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-6762927.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(基于Visual C++60的声音文件操作文档格式.docx)为本站会员(b****4)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

基于Visual C++60的声音文件操作文档格式.docx

1、LIST等,指定块的标志ID;数据大小用来指定块的数据域大小,它的尺寸也为4个字符;数据用来描述具体的声音信号,它可以由若干个子块构成,一般情况下块与块是平行的,不能相互嵌套,但是有两种类型的块可以嵌套子块,他们是或标志的块,其中RIFF块的级别最高,它可以包括LIST块。另外,RIFF块和LIST块与其他块不同,RIFF块的数据总是以一个指定文件中数据存储格式的四个字符码(称为格式类型)开始,如WAVE文件有一个WAVE的格式类型。LIST块的数据总是以一个指定列表内容的4个字符码(称为列表类型)开始,例如扩展名为.AVI的视频文件就有一个strl的列表类型。RIFF和LIST的块结构如下:

2、RIFF/LIST标志符数据1大小数据1 格式/列表类型图二、RIFF/LIST块结构 WAVE文件是非常简单的一种RIFF文件,它的格式类型为。RIFF块包含两个子块,这两个子块的ID分别是fmt和data,其中子块由结构PCMWAVEFORMAT所组成,其子块的大小就是sizeofof(PCMWAVEFORMAT),数据组成就是PCMWAVEFORMAT结构中的数据。WAVE文件的结构如下图三所示:标志符(RIFF)数据大小格式类型()Sizeof(PCMWAVEFORMAT)PCMWAVEFORMAT声音数据大小声音数据图三、WAVE文件结构图 PCMWAVEFORMAT结构定义如下:T

3、ypedef structWAVEFORMAT wf;/波形格式;WORD wBitsPerSample;/WAVE文件的采样大小;PCMWAVEFORMAT;WAVEFORMAT结构定义如下:typedef structWORD wFormatag;/编码格式,包括WAVE_FORMAT_PCM,WAVEFORMAT_ADPCM等WORD nChannls;/声道数,单声道为1,双声道为2;DWORD nSamplesPerSec;/采样频率;DWORD nAvgBytesperSec;/每秒的数据量;WORD nBlockAlign;/块对齐;WAVEFORMAT;子块包含WAVE文件的数

4、字化波形声音数据,其存放格式依赖于子块中wFormatTag成员指定的格式种类,在多声道WAVE文件中,样本是交替出现的。如16bit的单声道WAVE文件和双声道WAVE文件的数据采样格式分别如图四所示:16位单声道:采样一采样二 低字节高字节高字节 16位双声道:采样一 左声道右声道图四、WAVE文件数据采样格式三、声音文件的声音数据的读取操作操作声音文件,也就是将WAVE文件打开,获取其中的声音数据,根据所需要的声音数据处理算法,进行相应的数学运算,然后将结果重新存储与WAVE格式的文件中去。可以使用CFILE类来实现读取操作,也可以使用另外一种方法,拿就是使用Windows提供的多媒体处

5、理函数(这些函数都以mmino打头)。这里就介绍如何使用这些相关的函数来获取声音文件的数据,至于如何进行处理,那要根据你的目的来选择不同的算法了。WAVE文件的操作流程如下:1调用mminoOpen函数来打开WAVE文件,获取HMMIO类型的文件句柄;2根据WAVE文件的结构,调用mmioRead、mmioWrite和mmioSeek函数实现文件的读、写和定位操作;3调用mmioClose函数来关闭WAVE文件。下面的函数代码就是根据WAVE文件的格式,实现了读取双声道立体声数据,但是在使用下面的代码过程中,注意需要在程序中链接Winmm.lib库,并且包含头文件Mmsystem.hBYTE

6、* GetData(Cstring *pString) /获取声音文件数据的函数,pString参数指向要打开的声音文件;if (pString=NULL)return NULL;HMMIO file1;/定义HMMIO文件句柄;file1=mmioOpen(LPSTR)pString,NULL,MMIO_READWRITE);/以读写模式打开所给的WAVE文件;if(file1=NULL)MessageBox(WAVE文件打开失败!);Return NULL;char style4;/定义一个四字节的数据,用来存放文件的类型;mmioSeek(file1,8,SEEK_SET);/定位到WA

7、VE文件的类型位置mmioRead(file1,style,4);if(style0!=W|style1!A|style2!V|style3!E)/判断该文件是否为文件格式该文件不是WAVE格式的文件!PCMWAVEFORMAT format; /定义PCMWAVEFORMAT结构对象,用来判断WAVE文件格式;mmioSeek(file1,20,SEEK_SET);/对打开的文件进行定位,此时指向WAVE文件的PCMWAVEFORMAT结构的数据;mmioRead(file1,(char*)&format,sizeof(PCMWAVEFORMAT);/获取该结构的数据;if(format.w

8、f.nChannels!=2)/判断是否是立体声声音;该声音文件不是双通道立体声文件mmioSeek(file1,24+sizeof(PCMWAVEFORMAT),SEEK_SET);/获取WAVE文件的声音数据的大小;long size;size,4);BYTE *pData;pData=(BYTE*)new charsize;/根据数据的大小申请缓冲区;mmioSeek(file1,28+sizeof(PCMWAVEFORMAT),SEEK_SET);/对文件重新定位;mmioRead(file1,(char*)pData,size);/读取声音数据;mmioClose(file1, MM

9、IO_FHOPEN);/关闭WAVE文件;return pData; 四、使用MCI方法操作声音文件WAVE声音文件一个最基本的操作就是将文件中的声音数据播放出来,用Windows提供的API函数BOOL sndPlaySound(LPCSTR lpszSound, UINT fuSound)可以实现小型WAV文件的播放,其中参数lpszSound 为所要播放的声音文件,fuSound为播放声音文件时所用的标志位。例如实现Sound.wav 文件的异步播放,只要调用函数sndPlaySound(c:windowsSound.wav,SND_ASYNC)就可以了,由此可以看到sndPlaySou

10、nd函数使用是很简单的。但是当WAVE文件大于100K时,这时候系统无法将声音数据一次性的读入内存,sndPlaySound函数就不能进行播放了。为了解决这个问题,你的一个选择就是用MCI方法来操作声音文件了。在使用MCI方法之前,首先需要在你开发的项目设置Project-Setting-Link-Object/library modules中加入winmm.lib。并在头文件中包括mmsystem.h头文件。MicroSoft API提供了MCI(The Media Control Interface)的方法mciSendCommand()和mciSendString()来完成WAVE文件的

11、播放,这里仅介绍mciSendCommand()函数的使用。原型:DWORD mciSendCommand(UINT wDeviceID,UINT wMessage,DWORD dwParam1,DWORD dwParam2);参数:wDeviceID:接受消息的设备ID;Message:MCI命令消息;wParam1:命令的标志位;wParam2:所使用参数块的指针返值:调用成功,返回零;否则,返回双字中的低字存放有错误信息。在使用MCI播放声音文件时,首先要打开音频设备,为此要定义MCI_OPEN_PARMS变量 OpenParms,并设置该结构的相应分量:OpenParms.lpstrD

12、eviceType = (LPCSTR) MCI_DEVTYPE_WAVEFORM_AUDIO;/WAVE类型OpenParms.lpstrElementName = (LPCSTR) Filename;/打开的声音文件名;OpenParms.wDeviceID = 0;/打开的音频设备的IDmciSendCommand (NULL, MCI_OPEN,MCI_WAIT | MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID | MCI_OPEN_ELEMENT, (DWORD)(LPVOID) &OpenParms)函数调用发送MCI_OPEN命令后,返回的参数 OpenPar

13、ms中成员变量的wDeviceID指明打开了哪个设备。需要关闭音频设备时只要调用mciSendCommand (m_wDeviceID, MCI_CLOSE, NULL, NULL)就可以了。播放WAVE文件时,需要定义MCI_PLAY_PARMS变量PlayParms,对该变量进行如下设置:PlayParms.dwFrom = 0,这是为了指定从什么地方(时间)播放WAVE文件,设置好以后,调用函数mciSendCommand (m_wDeviceID, MCI_PLAY,MCI_FROM, (DWORD)(LPVOID)&PlayParms);就实现了WAVE声音文件的播放。另外,调用mc

14、iSendCommand (m_wDeviceID, MCI_PAUSE, 0,(DWORD)(LPVOID)&PlayParms)实现了暂停功能。调用mciSendCommand (m_wDeviceID, MCI_STOP, NULL, NULL)实现停止功能等,可以看出,这些不同的功能实现都是依靠参数Message取不同的值来实现的。 不同的Message和dwParam1、dwParam2的组合还可以实现文件的 跳跃功能。如下面的代码实现了跳转到WAVE文件末端的操作:mciSendCommand (m_wDeviceID, MCI_SEEK, MCI_SEEK_TO_END, NUL

15、L)。下面的代码实现了WAVE声音文件的播放:void CTest1View:OnMciPlayWave() / TODO: Add your command handler code hereMCI_OPEN_PARMS mciOpenParms;MCI_PLAY_PARMS PlayParms;mciOpenParms.dwCallback=0;mciOpenParms.lpstrElementName=d:chimes.wav;mciOpenParms.wDeviceID=0;mciOpenParms.lpstrDeviceType=waveaudiomciOpenParms.lpstr

16、Alias= PlayParms.dwCallback=0;PlayParms.dwTo=0;PlayParms.dwFrom=0;mciSendCommand(NULL,MCI_OPEN,MCI_OPEN_TYPE|MCI_OPEN_ELEMENT,(DWORD)(LPVOID)&mciOpenParms);/打开音频设备;mciSendCommand(mciOpenParms.wDeviceID,MCI_PLAY,MCI_WAIT,(DWORD)(LPVOID)&PlayParms);/播放WAVE声音文件;mciSendCommand(mciOpenParms.wDeviceID,MCI

17、_CLOSE,NULL,NULL);/关闭音频设备;五、DirectSound操作WAVE文件的方法MCI虽然调用简单,功能强大,可以满足声音文件处理的基本需要,但是MCI也有它的缺点,那就是它一次只能播放一个WAVE文件,有时在实际应用中,为了实现混音效果,需要同时播放两个或两个以上的WAVE文件时,就需要使用微软DirectX技术中的DirectSound了,该技术直接操作底层声卡设备,可以实现八个以上WAV文件的同时播放。实现DirectSound需要以下几个步骤:1.创建及初始化DirectSound;2.设定应用程序的声音设备优先级别方式,一般为DSSCL_NORMAL;2. 将WA

18、V文件读入内存,找到格式块、数据块位置及数据长度;3.创建声音缓冲区;4.载入声音数据;5.播放及停止:下面的函数利用DirectSound技术实现了一个WAVE声音文件的播放(注意项目设置中要包含dsound.lib、dxguid.lib的内容),代码和注释如下:void CPlaysoundView:OnPlaySound() LPVOID lpPtr1;/指针1;LPVOID lpPtr2;/指针2;HRESULT hResult;DWORD dwLen1,dwLen2;LPVOID m_pMemory;/内存指针;LPWAVEFORMATEX m_pFormat;/LPWAVEFORM

19、ATEX变量;LPVOID m_pData;/指向语音数据块的指针;DWORD m_dwSize;/WAVE文件中语音数据块的长度;CFile File;/Cfile对象;DWORD dwSize;/存放WAV文件长度;/打开sound.wav文件;if (!File.Open (/sound.wav, CFile:modeRead |CFile:shareDenyNone)return ;dwSize = File.Seek (0, CFile:end);/获取WAVE文件长度;File.Seek (0, CFile:begin);/定位到打开的WAVE文件头;/为m_pMemory分配内存

20、,类型为LPVOID,用来存放WAVE文件中的数据;m_pMemory = GlobalAlloc (GMEM_FIXED, dwSize);if (File.ReadHuge (m_pMemory, dwSize) != dwSize)/读取文件中的数据;File.Close ();LPDWORD pdw,pdwEnd;DWORD dwRiff,dwType, dwLength;if (m_pFormat) /格式块指针m_pFormat = NULL;if (m_pData) /数据块指针,类型:LPBYTEm_pData = NULL;if (m_dwSize) /数据长度,类型:DWO

21、RDm_dwSize = 0;pdw = (DWORD *) m_pMemory;dwRiff = *pdw+;dwLength = *pdw+;dwType = *pdw+;if (dwRiff != mmioFOURCC (R, IF)/判断文件头是否为字符;if (dwType !/判断文件格式是否为;/寻找格式块,数据块位置及数据长度pdwEnd = (DWORD *)(BYTE *) m_pMemory+dwLength -4);bool m_bend=false;while (pdw pdwEnd)&(!m_bend)/pdw文件没有指到文件末尾并且没有获取到声音数据时继续;swi

22、tch (dwType)case mmioFOURCC(fmt ):/如果为标志;m_pFormat)/获取LPWAVEFORMATEX结构数据;if (dwLength SetCooperativeLevel(this-GetSafeHwnd(), DSSCL_NORMAL);/设置声音设备优先级别为NORMAL/创建声音数据缓冲;LPDIRECTSOUNDBUFFER m_pDSoundBuffer;if (m_lpDirectSound-CreateSoundBuffer (&BufferDesc, &m_pDSoundBuffer, 0) = DS_OK)/载入声音数据,这里使用两个指

23、针lpPtr1,lpPtr2来指向DirectSoundBuffer缓冲区的数据,这是为了处理大型WAVE文件而设计的。dwLen1,dwLen2分别对应这两个指针所指向的缓冲区的长度。hResult=m_pDSoundBuffer-Lock(0,m_dwSize,&lpPtr1,&dwLen1,&lpPtr2,&dwLen2,0);if (hResult = DS_OK)memcpy (lpPtr1, m_pData, dwLen1);if(dwLen20) BYTE *m_pData1=(BYTE*)m_pData+dwLen1;m_pData=(void *)m_pData1;memcpy(lpPtr2,m_pData, dwLen2);m_pDSoundBuffer-Unlock (lpPtr1, dwLen1, lpPtr2, dwLen2);DWORD dwFlags = 0;Play (0, 0,

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2