From 917e607df5af49f82fbf858414e94d8cdca4989b Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Thu, 26 May 2016 19:30:43 -1000 Subject: [PATCH] Refactor container loading in amuseplay --- CMakeLists.txt | 2 +- driver/main.cpp | 201 +++++++++++++++++----------- include/amuse/AudioGroupData.hpp | 5 + include/amuse/ContainerRegistry.hpp | 1 + include/amuse/amuse.hpp | 1 + lib/ContainerRegistry.cpp | 100 +++++++++----- lib/Voice.cpp | 4 +- 7 files changed, 205 insertions(+), 109 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 90da12f..082adf0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -173,5 +173,5 @@ if(TARGET boo) endif() add_executable(amuseplay WIN32 driver/main.cpp) - target_link_libraries(amuseplay amuse boo ${BOO_SYS_LIBS} logvisor athena-core) + target_link_libraries(amuseplay amuse boo ${BOO_SYS_LIBS} logvisor athena-core ${ZLIB_LIBRARIES}) endif() diff --git a/driver/main.cpp b/driver/main.cpp index dd72ddb..c0356bb 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include static logvisor::Module Log("amuseplay"); @@ -28,6 +30,7 @@ static inline void SNPrintf(boo::SystemChar* str, size_t maxlen, const boo::Syst va_end(va); } +#if 0 static amuse::IntrusiveAudioGroupData LoadFromArgs(int argc, const boo::SystemChar** argv, std::string& descOut, bool& good) { @@ -140,6 +143,7 @@ static amuse::IntrusiveAudioGroupData LoadFromArgs(int argc, const boo::SystemCh return {nullptr, nullptr, nullptr, nullptr}; } +#endif struct AppCallback; @@ -676,12 +680,125 @@ struct AppCallback : boo::IApplicationCallback q->execute(); /* Load data */ - std::string desc; - bool good = false; - amuse::IntrusiveAudioGroupData data = LoadFromArgs(m_argc, m_argv, desc, good); - if (!good) - Log.report(logvisor::Fatal, "incomplete data in args"); - Log.report(logvisor::Info, "Found '%s' Audio Group data", desc.c_str()); + if (m_argc < 2) + Log.report(logvisor::Fatal, "needs group path argument"); + + amuse::ContainerRegistry::Type cType = amuse::ContainerRegistry::DetectContainerType(m_argv[1]); + if (cType == amuse::ContainerRegistry::Type::Invalid) + Log.report(logvisor::Fatal, "invalid/no data at path argument"); + Log.report(logvisor::Info, "Found '%s' Audio Group data", amuse::ContainerRegistry::TypeToName(cType)); + + std::vector> data = + amuse::ContainerRegistry::LoadContainer(m_argv[1]); + if (data.empty()) + Log.report(logvisor::Fatal, "invalid/no data at path argument"); + + std::list m_projs; + std::map*, const amuse::SongGroupIndex*>> allSongGroups; + std::map*, const amuse::SFXGroupIndex*>> allSFXGroups; + size_t totalGroups = 0; + + for (auto& grp : data) + { + /* Load project to assemble group list */ + m_projs.emplace_back(grp.second.getProj()); + amuse::AudioGroupProject& proj = m_projs.back(); + totalGroups += proj.sfxGroups().size() + proj.songGroups().size(); + + for (auto it = proj.songGroups().begin() ; it != proj.songGroups().end() ; ++it) + allSongGroups[it->first] = std::make_pair(&grp, &it->second); + + for (auto it = proj.sfxGroups().begin() ; it != proj.sfxGroups().end() ; ++it) + allSFXGroups[it->first] = std::make_pair(&grp, &it->second); + } + + /* Get group selection from user */ + if (m_groupId != -1) + { + if (allSongGroups.find(m_groupId) != allSongGroups.end()) + m_sfxGroup = false; + else if (allSFXGroups.find(m_groupId) != allSFXGroups.end()) + m_sfxGroup = true; + else + Log.report(logvisor::Fatal, "unable to find Group %d", m_groupId); + } + else if (totalGroups > 1) + { + /* Ask user to specify which group in project */ + printf("Multiple Audio Groups discovered:\n"); + for (const auto& pair :allSFXGroups) + { + printf(" %d %s (SFXGroup) %" PRISize " sfx-entries\n", + pair.first, pair.second.first->first.c_str(), + pair.second.second->m_sfxEntries.size()); + } + for (const auto& pair : allSongGroups) + { + printf(" %d %s (SongGroup) %" PRISize " normal-pages, %" PRISize " drum-pages\n", + pair.first, pair.second.first->first.c_str(), + pair.second.second->m_normPages.size(), pair.second.second->m_drumPages.size()); + } + + int userSel = 0; + printf("Enter Group Number: "); + if (scanf("%d", &userSel) <= 0) + Log.report(logvisor::Fatal, "unable to parse prompt"); + + if (allSongGroups.find(userSel) != allSongGroups.end()) + { + m_groupId = userSel; + m_sfxGroup = false; + } + else if (allSFXGroups.find(userSel) != allSFXGroups.end()) + { + m_groupId = userSel; + m_sfxGroup = true; + } + else + Log.report(logvisor::Fatal, "unable to find Group %d", userSel); + } + else if (totalGroups == 1) + { + /* Load one and only group */ + if (allSongGroups.size()) + { + const auto& pair = *allSongGroups.cbegin(); + m_groupId = pair.first; + m_sfxGroup = false; + } + else + { + const auto& pair = *allSFXGroups.cbegin(); + m_groupId = pair.first; + m_sfxGroup = true; + } + } + else + Log.report(logvisor::Fatal, "empty project"); + + /* Make final group selection */ + amuse::IntrusiveAudioGroupData* selData = nullptr; + const amuse::SongGroupIndex* songIndex = nullptr; + const amuse::SFXGroupIndex* sfxIndex = nullptr; + auto songSearch = allSongGroups.find(m_groupId); + if (songSearch != allSongGroups.end()) + { + selData = &songSearch->second.first->second; + songIndex = songSearch->second.second; + } + else + { + auto sfxSearch = allSFXGroups.find(m_groupId); + if (sfxSearch != allSFXGroups.end()) + { + selData = &sfxSearch->second.first->second; + sfxIndex = sfxSearch->second.second; + } + } + + if (!selData) + Log.report(logvisor::Fatal, "unable to select audio group data"); + /* Attempt loading song */ if (m_argc > 2) @@ -709,87 +826,21 @@ struct AppCallback : boo::IApplicationCallback } } - /* Load project to assemble group list */ - amuse::AudioGroupProject proj(data.getProj()); - - /* Get group selection from user */ - size_t totalGroups = proj.sfxGroups().size() + proj.songGroups().size(); - if (m_groupId != -1) - { - if (proj.getSongGroupIndex(m_groupId)) - m_sfxGroup = false; - else if (proj.getSFXGroupIndex(m_groupId)) - m_sfxGroup = true; - else - Log.report(logvisor::Fatal, "unable to find Group %d", m_groupId); - } - else if (totalGroups > 1) - { - /* Ask user to specify which group in project */ - printf("Multiple Audio Groups discovered:\n"); - for (const auto& pair : proj.songGroups()) - { - printf(" %d (SongGroup) %" PRISize " normal-pages, %" PRISize " drum-pages\n", - pair.first, pair.second.m_normPages.size(), pair.second.m_drumPages.size()); - } - for (const auto& pair : proj.sfxGroups()) - { - printf(" %d (SFXGroup) %" PRISize " sfx-entries\n", - pair.first, pair.second.m_sfxEntries.size()); - } - - int userSel = 0; - printf("Enter Group Number: "); - if (scanf("%d", &userSel) <= 0) - Log.report(logvisor::Fatal, "unable to parse prompt"); - - if (proj.getSongGroupIndex(userSel)) - { - m_groupId = userSel; - m_sfxGroup = false; - } - else if (proj.getSFXGroupIndex(userSel)) - { - m_groupId = userSel; - m_sfxGroup = true; - } - else - Log.report(logvisor::Fatal, "unable to find Group %d", userSel); - } - else if (totalGroups == 1) - { - /* Load one and only group */ - if (proj.songGroups().size()) - { - const auto& pair = *proj.songGroups().cbegin(); - m_groupId = pair.first; - m_sfxGroup = false; - } - else - { - const auto& pair = *proj.sfxGroups().cbegin(); - m_groupId = pair.first; - m_sfxGroup = true; - } - } - else - Log.report(logvisor::Fatal, "empty project"); - /* Build voice engine */ std::unique_ptr voxEngine = boo::NewAudioVoiceEngine(); amuse::BooBackendVoiceAllocator booBackend(*voxEngine); m_engine.emplace(booBackend, amuse::AmplitudeMode::BlockLinearized); /* Load group into engine */ - const amuse::AudioGroup* group = m_engine->addAudioGroup(data); + const amuse::AudioGroup* group = m_engine->addAudioGroup(*selData); if (!group) Log.report(logvisor::Fatal, "unable to add audio group"); /* Enter playback loop */ if (m_sfxGroup) - SFXLoop(*proj.getSFXGroupIndex(m_groupId)); + SFXLoop(*sfxIndex); else - SongLoop(*proj.getSongGroupIndex(m_groupId)); + SongLoop(*songIndex); return 0; } diff --git a/include/amuse/AudioGroupData.hpp b/include/amuse/AudioGroupData.hpp index ccbf92c..d1cd617 100644 --- a/include/amuse/AudioGroupData.hpp +++ b/include/amuse/AudioGroupData.hpp @@ -21,6 +21,11 @@ public: const unsigned char* getPool() const {return m_pool;} const unsigned char* getSdir() const {return m_sdir;} const unsigned char* getSamp() const {return m_samp;} + + operator bool() const + { + return m_proj != nullptr && m_pool != nullptr && m_sdir != nullptr && m_samp != nullptr; + } }; /** A buffer-owning version of AudioGroupData */ diff --git a/include/amuse/ContainerRegistry.hpp b/include/amuse/ContainerRegistry.hpp index 4b24756..364e0ea 100644 --- a/include/amuse/ContainerRegistry.hpp +++ b/include/amuse/ContainerRegistry.hpp @@ -22,6 +22,7 @@ public: RogueSquadron2, RogueSquadron3 }; + static const char* TypeToName(Type tp); static Type DetectContainerType(const char* path); static std::vector> LoadContainer(const char* path); }; diff --git a/include/amuse/amuse.hpp b/include/amuse/amuse.hpp index 7462db9..ca4a950 100644 --- a/include/amuse/amuse.hpp +++ b/include/amuse/amuse.hpp @@ -6,6 +6,7 @@ #include "AudioGroupPool.hpp" #include "AudioGroupProject.hpp" #include "AudioGroupSampleDirectory.hpp" +#include "ContainerRegistry.hpp" #include "EffectChorus.hpp" #include "EffectDelay.hpp" #include "EffectReverb.hpp" diff --git a/lib/ContainerRegistry.cpp b/lib/ContainerRegistry.cpp index 3e09a34..25d8145 100644 --- a/lib/ContainerRegistry.cpp +++ b/lib/ContainerRegistry.cpp @@ -33,6 +33,30 @@ static void *memmem(const void *haystack, size_t hlen, const void *needle, size_ namespace amuse { +const char* ContainerRegistry::TypeToName(Type tp) +{ + switch (tp) + { + case Type::Invalid: + default: + return nullptr; + case Type::Raw4: + return "4 RAW Chunks"; + case Type::MetroidPrime: + return "Metroid Prime (GCN)"; + case Type::MetroidPrime2: + return "Metroid Prime 2 (GCN)"; + case Type::RogueSquadronPC: + return "Star Wars: Rogue Squadron (PC)"; + case Type::RogueSquadronN64: + return "Star Wars: Rogue Squadron (N64)"; + case Type::RogueSquadron2: + return "Star Wars: Rogue Squadron 2 (GCN)"; + case Type::RogueSquadron3: + return "Star Wars: Rogue Squadron 3 (GCN)"; + } +} + static size_t FileLength(FILE* fp) { FSeek(fp, 0, SEEK_END); @@ -92,7 +116,7 @@ static bool ValidateMP1(FILE* fp) uint32_t nameLen; fread(&nameLen, 1, 4, fp); nameLen = SBig(nameLen); - FSeek(fp, 4 + nameLen, SEEK_CUR); + FSeek(fp, nameLen, SEEK_CUR); } uint32_t resCount; @@ -151,7 +175,7 @@ static std::vector> LoadMP1(FILE uint32_t nameLen; fread(&nameLen, 1, 4, fp); nameLen = SBig(nameLen); - FSeek(fp, 4 + nameLen, SEEK_CUR); + FSeek(fp, nameLen, SEEK_CUR); } uint32_t resCount; @@ -236,7 +260,7 @@ static bool ValidateMP2(FILE* fp) uint32_t nameLen; fread(&nameLen, 1, 4, fp); nameLen = SBig(nameLen); - FSeek(fp, 4 + nameLen, SEEK_CUR); + FSeek(fp, nameLen, SEEK_CUR); } uint32_t resCount; @@ -295,7 +319,7 @@ static std::vector> LoadMP2(FILE uint32_t nameLen; fread(&nameLen, 1, 4, fp); nameLen = SBig(nameLen); - FSeek(fp, 4 + nameLen, SEEK_CUR); + FSeek(fp, nameLen, SEEK_CUR); } uint32_t resCount; @@ -409,13 +433,14 @@ static bool ValidateRS1PC(FILE* fp) uint8_t foundComps = 0; for (uint32_t i=0 ; i> LoadRS1PC(FI for (uint32_t i=0 ; i> LoadRS2(FILE memcpy(samp.get(), audData.get() + head.sampOff, head.sampLen); char name[128]; - snprintf(name, 128, "Group%u", j); + snprintf(name, 128, "GroupFile%u", j); ret.emplace_back(name, IntrusiveAudioGroupData{proj.release(), pool.release(), sdir.release(), samp.release()}); } @@ -849,7 +887,7 @@ static std::vector> LoadRS3(FILE memcpy(samp.get(), audData.get() + head.sampOff, head.sampLen); char name[128]; - snprintf(name, 128, "Group%u", j); + snprintf(name, 128, "GroupFile%u", j); ret.emplace_back(name, IntrusiveAudioGroupData{proj.release(), pool.release(), sdir.release(), samp.release()}); } diff --git a/lib/Voice.cpp b/lib/Voice.cpp index 96435f0..fc7bea2 100644 --- a/lib/Voice.cpp +++ b/lib/Voice.cpp @@ -92,8 +92,8 @@ bool Voice::_checkSamplePos() { /* Turn over looped sample */ m_curSamplePos = m_curSample->first.m_loopStartSample; - m_prev1 = m_curSample->second.m_hist1; - m_prev2 = m_curSample->second.m_hist2; + m_prev1 = m_curSample->second.m_hist2; + m_prev2 = m_curSample->second.m_hist1; } else {