在程序中,很有可能会涉及到播放一些音频文件(比如:.wav文件)和音频数据,这个问题怎么解决呢?VC++中想要播放一个音频文件(.wav)是很容易的,只要调用WIndows API函数PlaySound()就可以了,但是,如果您想播放自己在程序中产生的一段音频数据,就不是那么简单了,需要利用WIndows wave I/O API的几个函数来实现。
下面结合实例来说明(完整实例可在我的CSDN资源中下载,该例子利用WIndows wave I/O API 函数,实现了播放自定义的一段音频数据(通过sin()函数产生);并且使用了PlaySound()函数播放“250.wav”文件):
- //需包含的头文件
- #include <MMSystem.h>
- #pragma comment(lib,"winmm.lib")
- //PlaySound()函数和其他WIndows wave I/O API 函数的使用
- #include "math.h"//sin()函数的使用
1.播放文件:
- CString path;
- path.Format("%s250.wav",g_BasePath);
- //g_BasePath的取值不用多说,前面已详细介绍了。
- PlaySound(_T(path),0,SND_FILENAME|SND_ASYNC);
2.播放数据:
(1)确定音频数据的格式及内容:
- int rate=1000; //刺激率
- int sampleRate = 44100; //采样率
- constint NUMPTS = (int) (44100 * 0.5); // 0.5s
- shortint waveOut[NUMPTS];//音频数据
- //内容
- for (int i=0;i<NUMPTS;i++)
- {
- waveOut[i] = (shortint)ceil(sin(2*3.1415926*rate*i/sampleRate)*20000);
- }
- //格式
- WAVEFORMATEX pFormat;
- pFormat.wFormatTag=WAVE_FORMAT_PCM;
- //simple,uncompressed format
- pFormat.nChannels=1;//1=mono, 2=stereo
- pFormat.nSamplesPerSec=sampleRate; // 44100
- pFormat.nAvgBytesPerSec=sampleRate*2;
- // = nSamplesPerSec * n.Channels * wBitsPerSample/8
- pFormat.nBlockAlign=2; // = n.Channels * wBitsPerSample/8
- pFormat.wBitsPerSample=16;
- //16 for high quality, 8 for telephone-grade
- pFormat.cbSize=0;
(2)打开一个给定的波形音频输出装置:
- HWAVEOUT hWaveOut;
- WAVEHDR WaveOutHdr;
- MMRESULT result;
- result = waveOutOpen(&hWaveOut, WAVE_MAPPER,&pFormat,0L, 0L, WAVE_FORMAT_DIRECT);
- if (result)
- {
- MessageBox(_T("Failed to open waveform output device."));
- return;
- }
(3)准备波形数据块:
- WaveOutHdr.lpData = (LPSTR)waveOut;
- WaveOutHdr.dwBufferLength = NUMPTS*2;
- WaveOutHdr.dwBytesRecorded=0;
- WaveOutHdr.dwUser = 0L;
- WaveOutHdr.dwFlags = 0L;
- WaveOutHdr.dwLoops = 0L;
- waveOutPrepareHeader(hWaveOut, &WaveOutHdr, sizeof(WAVEHDR));
(4)向给定音频媒体中输出波形数据块:
- result = waveOutWrite(hWaveOut, &WaveOutHdr, sizeof(WAVEHDR));
- if (result)
- {
- MessageBox(_T("Failed to play sound"));
- return;
- }
(5)清除准备:
- // Wait until finished sound play
- do {} while (waveOutUnprepareHeader(hWaveOut, &WaveOutHdr, sizeof(WAVEHDR))==WAVERR_STILLPLAYING);
(6)关闭给定音频媒体:
- waveOutClose(hWaveOut);