(一)DirectSound接口播放WAVE音频文件

本文介绍了如何利用DirectSound接口播放WAV音频文件,包括声明和初始化DirectSound接口,读取WAV文件头信息,创建主缓冲区和辅助缓冲区,加载音频数据,以及在渲染过程中实现声道和音量控制的详细步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先要声明三个接口,用于声音的播放

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;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值