mirror of https://github.com/AxioDL/amuse.git
Refactor container loading in amuseplay
This commit is contained in:
parent
276b7823c2
commit
917e607df5
|
@ -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()
|
||||
|
|
201
driver/main.cpp
201
driver/main.cpp
|
@ -9,6 +9,8 @@
|
|||
#include <string.h>
|
||||
#include <thread>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <stdarg.h>
|
||||
|
||||
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<std::pair<std::string, amuse::IntrusiveAudioGroupData>> data =
|
||||
amuse::ContainerRegistry::LoadContainer(m_argv[1]);
|
||||
if (data.empty())
|
||||
Log.report(logvisor::Fatal, "invalid/no data at path argument");
|
||||
|
||||
std::list<amuse::AudioGroupProject> m_projs;
|
||||
std::map<int, std::pair<std::pair<std::string, amuse::IntrusiveAudioGroupData>*, const amuse::SongGroupIndex*>> allSongGroups;
|
||||
std::map<int, std::pair<std::pair<std::string, amuse::IntrusiveAudioGroupData>*, 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<boo::IAudioVoiceEngine> 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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -22,6 +22,7 @@ public:
|
|||
RogueSquadron2,
|
||||
RogueSquadron3
|
||||
};
|
||||
static const char* TypeToName(Type tp);
|
||||
static Type DetectContainerType(const char* path);
|
||||
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadContainer(const char* path);
|
||||
};
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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<std::pair<std::string, IntrusiveAudioGroupData>> 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<std::pair<std::string, IntrusiveAudioGroupData>> 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<elemCount ; ++i)
|
||||
{
|
||||
if (!strncmp("proj_SND", entries[i].name, 16))
|
||||
RS1FSTEntry& entry = entries[i];
|
||||
if (!strncmp("proj_SND", entry.name, 16))
|
||||
foundComps |= 1;
|
||||
else if (!strncmp("pool_SND", entries[i].name, 16))
|
||||
else if (!strncmp("pool_SND", entry.name, 16))
|
||||
foundComps |= 2;
|
||||
else if (!strncmp("sdir_SND", entries[i].name, 16))
|
||||
else if (!strncmp("sdir_SND", entry.name, 16))
|
||||
foundComps |= 4;
|
||||
else if (!strncmp("samp_SND", entries[i].name, 16))
|
||||
else if (!strncmp("samp_SND", entry.name, 16))
|
||||
foundComps |= 8;
|
||||
}
|
||||
|
||||
|
@ -450,32 +475,45 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS1PC(FI
|
|||
|
||||
for (uint32_t i=0 ; i<elemCount ; ++i)
|
||||
{
|
||||
if (!strncmp("proj_SND", entries[i].name, 16))
|
||||
RS1FSTEntry& entry = entries[i];
|
||||
if (!strncmp("proj_SND", entry.name, 16))
|
||||
{
|
||||
proj.reset(new uint8_t[entries[i].compSz]);
|
||||
FSeek(fp, entries[i].offset, SEEK_SET);
|
||||
fread(proj.get(), 1, entries[i].compSz, fp);
|
||||
proj.reset(new uint8_t[entry.decompSz]);
|
||||
FSeek(fp, entry.offset, SEEK_SET);
|
||||
fread(proj.get(), 1, entry.decompSz, fp);
|
||||
FILE* wfp = fopen("/Users/jacko/Desktop/RS.proj", "wb");
|
||||
fwrite(proj.get(), 1, entry.decompSz, wfp);
|
||||
fclose(wfp);
|
||||
}
|
||||
else if (!strncmp("pool_SND", entries[i].name, 16))
|
||||
else if (!strncmp("pool_SND", entry.name, 16))
|
||||
{
|
||||
pool.reset(new uint8_t[entries[i].compSz]);
|
||||
FSeek(fp, entries[i].offset, SEEK_SET);
|
||||
fread(pool.get(), 1, entries[i].compSz, fp);
|
||||
pool.reset(new uint8_t[entry.decompSz]);
|
||||
FSeek(fp, entry.offset, SEEK_SET);
|
||||
fread(pool.get(), 1, entry.decompSz, fp);
|
||||
FILE* wfp = fopen("/Users/jacko/Desktop/RS.pool", "wb");
|
||||
fwrite(pool.get(), 1, entry.decompSz, wfp);
|
||||
fclose(wfp);
|
||||
}
|
||||
else if (!strncmp("sdir_SND", entries[i].name, 16))
|
||||
else if (!strncmp("sdir_SND", entry.name, 16))
|
||||
{
|
||||
sdir.reset(new uint8_t[entries[i].compSz]);
|
||||
FSeek(fp, entries[i].offset, SEEK_SET);
|
||||
fread(sdir.get(), 1, entries[i].compSz, fp);
|
||||
sdir.reset(new uint8_t[entry.decompSz]);
|
||||
FSeek(fp, entry.offset, SEEK_SET);
|
||||
fread(sdir.get(), 1, entry.decompSz, fp);
|
||||
FILE* wfp = fopen("/Users/jacko/Desktop/RS.sdir", "wb");
|
||||
fwrite(sdir.get(), 1, entry.decompSz, wfp);
|
||||
fclose(wfp);
|
||||
}
|
||||
else if (!strncmp("samp_SND", entries[i].name, 16))
|
||||
else if (!strncmp("samp_SND", entry.name, 16))
|
||||
{
|
||||
samp.reset(new uint8_t[entries[i].compSz]);
|
||||
FSeek(fp, entries[i].offset, SEEK_SET);
|
||||
fread(samp.get(), 1, entries[i].compSz, fp);
|
||||
samp.reset(new uint8_t[entry.decompSz]);
|
||||
FSeek(fp, entry.offset, SEEK_SET);
|
||||
fread(samp.get(), 1, entry.decompSz, fp);
|
||||
FILE* wfp = fopen("/Users/jacko/Desktop/RS.samp", "wb");
|
||||
fwrite(samp.get(), 1, entry.decompSz, wfp);
|
||||
fclose(wfp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ret.emplace_back("Group", IntrusiveAudioGroupData{proj.release(), pool.release(),
|
||||
sdir.release(), samp.release()});
|
||||
}
|
||||
|
@ -644,10 +682,10 @@ struct RS2FSTEntry
|
|||
|
||||
struct RS23GroupHead
|
||||
{
|
||||
uint32_t poolOff;
|
||||
uint32_t poolLen;
|
||||
uint32_t projOff;
|
||||
uint32_t projLen;
|
||||
uint32_t poolOff;
|
||||
uint32_t poolLen;
|
||||
uint32_t sdirOff;
|
||||
uint32_t sdirLen;
|
||||
uint32_t sampOff;
|
||||
|
@ -655,10 +693,10 @@ struct RS23GroupHead
|
|||
|
||||
void swapBig()
|
||||
{
|
||||
poolOff = SBig(poolOff);
|
||||
poolLen = SBig(poolLen);
|
||||
projOff = SBig(projOff);
|
||||
projLen = SBig(projLen);
|
||||
poolOff = SBig(poolOff);
|
||||
poolLen = SBig(poolLen);
|
||||
sdirOff = SBig(sdirOff);
|
||||
sdirLen = SBig(sdirLen);
|
||||
sampOff = SBig(sampOff);
|
||||
|
@ -743,7 +781,7 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> 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<std::pair<std::string, IntrusiveAudioGroupData>> 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()});
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue