VC++播放音频文件和音频数据的方法

时间:2021-03-28 19:44:54

在程序中,很有可能会涉及到播放一些音频文件(比如:.wav文件)和音频数据,这个问题怎么解决呢?VC++中想要播放一个音频文件(.wav)是很容易的,只要调用WIndows API函数PlaySound()就可以了,但是,如果您想播放自己在程序中产生的一段音频数据,就不是那么简单了,需要利用WIndows wave I/O API的几个函数来实现。

下面结合实例来说明(完整实例可在我的CSDN资源中下载,该例子利用WIndows wave I/O API 函数,实现了播放自定义的一段音频数据(通过sin()函数产生);并且使用了PlaySound()函数播放“250.wav”文件):

 

  1. //需包含的头文件 
  2. #include <MMSystem.h> 
  3. #pragma comment(lib,"winmm.lib") 
  4. //PlaySound()函数和其他WIndows wave I/O API 函数的使用 
  5. #include "math.h"//sin()函数的使用 

 

1.播放文件:

  1. CString path; 
  2. path.Format("%s250.wav",g_BasePath); 
  3. //g_BasePath的取值不用多说,前面已详细介绍了。 
  4. PlaySound(_T(path),0,SND_FILENAME|SND_ASYNC); 

2.播放数据:

(1)确定音频数据的格式及内容:

 

  1. int rate=1000;  //刺激率 
  2. int sampleRate = 44100;  //采样率 
  3. constint NUMPTS = (int) (44100 * 0.5);   // 0.5s 
  4. shortint waveOut[NUMPTS];//音频数据 
  5.  
  6. //内容 
  7. for (int i=0;i<NUMPTS;i++) 
  8.     waveOut[i] = (shortint)ceil(sin(2*3.1415926*rate*i/sampleRate)*20000); 
  9. //格式 
  10. WAVEFORMATEX pFormat; 
  11. pFormat.wFormatTag=WAVE_FORMAT_PCM;  
  12. //simple,uncompressed format 
  13. pFormat.nChannels=1;//1=mono, 2=stereo 
  14. pFormat.nSamplesPerSec=sampleRate; // 44100 
  15. pFormat.nAvgBytesPerSec=sampleRate*2; 
  16. // = nSamplesPerSec * n.Channels * wBitsPerSample/8 
  17. pFormat.nBlockAlign=2; // = n.Channels * wBitsPerSample/8 
  18. pFormat.wBitsPerSample=16; 
  19. //16 for high quality, 8 for telephone-grade 
  20. pFormat.cbSize=0; 

(2)打开一个给定的波形音频输出装置:

 

 

  1. HWAVEOUT     hWaveOut; 
  2. WAVEHDR      WaveOutHdr; 
  3. MMRESULT result; 
  4. result = waveOutOpen(&hWaveOut, WAVE_MAPPER,&pFormat,0L, 0L, WAVE_FORMAT_DIRECT); 
  5. if (result) 
  6.     MessageBox(_T("Failed to open waveform output device.")); 
  7.     return

(3)准备波形数据块:

 

 

  1. WaveOutHdr.lpData = (LPSTR)waveOut; 
  2. WaveOutHdr.dwBufferLength = NUMPTS*2; 
  3. WaveOutHdr.dwBytesRecorded=0; 
  4. WaveOutHdr.dwUser = 0L; 
  5. WaveOutHdr.dwFlags = 0L; 
  6. WaveOutHdr.dwLoops = 0L; 
  7. waveOutPrepareHeader(hWaveOut, &WaveOutHdr, sizeof(WAVEHDR)); 

(4)向给定音频媒体中输出波形数据块:

 

 

  1. result = waveOutWrite(hWaveOut, &WaveOutHdr, sizeof(WAVEHDR)); 
  2. if (result) 
  3.     MessageBox(_T("Failed to play sound")); 
  4.     return

(5)清除准备:

 

 

  1. // Wait until finished sound play 
  2. do {} while (waveOutUnprepareHeader(hWaveOut, &WaveOutHdr, sizeof(WAVEHDR))==WAVERR_STILLPLAYING); 

(6)关闭给定音频媒体:

 

 

  1. waveOutClose(hWaveOut);