From cbf599a64c52475f34cfd571a92c44ba3d1e76b3 Mon Sep 17 00:00:00 2001 From: Zhenjian Yang Date: Wed, 19 Jan 2022 17:05:24 +0900 Subject: [PATCH] refactor decoder --- solution/ed_voice/ed_voice.vcxproj | 3 + solution/ed_voice/ed_voice.vcxproj.filters | 9 ++ solution/googletest/gmock.vcxproj | 2 +- solution/googletest/gmock_main.vcxproj | 2 +- solution/googletest/gtest.vcxproj | 2 +- solution/googletest/gtest_main.vcxproj | 2 +- solution/test/player_test.vcxproj | 4 +- solution/unit_test/unit_test.vcxproj | 4 +- src/ed_voice/player/decoder.cpp | 19 ++++ src/ed_voice/player/decoder.h | 11 +-- src/ed_voice/player/decoder_ogg.cpp | 105 +++++++-------------- src/ed_voice/player/decoder_ogg.h | 30 ++++++ src/ed_voice/player/decoder_wav.cpp | 62 ++---------- src/ed_voice/player/decoder_wav.h | 29 ++++++ src/ed_voice/player/player.cpp | 14 +-- 15 files changed, 146 insertions(+), 152 deletions(-) create mode 100644 src/ed_voice/player/decoder.cpp create mode 100644 src/ed_voice/player/decoder_ogg.h create mode 100644 src/ed_voice/player/decoder_wav.h diff --git a/solution/ed_voice/ed_voice.vcxproj b/solution/ed_voice/ed_voice.vcxproj index 145f2cc..0e01602 100644 --- a/solution/ed_voice/ed_voice.vcxproj +++ b/solution/ed_voice/ed_voice.vcxproj @@ -29,6 +29,8 @@ + + @@ -62,6 +64,7 @@ + diff --git a/solution/ed_voice/ed_voice.vcxproj.filters b/solution/ed_voice/ed_voice.vcxproj.filters index 85a6dce..8b6cfdf 100644 --- a/solution/ed_voice/ed_voice.vcxproj.filters +++ b/solution/ed_voice/ed_voice.vcxproj.filters @@ -133,6 +133,12 @@ src\utils + + src\player + + + src\player + @@ -219,5 +225,8 @@ src\utils + + src\player + \ No newline at end of file diff --git a/solution/googletest/gmock.vcxproj b/solution/googletest/gmock.vcxproj index ffd2683..2648d0e 100644 --- a/solution/googletest/gmock.vcxproj +++ b/solution/googletest/gmock.vcxproj @@ -21,7 +21,7 @@ StaticLibrary MultiByte - v142 + $(DefaultPlatformToolset) diff --git a/solution/googletest/gmock_main.vcxproj b/solution/googletest/gmock_main.vcxproj index 630cfb8..bc9fc49 100644 --- a/solution/googletest/gmock_main.vcxproj +++ b/solution/googletest/gmock_main.vcxproj @@ -21,7 +21,7 @@ StaticLibrary MultiByte - v142 + $(DefaultPlatformToolset) diff --git a/solution/googletest/gtest.vcxproj b/solution/googletest/gtest.vcxproj index 13bd033..8ec85c1 100644 --- a/solution/googletest/gtest.vcxproj +++ b/solution/googletest/gtest.vcxproj @@ -21,7 +21,7 @@ StaticLibrary MultiByte - v142 + $(DefaultPlatformToolset) diff --git a/solution/googletest/gtest_main.vcxproj b/solution/googletest/gtest_main.vcxproj index 2ae0d90..67ba7ac 100644 --- a/solution/googletest/gtest_main.vcxproj +++ b/solution/googletest/gtest_main.vcxproj @@ -21,7 +21,7 @@ StaticLibrary MultiByte - v142 + $(DefaultPlatformToolset) diff --git a/solution/test/player_test.vcxproj b/solution/test/player_test.vcxproj index b450d53..a91a9e4 100644 --- a/solution/test/player_test.vcxproj +++ b/solution/test/player_test.vcxproj @@ -12,9 +12,9 @@ {8dcf0718-20e7-4bb9-a92e-00b3ae961945} Win32Proj - 10.0.19041.0 + 10.0 Application - v142 + v143 player_test diff --git a/solution/unit_test/unit_test.vcxproj b/solution/unit_test/unit_test.vcxproj index 1f4e405..b92838f 100644 --- a/solution/unit_test/unit_test.vcxproj +++ b/solution/unit_test/unit_test.vcxproj @@ -14,9 +14,9 @@ {d0b626ec-932d-4692-92c5-f49bff1f6213} Win32Proj - 10.0.19041.0 + 10.0 Application - v142 + v143 unit_test diff --git a/src/ed_voice/player/decoder.cpp b/src/ed_voice/player/decoder.cpp new file mode 100644 index 0000000..7fcae3e --- /dev/null +++ b/src/ed_voice/player/decoder.cpp @@ -0,0 +1,19 @@ +#include "player/decoder.h" + +#include "player/decoder_ogg.h" +#include "player/decoder_wav.h" + +bool player::Decoder::Init() { + return player::impl::Ogg::Init() && player::impl::Wav::Init(); +} + +std::unique_ptr player::Decoder::Get(std::string_view decoder_name) { + if (decoder_name == "ogg") { + return player::impl::Ogg::Get(); + } else if (decoder_name == "wav") { + return player::impl::Wav::Get(); + } else { + return nullptr; + } +} + diff --git a/src/ed_voice/player/decoder.h b/src/ed_voice/player/decoder.h index e8231e3..660bd5c 100644 --- a/src/ed_voice/player/decoder.h +++ b/src/ed_voice/player/decoder.h @@ -31,15 +31,8 @@ class Decoder { std::size_t samples_read_ = 0; public: - static std::unique_ptr GetWav(); - static std::unique_ptr GetOgg(); - static bool InitAllDecoders() { - return InitWav() && InitOgg(); - } - -protected: - static bool InitWav(); - static bool InitOgg(); + static std::unique_ptr Get(std::string_view decoder_name); + static bool Init(); }; // Decoder } // namespace player #endif // __PLAYER_DECODER_H__ diff --git a/src/ed_voice/player/decoder_ogg.cpp b/src/ed_voice/player/decoder_ogg.cpp index c4fe1e4..8d500c8 100644 --- a/src/ed_voice/player/decoder_ogg.cpp +++ b/src/ed_voice/player/decoder_ogg.cpp @@ -1,4 +1,4 @@ -#include "player/decoder.h" +#include "player/decoder_ogg.h" #include #include @@ -7,59 +7,31 @@ #include "utils/log.h" namespace { -using player::BuffByte; -using player::Decoder; -using player::WaveFormat; using std::int32_t; using std::uint32_t; using std::uint16_t; -class Ogg : public Decoder { -public: - bool Open(const char* file_name) override; - std::size_t Read(BuffByte* buff, std::size_t samples_count) override; - void Close() override; +decltype(::ov_open_callbacks)* _ov_open_callbacks; +decltype(::ov_info)* _ov_info; +decltype(::ov_read)* _ov_read; +decltype(::ov_clear)* _ov_clear; +decltype(::ov_pcm_total)* _ov_pcm_total; +bool _ready; +} // namespace - Ogg() = default; - ~Ogg() override { - this->Close(); - } - -private: - OggVorbis_File ov_file{}; - - Ogg(const Ogg&) = delete; - Ogg& operator=(const Ogg&) = delete; - Ogg(Ogg&&) = delete; - Ogg& operator=(Ogg&&) = delete; - -private: - static decltype(::ov_open_callbacks)* ov_open_callbacks; - static decltype(::ov_info)* ov_info; - static decltype(::ov_read)* ov_read; - static decltype(::ov_clear)* ov_clear; - static decltype(::ov_pcm_total)* ov_pcm_total; - static bool ready_; - -public: - static bool Init(); - static bool Ready() { - return ready_; - } -}; // Ogg -bool Ogg::Open(const char* file_name) { +bool player::impl::Ogg::Open(const char* file_name) { FILE* file = fopen(file_name, "rb"); if (file == NULL) { return false; } - if (ov_open_callbacks(file, &ov_file, nullptr, 0, OV_CALLBACKS_DEFAULT) != 0) { + if (_ov_open_callbacks(file, &this->ov_file, nullptr, 0, OV_CALLBACKS_DEFAULT) != 0) { fclose(file); return false; } - vorbis_info* info = ov_info(&ov_file, -1); + vorbis_info* info = _ov_info(&this->ov_file, -1); wave_format_.format_tag = 1; wave_format_.channels = static_cast(info->channels); @@ -69,12 +41,12 @@ bool Ogg::Open(const char* file_name) { wave_format_.avg_bytes_per_sec = wave_format_.samples_per_sec * wave_format_.block_align; samples_read_ = 0; - samples_total_ = static_cast(ov_pcm_total(&ov_file, -1)); + samples_total_ = static_cast(_ov_pcm_total(&this->ov_file, -1)); return true; } -std::size_t Ogg::Read(BuffByte* buff, std::size_t samples_count) { +std::size_t player::impl::Ogg::Read(BuffByte* buff, std::size_t samples_count) { if (!buff || !samples_count) { return 0; } @@ -89,7 +61,7 @@ std::size_t Ogg::Read(BuffByte* buff, std::size_t samples_count) { int bitstream = 0; while (read < request) { int block_bytes = std::min(static_cast(request - read) * wave_format_.block_align, block); - int bytes_read = ov_read(&ov_file, reinterpret_cast(buff), block_bytes, 0, 2, 1, &bitstream); + int bytes_read = _ov_read(&this->ov_file, reinterpret_cast(buff), block_bytes, 0, 2, 1, &bitstream); read += bytes_read / wave_format_.block_align; buff += bytes_read; } @@ -97,45 +69,36 @@ std::size_t Ogg::Read(BuffByte* buff, std::size_t samples_count) { return read; } -void Ogg::Close() { - ov_clear(&ov_file); - memset(&ov_file, 0, sizeof(ov_file)); +void player::impl::Ogg::Close() { + _ov_clear(&this->ov_file); + memset(&this->ov_file, 0, sizeof(this->ov_file)); } -decltype(::ov_open_callbacks)* Ogg::ov_open_callbacks; -decltype(::ov_info)* Ogg::ov_info; -decltype(::ov_read)* Ogg::ov_read; -decltype(::ov_clear)* Ogg::ov_clear; -decltype(::ov_pcm_total)* Ogg::ov_pcm_total; -bool Ogg::ready_; -bool Ogg::Init() { - if (!ready_) { + +bool player::impl::Ogg::Init() { + if (!_ready) { LOG("Loading ogg APIs..."); - ready_ = utils::LoadOggApis(reinterpret_cast(&ov_open_callbacks), - reinterpret_cast(&ov_info), - reinterpret_cast(&ov_read), - reinterpret_cast(&ov_clear), - reinterpret_cast(&ov_pcm_total)); - if (ready_) { + _ready = utils::LoadOggApis(reinterpret_cast(&_ov_open_callbacks), + reinterpret_cast(&_ov_info), + reinterpret_cast(&_ov_read), + reinterpret_cast(&_ov_clear), + reinterpret_cast(&_ov_pcm_total)); + if (_ready) { LOG("Load ogg APIs Finished."); } else { LOG("Load ogg APIs Failed."); } - LOG("Loaded ov_open_callbacks = 0x%08X", (unsigned)ov_open_callbacks); - LOG("Loaded ov_info = 0x%08X", (unsigned)ov_info); - LOG("Loaded ov_read = 0x%08X", (unsigned)ov_read); - LOG("Loaded ov_clear = 0x%08X", (unsigned)ov_clear); - LOG("Loaded ov_pcm_total = 0x%08X", (unsigned)ov_pcm_total); + LOG("Loaded _ov_open_callbacks = 0x%08X", (unsigned)_ov_open_callbacks); + LOG("Loaded _ov_info = 0x%08X", (unsigned)_ov_info); + LOG("Loaded _ov_read = 0x%08X", (unsigned)_ov_read); + LOG("Loaded _ov_clear = 0x%08X", (unsigned)_ov_clear); + LOG("Loaded _ov_pcm_total = 0x%08X", (unsigned)_ov_pcm_total); } - return ready_; + return _ready; } -} // namesapce -std::unique_ptr player::Decoder::GetOgg() { - return Ogg::Ready() ? std::make_unique() : nullptr; +std::unique_ptr player::impl::Ogg::Get() { + return _ready ? std::make_unique() : nullptr; } -bool player::Decoder::InitOgg() { - return Ogg::Init(); -} diff --git a/src/ed_voice/player/decoder_ogg.h b/src/ed_voice/player/decoder_ogg.h new file mode 100644 index 0000000..cfa73bc --- /dev/null +++ b/src/ed_voice/player/decoder_ogg.h @@ -0,0 +1,30 @@ +#include "player/decoder.h" + +#include + +namespace player::impl { + +class Ogg : public Decoder { +public: + bool Open(const char* file_name) override; + std::size_t Read(BuffByte* buff, std::size_t samples_count) override; + void Close() override; + + Ogg() = default; + ~Ogg() override { + this->Close(); + } + +private: + OggVorbis_File ov_file{}; + + Ogg(const Ogg&) = delete; + Ogg& operator=(const Ogg&) = delete; + Ogg(Ogg&&) = delete; + Ogg& operator=(Ogg&&) = delete; + +public: + static std::unique_ptr Get(); + static bool Init(); +}; // Ogg +} // namesapce player::impl diff --git a/src/ed_voice/player/decoder_wav.cpp b/src/ed_voice/player/decoder_wav.cpp index 4a4009c..7524636 100644 --- a/src/ed_voice/player/decoder_wav.cpp +++ b/src/ed_voice/player/decoder_wav.cpp @@ -1,49 +1,14 @@ -#include "player/decoder.h" +#include "player/decoder_wav.h" -#include namespace { -using player::BuffByte; -using player::Decoder; -using player::WaveFormat; -using std::int32_t; -using std::uint32_t; -using std::uint16_t; - constexpr uint32_t kTag_RIFF = 0x46464952; constexpr uint32_t kTag_WAVE = 0x45564157; constexpr uint32_t kTag_fmt = 0x20746D66; constexpr uint32_t kTag_data = 0x61746164; +}// namesapce -class Wav : public Decoder { -public: - bool Open(const char* file_name) override; - std::size_t Read(BuffByte* buff, std::size_t samples_count) override; - void Close() override; - - Wav() = default; - ~Wav() override { - this->Close(); - } -private: - std::ifstream ifs_; - - Wav(const Wav&) = delete; - Wav& operator=(const Wav&) = delete; - Wav(Wav&&) = delete; - Wav& operator=(Wav&&) = delete; - -private: - static bool ready_; - -public: - static bool Init(); - static bool Ready() { - return ready_; - } -}; // Wav - -bool Wav::Open(const char* file_name) { +bool player::impl::Wav::Open(const char* file_name) { ifs_ = std::ifstream(file_name, std::ios::binary | std::ios::in); if (!ifs_) { return false; @@ -76,7 +41,7 @@ bool Wav::Open(const char* file_name) { return true; } -std::size_t Wav::Read(BuffByte* buff, std::size_t samples_count) { +std::size_t player::impl::Wav::Read(BuffByte* buff, std::size_t samples_count) { if (!buff || !samples_count) { return 0; } @@ -92,23 +57,14 @@ std::size_t Wav::Read(BuffByte* buff, std::size_t samples_count) { return read; } -void Wav::Close() { +void player::impl::Wav::Close() { ifs_.close(); } -bool Wav::ready_; - -bool Wav::Init() { - ready_ = true; - return ready_; -} - -} // namesapce - -std::unique_ptr player::Decoder::GetWav() { - return Wav::Ready() ? std::make_unique() : nullptr; +bool player::impl::Wav::Init() { + return true; } -bool player::Decoder::InitWav() { - return Wav::Init(); +std::unique_ptr player::impl::Wav::Get() { + return std::make_unique(); } diff --git a/src/ed_voice/player/decoder_wav.h b/src/ed_voice/player/decoder_wav.h new file mode 100644 index 0000000..3aab44d --- /dev/null +++ b/src/ed_voice/player/decoder_wav.h @@ -0,0 +1,29 @@ +#include "player/decoder.h" + +#include + +namespace player::impl { + +class Wav : public Decoder { +public: + bool Open(const char* file_name) override; + std::size_t Read(BuffByte* buff, std::size_t samples_count) override; + void Close() override; + + Wav() = default; + ~Wav() override { + this->Close(); + } +private: + std::ifstream ifs_; + + Wav(const Wav&) = delete; + Wav& operator=(const Wav&) = delete; + Wav(Wav&&) = delete; + Wav& operator=(Wav&&) = delete; + +public: + static std::unique_ptr Get(); + static bool Init(); +}; // Wav +} // namesapce player::impl diff --git a/src/ed_voice/player/player.cpp b/src/ed_voice/player/player.cpp index b58d056..cbef3de 100644 --- a/src/ed_voice/player/player.cpp +++ b/src/ed_voice/player/player.cpp @@ -16,8 +16,6 @@ using player::Decoder; using player::Player; using player::SoundBuffer; using utils::Events; -constexpr char kAttrWav[] = ".wav"; -constexpr char kAttrOgg[] = ".ogg"; constexpr std::size_t kEventIndexNewPlay = 0; constexpr std::size_t kEventIndexReadOrEnd = 1; //constexpr std::size_t kEventIndexStopAll = 2; @@ -32,17 +30,11 @@ static std::unique_ptr GetDecoderByFilename(std::string_view file_name) if (pos == std::string::npos) { return nullptr; } - std::string attr = std::string(file_name.substr(pos)); + std::string attr = std::string(file_name.substr(pos + 1)); for (char& ch : attr) { ch = static_cast(std::tolower(ch)); } - if (attr == kAttrWav) { - return Decoder::GetWav(); - } else if (attr == kAttrOgg) { - return Decoder::GetOgg(); - } else { - return nullptr; - } + return Decoder::Get(attr); } class PlayerImpl : public player::Player { @@ -394,7 +386,7 @@ std::unique_ptr player::Player::GetPlayer(void* pDS8) { return nullptr; } LOG("Init Decoder..."); - if (!Decoder::InitAllDecoders()) { + if (!Decoder::Init()) { LOG("Init Decoder Failed!"); return nullptr; }