用DirectSound播放OGG格式的音乐 

2006-12-07 22:00 发布

3973 4 0


应shenqiren朋友的要求,我贴一段我自己播放OGG音乐的代码。
我的代码没经过仔细的设计,写的也很随意,希望大家帮我修正一下。
(写的时候参考了粘土游戏库的代码)。

头文件:


#include <dsound.h>

#include <assert.h>
#include <math.h>

#include <ogg/ogg.h>
#include <vorbis/codec.h>
#include <vorbis/vorbisfile.h>

#include <mmsystem.h>

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

class ljmMusicBuffer_DSound : public ljmMusicBuffer
{
public:
ljmMusicBuffer_DSound(IDirectSound8* pDS);
~ljmMusicBuffer_DSound();

bool LoadOggFile(const char* szFileName);

void Play(bool bLoop);
void Stop(void);

void Pause(void);
void Reset(void);

void SetVolume(float vol);
bool IsPlaying(void);

protected:
LPDIRECTSOUND8        m_pDS;
LPDIRECTSOUNDBUFFER    m_pBuffer;

LONG                   m_lVolume;

WAVEFORMATEX           m_wfx;
DWORD                  m_dwWritePos;

OggVorbis_File* m_pVorbisFile;
string m_strCurFile;
bool m_bMono ;
long m_lRate;

int  current_section;

bool m_bLoop;
bool m_bFinished;

// static const int BUFFERSIZE = 8192;

UINT m_TimerID;

void Clear(void);
void FillBuffer(void);
static void CALLBACK OnTimerCB(UINT uID, UINT uMsg,DWORD_PTR pUserData, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
};



TA的作品 TA的主页
B Color Smilies

全部评论4

  • fair
    fair 2006-12-7 22:00:00
    函数体



    ljmMusicBuffer_DSound::ljmMusicBuffer_DSound(IDirectSound8* pDS)
    :m_pDS(pDS)
    ,m_pBuffer(NULL)
    ,m_TimerID(0)
    ,m_pVorbisFile(NULL)
    ,m_bLoop(false)
    ,m_bFinished(false)
    {
    }

    ljmMusicBuffer_DSound::~ljmMusicBuffer_DSound()
    {
    Stop();
    Clear();

    }


    void ljmMusicBuffer_DSound::Play(bool bLoop)
    {
    if(!m_pBuffer)
    return;
    m_bLoop = bLoop;
    if(IsPlaying())
    Stop();


    m_dwWritePos = 0;
    FillBuffer();
    FillBuffer();


    m_pBuffer->Play(0,0,DSBPLAY_LOOPING);
    m_bFinished = false;
    m_TimerID = timeSetEvent(500,0,OnTimerCB,(DWORD_PTR)this,TIME_PERIODIC);
    }

    void ljmMusicBuffer_DSound::Stop(void)
    {
    timeKillEvent(m_TimerID);
    Reset();
    m_bFinished = true;

    }

    void ljmMusicBuffer_DSound::Pause(void)
    {
    m_pBuffer->Stop();
    }

    void ljmMusicBuffer_DSound::Reset(void)
    {
    if(!m_pBuffer)
    return;
    m_pBuffer->Stop();
    m_pBuffer->SetCurrentPosition(0);
    m_dwWritePos = 0;
    if(m_pVorbisFile)
    ov_pcm_seek(m_pVorbisFile,0);
    }

    void ljmMusicBuffer_DSound::SetVolume(float vol)
    {
    //vol 为 0.0f~1.0f , DSound的单位是分贝
    if (vol > 0)
    {
    m_lVolume = (LONG)(log10(vol) * 2000.0f);
    }
    else
    {
    m_lVolume = -10000;
    }


    if(!m_pBuffer)
    return;

    m_pBuffer->SetVolume((LONG)vol);
    }

    bool ljmMusicBuffer_DSound::IsPlaying(void)
    {
    DWORD dwStatus;
    if(!m_pBuffer)
    return false;

    m_pBuffer->GetStatus(&dwStatus);
    return (dwStatus & DSBSTATUS_PLAYING);

    }


    void ljmMusicBuffer_DSound::Clear(void)
    {
    SAFE_RELEASE(m_pBuffer);
    if(m_pVorbisFile)
    {
    ov_clear(m_pVorbisFile);
    delete m_pVorbisFile;
    m_pVorbisFile = NULL;
    }
    }


  • fair
    fair 2006-12-7 22:00:00
    bool ljmMusicBuffer_DSound::LoadOggFile(const char* szFileName)
    {
    Stop();
    Clear();
    if(m_strCurFile == szFileName)
    return true;

    FILE* pFile = fopen(szFileName,"rb");
    if(!pFile)
    return false;

    if(m_pVorbisFile)
    {
    ov_clear(m_pVorbisFile);
    delete m_pVorbisFile;
    }
    m_pVorbisFile = new OggVorbis_File;
    memset(m_pVorbisFile,0,sizeof(OggVorbis_File));
    ov_clear(m_pVorbisFile);

    if( 0!=ov_open(pFile,m_pVorbisFile,NULL,0) )
    {
    ov_clear(m_pVorbisFile);
    delete m_pVorbisFile;
    return false;
    }


    if(m_pVorbisFile->vi->channels == 1)
    {
    m_bMono = true;
    }
    else
    {
    m_bMono = false;
    }

    m_lRate = m_pVorbisFile->vi->rate;


    // WAVEFORMATEX wfx;

    m_wfx.wFormatTag     = WAVE_FORMAT_PCM;
    m_wfx.nSamplesPerSec = (DWORD)m_lRate;
    m_wfx.wBitsPerSample = 16;
    m_wfx.cbSize  = sizeof(WAVEFORMATEX);

    if(m_bMono)
    {
    m_wfx.nChannels = 1;
    }
    else
    {
    m_wfx.nChannels = 2;
    }

    m_wfx.nBlockAlign = m_wfx.nChannels * m_wfx.wBitsPerSample / 8;
    m_wfx.nAvgBytesPerSec = m_wfx.nSamplesPerSec * m_wfx.nBlockAlign;


    DSBUFFERDESC dsbd;
    ZeroMemory(&dsbd,sizeof(DSBUFFERDESC));
    dsbd.dwSize          = sizeof(dsbd);
    dsbd.dwFlags         = 0;//DSBCAPS_CTRLVOLUME;
    dsbd.dwBufferBytes   = m_wfx.nAvgBytesPerSec * 2; dsbd.guid3DAlgorithm = GUID_NULL;
    dsbd.lpwfxFormat     = &m_wfx;

    HRESULT hr;
    if(FAILED( hr = m_pDS->CreateSoundBuffer(&dsbd,&m_pBuffer,NULL)))
    {
    ov_clear(m_pVorbisFile);
    delete m_pVorbisFile;
    return false;
    }


    return true;
    }

  • fair
    fair 2006-12-7 22:01:00
    1. <p></p><p>void&nbsp;ljmMusicBuffer_DSound::FillBuffer(void)<br/>{</p><p>HRESULT&nbsp;hr;<br/>VOID*&nbsp;&nbsp;&nbsp;pDSLockedBuffer&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;NULL;&nbsp;//&nbsp;Pointer&nbsp;to&nbsp;locked&nbsp;buffer&nbsp;memory<br/>DWORD&nbsp;&nbsp;&nbsp;dwDSLockedBufferSize&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Size&nbsp;of&nbsp;the&nbsp;locked&nbsp;DirectSound&nbsp;buffer<br/>DWORD&nbsp;&nbsp;&nbsp;dwWavDataRead&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Amount&nbsp;of&nbsp;data&nbsp;read&nbsp;from&nbsp;the&nbsp;wav&nbsp;file</p><p>LPDIRECTSOUNDBUFFER&nbsp;pDSB&nbsp;=&nbsp;m_pBuffer;<br/>BOOL&nbsp;bRepeatWavIfBufferLarger&nbsp;=&nbsp;FALSE;<br/></p><p>if(&nbsp;pDSB&nbsp;==&nbsp;NULL&nbsp;)<br/>return&nbsp;;</p><p>//&nbsp;Make&nbsp;sure&nbsp;we&nbsp;have&nbsp;focus,&nbsp;and&nbsp;we&nbsp;didn't&nbsp;just&nbsp;switch&nbsp;in&nbsp;from<br/>//&nbsp;an&nbsp;app&nbsp;which&nbsp;had&nbsp;a&nbsp;DirectSound&nbsp;device<br/>//if(&nbsp;FAILED(&nbsp;hr&nbsp;=&nbsp;RestoreBuffer(&nbsp;pDSB,&nbsp;NULL&nbsp;)&nbsp;)&nbsp;)<br/>// return&nbsp;hr;</p><p><br/>// int&nbsp;&nbsp;buffer_size;<br/>long&nbsp;bytes_read;<br/></p><p>size_t&nbsp;length&nbsp;=&nbsp;m_wfx.nAvgBytesPerSec&nbsp;/&nbsp;2;&nbsp;</p><p>char*&nbsp;buffer&nbsp;=&nbsp;new&nbsp;char[length];<br/><br/>long&nbsp;leave&nbsp;=&nbsp;(long)length;<br/>long&nbsp;cur_pos&nbsp;=&nbsp;0;</p><p></p><p>do<br/>{<br/>bytes_read&nbsp;=&nbsp;ov_read(m_pVorbisFile,&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buffer+cur_pos,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(int)leave,0/*endian*/,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2/*16-bit*/,1/*signed*/,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;current_section);<br/>leave&nbsp;&nbsp;&nbsp;-=&nbsp;bytes_read;<br/>cur_pos&nbsp;+=&nbsp;bytes_read;<br/>if(bytes_read&lt;=0)<br/>break;<br/>}while(leave&gt;0);</p><p>bytes_read&nbsp;=&nbsp;cur_pos;<br/><br/>DWORD&nbsp;dwOffset&nbsp;=&nbsp;(DWORD)length&nbsp;*&nbsp;m_dwWritePos;</p><p><br/>//&nbsp;Lock&nbsp;the&nbsp;buffer&nbsp;down<br/>if(&nbsp;FAILED(&nbsp;hr&nbsp;=&nbsp;pDSB-&gt;Lock(&nbsp;dwOffset&nbsp;,&nbsp;(DWORD)length,<br/>&amp;pDSLockedBuffer,&nbsp;&amp;dwDSLockedBufferSize,<br/>NULL,&nbsp;NULL,&nbsp;0L&nbsp;)&nbsp;)&nbsp;)<br/>{<br/>delete&nbsp;buffer;<br/>return&nbsp;;<br/>}</p><p>memcpy(pDSLockedBuffer,buffer,(size_t)bytes_read);<br/>if((size_t)bytes_read&lt;length)<br/>{<br/>memset((char*)pDSLockedBuffer&nbsp;+&nbsp;bytes_read,0,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;length-(size_t)bytes_read);<br/>if(m_bLoop)<br/>{<br/>ov_pcm_seek(m_pVorbisFile,0);<br/>}<br/>else<br/>{<br/>m_bFinished&nbsp;=&nbsp;true;<br/>}<br/>}</p><p><br/>m_dwWritePos++;<br/>m_dwWritePos&nbsp;%=&nbsp;4;</p><p><br/>//&nbsp;Unlock&nbsp;the&nbsp;buffer,&nbsp;we&nbsp;don't&nbsp;need&nbsp;it&nbsp;anymore.<br/>pDSB-&gt;Unlock(&nbsp;pDSLockedBuffer,&nbsp;dwDSLockedBufferSize,&nbsp;NULL,&nbsp;0&nbsp;);</p><p><br/>delete&nbsp;buffer;</p><p>}</p><p>
    复制代码

  • fair
    fair 2006-12-7 22:01:00

    void CALLBACK ljmMusicBuffer_DSound::OnTimerCB(
                                    UINT uID, UINT uMsg,
                                    DWORD_PTR pUserData,
                    DWORD_PTR dwParam1, 
                                    DWORD_PTR dwParam2)
    {
    ljmMusicBuffer_DSound* pObj = (ljmMusicBuffer_DSound*)pUserData;
    if(pObj)
    {
    if(pObj->m_bFinished)
    {
    pObj->Stop();
    }
    else
    {
    pObj->FillBuffer();
    }
    }
    }

你可能喜欢

用DirectSound播放OGG格式的音乐 
联系
我们
快速回复 返回顶部 返回列表