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" #include#include #include "decoder.h" MPArgs *Args; struct frame fr; esPlayerError LastError = peNoError; HANDLE ThreadQueueEvent = NULL; HANDLE SeekEvent, SeekEvent2, FinishEvent; unsigned long NewSeekPosition; int xxx = 0; void HardAudioReset(MPPlayer *ptr) { FinishBuffer(); try { Done_MPAudio(); } catch(...) {} try { Init_MPAudio(); } catch(...) { LastError = peOutputError; throw 1; return; } } void SynthesisFilterInit() { typedef int (*func)(real *,int,unsigned char * , int *); typedef int (*func_mono)(real *,unsigned char * , int *); static func funcs[2][4] = { { synth_1to1, synth_2to1, synth_4to1, synth_ntom} , { synth_1to1_8bit, synth_2to1_8bit, synth_4to1_8bit , synth_ntom_8bit} }; static func_mono funcs_mono[2][2][4] = { { { synth_1to1_mono2stereo , synth_2to1_mono2stereo , synth_4to1_mono2stereo , synth_ntom_mono2stereo } , { synth_1to1_8bit_mono2stereo , synth_2to1_8bit_mono2stereo , synth_4to1_8bit_mono2stereo , synth_ntom_8bit_mono2stereo } } , { { synth_1to1_mono , synth_2to1_mono , synth_4to1_mono , synth_ntom_mono } , { synth_1to1_8bit_mono , synth_2to1_8bit_mono , synth_4to1_8bit_mono , synth_ntom_8bit_mono } } }; fr.synth = (synthProc) funcs[Args->Force8bit][fr.down_sample]; fr.synth_mono = funcs_mono[Args->ForceMono][Args->Force8bit][fr.down_sample]; fr.block_size = 128 >> (Args->ForceMono + Args->Force8bit + fr.down_sample); if(Args->Force8bit) { Args->AudioBits=8; make_conv16to8_table(); } } unsigned long __stdcall PlayThread(void *ptr) { MMRESULT mmRes; //int clip; long numframes = -1; MSG msg; PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); try { Init_MPAudio(); } catch(...) { LastError = peOutputError; SetEvent(ThreadQueueEvent); SetEvent(FinishEvent); ExitThread(0); return 0; } SetEvent(ThreadQueueEvent); 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; Args->IsVBR = false; try { while(numframes) { if (WaitForSingleObject(SeekEvent, 0) == WAIT_OBJECT_0) { if (Args->OutputMode == omMMSystem) { mmRes = waveOutReset(WaveDevice); ProcessAudioMessages(); BufferCount = 0; } if (Seek_Stream(NewSeekPosition)) NewSeekPosition = -1; else NewSeekPosition = 0; SetEvent(SeekEvent2); } ProcessAudioMessages(); OldBits = fr.bitrate_index; try { once_more: BOOL Res = ReadFrame(); if (Res == -2) break; if(Res) Args->CurrentPos++; /*if(Args->CurrentPos > MaxFrames) break; */ if(Player->UserBreak) { break; } if (Args->CurrentPos < Args->StartFrame) { 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->SampleRate >= 48000) && (Args->OutputMode == omMMSystem)) { fr.down_sample = 1; Args->SampleRate = Args->SampleRate/2; Args->ForceFreq = Args->SampleRate; Init_MPEGDecoder(fr.down_sample); } if(Args->ForceFreq < 0) { if(Args->SampleRate != freqs[fr.sampling_frequency>>(fr.down_sample)]) { Args->SampleRate = freqs[fr.sampling_frequency>>(fr.down_sample)]; reset_audio=1; } } else if (Args->SampleRate != Args->ForceFreq) { Args->SampleRate = Args->ForceFreq; reset_audio=1; } if ((OldBits != fr.bitrate_index) && (OldBits != 0)) { Args->IsVBR = true; } if(reset_audio) { HardAudioReset(Player); } fr.header_change = 0; } if(fr.error_protection) GetBits(16); xxx = Args->CurrentPos; 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) { 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) { mmRes = waveOutReset(WaveDevice); ProcessAudioMessages(); BufferCount = 0; } if (Seek_Stream(NewSeekPosition)) NewSeekPosition = -1; else NewSeekPosition = 0; SetEvent(SeekEvent2); } } if (Args->OutputMode == omMMSystem) Resume_Audio(); } } catch (...) { throw; } } } catch (...) { int kkk = 1; } if(!Player->UserBreak) { try { AudioFlush(); FinishBuffer(); } catch (...) { } if (Decoder_Initialized) { Done_MPEGDecoder(); Decoder_Initialized = false; } Reset_Stream(); Done_MPAudio(); Player->FPlayerMode = pmStopped; } else { if (Args->OutputMode == omMMSystem) { AudioFlush(); mmRes = waveOutReset(WaveDevice); ProcessAudioMessages(); BufferCount = 0; } if (Decoder_Initialized) { Done_MPEGDecoder(); Decoder_Initialized = false; } Reset_Stream(); Done_MPAudio(); Player->FPlayerMode = pmOpened; } Player->UserBreak=0; SetEvent(FinishEvent); ExitThread(0); return 0; } MPPlayer::~MPPlayer() { if (PlayerMode() > pmClosed) Close(); if (Args) delete Args; CloseHandle(FinishEvent); CloseHandle(SeekEvent); CloseHandle(SeekEvent2); } MPPlayer::MPPlayer() { ModuleTag = 0x14581458; FinishEvent = CreateEvent(NULL, false, false, NULL); SeekEvent = CreateEvent(NULL, false, false, NULL); SeekEvent2 = CreateEvent(NULL, false, false, NULL); Args = new MPArgs(); if (!Args) throw 1; Args->InputMode=imFile; Args->OutputMode=omMMSystem; Args->Player = this; FPlayerMode = pmClosed; UserBreak = false; LastError = peNoError; fr.single = -1; fr.down_sample = 0; 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; } }; 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 { memset(&fr, 0, sizeof(fr)); fr.single = -1; if (!ReadFrame()) { Reset_Stream(); return false; } Reset_Stream(); } catch ( ... ) { return false; } Args->SampleRate = freqs[fr.sampling_frequency]; if(fr.single>=0) Args->ForceMono=1; if(Args->ForceMono) { if(fr.single<0) fr.single=3; Args->Channels=1; } if(fr.down_sample==1) { Args->SampleRate = Args->SampleRate/2; Args->ForceFreq = Args->SampleRate; } if (fr.down_sample==2) { Args->SampleRate = Args->SampleRate/4; Args->ForceFreq = Args->SampleRate; } if ((Args->SampleRate >= 48000) && (Args->OutputMode == omMMSystem)) { /* This doesn't work :((( fr.down_sample = 3; synth_ntom_set_step(12, 11); Args->ForceFreq = Args->SampleRate = 44100; */ fr.down_sample = 1; Args->SampleRate = Args->SampleRate/2; Args->ForceFreq = Args->SampleRate; } SynthesisFilterInit(); try { // create decoder Init_MPEGDecoder(fr.down_sample); make_decode_tables(Args->ScaleFactor); } catch(...){ LastError = peInternalError; return false; } 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); fr.header_change = 0; ThreadQueueEvent = CreateEvent(NULL, false, false, NULL); if (!ThreadQueueEvent) { LastError = peInternalError; return false; } ResetEvent(FinishEvent); if (PlayThreadHan) { CloseHandle(PlayThreadHan); PlayThreadHan = NULL; } PlayThreadHan = CreateThread(NULL, 0, PlayThread, this, 0, &PlayerThreadID); if (!PlayThreadHan) { LastError = peInternalError; return false; } WaitForSingleObject(ThreadQueueEvent, INFINITE); CloseHandle(ThreadQueueEvent); 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(FinishEvent, INFINITE); if (PlayThreadHan) { CloseHandle(PlayThreadHan); PlayThreadHan = NULL; } 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 Totalms(); } else { LastError = peIncorrectMode; return -1; } } unsigned long MPPlayer::GetPos() { if (PlayerMode() >= pmStopped) { if (PlayerMode() == pmStopped) { return Totalms(); } return Currentms(); } 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; if ((EndPos != 0) && (EndPos < StartPos)) { Args->EndPos = 0xFFFFFFFF; } else { Args->EndPos = EndPos; } if (PlayerMode() >= pmReady) { Args->StartFrame = Args->StartPos / Frame2ms(); if ((!Args->EndPos) || (Args->EndPos == 0xFFFFFFFF)) { Args->EndPos = 0xFFFFFFFF; Args->EndFrame = 0xFFFFFFFF; } else Args->EndFrame = Args->EndPos / Frame2ms(); } 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; } }