当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>Visual C++教程

VC下实现DirectSound

    ---- 加入音乐是增强应用程序功能的所有方法中最简单的一个。音乐可以使用户心情
    愉快;在合适的场合播放恰当的音乐能够使程序员和他的VC++程序焕发光彩。

    ---- Microsoft Windows Multimedia API提供了三种方法来播放WAV文件:

    PlaySound()函数。它可以通过单行编码来播放Wave格式的声音。此函数有两个限制
    :必须将声音数据完整地载入物理内存;数据格式必须被所配置的某一音频驱动器支
    持。根据经验,PlaySound()适用于100K以下的文件。

    MCI(The Media Control Interface)。MCI功能强大,不仅可以实现WAV文件的播放,
    而且还可以播放MIDI及CD音频。

    低级Wave音频设备。用这些设备可以运行完全控制Wave数据的应用文件。
    ---- 前两种方法使用简单,但无法实现两个及两个以上的WAV文件的播放;第三种方法
    实现起来非常复杂,非专业人员很难完成。DirectSound可以实现八个及八个以上WAV文
    件的同时播放,能使多媒体程序更加生动,而且简单易用,但它仅适合于Windows 95下
    的程序,也不支持WAV文件的记录及存储""这是唯一让人遗憾的地方。实现
    DirectSound需要以下几个步骤:
    1. 创建及初始化DirectSound
    LPDIRECTSOUND m_pDirectObject;
    if(DirectSoundCreate(NULL,&m_pDirectObject,NULL)==DS_OK)
    file://设定应用程序的声音设备优先级别方式,一般为DSSCL_NORMAL
    m_pDirectObject->SetCooperativeLevel
    (this- >m_hWnd,DSSCL_NORMAL);
    else
    AfxMessageBox("DirectSound Create failed");

    2. 将WAV文件读入内存,找到格式块,数据块位置及数据长度。
    m_pMemory,m_pFormat,m_pData,m_dwSize在头文件中声明。
    BOOL CDirectWave::LoadFile (CString Filename){
    CFile File;
    DWORD dwSize;
    if (!File.Open (Filename,
    CFile::modeRead | CFile::shareDenyNone))
    return FALSE;
    dwSize = File.Seek (0, CFile::end);
    File.Seek (0, CFile::begin);
    file://m_pMemory内存存储块指针,类型:LPVOID
    m_pMemory = GlobalAlloc (GMEM_FIXED, dwSize);
    if (File.ReadHuge (m_pMemory, dwSize) != dwSize){
    File.Close ();
    return FALSE;
    }
    File.Close ();

    LPDWORD pdw,pdwEnd;
    DWORD dwRiff,dwType, dwLength, dwLength;
    if (m_pFormat) file://格式块指针,类型:LPWAVEFORMATEX
    m_pFormat = NULL;
    if (m_pData) file://数据块指针,类型:LPBYTE
    m_pData = NULL;
    if (m_dwSize) file://数据长度,类型:DWORD
    m_dwSize = 0;
    pdw = (DWORD *) m_pMemory;
    dwRiff = *pdw++;
    dwLength = *pdw++;
    dwType = *pdw++;

    if (dwRiff != mmioFOURCC ('R', 'I', 'F', 'F'))
    return FALSE;
    if (dwType != mmioFOURCC ('W', 'A', 'V', 'E'))
    return FALSE;
    file://寻找格式块,数据块位置及数据长度
    pdwEnd = (DWORD *)((BYTE *) pdw + dwLength - 4);
    while (pdw < pdwEnd){
    dwType = *pdw++;
    dwLength = *pdw++;
    switch (dwType){
    case mmioFOURCC('f', 'm', 't', ' '):
    if (!m_pFormat){
    if (dwLength < sizeof (WAVEFORMAT))
    return FALSE;
    m_pFormat = (LPWAVEFORMATEX) pdw;
    if (m_pData && m_dwSize)
    return TRUE;
    }
    break;

    case mmioFOURCC('d', 'a', 't', 'a'):
    if (!m_pData || !m_dwSize){
    m_pData = (LPBYTE) pdw;
    m_dwSize = dwLength;
    if (m_pFormat)
    return TRUE;
    }
    break;
    }
    pdw = (DWORD *)((BYTE *) pdw +
    ((dwLength + 1) &~ 1));
    }
    file://未找到,返回FALSE
    return FALSE;
    }

    3. 创建声音缓冲区
    DSBUFFERDESC BufferDesc;
    memset (&BufferDesc, 0, sizeof (BufferDesc));
    BufferDesc.lpwfxFormat = (LPWAVEFORMATEX) m_pFormat;
    BufferDesc.dwSize = sizeof (DSBUFFERDESC);
    BufferDesc.dwBufferBytes = m_dwSize;
    BufferDesc.dwFlags = 0;
    file://头文件中声明m_pDSoundBuffer,类
    型:LPDIRECTSOUNDBUFFER
    if (pDSoundObject->CreateSoundBuffer
    (&BufferDesc, &m_pDSoundBuffer, 0) != DS_OK)
    return FALSE;

    4. 载入声音数据
    BOOL CDirectWave::LoadData (void){
    LPVOID lpPtr1, lpPtr2;
    DWORD dwLen1, dwLen2;
    HRESULT hResult;

    TryLoad:
    hResult = m_pDSoundBuffer- >Lock
    (0, m_dwSize, &lpPtr1, &dwLen1, &lpPtr2, &dwLen2, 0);
    if (hResult == DS_OK){
    memcpy (lpPtr1, m_pData, dwLen1);
    if (lpPtr2)
    memcpy (lpPtr2, m_pData + dwLen1, dwLen2);
    m_pDSoundBuffer- >Unlock
    (lpPtr1, dwLen1, lpPtr2, dwLen2);
    return TRUE;
    }
    else if (hResult == DSERR_BUFFERLOST){
    hResult = m_pDSoundBuffer- >Restore ();
    if (hResult == DS_OK)
    goto TryLoad;
    }
    return FALSE;
    }

    5. 播放及停止
    void CDirectWave::Play (BOOL bLoop){
    DWORD dwFlags = 0;
    file://dwFlags= DSBPLAY_LOOPING可实现循环播放
    TryPlay:
    if (m_pDSoundBuffer- >
    Play (0, 0, dwFlags) == DSERR_BUFFERLOST){
    if (LoadData ())//数据丢失,重新装载
    goto TryPlay;
    }
    }
    void CDirectWave::Stop (void){
    m_pDSoundBuffer- >Stop ();
    }
    6. 关闭。释放内存块,声音缓冲区。

    DirectSound需要用到mmsystem.h,dsound.h两个头文件。

相关内容
赞助商链接