From 2eb845a4df10ffa90e50f8008d6c26e9d36bb5ef Mon Sep 17 00:00:00 2001 From: Nomango Date: Fri, 27 Apr 2018 17:07:47 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E5=81=9AMusic=E7=B1=BB=EF=BC=8C?= =?UTF-8?q?=E5=8E=BB=E9=99=A4MusicManager?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/Base/Game.cpp | 2 - core/Manager/MusicManager.cpp | 129 --------- core/Tool/Music.cpp | 360 ++++++++++++++++++-------- core/e2dmanager.h | 52 ---- core/e2dtool.h | 95 +++---- project/vs2012/Easy2D.vcxproj | 1 - project/vs2012/Easy2D.vcxproj.filters | 3 - project/vs2013/Easy2D.vcxproj | 1 - project/vs2013/Easy2D.vcxproj.filters | 3 - project/vs2017/Easy2D.vcxproj | 1 - project/vs2017/Easy2D.vcxproj.filters | 3 - 11 files changed, 287 insertions(+), 363 deletions(-) delete mode 100644 core/Manager/MusicManager.cpp diff --git a/core/Base/Game.cpp b/core/Base/Game.cpp index 1eee9bf1..cae159b2 100644 --- a/core/Base/Game.cpp +++ b/core/Base/Game.cpp @@ -179,8 +179,6 @@ void e2d::Game::destroy() ColliderManager::__uninit(); // 删除动画 ActionManager::__uninit(); - // 关闭音乐播放器 - MusicManager::__uninit(); // 删除所有对象 ObjectManager::__clear(); // 清空图片缓存 diff --git a/core/Manager/MusicManager.cpp b/core/Manager/MusicManager.cpp deleted file mode 100644 index 939fcdd0..00000000 --- a/core/Manager/MusicManager.cpp +++ /dev/null @@ -1,129 +0,0 @@ -#include "..\e2dmanager.h" -#include "..\e2dtool.h" -#include - - -typedef std::pair MusicPair; -typedef std::map MusicMap; - -static MusicMap& GetMusicList() -{ - static MusicMap s_List; - return s_List; -} - - -bool e2d::MusicManager::preload(String strFilePath) -{ - UINT nRet = strFilePath.getHashCode(); - - if (GetMusicList().end() != GetMusicList().find(nRet)) - { - return true; - } - else - { - Music * pPlayer = new Music(); - - if (pPlayer->open(strFilePath)) - { - GetMusicList().insert(MusicPair(nRet, pPlayer)); - pPlayer->retain(); - return true; - } - else - { - pPlayer->release(); - pPlayer = nullptr; - } - } - return false; -} - -bool e2d::MusicManager::play(String strFilePath, int nLoopCount) -{ - if (MusicManager::preload(strFilePath)) - { - UINT nRet = strFilePath.getHashCode(); - Music * pMusic = GetMusicList()[nRet]; - if (pMusic->play(nLoopCount)) - { - return true; - } - } - return false; -} - -void e2d::MusicManager::pause(String strFilePath) -{ - auto music = MusicManager::get(strFilePath); - if (music) - { - music->pause(); - } -} - -void e2d::MusicManager::resume(String strFilePath) -{ - auto music = MusicManager::get(strFilePath); - if (music) - { - music->resume(); - } -} - -void e2d::MusicManager::stop(String strFilePath) -{ - auto music = MusicManager::get(strFilePath); - if (music) - { - music->stop(); - } -} - -e2d::Music * e2d::MusicManager::get(String strFilePath) -{ - if (strFilePath.isEmpty()) - return nullptr; - - UINT nRet = strFilePath.getHashCode(); - - if (GetMusicList().end() != GetMusicList().find(nRet)) - return GetMusicList()[nRet]; - - return nullptr; -} - -void e2d::MusicManager::pauseAll() -{ - for (auto pair : GetMusicList()) - { - pair.second->pause(); - } -} - -void e2d::MusicManager::resumeAll() -{ - for (auto pair : GetMusicList()) - { - pair.second->resume(); - } -} - -void e2d::MusicManager::stopAll() -{ - for (auto pair : GetMusicList()) - { - pair.second->stop(); - } -} - -void e2d::MusicManager::__uninit() -{ - for (auto pair : GetMusicList()) - { - pair.second->close(); - pair.second->release(); - } - GetMusicList().clear(); -} diff --git a/core/Tool/Music.cpp b/core/Tool/Music.cpp index 1dd8d678..bc3bbe1a 100644 --- a/core/Tool/Music.cpp +++ b/core/Tool/Music.cpp @@ -1,7 +1,7 @@ #include "..\e2dtool.h" #include "..\e2dmanager.h" +#include -using namespace e2d; #ifndef SAFE_DELETE #define SAFE_DELETE(p) { if (p) { delete (p); (p)=nullptr; } } @@ -12,51 +12,89 @@ using namespace e2d; inline bool TraceError(wchar_t* sPrompt) { - WARN_IF(true, "Music error: %s failed!", sPrompt); + WARN_IF(true, "MusicInfo error: %s failed!", sPrompt); return false; } inline bool TraceError(wchar_t* sPrompt, HRESULT hr) { - WARN_IF(true, "Music error: %s (%#X)", sPrompt, hr); + WARN_IF(true, "MusicInfo error: %s (%#X)", sPrompt, hr); return false; } static IXAudio2 * s_pXAudio2 = nullptr; static IXAudio2MasteringVoice * s_pMasteringVoice = nullptr; +static float s_fMusicVolume = 1.0; -bool e2d::Music::__init() +// 音乐播放器 +class MusicPlayer { - HRESULT hr; +public: + MusicPlayer(); - if (FAILED(hr = XAudio2Create(&s_pXAudio2, 0))) - { - WARN_IF(true, "Failed to init XAudio2 engine"); - return false; - } + virtual ~MusicPlayer(); - if (FAILED(hr = s_pXAudio2->CreateMasteringVoice(&s_pMasteringVoice))) - { - WARN_IF(true, "Failed creating mastering voice"); - SafeReleaseInterface(&s_pXAudio2); - return false; - } + bool open( + e2d::String strFileName + ); - return true; + 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 m_bOpened; + mutable bool m_bPlaying; + DWORD m_dwSize; + CHAR* m_pResourceBuffer; + BYTE* m_pbWaveData; + HMMIO m_hmmio; + MMCKINFO m_ck; + MMCKINFO m_ckRiff; + WAVEFORMATEX* m_pwfx; + IXAudio2SourceVoice* m_pSourceVoice; +}; + +typedef std::map MusicMap; + +static MusicMap& GetMusicList() +{ + static MusicMap s_List; + return s_List; } -void e2d::Music::__uninit() -{ - if (s_pMasteringVoice) - { - s_pMasteringVoice->DestroyVoice(); - } - - SafeReleaseInterface(&s_pXAudio2); -} - -Music::Music() +MusicPlayer::MusicPlayer() : m_bOpened(false) , m_bPlaying(false) , m_pwfx(nullptr) @@ -68,35 +106,22 @@ Music::Music() { } -e2d::Music::Music(String strFileName) - : m_bOpened(false) - , m_bPlaying(false) - , m_pwfx(nullptr) - , m_hmmio(nullptr) - , m_pResourceBuffer(nullptr) - , m_pbWaveData(nullptr) - , m_dwSize(0) - , m_pSourceVoice(nullptr) -{ - this->open(strFileName); -} - -Music::~Music() +MusicPlayer::~MusicPlayer() { close(); } -bool Music::open(String strFileName) +bool MusicPlayer::open(e2d::String strFileName) { if (m_bOpened) { - WARN_IF(true, "Music can be opened only once!"); + WARN_IF(true, "MusicInfo can be opened only once!"); return false; } if (strFileName.isEmpty()) { - WARN_IF(true, "Music::open Invalid file name."); + WARN_IF(true, "MusicInfo::open Invalid file name."); return false; } @@ -158,17 +183,17 @@ bool Music::open(String strFileName) return true; } -bool Music::play(int nLoopCount) +bool MusicPlayer::play(int nLoopCount) { if (!m_bOpened) { - WARN_IF(true, "Music::play Failed: Music must be opened first!"); + WARN_IF(true, "MusicInfo::play Failed: MusicInfo must be opened first!"); return false; } if (m_pSourceVoice == nullptr) { - WARN_IF(true, "Music::play Failed: IXAudio2SourceVoice Null pointer exception!"); + WARN_IF(true, "MusicInfo::play Failed: IXAudio2SourceVoice Null pointer exception!"); return false; } @@ -204,7 +229,7 @@ bool Music::play(int nLoopCount) return SUCCEEDED(hr); } -void Music::pause() +void MusicPlayer::pause() { if (m_pSourceVoice) { @@ -215,7 +240,7 @@ void Music::pause() } } -void Music::resume() +void MusicPlayer::resume() { if (m_pSourceVoice) { @@ -226,7 +251,7 @@ void Music::resume() } } -void Music::stop() +void MusicPlayer::stop() { if (m_pSourceVoice) { @@ -239,7 +264,7 @@ void Music::stop() } } -void Music::close() +void MusicPlayer::close() { if (m_pSourceVoice) { @@ -263,7 +288,7 @@ void Music::close() m_bPlaying = false; } -bool Music::isPlaying() const +bool MusicPlayer::isPlaying() const { if (m_bOpened && m_pSourceVoice) { @@ -282,61 +307,16 @@ bool Music::isPlaying() const } } -double Music::getVolume() const -{ - float fVolume = 0.0f; - if (m_pSourceVoice) - { - m_pSourceVoice->GetVolume(&fVolume); - } - return static_cast(fVolume); -} - -bool Music::setVolume(double fVolume) +bool MusicPlayer::setVolume(float fVolume) { if (m_pSourceVoice) { - return SUCCEEDED(m_pSourceVoice->SetVolume(min(max(static_cast(fVolume), -224), 224))); + return SUCCEEDED(m_pSourceVoice->SetVolume(fVolume)); } return false; } -double Music::getFrequencyRatio() const -{ - float fFrequencyRatio = 0.0f; - if (m_pSourceVoice) - { - m_pSourceVoice->GetFrequencyRatio(&fFrequencyRatio); - } - return static_cast(fFrequencyRatio); -} - -bool Music::setFrequencyRatio(double fFrequencyRatio) -{ - if (m_pSourceVoice) - { - fFrequencyRatio = min(max(fFrequencyRatio, XAUDIO2_MIN_FREQ_RATIO), XAUDIO2_MAX_FREQ_RATIO); - return SUCCEEDED(m_pSourceVoice->SetFrequencyRatio(static_cast(fFrequencyRatio))); - } - return false; -} - -IXAudio2 * e2d::Music::getIXAudio2() -{ - return s_pXAudio2; -} - -IXAudio2MasteringVoice * e2d::Music::getIXAudio2MasteringVoice() -{ - return s_pMasteringVoice; -} - -IXAudio2SourceVoice * Music::getIXAudio2SourceVoice() const -{ - return m_pSourceVoice; -} - -bool Music::_readMMIO() +bool MusicPlayer::_readMMIO() { MMCKINFO ckIn; PCMWAVEFORMAT pcmWaveFormat; @@ -408,7 +388,7 @@ bool Music::_readMMIO() return true; } -bool Music::_resetFile() +bool MusicPlayer::_resetFile() { // Seek to the data if (-1 == mmioSeek(m_hmmio, m_ckRiff.dwDataOffset + sizeof(FOURCC), @@ -423,7 +403,7 @@ bool Music::_resetFile() return true; } -bool Music::_read(BYTE* pBuffer, DWORD dwSizeToRead) +bool MusicPlayer::_read(BYTE* pBuffer, DWORD dwSizeToRead) { MMIOINFO mmioinfoIn; // current status of m_hmmio @@ -459,7 +439,7 @@ bool Music::_read(BYTE* pBuffer, DWORD dwSizeToRead) return true; } -bool Music::_findMediaFileCch(wchar_t* strDestPath, int cchDest, const wchar_t * strFilename) +bool MusicPlayer::_findMediaFileCch(wchar_t* strDestPath, int cchDest, const wchar_t * strFilename) { bool bFound = false; @@ -534,3 +514,175 @@ bool Music::_findMediaFileCch(wchar_t* strDestPath, int cchDest, const wchar_t * } +bool e2d::Music::preload(String strFilePath) +{ + UINT nRet = strFilePath.getHashCode(); + + if (GetMusicList().end() != GetMusicList().find(nRet)) + { + return true; + } + else + { + MusicPlayer * pPlayer = new (std::nothrow) MusicPlayer(); + + if (pPlayer->open(strFilePath)) + { + pPlayer->setVolume(s_fMusicVolume); + GetMusicList().insert(std::pair(nRet, pPlayer)); + return true; + } + else + { + delete pPlayer; + pPlayer = nullptr; + } + } + return false; +} + +bool e2d::Music::play(String strFilePath, int nLoopCount) +{ + if (Music::preload(strFilePath)) + { + UINT nRet = strFilePath.getHashCode(); + auto pMusic = GetMusicList()[nRet]; + if (pMusic->play(nLoopCount)) + { + return true; + } + } + return false; +} + +void e2d::Music::pause(String strFilePath) +{ + if (strFilePath.isEmpty()) + return; + + UINT nRet = strFilePath.getHashCode(); + + if (GetMusicList().end() != GetMusicList().find(nRet)) + GetMusicList()[nRet]->pause(); +} + +void e2d::Music::resume(String strFilePath) +{ + if (strFilePath.isEmpty()) + return; + + UINT nRet = strFilePath.getHashCode(); + + if (GetMusicList().end() != GetMusicList().find(nRet)) + GetMusicList()[nRet]->resume(); +} + +void e2d::Music::stop(String strFilePath) +{ + if (strFilePath.isEmpty()) + return; + + UINT nRet = strFilePath.getHashCode(); + + if (GetMusicList().end() != GetMusicList().find(nRet)) + GetMusicList()[nRet]->stop(); +} + +bool e2d::Music::isPlaying(String strFilePath) +{ + if (strFilePath.isEmpty()) + return false; + + UINT nRet = strFilePath.getHashCode(); + + if (GetMusicList().end() != GetMusicList().find(nRet)) + return GetMusicList()[nRet]->isPlaying(); + + return false; +} + +double e2d::Music::getVolume() +{ + return s_fMusicVolume; +} + +void e2d::Music::setVolume(double fVolume) +{ + s_fMusicVolume = min(max(static_cast(fVolume), -224), 224); + for (auto pair : GetMusicList()) + { + pair.second->setVolume(s_fMusicVolume); + } +} + +void e2d::Music::pauseAll() +{ + for (auto pair : GetMusicList()) + { + pair.second->pause(); + } +} + +void e2d::Music::resumeAll() +{ + for (auto pair : GetMusicList()) + { + pair.second->resume(); + } +} + +void e2d::Music::stopAll() +{ + for (auto pair : GetMusicList()) + { + pair.second->stop(); + } +} + +IXAudio2 * e2d::Music::getIXAudio2() +{ + return s_pXAudio2; +} + +IXAudio2MasteringVoice * e2d::Music::getIXAudio2MasteringVoice() +{ + return s_pMasteringVoice; +} + +bool e2d::Music::__init() +{ + HRESULT hr; + + if (FAILED(hr = XAudio2Create(&s_pXAudio2, 0))) + { + WARN_IF(true, "Failed to init XAudio2 engine"); + return false; + } + + if (FAILED(hr = s_pXAudio2->CreateMasteringVoice(&s_pMasteringVoice))) + { + WARN_IF(true, "Failed creating mastering voice"); + e2d::SafeReleaseInterface(&s_pXAudio2); + return false; + } + + return true; +} + +void e2d::Music::__uninit() +{ + for (auto pair : GetMusicList()) + { + pair.second->close(); + delete pair.second; + } + + GetMusicList().clear(); + + if (s_pMasteringVoice) + { + s_pMasteringVoice->DestroyVoice(); + } + + e2d::SafeReleaseInterface(&s_pXAudio2); +} diff --git a/core/e2dmanager.h b/core/e2dmanager.h index 987710ab..db09c6d9 100644 --- a/core/e2dmanager.h +++ b/core/e2dmanager.h @@ -173,58 +173,6 @@ private: }; -// 音乐管理工具 -class MusicManager -{ - friend Game; - -public: - // 预加载音乐资源 - static bool preload( - String strFilePath /* 音乐文件路径 */ - ); - - // 播放音乐 - static bool play( - String strFilePath, /* 音乐文件路径 */ - int nLoopCount = 0 /* 重复播放次数,设置 -1 为循环播放 */ - ); - - // 暂停音乐 - static void pause( - String strFilePath /* 音乐文件路径 */ - ); - - // 继续播放音乐 - static void resume( - String strFilePath /* 音乐文件路径 */ - ); - - // 停止音乐 - static void stop( - String strFilePath /* 音乐文件路径 */ - ); - - // 获取指定音乐的 Music 对象 - static Music * get( - String strFilePath /* 音乐文件路径 */ - ); - - // 暂停所有音乐 - static void pauseAll(); - - // 继续播放所有音乐 - static void resumeAll(); - - // 停止所有音乐 - static void stopAll(); - -private: - // 回收音乐资源 - static void __uninit(); -}; - - // 键盘和鼠标消息管理器 class InputManager { diff --git a/core/e2dtool.h b/core/e2dtool.h index 9cce01e1..d1fc5ce2 100644 --- a/core/e2dtool.h +++ b/core/e2dtool.h @@ -5,7 +5,6 @@ namespace e2d { -class MusicManager; class InputManager; class ColliderManager; @@ -59,54 +58,53 @@ class Music : friend Game; public: - Music(); - - Music( - String strFileName /* 音乐文件路径 */ + // 预加载音乐资源 + static bool preload( + String strFilePath /* 音乐文件路径 */ ); - virtual ~Music(); - - // 打开音乐文件 - bool open( - String strFileName /* 音乐文件路径 */ - ); - - // 播放 - bool play( + // 播放音乐 + static bool play( + String strFilePath, /* 音乐文件路径 */ int nLoopCount = 0 /* 重复播放次数,设置 -1 为循环播放 */ ); - // 暂停 - void pause(); + // 暂停音乐 + static void pause( + String strFilePath /* 音乐文件路径 */ + ); - // 继续 - void resume(); + // 继续播放音乐 + static void resume( + String strFilePath /* 音乐文件路径 */ + ); - // 停止 - void stop(); - - // 关闭音乐文件 - void close(); + // 停止音乐 + static void stop( + String strFilePath /* 音乐文件路径 */ + ); // 获取音乐播放状态 - bool isPlaying() const; + static bool isPlaying( + String strFilePath /* 音乐文件路径 */ + ); // 获取音量 - double getVolume() const; - - // 获取频率比 - double getFrequencyRatio() const; + static double getVolume(); // 设置音量 - bool setVolume( + static void setVolume( double fVolume /* 音量范围为 -224 ~ 224,其中 0 是静音,1 是正常音量 */ ); - // 设置频率比 - bool setFrequencyRatio( - double fFrequencyRatio /* 频率比范围为 1/1024.0f ~ 1024.0f,其中 1.0 为正常声调 */ - ); + // 暂停所有音乐 + static void pauseAll(); + + // 继续播放所有音乐 + static void resumeAll(); + + // 停止所有音乐 + static void stopAll(); // 获取 IXAudio2 对象 static IXAudio2 * getIXAudio2(); @@ -114,41 +112,10 @@ public: // 获取 IXAudio2MasteringVoice 对象 static IXAudio2MasteringVoice * getIXAudio2MasteringVoice(); - // 获取 IXAudio2SourceVoice 对象 - IXAudio2SourceVoice* getIXAudio2SourceVoice() const; - -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 m_bOpened; - mutable bool m_bPlaying; - DWORD m_dwSize; - CHAR* m_pResourceBuffer; - BYTE* m_pbWaveData; - HMMIO m_hmmio; - MMCKINFO m_ck; - MMCKINFO m_ckRiff; - WAVEFORMATEX* m_pwfx; - IXAudio2SourceVoice* m_pSourceVoice; }; diff --git a/project/vs2012/Easy2D.vcxproj b/project/vs2012/Easy2D.vcxproj index c93a6dab..a5006f03 100644 --- a/project/vs2012/Easy2D.vcxproj +++ b/project/vs2012/Easy2D.vcxproj @@ -57,7 +57,6 @@ - diff --git a/project/vs2012/Easy2D.vcxproj.filters b/project/vs2012/Easy2D.vcxproj.filters index 4246a997..39bc7437 100644 --- a/project/vs2012/Easy2D.vcxproj.filters +++ b/project/vs2012/Easy2D.vcxproj.filters @@ -129,9 +129,6 @@ Node - - Manager - Tool diff --git a/project/vs2013/Easy2D.vcxproj b/project/vs2013/Easy2D.vcxproj index ddbcde8b..e0688492 100644 --- a/project/vs2013/Easy2D.vcxproj +++ b/project/vs2013/Easy2D.vcxproj @@ -201,7 +201,6 @@ - diff --git a/project/vs2013/Easy2D.vcxproj.filters b/project/vs2013/Easy2D.vcxproj.filters index b89d51f7..45d94251 100644 --- a/project/vs2013/Easy2D.vcxproj.filters +++ b/project/vs2013/Easy2D.vcxproj.filters @@ -141,9 +141,6 @@ Node - - Manager - Common diff --git a/project/vs2017/Easy2D.vcxproj b/project/vs2017/Easy2D.vcxproj index 2283254a..82e892d6 100644 --- a/project/vs2017/Easy2D.vcxproj +++ b/project/vs2017/Easy2D.vcxproj @@ -233,7 +233,6 @@ - diff --git a/project/vs2017/Easy2D.vcxproj.filters b/project/vs2017/Easy2D.vcxproj.filters index bd9d743e..fca2dfcf 100644 --- a/project/vs2017/Easy2D.vcxproj.filters +++ b/project/vs2017/Easy2D.vcxproj.filters @@ -141,9 +141,6 @@ Tool - - Manager - Common