pref: move sound preload functions to SoundPlayer

This commit is contained in:
Nomango 2023-09-26 13:08:54 +08:00
parent 8201fac6bb
commit 03439bb431
6 changed files with 82 additions and 114 deletions

View File

@ -32,7 +32,7 @@ namespace audio
class VoiceCallback : public IXAudio2VoiceCallback class VoiceCallback : public IXAudio2VoiceCallback
{ {
public: public:
SoundCallback* cb; SoundCallback* cb = nullptr;
VoiceCallback(SoundCallback* cb) VoiceCallback(SoundCallback* cb)
: cb(cb) : cb(cb)
@ -99,8 +99,6 @@ void AudioModule::DestroyModule()
{ {
KGE_DEBUG_LOGF("Destroying audio resources"); KGE_DEBUG_LOGF("Destroying audio resources");
TranscoderCache::GetInstance().Clear();
if (mastering_voice_) if (mastering_voice_)
{ {
mastering_voice_->DestroyVoice(); mastering_voice_->DestroyVoice();

View File

@ -27,52 +27,6 @@ namespace kiwano
namespace audio namespace audio
{ {
SoundPtr Sound::Preload(const String& file_path, std::initializer_list<SoundCallbackPtr> callbacks)
{
auto ptr = MakePtr<Sound>();
for (auto& cb : callbacks)
{
ptr->AddCallback(cb);
}
size_t hash_code = std::hash<String>{}(file_path);
if (TranscoderPtr transcoder = TranscoderCache::GetInstance().Get(hash_code))
{
if (ptr->Load(transcoder))
return ptr;
return nullptr;
}
if (ptr && ptr->Load(file_path))
{
TranscoderCache::GetInstance().Add(hash_code, ptr->coder_);
}
return ptr;
}
SoundPtr Sound::Preload(const Resource& res, std::initializer_list<SoundCallbackPtr> callbacks)
{
auto ptr = MakePtr<Sound>();
for (auto& cb : callbacks)
{
ptr->AddCallback(cb);
}
size_t hash_code = res.GetId();
if (TranscoderPtr transcoder = TranscoderCache::GetInstance().Get(hash_code))
{
if (ptr->Load(transcoder))
return ptr;
return nullptr;
}
if (ptr && ptr->Load(res))
{
TranscoderCache::GetInstance().Add(hash_code, ptr->coder_);
}
return ptr;
}
Sound::Sound(const String& file_path) Sound::Sound(const String& file_path)
: Sound() : Sound()
{ {
@ -85,6 +39,12 @@ Sound::Sound(const Resource& res)
Load(res); Load(res);
} }
Sound::Sound(TranscoderPtr transcoder)
: Sound()
{
Load(transcoder);
}
Sound::Sound() Sound::Sound()
: opened_(false) : opened_(false)
, playing_(false) , playing_(false)
@ -308,7 +268,7 @@ SoundCallbackPtr Sound::GetCallbackChain()
class SoundCallbackChain : public SoundCallback class SoundCallbackChain : public SoundCallback
{ {
public: public:
Sound* sound; Sound* sound = nullptr;
void OnStart(Sound*) override void OnStart(Sound*) override
{ {

View File

@ -92,14 +92,6 @@ class KGE_API Sound : public NativeObject
friend class SoundPlayer; friend class SoundPlayer;
public: public:
/// \~chinese
/// @brief 预加载音频
static SoundPtr Preload(const String& file_path, std::initializer_list<SoundCallbackPtr> callbacks = {});
/// \~chinese
/// @brief 预加载音频资源
static SoundPtr Preload(const Resource& res, std::initializer_list<SoundCallbackPtr> callbacks = {});
/// \~chinese /// \~chinese
/// @brief 创建音频对象 /// @brief 创建音频对象
/// @param res 本地音频文件路径 /// @param res 本地音频文件路径
@ -110,6 +102,11 @@ public:
/// @param res 音频资源 /// @param res 音频资源
Sound(const Resource& res); Sound(const Resource& res);
/// \~chinese
/// @brief 创建音频对象
/// @param transcoder 音频解码器
Sound(TranscoderPtr transcoder);
Sound(); Sound();
virtual ~Sound(); virtual ~Sound();
@ -162,18 +159,18 @@ public:
protected: protected:
/// \~chinese /// \~chinese
/// @brief 打开本地音频文件 /// @brief 加载本地音频文件
/// @param res 本地音频文件路径 /// @param res 本地音频文件路径
bool Load(const String& file_path); bool Load(const String& file_path);
/// \~chinese /// \~chinese
/// @brief 打开音频资源 /// @brief 加载音频资源
/// @param res 音频资源 /// @param res 音频资源
bool Load(const Resource& res); bool Load(const Resource& res);
/// \~chinese /// \~chinese
/// @brief 打开音频资源 /// @brief 加载音频
/// @param res 音频资源 /// @param transcoder 音频解码器
bool Load(TranscoderPtr transcoder); bool Load(TranscoderPtr transcoder);
SoundCallbackPtr GetCallbackChain(); SoundCallbackPtr GetCallbackChain();

View File

@ -19,6 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano-audio/SoundPlayer.h> #include <kiwano-audio/SoundPlayer.h>
#include <kiwano-audio/AudioModule.h>
#include <kiwano/platform/Application.h> #include <kiwano/platform/Application.h>
namespace kiwano namespace kiwano
@ -53,7 +54,36 @@ SoundPlayer::SoundPlayer()
} }
SoundPlayer::~SoundPlayer() SoundPlayer::~SoundPlayer()
{}
TranscoderPtr SoundPlayer::Preload(const String& file_path)
{ {
size_t hash_code = std::hash<String>{}(file_path);
if (cache_.count(hash_code))
{
return cache_.at(hash_code);
}
TranscoderPtr ptr = AudioModule::GetInstance().CreateTranscoder(file_path);
if (ptr)
{
cache_.insert(std::make_pair(hash_code, ptr));
}
return ptr;
}
TranscoderPtr SoundPlayer::Preload(const Resource& res)
{
size_t hash_code = res.GetId();
if (cache_.count(hash_code))
{
return cache_.at(hash_code);
}
TranscoderPtr ptr = AudioModule::GetInstance().CreateTranscoder(res);
if (ptr)
{
cache_.insert(std::make_pair(hash_code, ptr));
}
return ptr;
} }
void SoundPlayer::Play(SoundPtr sound, int loop_count) void SoundPlayer::Play(SoundPtr sound, int loop_count)
@ -68,14 +98,26 @@ void SoundPlayer::Play(SoundPtr sound, int loop_count)
SoundPtr SoundPlayer::Play(const String& file_path, int loop_count, std::initializer_list<SoundCallbackPtr> callbacks) SoundPtr SoundPlayer::Play(const String& file_path, int loop_count, std::initializer_list<SoundCallbackPtr> callbacks)
{ {
SoundPtr sound = Sound::Preload(file_path, callbacks); TranscoderPtr transcoder = Preload(file_path);
SoundPtr sound = new Sound(transcoder);
for (const auto& cb : callbacks)
{
sound->AddCallback(cb);
}
Play(sound, loop_count); Play(sound, loop_count);
return sound; return sound;
} }
SoundPtr SoundPlayer::Play(const Resource& res, int loop_count, std::initializer_list<SoundCallbackPtr> callbacks) SoundPtr SoundPlayer::Play(const Resource& res, int loop_count, std::initializer_list<SoundCallbackPtr> callbacks)
{ {
SoundPtr sound = Sound::Preload(res, callbacks); TranscoderPtr transcoder = Preload(res);
SoundPtr sound = new Sound(transcoder);
for (const auto& cb : callbacks)
{
sound->AddCallback(cb);
}
Play(sound, loop_count); Play(sound, loop_count);
return sound; return sound;
} }
@ -114,6 +156,11 @@ void SoundPlayer::StopAll()
} }
} }
void SoundPlayer::ClearCache()
{
cache_.clear();
}
void SoundPlayer::OnEnd(Sound* sound) void SoundPlayer::OnEnd(Sound* sound)
{ {
// remove callback // remove callback

View File

@ -45,6 +45,15 @@ public:
~SoundPlayer(); ~SoundPlayer();
/// \~chinese
/// @brief 渡속潼稜틉
/// @details
TranscoderPtr Preload(const String& file_path);
/// \~chinese
/// @brief 渡속潼稜틉栗都
TranscoderPtr Preload(const Resource& res);
/// \~chinese /// \~chinese
/// @brief 播放音频 /// @brief 播放音频
/// @param sound 音频 /// @param sound 音频
@ -90,6 +99,10 @@ public:
/// @param volume 音量大小1.0 为原始音量, 大于 1 为放大音量, 0 为最小音量 /// @param volume 音量大小1.0 为原始音量, 大于 1 为放大音量, 0 为最小音量
void SetVolume(float volume); void SetVolume(float volume);
/// \~chinese
/// @brief 헌왕뻠닸
void ClearCache();
protected: protected:
void OnEnd(Sound* sound); void OnEnd(Sound* sound);
@ -106,6 +119,8 @@ protected:
SoundList sound_list_; SoundList sound_list_;
SoundList trash_; SoundList trash_;
SoundCallbackPtr callback_; SoundCallbackPtr callback_;
UnorderedMap<size_t, TranscoderPtr> cache_;
}; };
/** @} */ /** @} */

View File

@ -89,56 +89,7 @@ private:
WAVEFORMATEX* wave_format_; WAVEFORMATEX* wave_format_;
}; };
class KGE_API TranscoderCache final : public Singleton<TranscoderCache>
{
friend Singleton<TranscoderCache>;
public:
/// \~chinese
/// @brief 警속뻠닸
inline void Add(size_t key, TranscoderPtr v)
{
cache_.insert(std::make_pair(key, v));
}
/// \~chinese
/// @brief 삿혤뻠닸
inline TranscoderPtr Get(size_t key) const
{
if (cache_.count(key))
{
return cache_.at(key);
}
return nullptr;
}
/// \~chinese
/// @brief 盧뇜뻠닸
inline void Remove(size_t key)
{
cache_.erase(key);
}
/// \~chinese
/// @brief 헌왕뻠닸
inline void Clear()
{
cache_.clear();
}
~TranscoderCache()
{
Clear();
}
private:
TranscoderCache() = default;
private:
UnorderedMap<size_t, TranscoderPtr> cache_;
};
/** @} */ /** @} */
} // namespace audio } // namespace audio
} // namespace kiwano } // namespace kiwano