首    页 界面/窗口 网络/通讯 数据库 组件开发 图像/多媒体 NET/Web 其它技术 源码下载 资料下载 软件共享 软件外包 曲艺杂谈
栏目导航:  首    页  |  图像/多媒体  |  音频技术   


VC下实现DirectSound


原作者:不详    源出处:不详    发布者:施昌权    发布类型:转载    发布日期:2008-08-30

 

        加入音乐是增强应用程序功能的所有方法中最简单的一个。音乐可以使用户心情愉快;在合适的场合播放恰当的音乐能够使程序员和他的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两个头文件。

  


关于我们 版权声明 广告服务 联系我们 友情链接 加入收藏
站长:施昌权    Email:scq2099yt@163.com    MSN:scq2099yt@live.cn    QQ:14046300    本站QQ群:67202409
Copyright © 2008     卓为VC(www.joyvc.cn)    All Rights Reserved    建议分辨率 1024×768
本站由施昌权制作维护
京ICP备09012297号