📄 player.cpp
字号:
#include <windows.h>
#include <math.h>
#include "maplay.h"
#include "helper.h"
#include "player.h"
#include "libovd.h"
#define INITIAL_THREAD_PRIORITY THREAD_PRIORITY_BELOW_NORMAL
CPlayer::CPlayer() :
m_Echo(TRUE), m_Reverb(FALSE)
{
m_hwndMessage = NULL;
m_szFile[0] = NULL;
m_dwThreadID = 0;
m_hThread = NULL;
m_nDuration = 0;
m_nSeek = 0;
m_nWritten = 0;
m_fSuppress = FALSE;
m_Status = MAP_STATUS_STOP;
m_StreamingStatus = MAP_STREAMING_DISABLED;
memset(&m_Info, 0, sizeof(MPEG_AUDIO_INFO));
m_fOpen = OPEN_NONE;
m_fStop = FALSE;
m_Options.nThreadPriority = THREAD_PRIORITY_ABOVE_NORMAL;
m_Output.GetOutputParam((LPDWORD)&m_Options.nOutputBufferLen,
&m_Options.fAlwaysOpenDevice, &m_Options.fFadeIn);
//m_Options.fAlwaysOpenDevice = TRUE;
m_Options.nOutputPrebuffer = 10;
m_Options.fScanMpegCompletely = FALSE;
m_Options.fFadeIn = FALSE;
m_Options.fSuppressZeroSamples = FALSE;
m_pOutHdr = NULL;
m_cbOutBuf = 0;
m_cbOutBufLeft = 0;
m_fPlay = FALSE;
m_fSeek = FALSE;
m_fFileBegin = TRUE;
m_Decoder.GetEqualizer(&m_Equalizer);
m_fPreamp = FALSE;
m_nPreamp = 31;
m_nPreampRate = PREAMP_FIXED_FLAT;
m_hOvd = NULL;
m_pOvd_buf = NULL;
m_fNet = NET_OPEN_NONE;
m_szOvdTitle[0] = NULL;
m_hAcm = NULL;
m_pwfxSrc = NULL;
m_pwfxDst = NULL;
m_llDataOffset = 0;
m_dwDataSize = 0;
m_dwCurrentSize = 0;
PlugInLoad();
}
CPlayer::~CPlayer()
{
Close();
m_Output.CloseAll();
PlugInFree();
}
BOOL CPlayer::OpenFile(LPCTSTR pszFile)
{
CAutoLock lock(&m_csecInterface);
Close();
m_fFileBegin = TRUE;
// PlugIn
if (PlugInOpenFile(pszFile))
return TRUE;
// MPEG Audio
if (MpgOpenFile(pszFile))
return TRUE;
// Ogg Vorbis
if (OvOpenFile(pszFile))
return TRUE;
// Wave
if (WavOpenFile(pszFile))
return TRUE;
return FALSE;
}
BOOL CPlayer::OpenURL(LPCTSTR pszURL)
{
CAutoLock lock(&m_csecInterface);
Close();
if (!m_Receiver.Open(pszURL))
return FALSE;
m_fOpen = OPEN_URL;
m_StreamingStatus = MAP_STREAMING_DISCONNECTED;
return TRUE;
}
void CPlayer::Close()
{
CAutoLock lock(&m_csecInterface);
Stop();
PlugInClose();
MpgClose();
OvClose();
WavClose();
NetClose();
memset(&m_Info, 0, sizeof(m_Info));
m_szFile[0] = NULL;
m_nDuration = 0;
m_fOpen = OPEN_NONE;
m_StreamingStatus = MAP_STREAMING_DISABLED;
}
BOOL CPlayer::Play()
{
CAutoLock lock(&m_csecInterface);
if (m_fOpen == OPEN_NONE)
return FALSE;
if (m_Status == MAP_STATUS_PAUSE) {
Pause();
return TRUE;
}
if (m_Status == MAP_STATUS_STOP) {
m_hThread = CreateThread(NULL, 0, PlayerThreadProc, this, 0, &m_dwThreadID);
return m_hThread != NULL;
}
return FALSE;
}
void CPlayer::Pause()
{
CAutoLock lock(&m_csecInterface);
if (m_fOpen == OPEN_NONE)
return;
if (m_fOpen == OPEN_URL)
return;
if (m_Status == MAP_STATUS_PLAY) {
UpdateStatus(MAP_STATUS_PAUSE);
m_Output.Pause(TRUE);
m_fPlay = FALSE;
}
else if (m_Status == MAP_STATUS_PAUSE) {
if (m_Output.GetBufferingCount() == m_Output.GetBufferCount())
m_Output.Pause(FALSE);
else
m_fPlay = TRUE;
UpdateStatus(MAP_STATUS_PLAY);
}
}
void CPlayer::Stop()
{
CAutoLock lock(&m_csecInterface);
if (m_hThread) {
m_fStop = TRUE;
m_Receiver.Stop();
m_Output.Reset();
WaitForSingleObject(m_hThread, INFINITE);
CloseHandle(m_hThread);
m_hThread = NULL;
}
m_nSeek = 0;
m_nWritten = 0;
m_fSuppress = FALSE;
m_fPlay = FALSE;
m_fStop = FALSE;
m_fSeek = FALSE;
Seek(0);
}
BOOL CPlayer::Ff(long lSkip)
{
CAutoLock lock(&m_csecInterface);
if (m_fOpen == OPEN_NONE)
return FALSE;
LONG lTime = GetCurrent();
lTime += lSkip;
return Seek(lTime);
}
BOOL CPlayer::Rew(long lSkip)
{
CAutoLock lock(&m_csecInterface);
if (m_fOpen == OPEN_NONE)
return FALSE;
LONG lTime = GetCurrent();
lTime -= lSkip;
return Seek(lTime);
}
BOOL CPlayer::Seek(long lTime)
{
CAutoLock lock(&m_csecInterface);
CAutoLock lock2(&m_csecThread);
if (m_fOpen == OPEN_NONE)
return FALSE;
// 帪娫偺僠僃僢僋
if (lTime < 0)
lTime = 0;
if (lTime >= int((double)m_nDuration / m_Info.nSamplingRate * 1000))
return FALSE;
BOOL fRet = FALSE;
if (m_fOpen == OPEN_PLUGIN)
fRet = PlugInSeekFile(lTime);
else if (m_fOpen == OPEN_MPG_FILE)
fRet = MpgSeekFile(lTime);
else if (m_fOpen == OPEN_OV_FILE)
fRet = OvSeekFile(lTime);
else if (m_fOpen == OPEN_WAV_FILE)
fRet = WavSeekFile(lTime);
m_fFileBegin = m_nSeek == 0;
if (fRet) {
m_nWritten = 0;
m_fSuppress = FALSE;
SetThreadPriority(m_hThread, INITIAL_THREAD_PRIORITY);
}
return fRet;
}
void CPlayer::SetMessageWindow(HWND hwndMessage)
{
m_hwndMessage = hwndMessage;
m_Receiver.SetMessageWindow(hwndMessage);
}
long CPlayer::GetCurrent()
{
CAutoLock lock(&m_csecInterface);
if (m_fOpen == OPEN_NONE)
return 0;
if (GetStatus() == MAP_STATUS_STOP)
return (int)(((double)m_nSeek) * 1000 / m_Info.nSamplingRate);
else
return (int)(((double)m_Output.GetCurrent() + m_nSeek) * 1000 / m_Info.nSamplingRate);
}
long CPlayer::GetDuration()
{
if (m_fOpen == OPEN_NONE)
return 0;
return (int)((double)m_nDuration / m_Info.nSamplingRate * 1000);
}
MAP_STATUS CPlayer::GetStatus()
{
return m_Status;
}
void CPlayer::SetEqualizer(EQUALIZER* value)
{
m_Equalizer = *value;
m_Decoder.SetEqualizer(&m_Equalizer);
m_fPreamp = value->fEnable;
m_nPreamp = value->preamp;
double dLevel = -((double)value->preamp - 31) * 20 / 31;
m_nPreampRate = (int)(pow(10, dLevel / 20) * PREAMP_FIXED_FLAT);
PlugInSetEqualizer();
}
void CPlayer::GetEqualizer(EQUALIZER* value)
{
*value = m_Equalizer;
}
void CPlayer::SetEffect(int nEffect, EFFECT* value)
{
switch (nEffect) {
case EFFECT_REVERB:
m_Reverb.SetParameter(value);
break;
case EFFECT_ECHO:
m_Echo.SetParameter(value);
break;
case EFFECT_SURROUND:
m_Surround.SetParameter(value);
break;
case EFFECT_3DCHORUS:
m_3DChorus.SetParameter(value);
break;
}
}
void CPlayer::GetEffect(int nEffect, EFFECT* value)
{
switch (nEffect) {
case EFFECT_REVERB:
m_Reverb.GetParameter(value);
break;
case EFFECT_ECHO:
m_Echo.GetParameter(value);
break;
case EFFECT_SURROUND:
m_Surround.GetParameter(value);
break;
case EFFECT_3DCHORUS:
m_3DChorus.GetParameter(value);
break;
}
}
void CPlayer::SetBassBoostLevel(int nLevel)
{
m_BassBoost.SetLevel(nLevel);
}
int CPlayer::GetBassBoostLevel()
{
return m_BassBoost.GetLevel();
}
void CPlayer::GetFileInformation(MAP_INFORMATION* pInfo)
{
if (m_fOpen == OPEN_NONE)
return;
pInfo->nBitRate = m_Info.nBitRate;
pInfo->nChannels = m_Info.nChannels;
pInfo->nLayer = m_Info.nLayer;
pInfo->nSamplingRate = m_Info.nSamplingRate;
pInfo->nVersion = m_Info.nVersion;
pInfo->nDuration = (int)((double)m_nDuration / m_Info.nSamplingRate * 1000);
}
BOOL CPlayer::GetId3Tag(ID3TAGV1* pTag)
{
if (m_fOpen == OPEN_MPG_FILE)
return MpgGetId3Tag(pTag);
else if (m_fOpen == OPEN_OV_FILE)
return OvGetId3Tag(pTag);
else if (m_fOpen == OPEN_PLUGIN)
return PlugInGetId3Tag(pTag);
return FALSE;
}
BOOL CPlayer::SetId3Tag(ID3TAGV1* pTag)
{
return FALSE; // not support
}
BOOL CPlayer::GetStreamInfo(LPTSTR pszName, LPTSTR pszGenre, LPTSTR pszURL)
{
return m_Receiver.GetStreamInfo(pszName, pszGenre, pszURL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -