一个读取wav,用DirectSound 播放的c++代码

原创 2007年10月14日 06:27:00

 

#define WIN32_LEAN_AND_MEAN

#include 
<iostream>
#include 
<windows.h>
#include 
<mmsystem.h>
#include 
<dsound.h>
using namespace std;


#pragma comment(lib,"dxguid.lib")
#pragma comment(lib,"dsound.lib")
#pragma comment(lib,"winmm.lib")
#define WINCLASSNAME "winclass1"

#ifndef DSBCAPS_CTRLDEFAULT
#define DSBCAPS_CTRLDEFAULT (DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME)
#endif

////////////////////////////////
LPDIRECTSOUND    lpds            =    NULL;
LPDIRECTSOUNDBUFFER    lpdbsBuffer    =    NULL;
DSBUFFERDESC    dsbd;
WAVEFORMATEX    wfmx;
UCHAR*            sndBuffer        =    NULL;
HWND            main_window_handle    =NULL;
//////////////////////////////////
LRESULT    CALLBACK    WinProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
int GameInit(void* params =NULL,int num =0);
int GameMain(void* params =NULL,int num =0);
int GameShutdown(void* params =NULL,int num =0);
int DSound_Load_Wav(char* filename,int control_flags =DSBCAPS_CTRLDEFAULT);
int GameInit(void* params,int num )
{
    if(DirectSoundCreate(NULL,
&lpds,NULL) != DS_OK)
        return 0;

    if(lpds ->SetCooperativeLevel(main_window_handle,DSSCL_NORMAL)!=DS_OK)
        return 0;
    DSound_Load_Wav("Windows XP Startup.wav");

    lpdbsBuffer ->Play(0,0,1);
    return 1;
}
//-----------------------------------------------------------
//名称:DSound_Load_Wav
//功能:利用微软提供的mmio库,解析wav文件,将数据读入内存,然后拷贝到
//DirectSound建立的 辅助缓冲区 从而实现文件的播放(GameInit())
//----------------------------------------------------------


int DSound_Load_Wav(char* filename,int control_flags)
{
    HMMIO handle ;
    MMCKINFO mmckriff,mmckIn;
    PCMWAVEFORMAT    pwfm;
    memset(
&mmckriff,0,sizeof(MMCKINFO));
    if((handle= mmioOpen(filename,NULL,MMIO_READ|MMIO_ALLOCBUF))==NULL)
        return 0;

    //--------------------------------------------
    //进入块(chunk),查找 riff和wave的标记
    //----------------------------------------------
    if(0 !=mmioDescend(handle,
&mmckriff,NULL,0))
    {
        mmioClose(handle,0);
        return -1;
    }

    //-----------------------------------------
    //#define FOURCC_RIFF  mmioFOURCC('R','I','F','F')
    //----------------------------------------------
    if(mmckriff.ckid !=FOURCC_RIFF||mmckriff.fccType !=mmioFOURCC('W','A','V','E'))
    {
        mmioClose(handle,0);
        return -1;
    }

    /////////////////////////////////////////////
    //查找 fmt 块
    ////////////////////////////////////////////
    mmckIn.ckid = mmioFOURCC('f','m','t',' ');
    if(0 !=mmioDescend(handle,
&mmckIn,&mmckriff,MMIO_FINDCHUNK))
    {
        mmioClose(handle,0);
        return -1;
    }

    ////////////////////////////////////////////////////
    //fmt块的格式与PCMWAVEFORMAT 的格式定义相同
    //所以读入临时变量,最后写入 wmtf中
    ////////////////////////////////////////////////////
    if(mmioRead(handle,(HPSTR)
&pwfm,sizeof(PCMWAVEFORMAT))!=sizeof(PCMWAVEFORMAT))
    {
        mmioClose(handle,0);
        return -1;
    }
    ////////////////////////////////////
    //检测是不是 pc的wave标准格式
    //
    //////////////////////////////
    if(pwfm.wf.wFormatTag != WAVE_FORMAT_PCM)
    {
        mmioClose(handle,0);
        return -1;
    }

    /////////////////////////////
    //给wmfx赋值
    /////////////////////////
    memcpy(
&wfmx,&pwfm,sizeof(pwfm));
    wfmx.cbSize =0;

    if(0 != mmioAscend(handle,
&mmckIn,0))
    {
        mmioClose(handle,0);
        return -1;
    }

    /////////////////////////////
    //查找 data chunk
    /////////////////////////
    mmckIn.ckid = mmioFOURCC('d','a','t','a');
    
    if(0 !=mmioDescend(handle,
&mmckIn,&mmckriff,MMIO_FINDCHUNK))
    {
        mmioClose(handle,0);
        return -1;
    }

    sndBuffer = new UCHAR[mmckIn.cksize];

    /////////////////////////////
    //数据写入sndBuffer
    /////////////////////////
    mmioRead(handle,(HPSTR)sndBuffer,mmckIn.cksize);

    mmioClose(handle,0);

    /////////////////////////////
    //建立directsound的辅助缓存
    //
    /////////////////////////
    dsbd.dwSize = sizeof(DSBUFFERDESC);
    dsbd.dwBufferBytes =mmckIn.cksize;
    dsbd.dwFlags = (control_flags|DSBCAPS_STATIC|DSBCAPS_LOCSOFTWARE);
    dsbd.lpwfxFormat  =
&wfmx;

    if(FAILED(lpds ->CreateSoundBuffer(
&dsbd,&lpdbsBuffer,NULL)))
    {
        delete [] sndBuffer;
        return -1;
    }
    VOID* pDSLockedBuffer =NULL;
    DWORD    dwDSLockedBufferSize =0;

    ////////////////////
    //lock 住内存,现在他是可操作的,拷贝进去即可
    ////////////////
    if(lpdbsBuffer ->Lock(0,mmckIn.cksize,
&pDSLockedBuffer,&dwDSLockedBufferSize,NULL,NULL,0L))
        return 0;
    memcpy(pDSLockedBuffer,sndBuffer,mmckIn.cksize);

    ///////////////
    //Unlock 缓冲区内存
    //
    ////////////////
    if(FAILED(lpdbsBuffer ->Unlock(pDSLockedBuffer,dwDSLockedBufferSize,NULL,0)))
    {
        delete [] sndBuffer;
        return 0;
    }

    return 1;
}
int GameMain(void* params ,int num )
{
    return 1;
}
INT WINAPI WinMain(HINSTANCE hinst,HINSTANCE hprev,LPSTR lCmdline,int nCmdshow)
{
    MSG    msg;
    HWND hwnd;
    WNDCLASSEX wndclass;

    wndclass.cbClsExtra        =    0;
    wndclass.cbSize            =    sizeof(WNDCLASSEX);
    wndclass.cbWndExtra        =    0;
    wndclass.hbrBackground    =    (HBRUSH)CreateSolidBrush(RGB(0,255,255));
    wndclass.hCursor        =    LoadCursor(NULL,IDC_ARROW);
    wndclass.hIcon            =    LoadIcon(NULL,IDI_APPLICATION);
    wndclass.hIconSm        =    LoadIcon(NULL,IDI_APPLICATION);
    wndclass.hInstance        =    hinst;
    wndclass.lpfnWndProc    =    WinProc;
    wndclass.lpszClassName    =    WINCLASSNAME;
    wndclass.lpszMenuName    =    NULL;
    wndclass.style            =    CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;

    RegisterClassEx(
&wndclass);

    if(!(hwnd =CreateWindowEx(NULL,WINCLASSNAME,"DSOUND DEMO",
                                WS_OVERLAPPEDWINDOW|WS_VISIBLE,
                                0,0,
                                640,480,
                                NULL,
                                NULL,
                                hinst,
                                NULL)))
            return 0;

    main_window_handle =hwnd;
    GameInit();
    while(TRUE)
    {
        
        if(PeekMessage(
&msg,NULL,0,0,PM_REMOVE))
        {
            if (msg.message == WM_QUIT)
                break;
            TranslateMessage(
&msg);
            DispatchMessage(
&msg);
            GameMain();
        }
    }
    return (int)(msg.wParam);
}

LRESULT    CALLBACK    WinProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
    PAINTSTRUCT        ps;
    HDC                hdc;

    switch(msg)
    {
    case WM_CREATE:
        break;
    case WM_PAINT:
        hdc =BeginPaint(hwnd,
&ps);
        EndPaint(hwnd,
&ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        break;
    }

    return (DefWindowProc(hwnd,msg,wparam,lparam));
}

最近研究dsound,看了些资料,基本了解了wav的数据结构,写了个播放wav的小程序,代码放上来,有兴趣的可以看看,仓促完成,肯定不严谨,行家见笑了,呵呵。欢迎交流

 

建立第一个directX程序——在C#下利用DirectSound实现声音播放

//转自:http://blog.csdn.net/cutebab0888/article/details/1143310 这是给directX初学者的教程,如果你是大虾,大可不必理...
  • u012637735
  • u012637735
  • 2014年11月20日 16:49
  • 1676

DirectSound编程实现实时混音

利用DirectSound编程实现实时混音   摘要:将多个音频文件或多路音频数据同时输出到音频输出设备上,就可同时听到多个不同的声音,这就是混音。在游戏开发,网络视频会议开发中都会用到混音技术,...
  • FrankieWang008
  • FrankieWang008
  • 2013年10月28日 09:59
  • 4211

最简单的视音频播放示例8:DirectSound播放PCM

本文记录DirectSound播放音频的技术。DirectSound是Windows下最常见的音频播放技术。目前大部分的音频播放应用都是通过DirectSound来播放的。本文记录一个使用Direct...
  • leixiaohua1020
  • leixiaohua1020
  • 2014年10月30日 00:08
  • 21333

DirectX初级编程:C#利用DirectSound播放WAV文件[最少只要4句话]

1.注意:       a.DirectSound引用方法:http://blog.csdn.net/woaixiaozhe/article/details/7861340       b.Mix...
  • woaixiaozhe
  • woaixiaozhe
  • 2012年08月14日 13:36
  • 3173

DirectSound播放wav简单例子

  • 2016年12月01日 21:18
  • 3KB
  • 下载

多声道wav文件的播放和音量控制C++代码

  • 2013年12月05日 15:50
  • 18.79MB
  • 下载

wav格式读取,及其用api尽心播放,c#代码

  • 2017年12月05日 10:40
  • 470KB
  • 下载

c++ 下利用waveOutWrite(directsound)编写的双缓冲区音频播放程序

  • 2013年09月14日 13:49
  • 4.42MB
  • 下载

DirectSound播放声音实例代码VC8

  • 2011年03月07日 17:42
  • 60KB
  • 下载

DirectSound学习笔记:使用WAV数据

使用WAV数据在Windows 驱动模型(WDM)中,DirectSound硬件缓冲区能够播放任何未压缩或压缩的声音格式,这些格式能够被一个WAVEFORMATEX或WAVEFORMATEXTENSI...
  • ddkxddkx
  • ddkxddkx
  • 2011年05月20日 00:21
  • 769
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:一个读取wav,用DirectSound 播放的c++代码
举报原因:
原因补充:

(最多只允许输入30个字)