(一)DirectSound接口播放WAVE音频文件
来源:互联网 发布:汪小菲为什么选大s知乎 编辑:程序博客网 时间:2024/05/27 09:45
首先要声明三个接口,用于声音的播放
LPDIRECTSOUND8 g_pDirectSound=NULL; //directSound接口
LPDIRECTSOUNDBUFFER g_pPrimaryBuffer =NULL;//主缓冲区接口
LPDIRECTSOUNDBUFFER8 g_pSecondaryBuffer = NULL;//辅助缓冲区接口
建立一个结构体,标识wav文件的相关信息。
struct WAVEHEADER
{
char riff_sig[4]; // 'RIFF'
long waveform_chunk_size; // 8
char wave_sig[4]; // 'WAVE'
char format_sig[4]; // 'fmt ' (notice space after)
long format_chunk_size; // 16;
short format_tag; //WAVE_FORMAT_PCM
short channels; // #of channels
long sample_rate; // samplingrate
long bytes_per_sec; // bytesper second
short block_align; // sampleblock alignment
short bits_per_sample; // bits persecond
char data_sig[4]; // 'data'
long data_size; // sizeof waveform data
};
附录:wav文件的格式http://wenku.baidu.com/view/801b1537f111f18583d05aa7.html
然后在初始化函数中,
//创建directsound接口
if(FAILED(DirectSoundCreate8(NULL,&g_pDirectSound,NULL)))
::MessageBox(NULL,"Create DirectSound failed","DirectSoundCreate",0);
//设置 directsound协作级别
if(FAILED(g_pDirectSound->SetCooperativeLevel(hWnd,DSSCL_NORMAL)))
::MessageBox(NULL,"Set cooperative level failed!","SetCooperativeLevel",0);
//读取WAV音频信息
WAVEHEADER wave_header;
::ZeroMemory(&wave_header, sizeof(WAVEHEADER));
FILE* fp = fopen("example.wav","rb");
fread((void*)&wave_header, 1, sizeof(WAVEHEADER), fp);
//根据wav文件,赋值结构体
WAVEFORMATEX wave_format;
ZeroMemory(&wave_format, sizeof(WAVEFORMATEX));
wave_format.wFormatTag=WAVE_FORMAT_PCM;
wave_format.nChannels=wave_header.channels; //2声道
wave_format.nSamplesPerSec=wave_header.sample_rate; //44100Hz回放频率
wave_format.wBitsPerSample=wave_header.bits_per_sample; //16位采样
wave_format.nBlockAlign=wave_format.wBitsPerSample/8*wave_format.nChannels;
wave_format.nAvgBytesPerSec=wave_format.nSamplesPerSec*wave_format.nBlockAlign;
DSBUFFERDESC ds_buf_desc;
ZeroMemory(&ds_buf_desc, sizeof(DSBUFFERDESC));
ds_buf_desc.dwSize= sizeof(DSBUFFERDESC);
ds_buf_desc.dwFlags=DSBCAPS_CTRLVOLUME;
ds_buf_desc.dwBufferBytes=wave_header.data_size; //缓冲区
ds_buf_desc.lpwfxFormat=&wave_format;
//创建主音频缓存和辅助音频缓存
g_pDirectSound->CreateSoundBuffer(&ds_buf_desc,&g_pPrimaryBuffer, NULL);
g_pPrimaryBuffer->QueryInterface(IID_IDirectSoundBuffer8, (void**)&g_pSecondaryBuffer);
// 加载WAV音频数据到辅助缓冲区
char *ptr1, *ptr2;
DWORD size1, size2;
fseek(fp, sizeof(WAVEHEADER), SEEK_SET);
g_pSecondaryBuffer->Lock(0,wave_header.data_size, (void**)&ptr1,&size1, (void**)&ptr2, &size2, 0);
if(ptr1) fread(ptr1, 1, size1, fp);
if(ptr2) fread(ptr2, 1, size2, fp);
g_pSecondaryBuffer->Unlock(ptr1, size1, ptr2, size2);
fclose(fp);
// 初始化时,音频数据放到了辅助缓冲区,辅助缓冲区与主缓冲区关联,主缓冲区与directsound接口关联
接着在渲染函数中播放声音
static longlPan = 0, lVolume = DSBVOLUME_MAX;
if(::GetAsyncKeyState(VK_LEFT) & 0x8000f)
lPan -= 500,g_pSecondaryBuffer->SetPan(lPan); //声道控制
if(::GetAsyncKeyState(VK_RIGHT) & 0x8000f)
lPan += 500,g_pSecondaryBuffer->SetPan(lPan);
if(::GetAsyncKeyState(VK_UP) & 0x8000f)
lVolume += 500,g_pSecondaryBuffer->SetVolume(lVolume); //音量控制
if(::GetAsyncKeyState(VK_DOWN) & 0x8000f)
lVolume -= 500,g_pSecondaryBuffer->SetVolume(lVolume);
if(::GetAsyncKeyState(VK_SPACE) & 0x8000f)
g_pSecondaryBuffer->Play(0,0, DSBPLAY_LOOPING); //循环播放
if(::GetAsyncKeyState('S') & 0x8000f)
g_pSecondaryBuffer->Stop(); // 停止播放
最后释放掉directSound接口
If(g_pDirectSound!=NULL)
{
g_pDirectSound->Release();
g_pDirectSound=NULL;
}
- (一)DirectSound接口播放WAVE音频文件
- 简单的用 Microsoft.DirectX.DirectSound播放wave音频文件
- MMIO编程播放wave音频文件
- (二)DirectShow接口播放Mp3音频文件
- Directsound 实现录音,以及对wave 文件的读写(一)
- 播放Wave的缓冲区《一》
- IOS音频6:之基于FFmpeg播放音频文件(一)
- WebRTC学习记录(2):播放音频文件原理一探
- vc编辑wave音频文件
- 详解WAVE音频文件格式
- 详解WAVE音频文件格式
- 在 Delphi 下使用 DirectSound (7): 播放资源文件中的 Wave 数据
- Matlab播放音频文件(音乐)!
- Android系列之音乐播放器的实现一(播放手机内存音频文件)
- Android系列之音乐播放器的实现一(播放网络音频文件)
- DirectSound入门指南(0)播放声音
- DirectSound入门指南(0)播放声音
- Windows和Linux下播放采集wave格式音频文件的简单记录
- 分享:每天工作4小时的程序员 -时间管理
- C和指针读书笔记——指针
- java String常见细节问题探究
- 真实案例教你玩转移动广告
- 查看自己的ubuntu 的版本
- (一)DirectSound接口播放WAVE音频文件
- 问题小结(8)-获取wifi网关和ip
- Lucene学习总结之三:Lucene的索引文件格式(2)
- ZigBee网络的建立 & ZigBee系统初始化流程
- windows删除oracle10g时,oci.dll无法删除解决办法
- ubuntu debian 安装fcitx
- VS2005(vs2008,vs2010)使用map文件查找程序崩溃原因
- 判断sql语句中exists的用法
- 『Linux & Oracle 优化』kernel 说明