vc中的音频

 VC++是微软公司开发的一个IDE(集成开发环境),换句话说,就是使用c++的一个开发平台.有些软件就是这个编出来的...另外还有VB,VF.只是使用不同语言...但是,

  vc++是Windows平台上的C++编程环境,学习VC要了解很多Windows平台的特性并且还要掌握MFCATLCOM等的知识,难度比较大。Windows下编程需要了解Windows的消息机制以及回调(callback)函数的原理;MFC是Win32API的包装类,需要理解文档视图类的结构,窗口类的结构,消息流向等等;COM是代码共享的二进制标准,需要掌握其基本原理等等。

c++的安装

  作为visual studio的一个组件,可以通过安装visual studio来获得

  VC作为一个主流的开发平台一直深受编程爱好者的喜爱,但是很多人却对它的入门感到难于上青天,究其原因主要是大家对他错误的认识造成的,严格的来说VC++不是门语言,虽然它和C++之间有密切的关系,如果形象点比喻的话,可以把C++看作为一种“工业标准”,而VC++则是某种操作系统平台下的“厂商标准”,而“厂商标准”是在遵循“工业标准”的前提下扩展而来的。

  VC++应用程序的开发主要有两种模式,一种是WIN API方式,另一种则是MFC方式,传统的WIN API开发方式比较繁琐,而MFC则是对WIN API再次封装,所以MFC相对于WIN API开发更具备效率优势,但为了对WINDOWS开发有一个较为全面细致的认识,笔者在这里还是以讲解WIN API的相关内容为主线。

  话说到这里可能更多人关心的是学习VC++需要具备什么条件,为什么对于这扇门屡攻不破呢?

  要想学习好VC必须具备良好的C/C++的基础,必要的英语阅读能力也是必不可少的,因为大量的技术文档多以英文形式发布。

  VC基于C,C++语言,主要由是MFC组成,是与系统联系非常紧密的编程工具,它兼有高级,和低级语言的双重性,功能强大,灵活,执行效率高,几乎可说VC在 Windows平台无所不能。 最大缺点是开发效率不高。

  VC适用范围

  1、 VC主要是针对Windows系统,适合一些系统级的开发,可以方便实现一些底层 的调用。在VC里边嵌入汇编语言很简单。

  2、 VC主要用在驱动程序开发

  3、 VC执行效率高,当对系统性能要求很高的时候,可用VC开发。

  4、 VC主要适用于游戏开发

  5、 VC多用于单片机,工业控制等软件开发,如直接对I/O地址操作,就要用C++。

  6、 VC适用开发高效,短小,轻量级的COM组件,DLL。比如WEB上的控件。

  7、 VC可以开发优秀的基于通信的程序。

  8、 VC可以开发高效灵活的文件操作程序。

  9、 VC可以开发灵活高效的数据库操作程序。

  10、 VC是编CAD软件的唯一选择!!!包括AUTOCAD,UG的二次开发。

  11、VC在多线程、网络通信、分布应用方面,VC++有不可比拟的优势。

VC++中播放声音的方法

  声音是多媒体的一个重要组成部分,在应用程序中加入声音可以使界面更友好。在VC++中可以根据不同的应用要求,用不同的方法实现声音的播放。

  一.播放声音文件的简单方法

  在VC++ 中的多媒体动态连接库中提供了一组与音频设备有关的函数。利用这些函数可以方便地播放声音。最简单的播放声音方法就是直接调用VC++中提供的声音播放函数BOOL sndPlaySound ( LPCSTR lpszSound,UINT fuSound ); 或BOOL PlaySound( LPCSTR lpszSound, HMODULE hmod, DWORD fuSound );其中参数lpszSound是需要播放声音的.WAV文件的路径和文件名, hmod在这里为NULL,fuSound是播放声音的标志,详细说明请参考VC++中的帮助。 例如播放C:soundmusic.wav可以用sndPlaySound ("c:/sound/music.wav",SND_ASYNC);或PlaySound("c:/sound/music.wav",NULL, SND_ASYNC|SND_NODEFAULT );如果没有找到music.wav文件,第一种格式将播放系统默认的声音,第二种格式不会播放系统默认的声音。

  二.将声音文件加入到程序中

   在VC++的程序设计中,可以利用各种标准的资源,如位图,菜单,对话框等。同时VC++也允许用户自定义资源,因此我们可以将声音文件作为用户自定义资源加入程序资源文件中,经过编译连接生成EXE文件,实现无.WAV文件的声音播放。

  要实现作为资源的声音文件的播放,首先要在资源管理器中加入待播放的声音文件(实现过程并不复杂,这里不在叙述)。假设生成的声音文件资源标识符为IDR_WAVE1。在播放时只需要调用下面的语句:

  PlaySound(MAKEINTRESOURCE(IDR_WAVE1),AfxGetResourceHandle(), SND_ASYNC|SND_RESOURCE|SND_NODEFAULT|SND_LOOP);

  其中MAKEINTRESOURCE()宏将整数资源标识符转变为字符串,AfxGetResourceHandle()函数返回包含资源的模块句柄,

  SND_RESOURCE是必须的标志。

  作为资源的声音文件的第二种播放方法是把资源读入内存后作为内存数据播放。具体步骤入下:

  1.获得包含资源的模块句柄:

  HMODULE hmod=AfxGetResourceHandle();

  2.检索资源块信息:

  HRSRC hSndResource=FindResource(hmod,MAKEINTRESOURCE(IDR_WAVE1),_T("WAVE"));

  3. 装载资源数据并加锁:

  HGLOBAL hGlobalMem=LoadResource(hmod,hSndResource);

  LPCTSTR lpMemSound=(LPCSTR)LockResource(hGlobalMem);

  4.播放声音文件:

  sndPlaySound(lpMemSound,SND_MEMORY));

  5.释放资源句柄:

  FreeResource(hGlobalMem);

  三.播放声音文件的高级方法

   在VC++中提供了一组对音频设备及多媒体文件直接进行操作的函数。利用这些函数可以灵活地对声音文件进行各种处理。

  首先介绍几个要用到的数据结构。WAVEFORMATEX结构定义了WAVE音频数据文件的格式。WAVEHDR结构定义了波形音频缓冲区。读出的数据首先要填充此缓冲区才能送音频设备播放。WAVEOUTCAPS结构描述了音频设备的性能。MMCKINFO结构包含了RIFF文件中一个块的信息。详细的说明请参考VC++中的帮助。

  下面给出程序流程简图及程序源代码清单,在VC++环境下可直接使用:

  源程序清单如下:

  LPSTR szFileName;//声音文件名

  MMCKINFO mmckinfoParent;

  MMCKINFO mmckinfoSubChunk;

  DWORD dwFmtSize;

  HMMIO m_hmmio;//音频文件句柄

  DWORD m_WaveLong;

  HPSTR lpData;//音频数据

  HANDLE m_hData;

  HANDLE m_hFormat;

  WAVEFORMATEX * lpFormat;

  DWORD m_dwDataOffset;

  DWORD m_dwDataSize;

  WAVEHDR pWaveOutHdr;

  WAVEOUTCAPS pwoc;

  HWAVEOUT hWaveOut;

  //打开波形文件

  if(!(m_hmmio=mmioOpen(szFileName,NULL,MMIO_READ|MMIO_ALLOCBUF)))

  {

  //File open Error

  Error("Failed to open the file.");//错误处理函数

  return false;

  }

  //检查打开文件是否是声音文件

  mmckinfoParent.fccType =mmioFOURCC(’W’,’A’,’V’,’E’);

  if(mmioDescend(m_hmmio,(LPMMCKINFO)&mmckinfoParent,NULL,MMIO_FINDRIFF))

  {

  //NOT WAVE FILE AND QUIT

  }

  //寻找 ’fmt’ 块

  mmckinfoSubChunk.ckid =mmioFOURCC(’f’,’m’,’t’,’ ’);

  if(mmioDescend(m_hmmio,&mmckinfoSubChunk,&mmckinfoParent,MMIO_FINDCHUNK))

  {

  //Can’t find ’fmt’ chunk

  }

  //获得 ’fmt ’块的大小,申请内存

  dwFmtSize=mmckinfoSubChunk.cksize ;

  m_hFormat=LocalAlloc(LMEM_MOVEABLE,LOWORD(dwFmtSize));

  if(!m_hFormat)

  {

  //failed alloc memory

  }

  lpFormat=(WAVEFORMATEX*)LocalLock(m_hFormat);

  if(!lpFormat)

  {

  //failed to lock the memory

  }

  if((unsigned long)mmioRead(m_hmmio,(HPSTR)lpFormat,dwFmtSize)!=dwFmtSize)

  {

  //failed to read format chunk

  }

  //离开 fmt 块

  mmioAscend(m_hmmio,&mmckinfoSubChunk,0);

  //寻找 ’data’ 块

  mmckinfoSubChunk.ckid=mmioFOURCC(’d’,’a’,’t’,’a’);

  if(mmioDescend(m_hmmio,&mmckinfoSubChunk,&mmckinfoParent,MMIO_FINDCHUNK))

  {

  //Can’t find ’data’ chunk

  }

  //获得 ’data’块的大小

  m_dwDataSize=mmckinfoSubChunk.cksize ;

  m_dwDataOffset =mmckinfoSubChunk.dwDataOffset ;

  if(m_dwDataSize==0L)

  {

  //no data in the ’data’ chunk

  }

  //为音频数据分配内存

  lpData=new char[m_dwDataSize];

  if(!lpData)

  {

  //faile

  }

  if(mmioSeek(m_hmmio,SoundOffset,SEEK_SET)<0)

  {

  //Failed to read the data chunk

  }

  m_WaveLong=mmioRead(m_hmmio,lpData,SoundLong);

  if(m_WaveLong<0)

  {

  //Failed to read the data chunk

  }

  //检查音频设备,返回音频输出设备的性能

  if(waveOutGetDeVCaps(WAVE_MAPPER,&pwoc,sizeof(WAVEOUTCAPS))!=0)

  {

  //Unable to allocate or lock memory

  }

  //检查音频输出设备是否能播放指定的音频文件

  if(waveOutOpen(&hWaveOut,DevsNum,lpFormat,NULL,NULL,CALLBACK_NULL)!=0)

  {

  //Failed to OPEN the wave out devices

  }

  //准备待播放的数据

  pWaveOutHdr.lpData =(HPSTR)lpData;

  pWaveOutHdr.dwBufferLength =m_WaveLong;

  pWaveOutHdr.dwFlags =0;

  if(waveOutPrepareHeader(hWaveOut,&pWaveOutHdr,sizeof(WAVEHDR))!=0)

  {

  //Failed to prepare the wave data buffer

  }

  //播放音频数据文件

  if(waveOutWrite(hWaveOut,&pWaveOutHdr,sizeof(WAVEHDR))!=0)

  {

  //Failed to write the wave data buffer

  }

  //关闭音频输出设备,释放内存

  waveOutReset(hWaveOut);

  waveOutClose(hWaveOut);

  LocalUnlock(m_hFormat);

  LocalFree(m_hFormat);

  delete [] lpData;

  说明:1)以上使用的音频设备和声音文件操作函数的声明包含在mmsystem.h头文件中,因此在程序中必须用#include "mmsystem.h"语句加入头文件。同时在编译时要加入动态连接导入库winmm.lib,具体实现方法是从Developer Studio的Project菜单中选择Settings,然后在Link选项卡上的Object/Library Modules控制中加入winmm.lib。2)在pWaveOutHdr.lpData中指定不同的数据,可以播放音频数据文件中任意指定位置的声音。3) 以上程序均在VC++6.0中调试通过,在文中省略了对错误及异常情况的处理,在实际应用中必须加入。

  四.结论

  在VC++中可以根据应用需要采用不同的方法播放声音文件。简单应用可以直接调用声音播放函数。第二种方法可以把声音作为资源加入可执行文件中。如果在播放之前要对声音数据进行处理,可用第三种方法。

  五.Visual C++.NET

  随着NET的时代来临,VC++也如同VB一样,脱胎换骨到VC++.NET

----------------------------------------------------------------------------------------------------------转自新浪博客

录音程序,可在DEC++vc++6.0编译环境下成功运行 部分代码: int main() { creat_file(); //新建文件,原文件数据被删除 RecordWave(); //录音函数 simplest_pcm16le_to_wave("NocturneNo2inEflat_44.1k_s16le.pcm", 1, 44100, "output_nocture.wav"); //将二进制录音信息从内存提取,并生成 wav 文件 测控 1602 DEV C ++ 环境下 控制台应用程序 善解人意 成员:王帅、赵永玻、侯雅茹 3 return 0; } void RecordWave() { int count = waveInGetNumDevs(); //检测录音设备 printf("\n 音频输入数量:%d\n", count); WAVEINCAPS waveIncaps; MMRESULT mmResult = waveInGetDevCaps(0, &waveIncaps;, sizeof(WAVEINCAPS)); printf("\n 音频输入设备:%s\n", waveIncaps.szPname); if (MMSYSERR_NOERROR == mmResult) { //HWAVEIN phwi; WAVEFORMATEX pwfx; //录音格式指针 WaveInitFormat (&pwfx;, //波形声音的格式,单声道双声道使用 WAVE_FORMAT_PCM.当包含在 WAVEFORMATEXTENSIBLE 结构时,使用 WAVE_FORMAT_EXTENSIBLE 1, //声道数量 44100, //采样率 16 // 采样位数 ); printf("\n 正在打开音频输入设备"); printf("\n 采样参数:声道 44.1kHz 16bit\n"); mmResult = waveInOpen( &phwi;, WAVE_MAPPER, &pwfx;, (DWORD)(MicCallback), NULL, CALLBACK_FUNCTION );//3 if (MMSYSERR_NOERROR == mmResult) { //WAVEHDR pwh1; char buffer1[10240]; pwh1.lpData = buffer1; pwh1.dwBufferLength = 10240; pwh1.dwUser = 1; pwh1.dwFlags = 0; 测控 1602 DEV C ++ 环境下 控制台应用程序 善解人意 成员:王帅、赵永玻、侯雅茹 4 mmResult = waveInPrepareHeader(phwi, &pwh1;, sizeof(WAVEHDR));//为波形输 入设备准备缓冲区 printf("\n 准备缓冲区 1"); //WAVEHDR pwh2; char buffer2[10240]; pwh2.lpData = buffer2; pwh2.dwBufferLength = 10240; pwh2.dwUser = 2; pwh2.dwFlags = 0; mmResult = waveInPrepareHeader(phwi, &pwh2;, sizeof(WAVEHDR));//为波形输 入设备准备缓冲区 printf("\n 准备缓冲区 2\n"); // WAVEHDR pwh3; char buffer3[10240]; pwh3.lpData = buffer3; pwh3.dwBufferLength = 10240; pwh3.dwUser = 3; pwh3.dwFlags = 0; mmResult = waveInPrepareHeader(phwi, &pwh3;, sizeof(WAVEHDR));//为波形输 入设备准备缓冲区 printf("准备缓冲区 3\n"); if (MMSYSERR_NOERROR == mmResult) { mmResult = waveInAddBuffer(phwi, &pwh1;, sizeof(WAVEHDR));//给输入设 备增加一个缓存 printf("\n 将缓冲区 1 加入音频输入设备"); mmResult = waveInAddBuffer(phwi, &pwh2;, sizeof(WAVEHDR));//给输入设 备增加一个缓存 printf("\n 将缓冲区 2 加入音频输入设备\n"); mmResult = waveInAddBuffer(phwi, &pwh3;, sizeof(WAVEHDR));//给输入设 备增加一个缓存 printf("将缓冲区 3 加入音频输入设备\n");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值