www.pudn.com > 播放mp3的控件.rar > player.cpp
#include "common.h" #include "args.h" #include "player.h" #include "helper.h" #include "stream.h" #include "audio.h" #includeMPArgs *Args; esPlayerError LastError = peNoError; HANDLE ThreadQueueEvent = NULL; HANDLE SeekEvent, SeekEvent2; unsigned long NewSeekPosition; int xxx = 0; unsigned long __stdcall PlayThread(void *ptr) { MSG msg; PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); try { Init_MPAudio(); } catch(...) { LastError = peOutputError; SetEvent(ThreadQueueEvent); return false; } SetEvent(ThreadQueueEvent); MPPlayer *Player = (MPPlayer *)ptr; try { unsigned long BytesLeft; void *p; BytesLeft = Stream_GetSize() - Stream_GetPosition(); if (BytesLeft > 16384) BytesLeft = 16384; while (BytesLeft > 0) { int NumLeft = Stream_GetSize() - Stream_GetPosition(); Args->CurrentPos = Stream_GetPosition() / Args->AudioBits * 8 / Args->SampleRate / Args->Channels * 1000; ProcessAudioMessages(); if (WaitForSingleObject(SeekEvent, 0) == WAIT_OBJECT_0) { if (Args->OutputMode == omMMSystem) { waveOutReset(WaveDevice); ProcessAudioMessages(); BufferCount = 0; } if (Seek_Stream(NewSeekPosition)) NewSeekPosition = -1; else NewSeekPosition = 0; SetEvent(SeekEvent2); } try { if (Args->CurrentPos < Args->StartPos) { continue; } if (Args->CurrentPos > Args->EndPos) break; p = malloc(BytesLeft); if (Stream_Read(p, BytesLeft)) { PlaySamples((unsigned char *)p, BytesLeft); BytesLeft = 0; } else { free(p); throw 1; } free(p); BytesLeft = Stream_GetSize() - Stream_GetPosition(); if (BytesLeft > 16384) BytesLeft = 16384; if (Player->PauseFlag) { if (Args->OutputMode = omMMSystem) Pause_Audio(); Player->ThreadSync = 1; while(Player->PauseFlag) { Sleep(77); if (Player->UserBreak) break; if (WaitForSingleObject(SeekEvent, 0) == WAIT_OBJECT_0) { if (Args->OutputMode == omMMSystem) { waveOutReset(WaveDevice); ProcessAudioMessages(); BufferCount = 0; } if (Seek_Stream(NewSeekPosition)) NewSeekPosition = -1; else NewSeekPosition = 0; SetEvent(SeekEvent2); } } if (Args->OutputMode = omMMSystem) Resume_Audio(); } if(Player->UserBreak) break; } catch (...) { throw; } } } catch (...) { int kkk = 1; } Player->EndOfTune = false; if(!Player->UserBreak) { try { FinishBuffer(); } catch (...) { } Player->EndOfTune = true; Reset_Stream(); Done_MPAudio(); Player->FPlayerMode = pmStopped; } else { if (Args->OutputMode == omMMSystem) { waveOutReset(WaveDevice); ProcessAudioMessages(); } Reset_Stream(); Done_MPAudio(); Player->FPlayerMode = pmOpened; } Player->UserBreak=0; return 0; } MPPlayer::~MPPlayer() { if (PlayerMode() > pmClosed) Close(); if (Args) delete Args; CloseHandle(SeekEvent); CloseHandle(SeekEvent2); } MPPlayer::MPPlayer() { ModuleTag = 0x14581458; Args = new MPArgs(); if (!Args) throw 1; Args->InputMode=imFile; Args->OutputMode=omMMSystem; Args->Player = this; EndOfTune = false; FPlayerMode = pmClosed; UserBreak = false; LastError = peNoError; SeekEvent = CreateEvent(NULL, false, false, NULL); SeekEvent2 = CreateEvent(NULL, false, false, NULL); }; esPlayerError MPPlayer::ESGetLastError() { esPlayerError res = LastError; LastError = peNoError; return res; } bool MPPlayer::SetInName (const char *FileName){ if (PlayerMode() != pmClosed) { LastError = peIncorrectMode; return false; } if (Args->InName) free(Args->InName); Args->InName = (char *) xstrdup((LPTSTR) FileName); return true; } bool MPPlayer::SetOutName(const char *FileName){ if (PlayerMode() >= pmPlaying) { LastError = peIncorrectMode; return false; } if (Args->OutName) free(Args->OutName); Args->OutName = (char *) xstrdup((LPTSTR) 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; } bool MPPlayer::Open(){ if ((PlayerMode() != pmClosed) || ((Args->InputMode == imFile) && (!Args->InName))) { if (PlayerMode() != pmClosed) LastError = peIncorrectMode; else LastError = peInputError; return false; } PauseFlag = 0; try { Init_Stream(); } catch (...) { LastError = peInputError; return false; } FPlayerMode = pmOpened; return true; } bool MPPlayer::InitStream(){ if ((PlayerMode() != pmOpened) && (PlayerMode() != pmStopped)) { LastError = peIncorrectMode; return false; } try { if (!Stream_ReadHeader()) { Reset_Stream(); return false; } } catch ( ... ) { return false; } if(Args->ForceMono) { Args->Channels=1; } if ((Args->SampleRate >= 48000) && (Args->OutputMode == omMMSystem)) { Args->SampleRate = Args->SampleRate/2; Args->ForceFreq = Args->SampleRate; } 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; } if (Args->EndPos == 0) SetLimits(Args->StartPos, Args->EndPos); ThreadQueueEvent = CreateEvent(NULL, false, false, NULL); if (!ThreadQueueEvent) { LastError = peInternalError; return false; } PlayThreadHan = CreateThread(NULL, 0, PlayThread, this, 0, &PlayerThreadID); WaitForSingleObject(ThreadQueueEvent, INFINITE); CloseHandle(ThreadQueueEvent); if (!PlayThreadHan) { LastError = peInternalError; return false; } if (LastError != peNoError) return false; SetThreadPriority(PlayThreadHan, Args->PlayPriority); 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; WaitForSingleObject(PlayThreadHan, INFINITE); CloseHandle(PlayThreadHan); LastError = peNoError; return true; } if (PlayerMode() == pmStopped) { FPlayerMode = pmOpened; return true; } else { LastError = peIncorrectMode; return false; } } bool MPPlayer::Close(){ if ((PlayerMode() == pmPlaying) || (PlayerMode() == pmPaused)) Stop(); if (StreamInit) { Done_Stream(); StreamInit = false; } FPlayerMode = pmClosed; return true; } unsigned long MPPlayer::GetSize(){ if (PlayerMode() > pmOpened) { return Stream_GetSize() / Args->AudioBits * 8 / Args->SampleRate / Args->Channels * 1000; } else { LastError = peIncorrectMode; return -1; } } unsigned long MPPlayer::GetPos() { if (PlayerMode() >= pmStopped) { if (PlayerMode() == pmStopped) { return Stream_GetSize() / Args->AudioBits * 8 / Args->SampleRate / Args->Channels * 1000; } return Stream_GetPosition() / Args->AudioBits * 8 / Args->SampleRate / Args->Channels * 1000; } 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)) { NewSeekPosition = NewPos; SetEvent(SeekEvent); WaitForSingleObject(SeekEvent2, INFINITE); return (NewSeekPosition == -1); } else { LastError = peIncorrectMode; return false; } } bool MPPlayer::SetAudioBuffers(unsigned long buffers, unsigned long size){ if (PlayerMode() >= pmReady) { 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) || (Args->EndPos == 0xFFFFFFFF)) { Args->EndPos = 0xFFFFFFFF; } } return true; } bool MPPlayer::SetPriority(long Priority) { if (PlayerMode() >= pmPlaying) { return SetThreadPriority(PlayThreadHan, Priority); } else { Args->PlayPriority = Priority; 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; } }