分离Music和Player类

This commit is contained in:
Nomango 2018-05-17 23:53:27 +08:00
parent b2ec817c81
commit 5ab9d822f3
10 changed files with 513 additions and 423 deletions

View File

@ -203,6 +203,8 @@ void e2d::Game::destroy()
ColliderManager::__uninit();
// 删除动作
ActionManager::__uninit();
// 回收音乐播放器资源
Player::__uninit();
// 删除所有对象
ObjectManager::__clear();
// 清空图片缓存
@ -213,9 +215,7 @@ void e2d::Game::destroy()
Timer::__uninit();
// 关闭输入
Input::__uninit();
// 恢复计时操作
Time::__uninit();
// 删除渲染相关资源
// 回收渲染相关资源
Renderer::__discardResources();
// 销毁窗口
Window::__uninit();

View File

@ -48,10 +48,6 @@ bool e2d::Time::__init()
return true;
}
void e2d::Time::__uninit()
{
}
bool e2d::Time::__isReady()
{
return s_tExceptedInvertal < duration_cast<milliseconds>(s_tNow - s_tFixedUpdate);

View File

@ -1,6 +1,4 @@
#include "..\e2dtool.h"
#include "..\e2dmanager.h"
#include <map>
#ifndef SAFE_DELETE
@ -22,109 +20,72 @@ inline bool TraceError(wchar_t* sPrompt, HRESULT hr)
return false;
}
static IXAudio2 * s_pXAudio2 = nullptr;
static IXAudio2MasteringVoice * s_pMasteringVoice = nullptr;
static float s_fMusicVolume = 1.0;
// ÒôÀÖ²¥·ÅÆ÷
class MusicPlayer
{
public:
MusicPlayer();
virtual ~MusicPlayer();
bool open(
const e2d::String& filePath
);
bool MusicPlayer::open(
int resNameId,
const e2d::String& resType
);
bool play(
int nLoopCount = 0
);
void pause();
void resume();
void stop();
void close();
bool setVolume(
float fVolume
);
bool isPlaying() const;
protected:
bool _readMMIO();
bool _resetFile();
bool _read(
BYTE* pBuffer,
DWORD dwSizeToRead
);
bool _findMediaFileCch(
wchar_t* strDestPath,
int cchDest,
const wchar_t * strFilename
);
protected:
bool _bOpened;
mutable bool _bPlaying;
DWORD _dwSize;
CHAR* _pResourceBuffer;
BYTE* _pbWaveData;
HMMIO _hmmio;
MMCKINFO _ck;
MMCKINFO _ckRiff;
WAVEFORMATEX* _pwfx;
IXAudio2SourceVoice* _pSourceVoice;
};
typedef std::map<UINT, MusicPlayer *> MusicMap;
static MusicMap& GetMusicFileList()
{
static MusicMap s_MusicFileList;
return s_MusicFileList;
}
static MusicMap& GetMusicResList()
{
static MusicMap s_MusicResList;
return s_MusicResList;
}
MusicPlayer::MusicPlayer()
: _bOpened(false)
, _bPlaying(false)
, _pwfx(nullptr)
e2d::Music::Music()
: _opened(false)
, _playing(false)
, _wfx(nullptr)
, _hmmio(nullptr)
, _pResourceBuffer(nullptr)
, _pbWaveData(nullptr)
, _resBuffer(nullptr)
, _waveData(nullptr)
, _dwSize(0)
, _pSourceVoice(nullptr)
, _voice(nullptr)
{
}
MusicPlayer::~MusicPlayer()
e2d::Music::Music(const e2d::String & filePath)
: _opened(false)
, _playing(false)
, _wfx(nullptr)
, _hmmio(nullptr)
, _resBuffer(nullptr)
, _waveData(nullptr)
, _dwSize(0)
, _voice(nullptr)
{
this->open(filePath);
}
e2d::Music::Music(int resNameId, const String & resType)
: _opened(false)
, _playing(false)
, _wfx(nullptr)
, _hmmio(nullptr)
, _resBuffer(nullptr)
, _waveData(nullptr)
, _dwSize(0)
, _voice(nullptr)
{
this->open(resNameId, resType);
}
e2d::Music::~Music()
{
close();
}
bool MusicPlayer::open(const e2d::String& filePath)
e2d::Music * e2d::Music::create()
{
if (_bOpened)
return Create<Music>();
}
e2d::Music * e2d::Music::create(const e2d::String & filePath)
{
return Create<Music>(filePath);
}
e2d::Music * e2d::Music::create(int resNameId, const String & resType)
{
return Create<Music>(resNameId, resType);
}
bool e2d::Music::open(const e2d::String& filePath)
{
if (_opened)
{
WARN_IF(true, "MusicInfo can be opened only once!");
return false;
@ -171,37 +132,37 @@ bool MusicPlayer::open(const e2d::String& filePath)
_dwSize = _ck.cksize;
// 将样本数据读取到内存中
_pbWaveData = new (std::nothrow) BYTE[_dwSize];
_waveData = new (std::nothrow) BYTE[_dwSize];
if (!_read(_pbWaveData, _dwSize))
if (!_read(_waveData, _dwSize))
{
TraceError(L"Failed to read WAV data");
SAFE_DELETE_ARRAY(_pbWaveData);
SAFE_DELETE_ARRAY(_waveData);
return false;
}
// 创建音源
HRESULT hr;
if (FAILED(hr = s_pXAudio2->CreateSourceVoice(&_pSourceVoice, _pwfx)))
if (FAILED(hr = s_pXAudio2->CreateSourceVoice(&_voice, _wfx)))
{
TraceError(L"Create source voice error", hr);
SAFE_DELETE_ARRAY(_pbWaveData);
SAFE_DELETE_ARRAY(_waveData);
return false;
}
_bOpened = true;
_bPlaying = false;
_opened = true;
_playing = false;
return true;
}
bool MusicPlayer::open(int resNameId, const e2d::String& resType)
bool e2d::Music::open(int resNameId, const e2d::String& resType)
{
HRSRC hResInfo;
HGLOBAL hResData;
DWORD dwSize;
void* pvRes;
if (_bOpened)
if (_opened)
{
WARN_IF(true, "MusicInfo can be opened only once!");
return false;
@ -213,7 +174,6 @@ bool MusicPlayer::open(int resNameId, const e2d::String& resType)
return false;
}
// Loading it as a file failed, so try it as a resource
if (nullptr == (hResInfo = FindResourceW(HINST_THISCOMPONENT, MAKEINTRESOURCE(resNameId), resType)))
return TraceError(L"FindResource");
@ -226,20 +186,20 @@ bool MusicPlayer::open(int resNameId, const e2d::String& resType)
if (nullptr == (pvRes = LockResource(hResData)))
return TraceError(L"LockResource");
_pResourceBuffer = new (std::nothrow) CHAR[dwSize];
memcpy(_pResourceBuffer, pvRes, dwSize);
_resBuffer = new (std::nothrow) CHAR[dwSize];
memcpy(_resBuffer, pvRes, dwSize);
MMIOINFO mmioInfo;
ZeroMemory(&mmioInfo, sizeof(mmioInfo));
mmioInfo.fccIOProc = FOURCC_MEM;
mmioInfo.cchBuffer = dwSize;
mmioInfo.pchBuffer = (CHAR*)_pResourceBuffer;
mmioInfo.pchBuffer = (CHAR*)_resBuffer;
_hmmio = mmioOpen(nullptr, &mmioInfo, MMIO_ALLOCBUF | MMIO_READ);
if (!_readMMIO())
{
// ReadMMIO will fail if its an not a wave file
// 读取非 wave 文件时 ReadMMIO 调用失败
mmioClose(_hmmio, 0);
return TraceError(L"ReadMMIO");
}
@ -247,48 +207,48 @@ bool MusicPlayer::open(int resNameId, const e2d::String& resType)
if (!_resetFile())
return TraceError(L"ResetFile");
// After the reset, the size of the wav file is _ck.cksize so store it now
// 重置文件后wave 文件的大小是 _ck.cksize
_dwSize = _ck.cksize;
// Read the sample data into memory
_pbWaveData = new (std::nothrow) BYTE[_dwSize];
// 将样本数据读取到内存中
_waveData = new (std::nothrow) BYTE[_dwSize];
if (!_read(_pbWaveData, _dwSize))
if (!_read(_waveData, _dwSize))
{
TraceError(L"Failed to read WAV data");
SAFE_DELETE_ARRAY(_pbWaveData);
SAFE_DELETE_ARRAY(_waveData);
return false;
}
// 创建音源
HRESULT hr;
if (FAILED(hr = s_pXAudio2->CreateSourceVoice(&_pSourceVoice, _pwfx)))
if (FAILED(hr = s_pXAudio2->CreateSourceVoice(&_voice, _wfx)))
{
TraceError(L"Create source voice error", hr);
SAFE_DELETE_ARRAY(_pbWaveData);
SAFE_DELETE_ARRAY(_waveData);
return false;
}
_bOpened = true;
_bPlaying = false;
_opened = true;
_playing = false;
return true;
}
bool MusicPlayer::play(int nLoopCount)
bool e2d::Music::play(int nLoopCount)
{
if (!_bOpened)
if (!_opened)
{
WARN_IF(true, "MusicInfo::play Failed: MusicInfo must be opened first!");
return false;
}
if (_pSourceVoice == nullptr)
if (_voice == nullptr)
{
WARN_IF(true, "MusicInfo::play Failed: IXAudio2SourceVoice Null pointer exception!");
return false;
}
if (_bPlaying)
if (_playing)
{
stop();
}
@ -298,71 +258,72 @@ bool MusicPlayer::play(int nLoopCount)
// 提交 wave 样本数据
XAUDIO2_BUFFER buffer = { 0 };
buffer.pAudioData = _pbWaveData;
buffer.pAudioData = _waveData;
buffer.Flags = XAUDIO2_END_OF_STREAM;
buffer.AudioBytes = _dwSize;
buffer.LoopCount = nLoopCount;
HRESULT hr;
if (FAILED(hr = _pSourceVoice->SubmitSourceBuffer(&buffer)))
if (FAILED(hr = _voice->SubmitSourceBuffer(&buffer)))
{
TraceError(L"Submitting source buffer error", hr);
_pSourceVoice->DestroyVoice();
SAFE_DELETE_ARRAY(_pbWaveData);
_voice->DestroyVoice();
SAFE_DELETE_ARRAY(_waveData);
return false;
}
if (SUCCEEDED(hr = _pSourceVoice->Start(0)))
if (SUCCEEDED(hr = _voice->Start(0)))
{
_bPlaying = true;
// 播放成功,保留这个对象
_playing = true;
}
return SUCCEEDED(hr);
}
void MusicPlayer::pause()
void e2d::Music::pause()
{
if (_pSourceVoice)
if (_voice)
{
if (SUCCEEDED(_pSourceVoice->Stop()))
if (SUCCEEDED(_voice->Stop()))
{
_bPlaying = false;
_playing = false;
}
}
}
void MusicPlayer::resume()
void e2d::Music::resume()
{
if (_pSourceVoice)
if (_voice)
{
if (SUCCEEDED(_pSourceVoice->Start()))
if (SUCCEEDED(_voice->Start()))
{
_bPlaying = true;
_playing = true;
}
}
}
void MusicPlayer::stop()
void e2d::Music::stop()
{
if (_pSourceVoice)
if (_voice)
{
if (SUCCEEDED(_pSourceVoice->Stop()))
if (SUCCEEDED(_voice->Stop()))
{
_pSourceVoice->ExitLoop();
_pSourceVoice->FlushSourceBuffers();
_bPlaying = false;
_voice->ExitLoop();
_voice->FlushSourceBuffers();
_playing = false;
}
}
}
void MusicPlayer::close()
void e2d::Music::close()
{
if (_pSourceVoice)
if (_voice)
{
_pSourceVoice->Stop();
_pSourceVoice->FlushSourceBuffers();
_pSourceVoice->DestroyVoice();
_pSourceVoice = nullptr;
_voice->Stop();
_voice->FlushSourceBuffers();
_voice->DestroyVoice();
_voice = nullptr;
}
if (_hmmio != nullptr)
@ -371,26 +332,26 @@ void MusicPlayer::close()
_hmmio = nullptr;
}
SAFE_DELETE_ARRAY(_pResourceBuffer);
SAFE_DELETE_ARRAY(_pbWaveData);
SAFE_DELETE_ARRAY(_pwfx);
SAFE_DELETE_ARRAY(_resBuffer);
SAFE_DELETE_ARRAY(_waveData);
SAFE_DELETE_ARRAY(_wfx);
_bOpened = false;
_bPlaying = false;
_opened = false;
_playing = false;
}
bool MusicPlayer::isPlaying() const
bool e2d::Music::isPlaying() const
{
if (_bOpened && _pSourceVoice)
if (_opened && _voice)
{
XAUDIO2_VOICE_STATE state;
_pSourceVoice->GetState(&state);
_voice->GetState(&state);
if (state.BuffersQueued == 0)
{
_bPlaying = false;
_playing = false;
}
return _bPlaying;
return _playing;
}
else
{
@ -398,23 +359,28 @@ bool MusicPlayer::isPlaying() const
}
}
bool MusicPlayer::setVolume(float fVolume)
IXAudio2SourceVoice * e2d::Music::getIXAudio2SourceVoice() const
{
if (_pSourceVoice)
return _voice;
}
bool e2d::Music::setVolume(double volume)
{
return SUCCEEDED(_pSourceVoice->SetVolume(fVolume));
if (_voice)
{
return SUCCEEDED(_voice->SetVolume(float(volume)));
}
return false;
}
bool MusicPlayer::_readMMIO()
bool e2d::Music::_readMMIO()
{
MMCKINFO ckIn;
PCMWAVEFORMAT pcmWaveFormat;
memset(&ckIn, 0, sizeof(ckIn));
_pwfx = nullptr;
_wfx = nullptr;
if ((0 != mmioDescend(_hmmio, &_ckRiff, nullptr, 0)))
return TraceError(L"mmioDescend");
@ -442,11 +408,11 @@ bool MusicPlayer::_readMMIO()
// 的数据,这个数据就是额外分配的大小
if (pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_PCM)
{
_pwfx = (WAVEFORMATEX*) new (std::nothrow) CHAR[sizeof(WAVEFORMATEX)];
_wfx = (WAVEFORMATEX*) new (std::nothrow) CHAR[sizeof(WAVEFORMATEX)];
// 拷贝数据
memcpy(_pwfx, &pcmWaveFormat, sizeof(pcmWaveFormat));
_pwfx->cbSize = 0;
memcpy(_wfx, &pcmWaveFormat, sizeof(pcmWaveFormat));
_wfx->cbSize = 0;
}
else
{
@ -455,31 +421,31 @@ bool MusicPlayer::_readMMIO()
if (mmioRead(_hmmio, (CHAR*)&cbExtraBytes, sizeof(WORD)) != sizeof(WORD))
return TraceError(L"mmioRead");
_pwfx = (WAVEFORMATEX*) new (std::nothrow) CHAR[sizeof(WAVEFORMATEX) + cbExtraBytes];
_wfx = (WAVEFORMATEX*) new (std::nothrow) CHAR[sizeof(WAVEFORMATEX) + cbExtraBytes];
// 拷贝数据
memcpy(_pwfx, &pcmWaveFormat, sizeof(pcmWaveFormat));
_pwfx->cbSize = cbExtraBytes;
memcpy(_wfx, &pcmWaveFormat, sizeof(pcmWaveFormat));
_wfx->cbSize = cbExtraBytes;
// 读取额外数据
if (mmioRead(_hmmio, (CHAR*)(((BYTE*)&(_pwfx->cbSize)) + sizeof(WORD)),
if (mmioRead(_hmmio, (CHAR*)(((BYTE*)&(_wfx->cbSize)) + sizeof(WORD)),
cbExtraBytes) != cbExtraBytes)
{
SAFE_DELETE(_pwfx);
SAFE_DELETE(_wfx);
return TraceError(L"mmioRead");
}
}
if (0 != mmioAscend(_hmmio, &ckIn, 0))
{
SAFE_DELETE(_pwfx);
SAFE_DELETE(_wfx);
return TraceError(L"mmioAscend");
}
return true;
}
bool MusicPlayer::_resetFile()
bool e2d::Music::_resetFile()
{
// Seek to the data
if (-1 == mmioSeek(_hmmio, _ckRiff.dwDataOffset + sizeof(FOURCC),
@ -494,7 +460,7 @@ bool MusicPlayer::_resetFile()
return true;
}
bool MusicPlayer::_read(BYTE* pBuffer, DWORD dwSizeToRead)
bool e2d::Music::_read(BYTE* pBuffer, DWORD dwSizeToRead)
{
MMIOINFO mmioinfoIn; // current status of _hmmio
@ -530,7 +496,7 @@ bool MusicPlayer::_read(BYTE* pBuffer, DWORD dwSizeToRead)
return true;
}
bool MusicPlayer::_findMediaFileCch(wchar_t* strDestPath, int cchDest, const wchar_t * strFilename)
bool e2d::Music::_findMediaFileCch(wchar_t* strDestPath, int cchDest, const wchar_t * strFilename)
{
bool bFound = false;
@ -604,195 +570,6 @@ bool MusicPlayer::_findMediaFileCch(wchar_t* strDestPath, int cchDest, const wch
return false;
}
bool e2d::Music::preload(const String& filePath)
{
UINT nRet = filePath.getHashCode();
if (GetMusicFileList().end() != GetMusicFileList().find(nRet))
{
return true;
}
else
{
MusicPlayer * pPlayer = new (std::nothrow) MusicPlayer();
if (pPlayer->open(filePath))
{
pPlayer->setVolume(s_fMusicVolume);
GetMusicFileList().insert(std::pair<UINT, MusicPlayer *>(nRet, pPlayer));
return true;
}
else
{
delete pPlayer;
pPlayer = nullptr;
}
}
return false;
}
bool e2d::Music::preload(int resNameId, const String& resType)
{
if (GetMusicResList().end() != GetMusicResList().find(resNameId))
{
return true;
}
else
{
MusicPlayer * pPlayer = new (std::nothrow) MusicPlayer();
if (pPlayer->open(resNameId, resType))
{
pPlayer->setVolume(s_fMusicVolume);
GetMusicResList().insert(std::pair<UINT, MusicPlayer *>(resNameId, pPlayer));
return true;
}
else
{
delete pPlayer;
pPlayer = nullptr;
}
}
return false;
}
bool e2d::Music::play(const String& filePath, int nLoopCount)
{
if (Music::preload(filePath))
{
UINT nRet = filePath.getHashCode();
auto pMusic = GetMusicFileList()[nRet];
if (pMusic->play(nLoopCount))
{
return true;
}
}
return false;
}
bool e2d::Music::play(int resNameId, const String& resType, int nLoopCount)
{
if (Music::preload(resNameId, resType))
{
auto pMusic = GetMusicResList()[resNameId];
if (pMusic->play(nLoopCount))
{
return true;
}
}
return false;
}
void e2d::Music::pause(const String& filePath)
{
if (filePath.isEmpty())
return;
UINT nRet = filePath.getHashCode();
if (GetMusicFileList().end() != GetMusicFileList().find(nRet))
GetMusicFileList()[nRet]->pause();
}
void e2d::Music::pause(int resNameId, const String& resType)
{
if (GetMusicResList().end() != GetMusicResList().find(resNameId))
GetMusicResList()[resNameId]->pause();
}
void e2d::Music::resume(const String& filePath)
{
if (filePath.isEmpty())
return;
UINT nRet = filePath.getHashCode();
if (GetMusicFileList().end() != GetMusicFileList().find(nRet))
GetMusicFileList()[nRet]->resume();
}
void e2d::Music::resume(int resNameId, const String& resType)
{
if (GetMusicResList().end() != GetMusicResList().find(resNameId))
GetMusicResList()[resNameId]->pause();
}
void e2d::Music::stop(const String& filePath)
{
if (filePath.isEmpty())
return;
UINT nRet = filePath.getHashCode();
if (GetMusicFileList().end() != GetMusicFileList().find(nRet))
GetMusicFileList()[nRet]->stop();
}
void e2d::Music::stop(int resNameId, const String& resType)
{
if (GetMusicResList().end() != GetMusicResList().find(resNameId))
GetMusicResList()[resNameId]->stop();
}
bool e2d::Music::isPlaying(const String& filePath)
{
if (filePath.isEmpty())
return false;
UINT nRet = filePath.getHashCode();
if (GetMusicFileList().end() != GetMusicFileList().find(nRet))
return GetMusicFileList()[nRet]->isPlaying();
return false;
}
bool e2d::Music::isPlaying(int resNameId, const String& resType)
{
if (GetMusicResList().end() != GetMusicResList().find(resNameId))
return GetMusicResList()[resNameId]->isPlaying();
return false;
}
double e2d::Music::getVolume()
{
return s_fMusicVolume;
}
void e2d::Music::setVolume(double fVolume)
{
s_fMusicVolume = min(max(float(fVolume), -224), 224);
for (auto pair : GetMusicFileList())
{
pair.second->setVolume(s_fMusicVolume);
}
}
void e2d::Music::pauseAll()
{
for (auto pair : GetMusicFileList())
{
pair.second->pause();
}
}
void e2d::Music::resumeAll()
{
for (auto pair : GetMusicFileList())
{
pair.second->resume();
}
}
void e2d::Music::stopAll()
{
for (auto pair : GetMusicFileList())
{
pair.second->stop();
}
}
IXAudio2 * e2d::Music::getIXAudio2()
{
return s_pXAudio2;
@ -825,14 +602,6 @@ bool e2d::Music::__init()
void e2d::Music::__uninit()
{
for (auto pair : GetMusicFileList())
{
pair.second->close();
delete pair.second;
}
GetMusicFileList().clear();
if (s_pMasteringVoice)
{
s_pMasteringVoice->DestroyVoice();

218
core/Tool/Player.cpp Normal file
View File

@ -0,0 +1,218 @@
#include "..\e2dtool.h"
#include <map>
typedef std::map<UINT, e2d::Music *> MusicMap;
static MusicMap& GetMusicFileList()
{
static MusicMap s_MusicFileList;
return s_MusicFileList;
}
static MusicMap& GetMusicResList()
{
static MusicMap s_MusicResList;
return s_MusicResList;
}
static float s_fMusicVolume = 1.0;
bool e2d::Player::preload(const String& filePath)
{
UINT hash = filePath.getHashCode();
if (GetMusicFileList().end() != GetMusicFileList().find(hash))
{
return true;
}
else
{
Music * music = new (std::nothrow) Music();
if (music->open(filePath))
{
music->setVolume(s_fMusicVolume);
GetMusicFileList().insert(std::pair<UINT, Music *>(hash, music));
return true;
}
else
{
delete music;
music = nullptr;
}
}
return false;
}
bool e2d::Player::preload(int resNameId, const String& resType)
{
if (GetMusicResList().end() != GetMusicResList().find(resNameId))
{
return true;
}
else
{
Music * music = new (std::nothrow) Music();
if (music->open(resNameId, resType))
{
music->setVolume(s_fMusicVolume);
GetMusicResList().insert(std::pair<UINT, Music *>(resNameId, music));
return true;
}
else
{
delete music;
music = nullptr;
}
}
return false;
}
bool e2d::Player::play(const String& filePath, int nLoopCount)
{
if (Player::preload(filePath))
{
UINT hash = filePath.getHashCode();
auto music = GetMusicFileList()[hash];
if (music->play(nLoopCount))
{
return true;
}
}
return false;
}
bool e2d::Player::play(int resNameId, const String& resType, int nLoopCount)
{
if (Player::preload(resNameId, resType))
{
auto music = GetMusicResList()[resNameId];
if (music->play(nLoopCount))
{
return true;
}
}
return false;
}
void e2d::Player::pause(const String& filePath)
{
if (filePath.isEmpty())
return;
UINT hash = filePath.getHashCode();
if (GetMusicFileList().end() != GetMusicFileList().find(hash))
GetMusicFileList()[hash]->pause();
}
void e2d::Player::pause(int resNameId, const String& resType)
{
if (GetMusicResList().end() != GetMusicResList().find(resNameId))
GetMusicResList()[resNameId]->pause();
}
void e2d::Player::resume(const String& filePath)
{
if (filePath.isEmpty())
return;
UINT hash = filePath.getHashCode();
if (GetMusicFileList().end() != GetMusicFileList().find(hash))
GetMusicFileList()[hash]->resume();
}
void e2d::Player::resume(int resNameId, const String& resType)
{
if (GetMusicResList().end() != GetMusicResList().find(resNameId))
GetMusicResList()[resNameId]->pause();
}
void e2d::Player::stop(const String& filePath)
{
if (filePath.isEmpty())
return;
UINT hash = filePath.getHashCode();
if (GetMusicFileList().end() != GetMusicFileList().find(hash))
GetMusicFileList()[hash]->stop();
}
void e2d::Player::stop(int resNameId, const String& resType)
{
if (GetMusicResList().end() != GetMusicResList().find(resNameId))
GetMusicResList()[resNameId]->stop();
}
bool e2d::Player::isPlaying(const String& filePath)
{
if (filePath.isEmpty())
return false;
UINT hash = filePath.getHashCode();
if (GetMusicFileList().end() != GetMusicFileList().find(hash))
return GetMusicFileList()[hash]->isPlaying();
return false;
}
bool e2d::Player::isPlaying(int resNameId, const String& resType)
{
if (GetMusicResList().end() != GetMusicResList().find(resNameId))
return GetMusicResList()[resNameId]->isPlaying();
return false;
}
double e2d::Player::getVolume()
{
return s_fMusicVolume;
}
void e2d::Player::setVolume(double volume)
{
s_fMusicVolume = min(max(float(volume), -224), 224);
for (auto pair : GetMusicFileList())
{
pair.second->setVolume(s_fMusicVolume);
}
}
void e2d::Player::pauseAll()
{
for (auto pair : GetMusicFileList())
{
pair.second->pause();
}
}
void e2d::Player::resumeAll()
{
for (auto pair : GetMusicFileList())
{
pair.second->resume();
}
}
void e2d::Player::stopAll()
{
for (auto pair : GetMusicFileList())
{
pair.second->stop();
}
}
void e2d::Player::__uninit()
{
for (auto pair : GetMusicFileList())
{
pair.second->close();
delete pair.second;
}
GetMusicFileList().clear();
}

View File

@ -164,9 +164,6 @@ private:
// 初始化计时操作
static bool __init();
// 重置计时操作
static void __uninit();
// 是否达到更新时间
static bool __isReady();

View File

@ -11,7 +11,7 @@ class Renderer;
class Node;
class Timer;
class Action;
class Music;
class Player;
class Collider;
class Transition;

View File

@ -50,8 +50,122 @@ private:
};
// 音乐
class Music :
public Object
{
friend Game;
public:
Music();
Music(
const e2d::String& filePath /* 音乐文件路径 */
);
Music(
int resNameId, /* 音乐资源名称 */
const String& resType /* 音乐资源类型 */
);
virtual ~Music();
// 创建音乐对象
static Music * create();
// 创建音乐对象
static Music * create(
const e2d::String& filePath /* 音乐文件路径 */
);
// 创建音乐对象
static Music * create(
int resNameId, /* 音乐资源名称 */
const String& resType /* 音乐资源类型 */
);
// 打开音乐文件
bool open(
const e2d::String& filePath /* 音乐文件路径 */
);
// 打开音乐资源
bool open(
int resNameId, /* 音乐资源名称 */
const String& resType /* 音乐资源类型 */
);
// 播放
bool play(
int nLoopCount = 0
);
// 暂停
void pause();
// 继续
void resume();
// 停止
void stop();
// 关闭并回收资源
void close();
// 设置音量
bool setVolume(
double volume
);
// 是否正在播放
bool isPlaying() const;
// 获取 IXAudio2SourceVoice 对象
IXAudio2SourceVoice * getIXAudio2SourceVoice() const;
// 获取 IXAudio2 对象
static IXAudio2 * getIXAudio2();
// 获取 IXAudio2MasteringVoice 对象
static IXAudio2MasteringVoice * getIXAudio2MasteringVoice();
protected:
bool _readMMIO();
bool _resetFile();
bool _read(
BYTE* pBuffer,
DWORD dwSizeToRead
);
bool _findMediaFileCch(
wchar_t* strDestPath,
int cchDest,
const wchar_t * strFilename
);
private:
static bool __init();
static void __uninit();
protected:
bool _opened;
mutable bool _playing;
DWORD _dwSize;
CHAR* _resBuffer;
BYTE* _waveData;
HMMIO _hmmio;
MMCKINFO _ck;
MMCKINFO _ckRiff;
WAVEFORMATEX* _wfx;
IXAudio2SourceVoice* _voice;
};
// 稜있꺄렴포
class Music
class Player
{
friend Game;
@ -61,18 +175,38 @@ public:
const String& filePath /* 稜있匡숭쨌쓺 */
);
// 预加载音乐资源
static bool preload(
int resNameId, /* 音乐资源名称 */
const String& resType /* 音乐资源类型 */
);
// 꺄렴稜있
static bool play(
const String& filePath, /* 稜있匡숭쨌쓺 */
int nLoopCount = 0 /* 路릿꺄렴늴鑒<E99192>零 -1 槨琦뻔꺄렴 */
);
// 暂停音乐
static void pause(
const String& filePath /* 音乐文件路径 */
);
// 继续播放音乐
static void resume(
const String& filePath /* 音乐文件路径 */
);
// 停止音乐
static void stop(
const String& filePath /* 音乐文件路径 */
);
// 获取音乐播放状态
static bool isPlaying(
const String& filePath /* 音乐文件路径 */
);
// 预加载音乐资源
static bool preload(
int resNameId, /* 音乐资源名称 */
const String& resType /* 音乐资源类型 */
);
// 꺄렴稜있
static bool play(
int resNameId, /* 稜있栗都츰냔 */
@ -80,44 +214,24 @@ public:
int nLoopCount = 0 /* 路릿꺄렴늴鑒<E99192>零 -1 槨琦뻔꺄렴 */
);
// 暂停音乐
static void pause(
const String& filePath /* 音乐文件路径 */
);
// 董界稜있
static void pause(
int resNameId, /* 稜있栗都츰냔 */
const String& resType /* 稜있栗都잚謹 */
);
// 继续播放音乐
static void resume(
const String& filePath /* 音乐文件路径 */
);
// 셨崎꺄렴稜있
static void resume(
int resNameId, /* 稜있栗都츰냔 */
const String& resType /* 稜있栗都잚謹 */
);
// 停止音乐
static void stop(
const String& filePath /* 音乐文件路径 */
);
// 界岺稜있
static void stop(
int resNameId, /* 稜있栗都츰냔 */
const String& resType /* 稜있栗都잚謹 */
);
// 获取音乐播放状态
static bool isPlaying(
const String& filePath /* 音乐文件路径 */
);
// 삿혤稜있꺄렴榴檄
static bool isPlaying(
int resNameId, /* 稜있栗都츰냔 */
@ -129,7 +243,7 @@ public:
// <20>零稜좆
static void setVolume(
double fVolume /* 音量范围为 -224 ~ 2240 是静音1 是正常音量 */
double volume /* 音量范围为 -224 ~ 2240 是静音1 是正常音量 */
);
// 董界杰唐稜있
@ -141,15 +255,7 @@ public:
// 界岺杰唐稜있
static void stopAll();
// 获取 IXAudio2 对象
static IXAudio2 * getIXAudio2();
// 获取 IXAudio2MasteringVoice 对象
static IXAudio2MasteringVoice * getIXAudio2MasteringVoice();
private:
static bool __init();
static void __uninit();
};

View File

@ -250,8 +250,9 @@
<ClCompile Include="..\..\core\Node\Sprite.cpp" />
<ClCompile Include="..\..\core\Node\Text.cpp" />
<ClCompile Include="..\..\core\Tool\Data.cpp" />
<ClCompile Include="..\..\core\Tool\Path.cpp" />
<ClCompile Include="..\..\core\Tool\Music.cpp" />
<ClCompile Include="..\..\core\Tool\Path.cpp" />
<ClCompile Include="..\..\core\Tool\Player.cpp" />
<ClCompile Include="..\..\core\Tool\Random.cpp" />
<ClCompile Include="..\..\core\Tool\Timer.cpp" />
<ClCompile Include="..\..\core\Transition\Transition.cpp" />

View File

@ -96,9 +96,6 @@
<ClCompile Include="..\..\core\Base\Renderer.cpp">
<Filter>Base</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Tool\Music.cpp">
<Filter>Tool</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Common\Point.cpp">
<Filter>Common</Filter>
</ClCompile>
@ -219,6 +216,12 @@
<ClCompile Include="..\..\core\Action\JumpTo.cpp">
<Filter>Action</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Tool\Player.cpp">
<Filter>Tool</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Tool\Music.cpp">
<Filter>Tool</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\core\easy2d.h" />