www.pudn.com > 播放mp3的控件.rar > player.cpp
#include "args.h" #include "player.h" #include "helper.h" #include "audio.h" #include#include "..\SDK\include\wmaudiosdk.h" MPArgs *Args; esPlayerError LastError; void HardAudioReset(MPPlayer *ptr){ if(ptr !=NULL) { try { Done_MPAudio(); } catch(...) {} try { Init_MPAudio(); } catch(...) { LastError = peOutputError; throw 1; return; } } } /* unsigned long __stdcall PlayThread(void *ptr) { long FreqIndex[7]={44100,48000,32000,22050,24000,16000,11025}; int clip; long OldRate = 0, NewRate = 0; int OldBits = 0, OldChannel = 0; //unsigned long left,right; unsigned long FrameNum = 0; long OldScaleFactor = 32768; MPPlayer *Player = (MPPlayer *)ptr; try { while(numframes) { once_more: BOOL Res = ReadFrame(); if(Res) Args->CurrentPos++; if(Args->CurrentPos >= MaxFrames) break; if (Args->CurrentPos < Args->StartFrame) { if(fr.lay == 3) SetPointer(512); continue; } if(Args->CurrentPos > Args->EndFrame) break; if(!Res && Res !=-2) goto once_more; numframes--; if(OldScaleFactor != Args->ScaleFactor) { make_decode_tables(Args->ScaleFactor); OldScaleFactor = Args->ScaleFactor; } if(fr.header_change){ int reset_audio=0; if(Args->ForceFreq < 0) { if(Args->SampleRate != FreqIndex[fr.sampling_frequency>>(fr.down_sample)]) { Args->SampleRate = FreqIndex[fr.sampling_frequency>>(fr.down_sample)]; reset_audio=1; } } else if(Args->SampleRate != Args->ForceFreq) { Args->SampleRate = Args->ForceFreq; reset_audio=1; } if(reset_audio) { HardAudioReset(Player); } fr.header_change = 0; } if(fr.error_protection) GetBits(16); if(fr.WhatLayer==3) clip=do_layer3(); else if(fr.WhatLayer==2) clip=do_layer2(); else if(fr.WhatLayer==1) clip=do_layer1(); if (Player->PauseFlag) { Player->ThreadSync = 1; while(Player->PauseFlag){ Sleep(77); if (Player->UserBreak) break; } } if(Player->UserBreak) break; } } catch (...) { } Player->EndOfTune = false; if(!Player->UserBreak){ try { FinishBuffer(); } catch (...) {} Player->EndOfTune = true; Player->FPlayerMode = pmStopped; } else { Player->FPlayerMode = pmOpened; } Reset_Stream(); Done_MPAudio(); Player->UserBreak=0; return 0; } */ MPPlayer::~MPPlayer() { if (PlayerMode() > pmClosed) Close(); if( m_pReader != NULL ) { m_pReader->Release(); m_pReader = NULL; } if (Args) delete Args; } MPPlayer::MPPlayer() { ModuleTag = 0x14581458; m_pReader = NULL; Args = new MPArgs(); if (!Args) throw 1; Args->InputMode=imFile; Args->OutputMode=omMMSystem; EndOfTune = false; FPlayerMode = pmClosed; UserBreak = false; LastError = peNoError; m_cRef = 1; /*equalizer_cnt=0; for(int i=0; i<32; i++) { equalizer[0][i]=equalizer[1][i]=1.0; equalizer_sum[0][i]=equalizer_sum[1][i]=0.0; }*/ }; HRESULT STDMETHODCALLTYPE MPPlayer::QueryInterface( REFIID riid, void **ppvObject ) { return( E_NOINTERFACE ); } /////////////////////////////////////////////////////////////////////////////// ULONG STDMETHODCALLTYPE MPPlayer::AddRef() { return( InterlockedIncrement( &m_cRef ) ); } /////////////////////////////////////////////////////////////////////////////// ULONG STDMETHODCALLTYPE MPPlayer::Release() { ULONG uRet = InterlockedDecrement( &m_cRef ); if( 0 == uRet ) { delete this; } return( uRet ); } /////////////////////////////////////////////////////////////////////////////// HRESULT STDMETHODCALLTYPE MPPlayer::OnSample( /* [in] */ const BYTE *pData, /* [in] */ DWORD cbData, /* [in] */ DWORD dwMsTime ) { try { int i; Args->BufferSize = cbData; i = cbData * 1000 / (Args->Channels * Args->SampleRate * Args->AudioBits / 8); Args->Position += i; //Args->Position += dwMsTime; if (Player->PauseFlag) { while(Player->PauseFlag) { Sleep(77); if (Player->UserBreak) break; } } if (Args->Position > Args->EndPos) { m_pReader->Stop(); try { FinishBuffer(); } catch (...) {} Done_MPAudio(); FPlayerMode = pmStopped; return S_OK; } PlaySamples((unsigned char *) pData, cbData); return S_OK; } catch ( ... ) { return E_FAIL; } } esPlayerError MPPlayer::ESGetLastError() { esPlayerError res = LastError; LastError = peNoError; return res; } bool MPPlayer::SetInName (char *FileName){ if (PlayerMode() != pmClosed) { LastError = peIncorrectMode; return false; } if (Args->InName) free(Args->InName); Args->InName = xstrdup(FileName); return true; } bool MPPlayer::SetOutName(char *FileName){ if (PlayerMode() >= pmPlaying) { LastError = peIncorrectMode; return false; } if (Args->OutName) free(Args->OutName); Args->OutName = xstrdup(FileName); return true; } bool MPPlayer::SetInMode (esInputMode InMode){ if (PlayerMode() > pmClosed) { LastError = peIncorrectMode; return false; } Args->InputMode = InMode; return true; } bool MPPlayer::SetOutMode(esOutputMode OutMode){ if (PlayerMode() >= pmPlaying) { LastError = peIncorrectMode; return false; } #ifndef _DIRECTX if (OutMode == omDirectSound) { LastError = peNotImplemented; return false; } #endif Args->OutputMode = OutMode; return true; } HRESULT STDMETHODCALLTYPE MPPlayer::OnStatus( /* [in] */ WMT_STATUS Status, /* [in] */ HRESULT hr, /* [in] */ const VARIANT *pParam ) { switch( Status ) { case WMT_NO_RIGHTS: case WMT_MISSING_CODEC: case WMT_ERROR: LastError = peInternalError; m_pReader->Stop(); try { FinishBuffer(); } catch (...) { } Done_MPAudio(); FPlayerMode = pmOpened; break; case WMT_BUFFERING_START: break; case WMT_BUFFERING_STOP: break; case WMT_EOF: try { FinishBuffer(); } catch (...) { } m_pReader->Stop(); Done_MPAudio(); FPlayerMode = pmStopped; break; case WMT_LOCATING: break; case WMT_CONNECTING: break; }; return( S_OK ); } bool MPPlayer::Open() { ZeroMemory(&StreamInfo, sizeof TextInfo); if ((PlayerMode() != pmClosed) || ((Args->InputMode == imFile) && (!Args->InName))) { if (PlayerMode() != pmClosed) LastError = peIncorrectMode; else LastError = peInputError; return false; } PauseFlag = 0; Args->Position = 0; WCHAR szUrl[1024]; try { if( 0 == MultiByteToWideChar( CP_ACP, 0, Args->InName, strlen(Args->InName) + 1, szUrl, 1024 ) ) { LastError = peInternalError; return false; } if (FAILED(WMAudioCreateReader(szUrl, this, &m_pReader, NULL))) { LastError = peInputError; return false; } } catch (...) { LastError = peInputError; return false; } FPlayerMode = pmOpened; return true; } bool MPPlayer::InitStream(){ if (PlayerMode() != pmOpened) { LastError = peIncorrectMode; return false; } WORD i, AttrCount; hr = m_pReader->GetAttributeCount(&AttrCount); if (hr != S_OK) { LastError = peInputError; return false; } Args->SampleRate = 0; WCHAR wName[512]; WORD cbNamelen; WMT_ATTR_DATATYPE type; BYTE pValue[512]; WORD cbLength; char buff[512]; for (i = 0; i < AttrCount; i++) { cbNamelen = sizeof ( wName ); cbLength = sizeof( pValue ); hr = m_pReader->GetAttributeByIndex(i, wName, &cbNamelen, &type, pValue, &cbLength ); if (FAILED(hr)) { if ( hr == E_NOTIMPL ) { continue; } LastError = peInputError; return false; } switch ( type ) { case WMT_TYPE_DWORD: if (wcscmp(wName, g_wszWMADuration) == 0) { Args->SLength = *((DWORD *) pValue); } if (wcscmp(wName, g_wszWMABitrate) == 0) { Args->bitrate = *((DWORD *) pValue); } break; case WMT_TYPE_STRING: if( 0 == WideCharToMultiByte( CP_ACP, 0, (WCHAR *)pValue, -1, buff, 511, NULL, NULL ) ) { continue; } if (wcscmp(wName, g_wszWMAAlbumTitle) == 0) { strcpy(StreamInfo.Album, buff); } if (wcscmp(wName, g_wszWMATitle) == 0) { strcpy(StreamInfo.Title, buff); } if (wcscmp(wName, g_wszWMAAuthor) == 0) { strcpy(StreamInfo.Artist, buff); } if (wcscmp(wName, g_wszWMACopyright) == 0) { strcpy(StreamInfo.Copyright, buff); } if (wcscmp(wName, g_wszWMADescription) == 0) { strcpy(StreamInfo.Comment, buff); } if (wcscmp(wName, g_wszWMAGenre) == 0) { strcpy(StreamInfo.Genre, buff); } if (wcscmp(wName, L"WM/Year") == 0) { strcpy(StreamInfo.Year, buff); } break; case WMT_TYPE_BOOL: if (wcscmp(wName, g_wszWMASeekable) == 0) { Args->Seekable = *((BOOL *) pValue); } break; default: break; } } // for Args->Position = 0; WAVEFORMATEX waveFmt; hr = m_pReader->GetOutputFormat(&waveFmt, sizeof waveFmt); if (hr != S_OK) { LastError = peInputError; return false; } Args->Channels = waveFmt.nChannels; Args->SampleRate = waveFmt.nSamplesPerSec; Args->AudioBits = waveFmt.wBitsPerSample; FPlayerMode = pmReady; return true; } bool MPPlayer::Play() { if (PlayerMode() != pmReady) { LastError = peIncorrectMode; return false; } if ((Args->OutputMode == omCallback) && ((!Args->BufferCB) || (!Args->OutActionCB))) { LastError = peNoCallback; return false; } try { Init_MPAudio(); } catch(...){ return false; } if (Args->EndPos == 0) SetLimits(Args->StartPos, Args->EndPos); hr = m_pReader->Seek(Args->StartPos); if (hr == S_OK) { Args->Position = Args->StartPos; } else { hr = m_pReader->Seek(0); if (hr != S_OK) { LastError = peInputError; return false; } Args->Position = 0; } hr = m_pReader->Start(); if (hr != S_OK) { LastError = peInputError; return false; } FPlayerMode = pmPlaying; return true; } bool MPPlayer::Pause(){ if ((PlayerMode() == pmPlaying) || (PlayerMode() == pmPaused)) { PauseFlag = true; FPlayerMode = pmPaused; return true; } else { LastError = peIncorrectMode; return false; } } bool MPPlayer::Resume(){ if ((PlayerMode() == pmPlaying) || (PlayerMode() == pmPaused)) { PauseFlag = false; FPlayerMode = pmPlaying; return true; } else { LastError = peIncorrectMode; return false; } } bool MPPlayer::Stop(){ if ((PlayerMode() == pmPlaying) || (PlayerMode() == pmPaused)) { UserBreak = 1; m_pReader->Stop(); Done_MPAudio(); UserBreak = 0; FPlayerMode = pmOpened; return true; } if (PlayerMode() == pmStopped) { FPlayerMode = pmOpened; return true; } else { LastError = peIncorrectMode; return false; } } bool MPPlayer::Close(){ if ((PlayerMode() == pmPlaying) || (PlayerMode() == pmPaused)) Stop(); if (m_pReader) { m_pReader->Release(); m_pReader = NULL; } FPlayerMode = pmClosed; return true; } unsigned long MPPlayer::GetSize(){ if (PlayerMode() > pmOpened) { return Args->SLength; } else { LastError = peIncorrectMode; return -1; } } unsigned long MPPlayer::GetPos(){ if (PlayerMode() >= pmStopped) { if (PlayerMode() == pmStopped) { return Args->SLength; } return Args->Position; } else { LastError = peIncorrectMode; return -1; } } bool MPPlayer::CanSetPos() { if (PlayerMode() >= pmOpened) { return Args->Seekable; } else { LastError = peIncorrectMode; return false; } } bool MPPlayer::SetPos(unsigned long NewPos){ if ((PlayerMode() == pmPlaying) || (PlayerMode() == pmPaused)) { MPAudioEvents[2] = 1; if (Args->OutputMode != omDirectSound) FinishBuffer(); MPAudioEvents[2] = 0; m_pReader->Stop(); hr = m_pReader->Seek(NewPos); m_pReader->Start(); if (hr == S_OK) { Args->Position = NewPos; } return true; } else { LastError = peIncorrectMode; return false; } } bool MPPlayer::SetAudioBuffers(unsigned long buffers, unsigned long size){ if (PlayerMode() >= pmPlaying) { LastError = peIncorrectMode; return false; } else { if (buffers) Args->Buffers = buffers; if (size) Args->BufferSize = size; } return true; } bool MPPlayer::SetOutputDevice(unsigned long DevNum) { if (PlayerMode() != pmClosed) { LastError = peIncorrectMode; return false; } else { Args->AudioDevice = DevNum; return true; } } bool MPPlayer::SetLimits(unsigned long StartPos, unsigned long EndPos) { Args->StartPos = StartPos; EndPos < StartPos ? Args->EndPos = StartPos : Args->EndPos = EndPos; if (PlayerMode() >= pmReady) { if (Args->EndPos == 0) { Args->EndPos = 0xFFFFFFFF; } } return true; } esPlayerMode MPPlayer::PlayerMode() { //esPlayerMode mode = FPlayerMode; //if (mode == pmStopped) FPlayerMode = pmOpened; return FPlayerMode; } bool MPPlayer::SetInCB(InFileOpenCB openCB, InFileCloseCB closeCB, InFileGetSizeCB getsizeCB, InFileSeekCB seekCB, InFileReadCB readCB, unsigned long UserData1) { if (PlayerMode() != pmClosed) { LastError = peIncorrectMode; return false; } Args->InOpenCB = openCB; Args->InCloseCB = closeCB; Args->InGetSizeCB = getsizeCB; Args->InSeekCB = seekCB; Args->InReadCB = readCB; Args->InCBData1 = UserData1; return true; } bool MPPlayer::SetOutCB(WaveOutCB OutCB, WaveOutActionCB OutActionCB, unsigned long UserData) { if (PlayerMode() >= pmPlaying) { LastError = peIncorrectMode; return false; } else { Args->BufferCB = (WaveOutCB) OutCB; Args->OutActionCB = (WaveOutActionCB) OutActionCB; Args->OutCBData = UserData; return true; } } bool MPPlayer::CanSetVolume(bool *Separate) { return Audio_CanSetVolume(Separate); } bool MPPlayer::SetVolume(unsigned long Volume) { return Audio_SetVolume(Volume); } bool MPPlayer::GetVolume(unsigned long *Volume){ return Audio_GetVolume(Volume); } bool MPPlayer::SetDevNum(unsigned long DevNum) { if (PlayerMode() >= pmPlaying) { LastError = peIncorrectMode; return false; } else { Args->AudioDevice = DevNum; return true; } } bool MPPlayer::SetWindow(HWND Wnd) { if (PlayerMode() >= pmPlaying) { LastError = peIncorrectMode; return false; } else { Args->wnd = Wnd; return true; } } bool MPPlayer::UseOutCB(bool UseCB) { if (PlayerMode() >= pmPlaying) { LastError = peIncorrectMode; return false; } else { Args->UseHdrCB = UseCB; return true; } }