From fdf992450aa35a7d6d95b70780d2e8e9130f1ac2 Mon Sep 17 00:00:00 2001 From: Louis <35883445+louist103@users.noreply.github.com> Date: Sat, 29 Jun 2024 23:57:14 -0400 Subject: [PATCH 1/8] WIP --- OTRExporter/AudioExporter.cpp | 450 ++++++++++++++++++++++------------ OTRExporter/AudioExporter.h | 21 +- 2 files changed, 308 insertions(+), 163 deletions(-) diff --git a/OTRExporter/AudioExporter.cpp b/OTRExporter/AudioExporter.cpp index f79b23f..78ea2bc 100644 --- a/OTRExporter/AudioExporter.cpp +++ b/OTRExporter/AudioExporter.cpp @@ -5,187 +5,321 @@ #include #include "DisplayListExporter.h" -void OTRExporter_Audio::WriteSampleEntryReference(ZAudio* audio, SampleEntry* entry, std::map samples, BinaryWriter* writer) +const char* OTRExporter_Audio::GetMediumStr(uint8_t medium) { + switch (medium) { + case 0: + return "Ram"; + case 1: + return "Unk"; + case 2: + return "Cart"; + case 3: + return "Disk"; + case 5: + return "RamUnloaded"; + default: + return "ERROR"; + } +} + +const char* OTRExporter_Audio::GetCachePolicyStr(uint8_t policy) { + switch (policy) { + case 0: + return "Temporary"; + case 1: + return "Persistent"; + case 2: + return "Either"; + case 3: + return "Permanent"; + default: + return "ERROR"; + } +} + +std::string OTRExporter_Audio::GetSampleEntryReference(ZAudio* audio, SampleEntry* entry, std::map samples) { - writer->Write((uint8_t)(entry != nullptr ? 1 : 0)); - - if (entry != nullptr) - { - if (audio->sampleOffsets[entry->bankId].find(entry->sampleLoopOffset) != audio->sampleOffsets[entry->bankId].end()) - { - if (audio->sampleOffsets[entry->bankId][entry->sampleLoopOffset].find(entry->sampleDataOffset) != audio->sampleOffsets[entry->bankId][entry->sampleLoopOffset].end()) - { - writer->Write(StringHelper::Sprintf("audio/samples/%s", audio->sampleOffsets[entry->bankId][entry->sampleLoopOffset][entry->sampleDataOffset].c_str())); - } - else - writer->Write(entry->fileName); - } - else - writer->Write(entry->fileName); - } - else - writer->Write(""); + + if (entry != nullptr) + { + if (audio->sampleOffsets[entry->bankId].find(entry->sampleLoopOffset) != audio->sampleOffsets[entry->bankId].end()) + { + if (audio->sampleOffsets[entry->bankId][entry->sampleLoopOffset].find(entry->sampleDataOffset) != audio->sampleOffsets[entry->bankId][entry->sampleLoopOffset].end()) + { + return(StringHelper::Sprintf("audio/samples/%s", audio->sampleOffsets[entry->bankId][entry->sampleLoopOffset][entry->sampleDataOffset].c_str())); + } + else + return(entry->fileName); + } + else + return(entry->fileName); + } + else + return(""); } void OTRExporter_Audio::WriteSampleEntry(SampleEntry* entry, BinaryWriter* writer) { - WriteHeader(nullptr, "", writer, static_cast(SOH::ResourceType::SOH_AudioSample), 2); + WriteHeader(nullptr, "", writer, static_cast(SOH::ResourceType::SOH_AudioSample), 2); - writer->Write(entry->codec); - writer->Write(entry->medium); - writer->Write(entry->unk_bit26); - writer->Write(entry->unk_bit25); + writer->Write(entry->codec); + writer->Write(entry->medium); + writer->Write(entry->unk_bit26); + writer->Write(entry->unk_bit25); - writer->Write((uint32_t)entry->data.size()); - writer->Write((char*)entry->data.data(), entry->data.size()); + writer->Write((uint32_t)entry->data.size()); + writer->Write((char*)entry->data.data(), entry->data.size()); - writer->Write((uint32_t)(entry->loop.start)); - writer->Write((uint32_t)(entry->loop.end)); - writer->Write((uint32_t)(entry->loop.count)); - writer->Write((uint32_t)entry->loop.states.size()); + writer->Write((uint32_t)(entry->loop.start)); + writer->Write((uint32_t)(entry->loop.end)); + writer->Write((uint32_t)(entry->loop.count)); + writer->Write((uint32_t)entry->loop.states.size()); - for (size_t i = 0; i < entry->loop.states.size(); i++) - writer->Write((entry->loop.states[i])); + for (size_t i = 0; i < entry->loop.states.size(); i++) + writer->Write((entry->loop.states[i])); - writer->Write((uint32_t)(entry->book.order)); - writer->Write((uint32_t)(entry->book.npredictors)); - writer->Write((uint32_t)entry->book.books.size()); + writer->Write((uint32_t)(entry->book.order)); + writer->Write((uint32_t)(entry->book.npredictors)); + writer->Write((uint32_t)entry->book.books.size()); - for (size_t i = 0; i < entry->book.books.size(); i++) - writer->Write((entry->book.books[i])); + for (size_t i = 0; i < entry->book.books.size(); i++) + writer->Write((entry->book.books[i])); } void OTRExporter_Audio::WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, std::map samples, BinaryWriter* writer) { - writer->Write((uint8_t)(entry != nullptr ? 1 : 0)); + writer->Write((uint8_t)(entry != nullptr ? 1 : 0)); + + if (entry != nullptr) + { + writer->Write((uint8_t)(entry != nullptr ? 1 : 0)); + + writer->Write(GetSampleEntryReference(audio, entry->sampleEntry, samples)); + writer->Write(entry->tuning); + } +} - if (entry != nullptr) - { - WriteSampleEntryReference(audio, entry->sampleEntry, samples, writer); - writer->Write(entry->tuning); - } +void OTRExporter_Audio::WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, + std::map samples, tinyxml2::XMLElement* xmlDoc, + const char* name) { + if (entry == nullptr) { + return; + } + tinyxml2::XMLElement* sfEntry = xmlDoc->InsertNewChildElement(name); + + sfEntry->SetAttribute("SampleRef", GetSampleEntryReference(audio, entry->sampleEntry, samples).c_str()); + sfEntry->SetAttribute("Tuning", entry->tuning); + + xmlDoc->InsertEndChild(sfEntry); } void OTRExporter_Audio::WriteEnvData(std::vector envelopes, BinaryWriter* writer) { - writer->Write((uint32_t)envelopes.size()); + writer->Write((uint32_t)envelopes.size()); - for (auto env : envelopes) - { - writer->Write(env->delay); - writer->Write(env->arg); - } + for (auto env : envelopes) + { + writer->Write(env->delay); + writer->Write(env->arg); + } +} + +void OTRExporter_Audio::WriteEnvData(std::vector envelopes, tinyxml2::XMLElement* xmlDoc) { + tinyxml2::XMLElement* envs = xmlDoc->InsertNewChildElement("Envelopes"); + envs->SetAttribute("Count", envelopes.size()); + + for (auto e : envelopes) { + tinyxml2::XMLElement* env = envs->InsertNewChildElement("Envelope"); + env->SetAttribute("Delay", e->delay); + env->SetAttribute("Arg", e->arg); + } + xmlDoc->InsertEndChild(envs); +} + + +void OTRExporter_Audio::WriteSoundFontTableXML(ZAudio* audio) { + for (size_t i = 0; i < audio->soundFontTable.size(); i++) { + tinyxml2::XMLDocument soundFont; + tinyxml2::XMLElement* root = soundFont.NewElement("SoundFont"); + root->SetAttribute("Version", 0); + root->SetAttribute("Num", i); + root->SetAttribute("Medium", GetMediumStr(audio->soundFontTable[i].medium)); + root->SetAttribute("CachePolicy", GetCachePolicyStr(audio->soundFontTable[i].cachePolicy)); + root->SetAttribute("Data1", audio->soundFontTable[i].data1); + root->SetAttribute("Data2", audio->soundFontTable[i].data2); + root->SetAttribute("Data3", audio->soundFontTable[i].data3); + soundFont.InsertFirstChild(root); + + tinyxml2::XMLElement* drums = root->InsertNewChildElement("Drums"); + drums->SetAttribute("Count", audio->soundFontTable[i].drums.size()); + + for (const auto& d : audio->soundFontTable[i].drums) { + tinyxml2::XMLElement* drum = drums->InsertNewChildElement("Drum"); + drum->SetAttribute("ReleaseRate", d.releaseRate); + drum->SetAttribute("Pan", d.pan); + drum->SetAttribute("Loaded", d.loaded); + drum->SetAttribute("SampleRef", GetSampleEntryReference(audio, d.sample, audio->samples).c_str()); + drum->SetAttribute("Tuning", d.tuning); + + WriteEnvData(d.env, drum); + drums->InsertEndChild(drum); + } + root->InsertEndChild(drums); + + tinyxml2::XMLElement* instruments = root->InsertNewChildElement("Instruments"); + instruments->SetAttribute("Count", audio->soundFontTable[i].instruments.size()); + + //for (size_t k = 0; k < audio->soundFontTable[i].instruments.size(); k++) { + for (const auto i : audio->soundFontTable[i].instruments) { + tinyxml2::XMLElement* instrument = instruments->InsertNewChildElement("Instrument"); + + instrument->SetAttribute("IsValid", i.isValidInstrument); + instrument->SetAttribute("Loaded", i.loaded); + instrument->SetAttribute("NormalRangeLo", i.normalRangeLo); + instrument->SetAttribute("NormalRangeHi", i.normalRangeHi); + instrument->SetAttribute("ReleseRate", i.releaseRate); + + WriteEnvData(i.env, instrument); + + WriteSoundFontEntry(audio, i.lowNotesSound, audio->samples, instrument, "LowNotesSound"); + WriteSoundFontEntry(audio, i.normalNotesSound, audio->samples, instrument, "NormalNotesSound"); + WriteSoundFontEntry(audio, i.highNotesSound, audio->samples, instrument, "HighNotesSound"); + } + root->InsertEndChild(instruments); + + tinyxml2::XMLElement* sfxTbl = root->InsertNewChildElement("SfxTable"); + sfxTbl->SetAttribute("Count", audio->soundFontTable[i].soundEffects.size()); + + for (const auto s : audio->soundFontTable[i].soundEffects) { + WriteSoundFontEntry(audio, s, audio->samples, sfxTbl, "Sfx"); + } + root->InsertEndChild(sfxTbl); + soundFont.InsertEndChild(root); + + tinyxml2::XMLPrinter printer; + soundFont.Accept(&printer); + + std::string fName = OTRExporter_DisplayList::GetPathToRes( + (ZResource*)(audio), StringHelper::Sprintf("fonts/%s", audio->soundFontNames[i].c_str())); + std::vector xmlData((printer.CStr()), printer.CStr() + printer.CStrSize()); + AddFile(fName, xmlData); + } +} + +void OTRExporter_Audio::WriteSoundFontTableBinary(ZAudio* audio) { + for (size_t i = 0; i < audio->soundFontTable.size(); i++) { + MemoryStream* fntStream = new MemoryStream(); + BinaryWriter fntWriter = BinaryWriter(fntStream); + + WriteHeader(nullptr, "", &fntWriter, static_cast(SOH::ResourceType::SOH_AudioSoundFont), 2); + + fntWriter.Write((uint32_t)i); + fntWriter.Write(audio->soundFontTable[i].medium); + fntWriter.Write(audio->soundFontTable[i].cachePolicy); + fntWriter.Write(audio->soundFontTable[i].data1); + fntWriter.Write(audio->soundFontTable[i].data2); + fntWriter.Write(audio->soundFontTable[i].data3); + + fntWriter.Write((uint32_t)audio->soundFontTable[i].drums.size()); + fntWriter.Write((uint32_t)audio->soundFontTable[i].instruments.size()); + fntWriter.Write((uint32_t)audio->soundFontTable[i].soundEffects.size()); + + for (size_t k = 0; k < audio->soundFontTable[i].drums.size(); k++) { + fntWriter.Write(audio->soundFontTable[i].drums[k].releaseRate); + fntWriter.Write(audio->soundFontTable[i].drums[k].pan); + fntWriter.Write(audio->soundFontTable[i].drums[k].loaded); + + WriteEnvData(audio->soundFontTable[i].drums[k].env, &fntWriter); + fntWriter.Write((uint8_t)(audio->soundFontTable[i].drums[k].sample != nullptr ? 1 : 0)); + + fntWriter.Write(GetSampleEntryReference(audio, audio->soundFontTable[i].drums[k].sample, audio->samples)); + fntWriter.Write(audio->soundFontTable[i].drums[k].tuning); + } + + for (size_t k = 0; k < audio->soundFontTable[i].instruments.size(); k++) { + fntWriter.Write((uint8_t)audio->soundFontTable[i].instruments[k].isValidInstrument); + + fntWriter.Write(audio->soundFontTable[i].instruments[k].loaded); + fntWriter.Write(audio->soundFontTable[i].instruments[k].normalRangeLo); + fntWriter.Write(audio->soundFontTable[i].instruments[k].normalRangeHi); + fntWriter.Write(audio->soundFontTable[i].instruments[k].releaseRate); + + WriteEnvData(audio->soundFontTable[i].instruments[k].env, &fntWriter); + + WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].lowNotesSound, audio->samples, + &fntWriter); + WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].normalNotesSound, audio->samples, + &fntWriter); + WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].highNotesSound, audio->samples, + &fntWriter); + } + + for (size_t k = 0; k < audio->soundFontTable[i].soundEffects.size(); k++) { + WriteSoundFontEntry(audio, audio->soundFontTable[i].soundEffects[k], audio->samples, &fntWriter); + } + + // std::string fName = OTRExporter_DisplayList::GetPathToRes(res, StringHelper::Sprintf("fonts/font_%02X", i)); + std::string fName = OTRExporter_DisplayList::GetPathToRes( + (ZResource*)(audio), StringHelper::Sprintf("fonts/%s", audio->soundFontNames[i].c_str())); + AddFile(fName, fntStream->ToVector()); + } } void OTRExporter_Audio::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) { - ZAudio* audio = (ZAudio*)res; - - WriteHeader(res, outPath, writer, static_cast(SOH::ResourceType::SOH_Audio), 2); - - // Write Samples as individual files - for (auto pair : audio->samples) - { - MemoryStream* sampleStream = new MemoryStream(); - BinaryWriter sampleWriter = BinaryWriter(sampleStream); - - writer->Write((uint32_t)pair.first); - WriteSampleEntry(pair.second, &sampleWriter); - - std::string basePath = ""; - - if (audio->sampleOffsets[pair.second->bankId].find(pair.second->sampleLoopOffset) != audio->sampleOffsets[pair.second->bankId].end()) - { - if (audio->sampleOffsets[pair.second->bankId][pair.second->sampleLoopOffset].find(pair.second->sampleDataOffset) != audio->sampleOffsets[pair.second->bankId][pair.second->sampleLoopOffset].end()) - basePath = StringHelper::Sprintf("samples/%s", audio->sampleOffsets[pair.second->bankId][pair.second->sampleLoopOffset][pair.second->sampleDataOffset].c_str()); - else - basePath = StringHelper::Sprintf("samples/sample_%08X", pair.first); - } - else - basePath = StringHelper::Sprintf("samples/sample_%08X", pair.first); - - std::string fName = OTRExporter_DisplayList::GetPathToRes(res, basePath); - AddFile(fName, sampleStream->ToVector()); - } - - // Write the soundfont table - for (size_t i = 0; i < audio->soundFontTable.size(); i++) - { - MemoryStream* fntStream = new MemoryStream(); - BinaryWriter fntWriter = BinaryWriter(fntStream); - - WriteHeader(nullptr, "", &fntWriter, static_cast(SOH::ResourceType::SOH_AudioSoundFont), 2); - - fntWriter.Write((uint32_t)i); - fntWriter.Write(audio->soundFontTable[i].medium); - fntWriter.Write(audio->soundFontTable[i].cachePolicy); - fntWriter.Write(audio->soundFontTable[i].data1); - fntWriter.Write(audio->soundFontTable[i].data2); - fntWriter.Write(audio->soundFontTable[i].data3); - - fntWriter.Write((uint32_t)audio->soundFontTable[i].drums.size()); - fntWriter.Write((uint32_t)audio->soundFontTable[i].instruments.size()); - fntWriter.Write((uint32_t)audio->soundFontTable[i].soundEffects.size()); - - for (size_t k = 0; k < audio->soundFontTable[i].drums.size(); k++) - { - fntWriter.Write(audio->soundFontTable[i].drums[k].releaseRate); - fntWriter.Write(audio->soundFontTable[i].drums[k].pan); - fntWriter.Write(audio->soundFontTable[i].drums[k].loaded); - - WriteEnvData(audio->soundFontTable[i].drums[k].env, &fntWriter); - - WriteSampleEntryReference(audio, audio->soundFontTable[i].drums[k].sample, audio->samples, &fntWriter); - fntWriter.Write(audio->soundFontTable[i].drums[k].tuning); - } - - for (size_t k = 0; k < audio->soundFontTable[i].instruments.size(); k++) - { - fntWriter.Write((uint8_t)audio->soundFontTable[i].instruments[k].isValidInstrument); - - fntWriter.Write(audio->soundFontTable[i].instruments[k].loaded); - fntWriter.Write(audio->soundFontTable[i].instruments[k].normalRangeLo); - fntWriter.Write(audio->soundFontTable[i].instruments[k].normalRangeHi); - fntWriter.Write(audio->soundFontTable[i].instruments[k].releaseRate); - - WriteEnvData(audio->soundFontTable[i].instruments[k].env, &fntWriter); - - WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].lowNotesSound, audio->samples, &fntWriter); - WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].normalNotesSound, audio->samples, &fntWriter); - WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].highNotesSound, audio->samples, &fntWriter); - } - - for (size_t k = 0; k < audio->soundFontTable[i].soundEffects.size(); k++) - { - WriteSoundFontEntry(audio, audio->soundFontTable[i].soundEffects[k], audio->samples, &fntWriter); - } - - //std::string fName = OTRExporter_DisplayList::GetPathToRes(res, StringHelper::Sprintf("fonts/font_%02X", i)); - std::string fName = OTRExporter_DisplayList::GetPathToRes(res, StringHelper::Sprintf("fonts/%s", audio->soundFontNames[i].c_str())); - AddFile(fName, fntStream->ToVector()); - } - - // Write Sequences - for (size_t i = 0; i < audio->sequences.size(); i++) - { - auto seq = audio->sequences[i]; - - MemoryStream* seqStream = new MemoryStream(); - BinaryWriter seqWriter = BinaryWriter(seqStream); - - WriteHeader(nullptr, "", &seqWriter, static_cast(SOH::ResourceType::SOH_AudioSequence), 2); - - seqWriter.Write((uint32_t)seq.size()); - seqWriter.Write(seq.data(), seq.size()); - seqWriter.Write((uint8_t)i); - seqWriter.Write((uint8_t)audio->sequenceTable[i].medium); - seqWriter.Write((uint8_t)audio->sequenceTable[i].cachePolicy); - seqWriter.Write((uint32_t)audio->fontIndices[i].size()); - - for (size_t k = 0; k < audio->fontIndices[i].size(); k++) - seqWriter.Write((uint8_t)audio->fontIndices[i][k]); - - std::string fName = OTRExporter_DisplayList::GetPathToRes(res, StringHelper::Sprintf("sequences/%s", audio->seqNames[i].c_str())); - AddFile(fName, seqStream->ToVector()); - } + ZAudio* audio = (ZAudio*)res; + + WriteHeader(res, outPath, writer, static_cast(SOH::ResourceType::SOH_Audio), 2); + + // Write Samples as individual files + for (auto pair : audio->samples) + { + MemoryStream* sampleStream = new MemoryStream(); + BinaryWriter sampleWriter = BinaryWriter(sampleStream); + + writer->Write((uint32_t)pair.first); + WriteSampleEntry(pair.second, &sampleWriter); + + std::string basePath = ""; + + if (audio->sampleOffsets[pair.second->bankId].find(pair.second->sampleLoopOffset) != audio->sampleOffsets[pair.second->bankId].end()) + { + if (audio->sampleOffsets[pair.second->bankId][pair.second->sampleLoopOffset].find(pair.second->sampleDataOffset) != audio->sampleOffsets[pair.second->bankId][pair.second->sampleLoopOffset].end()) + basePath = StringHelper::Sprintf("samples/%s", audio->sampleOffsets[pair.second->bankId][pair.second->sampleLoopOffset][pair.second->sampleDataOffset].c_str()); + else + basePath = StringHelper::Sprintf("samples/sample_%08X", pair.first); + } + else + basePath = StringHelper::Sprintf("samples/sample_%08X", pair.first); + + std::string fName = OTRExporter_DisplayList::GetPathToRes(res, basePath); + AddFile(fName, sampleStream->ToVector()); + } + + // Write the soundfont table + WriteSoundFontTableXML(audio); + + // Write Sequences + for (size_t i = 0; i < audio->sequences.size(); i++) + { + auto seq = audio->sequences[i]; + + MemoryStream* seqStream = new MemoryStream(); + BinaryWriter seqWriter = BinaryWriter(seqStream); + + WriteHeader(nullptr, "", &seqWriter, static_cast(SOH::ResourceType::SOH_AudioSequence), 2); + + seqWriter.Write((uint32_t)seq.size()); + seqWriter.Write(seq.data(), seq.size()); + seqWriter.Write((uint8_t)i); + seqWriter.Write((uint8_t)audio->sequenceTable[i].medium); + seqWriter.Write((uint8_t)audio->sequenceTable[i].cachePolicy); + seqWriter.Write((uint32_t)audio->fontIndices[i].size()); + + for (size_t k = 0; k < audio->fontIndices[i].size(); k++) + seqWriter.Write((uint8_t)audio->fontIndices[i][k]); + + std::string fName = OTRExporter_DisplayList::GetPathToRes(res, StringHelper::Sprintf("sequences/%s", audio->seqNames[i].c_str())); + AddFile(fName, seqStream->ToVector()); + } } diff --git a/OTRExporter/AudioExporter.h b/OTRExporter/AudioExporter.h index 13a8cc0..12e0237 100644 --- a/OTRExporter/AudioExporter.h +++ b/OTRExporter/AudioExporter.h @@ -8,9 +8,20 @@ class OTRExporter_Audio : public OTRExporter { public: - void WriteSampleEntry(SampleEntry* entry, BinaryWriter* writer); - void WriteSampleEntryReference(ZAudio* audio, SampleEntry* entry, std::map samples, BinaryWriter* writer); - void WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, std::map samples, BinaryWriter* writer); - void WriteEnvData(std::vector envelopes, BinaryWriter* writer); - virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override; + void WriteSampleEntry(SampleEntry* entry, BinaryWriter* writer); + virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override; + +private: + void WriteSoundFontTableBinary(ZAudio* audio); + void WriteSoundFontTableXML(ZAudio* audio); + std::string GetSampleEntryReference(ZAudio* audio, SampleEntry* entry, std::map samples); + void WriteEnvData(std::vector envelopes, BinaryWriter* writer); + void WriteEnvData(std::vector envelopes, tinyxml2::XMLElement* xmlDoc); + void WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, std::map samples, + BinaryWriter* writer); + void WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, std::map samples, + tinyxml2::XMLElement* xmlDoc, const char* name); + const char* GetMediumStr(uint8_t medium); + const char* GetCachePolicyStr(uint8_t policy); + }; \ No newline at end of file From 5bc564bac2545f06a410fe0222a4c6b712b221fc Mon Sep 17 00:00:00 2001 From: Louis <35883445+louist103@users.noreply.github.com> Date: Sun, 30 Jun 2024 18:55:47 -0400 Subject: [PATCH 2/8] Fix spelling --- OTRExporter/AudioExporter.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OTRExporter/AudioExporter.cpp b/OTRExporter/AudioExporter.cpp index 78ea2bc..8478b98 100644 --- a/OTRExporter/AudioExporter.cpp +++ b/OTRExporter/AudioExporter.cpp @@ -102,14 +102,14 @@ void OTRExporter_Audio::WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry void OTRExporter_Audio::WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, std::map samples, tinyxml2::XMLElement* xmlDoc, const char* name) { - if (entry == nullptr) { - return; - } tinyxml2::XMLElement* sfEntry = xmlDoc->InsertNewChildElement(name); + if (entry != nullptr) { sfEntry->SetAttribute("SampleRef", GetSampleEntryReference(audio, entry->sampleEntry, samples).c_str()); sfEntry->SetAttribute("Tuning", entry->tuning); + + } xmlDoc->InsertEndChild(sfEntry); } @@ -177,7 +177,7 @@ void OTRExporter_Audio::WriteSoundFontTableXML(ZAudio* audio) { instrument->SetAttribute("Loaded", i.loaded); instrument->SetAttribute("NormalRangeLo", i.normalRangeLo); instrument->SetAttribute("NormalRangeHi", i.normalRangeHi); - instrument->SetAttribute("ReleseRate", i.releaseRate); + instrument->SetAttribute("ReleaseRate", i.releaseRate); WriteEnvData(i.env, instrument); From f52df0fafb4b46345f6c80f4215d90eb521fa786 Mon Sep 17 00:00:00 2001 From: Louis <35883445+louist103@users.noreply.github.com> Date: Wed, 3 Jul 2024 17:30:16 -0400 Subject: [PATCH 3/8] Fix mac --- OTRExporter/AudioExporter.cpp | 105 ++++++++++++++++++++++++---------- OTRExporter/AudioExporter.h | 2 + 2 files changed, 77 insertions(+), 30 deletions(-) diff --git a/OTRExporter/AudioExporter.cpp b/OTRExporter/AudioExporter.cpp index 8478b98..adba64a 100644 --- a/OTRExporter/AudioExporter.cpp +++ b/OTRExporter/AudioExporter.cpp @@ -86,14 +86,14 @@ void OTRExporter_Audio::WriteSampleEntry(SampleEntry* entry, BinaryWriter* write writer->Write((entry->book.books[i])); } + + void OTRExporter_Audio::WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, std::map samples, BinaryWriter* writer) { writer->Write((uint8_t)(entry != nullptr ? 1 : 0)); if (entry != nullptr) { - writer->Write((uint8_t)(entry != nullptr ? 1 : 0)); - writer->Write(GetSampleEntryReference(audio, entry->sampleEntry, samples)); writer->Write(entry->tuning); } @@ -126,7 +126,7 @@ void OTRExporter_Audio::WriteEnvData(std::vector envelopes, Binar void OTRExporter_Audio::WriteEnvData(std::vector envelopes, tinyxml2::XMLElement* xmlDoc) { tinyxml2::XMLElement* envs = xmlDoc->InsertNewChildElement("Envelopes"); - envs->SetAttribute("Count", envelopes.size()); + envs->SetAttribute("Count", (uint32_t)envelopes.size()); for (auto e : envelopes) { tinyxml2::XMLElement* env = envs->InsertNewChildElement("Envelope"); @@ -142,7 +142,7 @@ void OTRExporter_Audio::WriteSoundFontTableXML(ZAudio* audio) { tinyxml2::XMLDocument soundFont; tinyxml2::XMLElement* root = soundFont.NewElement("SoundFont"); root->SetAttribute("Version", 0); - root->SetAttribute("Num", i); + root->SetAttribute("Num", (uint32_t)i); root->SetAttribute("Medium", GetMediumStr(audio->soundFontTable[i].medium)); root->SetAttribute("CachePolicy", GetCachePolicyStr(audio->soundFontTable[i].cachePolicy)); root->SetAttribute("Data1", audio->soundFontTable[i].data1); @@ -151,7 +151,7 @@ void OTRExporter_Audio::WriteSoundFontTableXML(ZAudio* audio) { soundFont.InsertFirstChild(root); tinyxml2::XMLElement* drums = root->InsertNewChildElement("Drums"); - drums->SetAttribute("Count", audio->soundFontTable[i].drums.size()); + drums->SetAttribute("Count", (uint32_t)audio->soundFontTable[i].drums.size()); for (const auto& d : audio->soundFontTable[i].drums) { tinyxml2::XMLElement* drum = drums->InsertNewChildElement("Drum"); @@ -167,7 +167,7 @@ void OTRExporter_Audio::WriteSoundFontTableXML(ZAudio* audio) { root->InsertEndChild(drums); tinyxml2::XMLElement* instruments = root->InsertNewChildElement("Instruments"); - instruments->SetAttribute("Count", audio->soundFontTable[i].instruments.size()); + instruments->SetAttribute("Count", (uint32_t)audio->soundFontTable[i].instruments.size()); //for (size_t k = 0; k < audio->soundFontTable[i].instruments.size(); k++) { for (const auto i : audio->soundFontTable[i].instruments) { @@ -188,7 +188,7 @@ void OTRExporter_Audio::WriteSoundFontTableXML(ZAudio* audio) { root->InsertEndChild(instruments); tinyxml2::XMLElement* sfxTbl = root->InsertNewChildElement("SfxTable"); - sfxTbl->SetAttribute("Count", audio->soundFontTable[i].soundEffects.size()); + sfxTbl->SetAttribute("Count", (uint32_t)audio->soundFontTable[i].soundEffects.size()); for (const auto s : audio->soundFontTable[i].soundEffects) { WriteSoundFontEntry(audio, s, audio->samples, sfxTbl, "Sfx"); @@ -265,6 +265,72 @@ void OTRExporter_Audio::WriteSoundFontTableBinary(ZAudio* audio) { } } +void OTRExporter_Audio::WriteSequenceXML(ZAudio* audio) { + for (size_t i = 0; i < audio->sequences.size(); i++) { + MemoryStream* seqStream = new MemoryStream(); + BinaryWriter seqWriter = BinaryWriter(seqStream); + auto& seq = audio->sequences[i]; + + tinyxml2::XMLDocument sequence; + tinyxml2::XMLElement* root = sequence.NewElement("Sequence"); + root->SetAttribute("Index", (uint32_t)i); + root->SetAttribute("Medium", GetMediumStr(audio->sequenceTable[i].medium)); + root->SetAttribute("CachePolicy", GetCachePolicyStr(audio->sequenceTable[i].cachePolicy)); + root->SetAttribute("Size", (uint32_t)seq.size()); + + std::string seqName = OTRExporter_DisplayList::GetPathToRes( + (ZResource*)(audio), StringHelper::Sprintf("sequencedata/%s_RAW", audio->seqNames[i].c_str())); + root->SetAttribute("Path", seqName.c_str()); + + + tinyxml2::XMLElement* fontIndicies = root->InsertNewChildElement("FontIndicies"); + for (size_t k = 0; k < audio->fontIndices[i].size(); k++) { + tinyxml2::XMLElement* fontIndex = fontIndicies->InsertNewChildElement("FontIndex"); + fontIndex->SetAttribute("FontIdx", audio->fontIndices[i][k]); + + } + root->InsertEndChild(fontIndicies); + root->InsertEndChild(root); + sequence.InsertEndChild(root); + seqWriter.Write(seq.data(), seq.size()); + AddFile(seqName, seqStream->ToVector()); + + tinyxml2::XMLPrinter printer; + sequence.Accept(&printer); + + + std::string seqMetaName = OTRExporter_DisplayList::GetPathToRes( + (ZResource*)(audio), StringHelper::Sprintf("sequences/%s_META", audio->seqNames[i].c_str())); + std::vector xmlData((printer.CStr()), printer.CStr() + printer.CStrSize()); + AddFile(seqMetaName, xmlData); + } +} + +void OTRExporter_Audio::WriteSequenceBinary(ZAudio* audio) { + for (size_t i = 0; i < audio->sequences.size(); i++) { + auto& seq = audio->sequences[i]; + + MemoryStream* seqStream = new MemoryStream(); + BinaryWriter seqWriter = BinaryWriter(seqStream); + + WriteHeader(nullptr, "", &seqWriter, static_cast(SOH::ResourceType::SOH_AudioSequence), 2); + + seqWriter.Write((uint32_t)seq.size()); + seqWriter.Write(seq.data(), seq.size()); + seqWriter.Write((uint8_t)i); + seqWriter.Write((uint8_t)audio->sequenceTable[i].medium); + seqWriter.Write((uint8_t)audio->sequenceTable[i].cachePolicy); + seqWriter.Write((uint32_t)audio->fontIndices[i].size()); + + for (size_t k = 0; k < audio->fontIndices[i].size(); k++) + seqWriter.Write((uint8_t)audio->fontIndices[i][k]); + + std::string fName = OTRExporter_DisplayList::GetPathToRes( + (ZResource*)(audio), StringHelper::Sprintf("sequences/%s", audio->seqNames[i].c_str())); + AddFile(fName, seqStream->ToVector()); + } +} + void OTRExporter_Audio::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) { ZAudio* audio = (ZAudio*)res; @@ -298,28 +364,7 @@ void OTRExporter_Audio::Save(ZResource* res, const fs::path& outPath, BinaryWrit // Write the soundfont table WriteSoundFontTableXML(audio); - + // Write Sequences - for (size_t i = 0; i < audio->sequences.size(); i++) - { - auto seq = audio->sequences[i]; - - MemoryStream* seqStream = new MemoryStream(); - BinaryWriter seqWriter = BinaryWriter(seqStream); - - WriteHeader(nullptr, "", &seqWriter, static_cast(SOH::ResourceType::SOH_AudioSequence), 2); - - seqWriter.Write((uint32_t)seq.size()); - seqWriter.Write(seq.data(), seq.size()); - seqWriter.Write((uint8_t)i); - seqWriter.Write((uint8_t)audio->sequenceTable[i].medium); - seqWriter.Write((uint8_t)audio->sequenceTable[i].cachePolicy); - seqWriter.Write((uint32_t)audio->fontIndices[i].size()); - - for (size_t k = 0; k < audio->fontIndices[i].size(); k++) - seqWriter.Write((uint8_t)audio->fontIndices[i][k]); - - std::string fName = OTRExporter_DisplayList::GetPathToRes(res, StringHelper::Sprintf("sequences/%s", audio->seqNames[i].c_str())); - AddFile(fName, seqStream->ToVector()); - } + WriteSequenceXML(audio); } diff --git a/OTRExporter/AudioExporter.h b/OTRExporter/AudioExporter.h index 12e0237..4513260 100644 --- a/OTRExporter/AudioExporter.h +++ b/OTRExporter/AudioExporter.h @@ -14,6 +14,8 @@ class OTRExporter_Audio : public OTRExporter private: void WriteSoundFontTableBinary(ZAudio* audio); void WriteSoundFontTableXML(ZAudio* audio); + void WriteSequenceBinary(ZAudio* audio); + void WriteSequenceXML(ZAudio* audio); std::string GetSampleEntryReference(ZAudio* audio, SampleEntry* entry, std::map samples); void WriteEnvData(std::vector envelopes, BinaryWriter* writer); void WriteEnvData(std::vector envelopes, tinyxml2::XMLElement* xmlDoc); From 28d7c72373bab280711bae1a64f264e66ca924dc Mon Sep 17 00:00:00 2001 From: Louis <35883445+louist103@users.noreply.github.com> Date: Wed, 3 Jul 2024 20:21:31 -0400 Subject: [PATCH 4/8] Fix binary for V2 --- OTRExporter/AudioExporter.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/OTRExporter/AudioExporter.cpp b/OTRExporter/AudioExporter.cpp index adba64a..d8f8296 100644 --- a/OTRExporter/AudioExporter.cpp +++ b/OTRExporter/AudioExporter.cpp @@ -94,6 +94,8 @@ void OTRExporter_Audio::WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry if (entry != nullptr) { + // This second byte isn't used but is needed to maintain compatibility with the V2 format. + writer->Write((uint8_t)(entry != nullptr ? 1 : 0)); writer->Write(GetSampleEntryReference(audio, entry->sampleEntry, samples)); writer->Write(entry->tuning); } @@ -363,8 +365,8 @@ void OTRExporter_Audio::Save(ZResource* res, const fs::path& outPath, BinaryWrit } // Write the soundfont table - WriteSoundFontTableXML(audio); + WriteSoundFontTableBinary(audio); // Write Sequences - WriteSequenceXML(audio); + WriteSequenceBinary(audio); } From d0c223d0f991290649b1e444208b807391c48303 Mon Sep 17 00:00:00 2001 From: louist103 <35883445+louist103@users.noreply.github.com> Date: Fri, 4 Oct 2024 21:12:56 -0400 Subject: [PATCH 5/8] fix sample exporting (#31) * Sample XMLs. Needs importer to test * Fix names * fix sample exporting * Cleanups --- OTRExporter/AudioExporter.cpp | 210 +++++++++++++++++++++++++--------- OTRExporter/AudioExporter.h | 16 ++- 2 files changed, 163 insertions(+), 63 deletions(-) diff --git a/OTRExporter/AudioExporter.cpp b/OTRExporter/AudioExporter.cpp index d8f8296..c41a722 100644 --- a/OTRExporter/AudioExporter.cpp +++ b/OTRExporter/AudioExporter.cpp @@ -37,22 +37,40 @@ const char* OTRExporter_Audio::GetCachePolicyStr(uint8_t policy) { } } -std::string OTRExporter_Audio::GetSampleEntryReference(ZAudio* audio, SampleEntry* entry, std::map samples) -{ +const char* OTRExporter_Audio::GetCodecStr(uint8_t codec) { + switch (codec) { + case 0: + return "ADPCM"; + case 1: + return "S8"; + case 2: + return "S16MEM"; + case 3: + return "ADPCMSMALL"; + case 4: + return "REVERB"; + case 5: + return "S16"; + case 6: + return "UNK6"; + case 7: + return "UNK7"; + default: + return "ERROR"; + } +} +std::string OTRExporter_Audio::GetSampleEntryReference(ZAudio* audio, SampleEntry* entry) +{ if (entry != nullptr) { - if (audio->sampleOffsets[entry->bankId].find(entry->sampleLoopOffset) != audio->sampleOffsets[entry->bankId].end()) - { - if (audio->sampleOffsets[entry->bankId][entry->sampleLoopOffset].find(entry->sampleDataOffset) != audio->sampleOffsets[entry->bankId][entry->sampleLoopOffset].end()) - { - return(StringHelper::Sprintf("audio/samples/%s", audio->sampleOffsets[entry->bankId][entry->sampleLoopOffset][entry->sampleDataOffset].c_str())); - } - else - return(entry->fileName); + if (audio->sampleOffsets[entry->bankId].contains(entry->sampleDataOffset) && + audio->sampleOffsets[entry->bankId][entry->sampleDataOffset] != "") { + return (StringHelper::Sprintf("audio/samples/%s_META", + audio->sampleOffsets[entry->bankId][entry->sampleDataOffset].c_str())); } else - return(entry->fileName); + return StringHelper::Sprintf("audio/samples/sample_%d_%08X_META", entry->bankId, entry->sampleDataOffset); } else return(""); @@ -86,9 +104,36 @@ void OTRExporter_Audio::WriteSampleEntry(SampleEntry* entry, BinaryWriter* write writer->Write((entry->book.books[i])); } +void OTRExporter_Audio::WriteSampleEntry(SampleEntry* entry, tinyxml2::XMLElement* xmlDoc) { + tinyxml2::XMLElement* sEntry = xmlDoc; + + sEntry->SetAttribute("Codec", GetCodecStr(entry->codec)); + sEntry->SetAttribute("Medium", GetMediumStr(entry->medium)); + sEntry->SetAttribute("bit26", entry->unk_bit26); + sEntry->SetAttribute("Relocated", entry->unk_bit25); + + sEntry->SetAttribute("LoopStart", entry->loop.start); + sEntry->SetAttribute("LoopEnd", entry->loop.end); + sEntry->SetAttribute("LoopCount", entry->loop.count); + + for (size_t i = 0; i < entry->loop.states.size(); i++) { + tinyxml2::XMLElement* loop = sEntry->InsertNewChildElement("LoopState"); + loop->SetAttribute("Loop", entry->loop.states[i]); + sEntry->InsertEndChild(loop); + } + + sEntry->SetAttribute("Order", entry->book.order); + sEntry->SetAttribute("Npredictors", entry->book.npredictors); + for (size_t i = 0; i < entry->book.books.size(); i++) { + tinyxml2::XMLElement* book = sEntry->InsertNewChildElement("Books"); + book->SetAttribute("Book", entry->book.books[i]); + sEntry->InsertEndChild(book); + } + +} -void OTRExporter_Audio::WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, std::map samples, BinaryWriter* writer) +void OTRExporter_Audio::WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, BinaryWriter* writer) { writer->Write((uint8_t)(entry != nullptr ? 1 : 0)); @@ -96,21 +141,19 @@ void OTRExporter_Audio::WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry { // This second byte isn't used but is needed to maintain compatibility with the V2 format. writer->Write((uint8_t)(entry != nullptr ? 1 : 0)); - writer->Write(GetSampleEntryReference(audio, entry->sampleEntry, samples)); + writer->Write(GetSampleEntryReference(audio, entry->sampleEntry)); writer->Write(entry->tuning); } } -void OTRExporter_Audio::WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, - std::map samples, tinyxml2::XMLElement* xmlDoc, +void OTRExporter_Audio::WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, tinyxml2::XMLElement* xmlDoc, const char* name) { tinyxml2::XMLElement* sfEntry = xmlDoc->InsertNewChildElement(name); - if (entry != nullptr) { - sfEntry->SetAttribute("SampleRef", GetSampleEntryReference(audio, entry->sampleEntry, samples).c_str()); - sfEntry->SetAttribute("Tuning", entry->tuning); - - + if (entry != nullptr) + { + sfEntry->SetAttribute("SampleRef", GetSampleEntryReference(audio, entry->sampleEntry).c_str()); + sfEntry->SetAttribute("Tuning", entry->tuning); } xmlDoc->InsertEndChild(sfEntry); } @@ -160,7 +203,7 @@ void OTRExporter_Audio::WriteSoundFontTableXML(ZAudio* audio) { drum->SetAttribute("ReleaseRate", d.releaseRate); drum->SetAttribute("Pan", d.pan); drum->SetAttribute("Loaded", d.loaded); - drum->SetAttribute("SampleRef", GetSampleEntryReference(audio, d.sample, audio->samples).c_str()); + drum->SetAttribute("SampleRef", GetSampleEntryReference(audio, d.sample).c_str()); drum->SetAttribute("Tuning", d.tuning); WriteEnvData(d.env, drum); @@ -183,9 +226,9 @@ void OTRExporter_Audio::WriteSoundFontTableXML(ZAudio* audio) { WriteEnvData(i.env, instrument); - WriteSoundFontEntry(audio, i.lowNotesSound, audio->samples, instrument, "LowNotesSound"); - WriteSoundFontEntry(audio, i.normalNotesSound, audio->samples, instrument, "NormalNotesSound"); - WriteSoundFontEntry(audio, i.highNotesSound, audio->samples, instrument, "HighNotesSound"); + WriteSoundFontEntry(audio, i.lowNotesSound, instrument, "LowNotesSound"); + WriteSoundFontEntry(audio, i.normalNotesSound, instrument, "NormalNotesSound"); + WriteSoundFontEntry(audio, i.highNotesSound, instrument, "HighNotesSound"); } root->InsertEndChild(instruments); @@ -193,7 +236,7 @@ void OTRExporter_Audio::WriteSoundFontTableXML(ZAudio* audio) { sfxTbl->SetAttribute("Count", (uint32_t)audio->soundFontTable[i].soundEffects.size()); for (const auto s : audio->soundFontTable[i].soundEffects) { - WriteSoundFontEntry(audio, s, audio->samples, sfxTbl, "Sfx"); + WriteSoundFontEntry(audio, s, sfxTbl, "Sfx"); } root->InsertEndChild(sfxTbl); soundFont.InsertEndChild(root); @@ -203,7 +246,7 @@ void OTRExporter_Audio::WriteSoundFontTableXML(ZAudio* audio) { std::string fName = OTRExporter_DisplayList::GetPathToRes( (ZResource*)(audio), StringHelper::Sprintf("fonts/%s", audio->soundFontNames[i].c_str())); - std::vector xmlData((printer.CStr()), printer.CStr() + printer.CStrSize()); + std::vector xmlData((printer.CStr()), printer.CStr() + printer.CStrSize() - 1); AddFile(fName, xmlData); } } @@ -234,7 +277,7 @@ void OTRExporter_Audio::WriteSoundFontTableBinary(ZAudio* audio) { WriteEnvData(audio->soundFontTable[i].drums[k].env, &fntWriter); fntWriter.Write((uint8_t)(audio->soundFontTable[i].drums[k].sample != nullptr ? 1 : 0)); - fntWriter.Write(GetSampleEntryReference(audio, audio->soundFontTable[i].drums[k].sample, audio->samples)); + fntWriter.Write(GetSampleEntryReference(audio, audio->soundFontTable[i].drums[k].sample)); fntWriter.Write(audio->soundFontTable[i].drums[k].tuning); } @@ -248,19 +291,15 @@ void OTRExporter_Audio::WriteSoundFontTableBinary(ZAudio* audio) { WriteEnvData(audio->soundFontTable[i].instruments[k].env, &fntWriter); - WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].lowNotesSound, audio->samples, - &fntWriter); - WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].normalNotesSound, audio->samples, - &fntWriter); - WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].highNotesSound, audio->samples, - &fntWriter); + WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].lowNotesSound, &fntWriter); + WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].normalNotesSound, &fntWriter); + WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].highNotesSound, &fntWriter); } for (size_t k = 0; k < audio->soundFontTable[i].soundEffects.size(); k++) { - WriteSoundFontEntry(audio, audio->soundFontTable[i].soundEffects[k], audio->samples, &fntWriter); + WriteSoundFontEntry(audio, audio->soundFontTable[i].soundEffects[k], &fntWriter); } - // std::string fName = OTRExporter_DisplayList::GetPathToRes(res, StringHelper::Sprintf("fonts/font_%02X", i)); std::string fName = OTRExporter_DisplayList::GetPathToRes( (ZResource*)(audio), StringHelper::Sprintf("fonts/%s", audio->soundFontNames[i].c_str())); AddFile(fName, fntStream->ToVector()); @@ -303,7 +342,7 @@ void OTRExporter_Audio::WriteSequenceXML(ZAudio* audio) { std::string seqMetaName = OTRExporter_DisplayList::GetPathToRes( (ZResource*)(audio), StringHelper::Sprintf("sequences/%s_META", audio->seqNames[i].c_str())); - std::vector xmlData((printer.CStr()), printer.CStr() + printer.CStrSize()); + std::vector xmlData((printer.CStr()), printer.CStr() + printer.CStrSize() - 1); AddFile(seqMetaName, xmlData); } } @@ -333,40 +372,97 @@ void OTRExporter_Audio::WriteSequenceBinary(ZAudio* audio) { } } -void OTRExporter_Audio::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) -{ - ZAudio* audio = (ZAudio*)res; +std::string OTRExporter_Audio::GetSampleEntryStr(ZAudio* audio, SampleEntry* entry) { + std::string basePath = ""; - WriteHeader(res, outPath, writer, static_cast(SOH::ResourceType::SOH_Audio), 2); + if (audio->sampleOffsets[entry->bankId].contains(entry->sampleDataOffset) && + audio->sampleOffsets[entry->bankId][entry->sampleDataOffset] != "") { + basePath = StringHelper::Sprintf( + "samples/%s", audio->sampleOffsets[entry->bankId][entry->sampleDataOffset].c_str()); + } else + basePath = StringHelper::Sprintf("samples/sample_%d_%08X", entry->bankId, entry->sampleDataOffset); + return basePath; +} - // Write Samples as individual files - for (auto pair : audio->samples) - { +std::string OTRExporter_Audio::GetSampleDataStr(ZAudio* audio, SampleEntry* entry) { + std::string basePath = ""; + + if (audio->sampleOffsets[entry->bankId].contains(entry->sampleDataOffset) && + audio->sampleOffsets[entry->bankId][entry->sampleDataOffset] != "") { + basePath = StringHelper::Sprintf( + "samples/%s_RAW", + audio->sampleOffsets[entry->bankId][entry->sampleDataOffset].c_str()); + } else + basePath = StringHelper::Sprintf("samples/sample_%d_%08X_RAW", entry->bankId, entry->sampleDataOffset); + return basePath; +} + +void OTRExporter_Audio::WriteSampleBinary(ZAudio* audio) { + ZResource* res = audio; + + for (const auto& pair : audio->samples) { MemoryStream* sampleStream = new MemoryStream(); BinaryWriter sampleWriter = BinaryWriter(sampleStream); - writer->Write((uint32_t)pair.first); WriteSampleEntry(pair.second, &sampleWriter); - std::string basePath = ""; - - if (audio->sampleOffsets[pair.second->bankId].find(pair.second->sampleLoopOffset) != audio->sampleOffsets[pair.second->bankId].end()) - { - if (audio->sampleOffsets[pair.second->bankId][pair.second->sampleLoopOffset].find(pair.second->sampleDataOffset) != audio->sampleOffsets[pair.second->bankId][pair.second->sampleLoopOffset].end()) - basePath = StringHelper::Sprintf("samples/%s", audio->sampleOffsets[pair.second->bankId][pair.second->sampleLoopOffset][pair.second->sampleDataOffset].c_str()); - else - basePath = StringHelper::Sprintf("samples/sample_%08X", pair.first); - } - else - basePath = StringHelper::Sprintf("samples/sample_%08X", pair.first); + std::string basePath = GetSampleEntryStr(audio, pair.second); std::string fName = OTRExporter_DisplayList::GetPathToRes(res, basePath); AddFile(fName, sampleStream->ToVector()); } +} + +void OTRExporter_Audio::WriteSampleXML(ZAudio* audio) { + ZResource* res = audio; + + for (const auto& pair : audio->samples) { + tinyxml2::XMLDocument sample; + tinyxml2::XMLElement* root = sample.NewElement("Sample"); + root->SetAttribute("Version", 0); + + WriteSampleEntry(pair.second, root); + + root->SetAttribute("SampleSize", (size_t)pair.second->data.size()); + sample.InsertEndChild(root); + + std::string sampleDataPath = GetSampleDataStr(audio, pair.second); + sampleDataPath = OTRExporter_DisplayList::GetPathToRes(res, sampleDataPath); + + root->SetAttribute("SamplePath", sampleDataPath.c_str()); + + std::string basePath = GetSampleEntryStr(audio, pair.second); + std::string fName = OTRExporter_DisplayList::GetPathToRes(res, basePath); + + fName += "_META"; + + tinyxml2::XMLPrinter printer; + sample.Accept(&printer); + std::vector xmlData((printer.CStr()), printer.CStr() + printer.CStrSize() - 1); + AddFile(fName, xmlData); + + + + MemoryStream* stream = new MemoryStream(); + BinaryWriter sampleDataWriter = BinaryWriter(stream); + + sampleDataWriter.Write((char*)pair.second->data.data(), pair.second->data.size()); + AddFile(sampleDataPath, stream->ToVector()); + } +} + +void OTRExporter_Audio::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) +{ + ZAudio* audio = (ZAudio*)res; + + WriteHeader(res, outPath, writer, static_cast(SOH::ResourceType::SOH_Audio), 2); + + // Write Samples as individual files + WriteSampleXML(audio); // Write the soundfont table - WriteSoundFontTableBinary(audio); + WriteSoundFontTableXML(audio); // Write Sequences - WriteSequenceBinary(audio); + WriteSequenceXML(audio); } diff --git a/OTRExporter/AudioExporter.h b/OTRExporter/AudioExporter.h index 4513260..97c6142 100644 --- a/OTRExporter/AudioExporter.h +++ b/OTRExporter/AudioExporter.h @@ -4,11 +4,13 @@ #include "ZAudio.h" #include "Exporter.h" #include +#include class OTRExporter_Audio : public OTRExporter { public: void WriteSampleEntry(SampleEntry* entry, BinaryWriter* writer); + void WriteSampleEntry(SampleEntry* entry, tinyxml2::XMLElement* writer); virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override; private: @@ -16,14 +18,16 @@ class OTRExporter_Audio : public OTRExporter void WriteSoundFontTableXML(ZAudio* audio); void WriteSequenceBinary(ZAudio* audio); void WriteSequenceXML(ZAudio* audio); - std::string GetSampleEntryReference(ZAudio* audio, SampleEntry* entry, std::map samples); + void WriteSampleBinary(ZAudio* audio); + void WriteSampleXML(ZAudio* audio); + std::string GetSampleEntryReference(ZAudio* audio, SampleEntry* entry); + std::string GetSampleEntryStr(ZAudio* audio, SampleEntry* entry); + std::string GetSampleDataStr(ZAudio* audio, SampleEntry* entry); void WriteEnvData(std::vector envelopes, BinaryWriter* writer); void WriteEnvData(std::vector envelopes, tinyxml2::XMLElement* xmlDoc); - void WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, std::map samples, - BinaryWriter* writer); - void WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, std::map samples, - tinyxml2::XMLElement* xmlDoc, const char* name); + void WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, BinaryWriter* writer); + void WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, tinyxml2::XMLElement* xmlDoc, const char* name); const char* GetMediumStr(uint8_t medium); const char* GetCachePolicyStr(uint8_t policy); - + const char* GetCodecStr(uint8_t codec); }; \ No newline at end of file From f1a4ef2d5af2f81008e13134aedf323071485921 Mon Sep 17 00:00:00 2001 From: Louis <35883445+louist103@users.noreply.github.com> Date: Sat, 5 Oct 2024 18:06:03 -0400 Subject: [PATCH 6/8] Fix mac --- OTRExporter/AudioExporter.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OTRExporter/AudioExporter.cpp b/OTRExporter/AudioExporter.cpp index c41a722..f5cfc47 100644 --- a/OTRExporter/AudioExporter.cpp +++ b/OTRExporter/AudioExporter.cpp @@ -423,7 +423,9 @@ void OTRExporter_Audio::WriteSampleXML(ZAudio* audio) { WriteSampleEntry(pair.second, root); - root->SetAttribute("SampleSize", (size_t)pair.second->data.size()); + // There is no overload for size_t. MSVC and GCC are fine with `size` being cast + // to size_t and passed in, but apple clang is not. + root->SetAttribute("SampleSize", (uint64_t)pair.second->data.size()); sample.InsertEndChild(root); std::string sampleDataPath = GetSampleDataStr(audio, pair.second); From 3ffed5f965eb1b345eacfd4f70d28fb50c8e3e9b Mon Sep 17 00:00:00 2001 From: Louis <35883445+louist103@users.noreply.github.com> Date: Wed, 9 Oct 2024 22:18:32 -0400 Subject: [PATCH 7/8] fix binary samples --- OTRExporter/AudioExporter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/OTRExporter/AudioExporter.cpp b/OTRExporter/AudioExporter.cpp index f5cfc47..d6b1405 100644 --- a/OTRExporter/AudioExporter.cpp +++ b/OTRExporter/AudioExporter.cpp @@ -409,6 +409,7 @@ void OTRExporter_Audio::WriteSampleBinary(ZAudio* audio) { std::string basePath = GetSampleEntryStr(audio, pair.second); std::string fName = OTRExporter_DisplayList::GetPathToRes(res, basePath); + fName += "_META"; AddFile(fName, sampleStream->ToVector()); } } From e25686f7f4596bf38fb3f305d1f8819ff20f353e Mon Sep 17 00:00:00 2001 From: Louis <35883445+louist103@users.noreply.github.com> Date: Mon, 2 Dec 2024 17:46:33 -0500 Subject: [PATCH 8/8] Update for torch format --- OTRExporter/AudioExporter.cpp | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/OTRExporter/AudioExporter.cpp b/OTRExporter/AudioExporter.cpp index d6b1405..ee82980 100644 --- a/OTRExporter/AudioExporter.cpp +++ b/OTRExporter/AudioExporter.cpp @@ -112,24 +112,28 @@ void OTRExporter_Audio::WriteSampleEntry(SampleEntry* entry, tinyxml2::XMLElemen sEntry->SetAttribute("bit26", entry->unk_bit26); sEntry->SetAttribute("Relocated", entry->unk_bit25); - sEntry->SetAttribute("LoopStart", entry->loop.start); - sEntry->SetAttribute("LoopEnd", entry->loop.end); - sEntry->SetAttribute("LoopCount", entry->loop.count); - + tinyxml2::XMLElement* loopRoot = sEntry->InsertNewChildElement("ADPCMLoop"); + loopRoot->SetAttribute("Start", entry->loop.start); + loopRoot->SetAttribute("End", entry->loop.end); + loopRoot->SetAttribute("Count", (int)entry->loop.count); // Cast to int to -1 shows as -1. + for (size_t i = 0; i < entry->loop.states.size(); i++) { - tinyxml2::XMLElement* loop = sEntry->InsertNewChildElement("LoopState"); - loop->SetAttribute("Loop", entry->loop.states[i]); - sEntry->InsertEndChild(loop); + tinyxml2::XMLElement* loop = loopRoot->InsertNewChildElement("Predictor"); + loop->SetAttribute("State", entry->loop.states[i]); + loopRoot->InsertEndChild(loop); } + sEntry->InsertEndChild(loopRoot); - sEntry->SetAttribute("Order", entry->book.order); - sEntry->SetAttribute("Npredictors", entry->book.npredictors); + tinyxml2::XMLElement* bookRoot = sEntry->InsertNewChildElement("ADPCMBook"); + bookRoot->SetAttribute("Order", entry->book.order); + bookRoot->SetAttribute("Npredictors", entry->book.npredictors); for (size_t i = 0; i < entry->book.books.size(); i++) { - tinyxml2::XMLElement* book = sEntry->InsertNewChildElement("Books"); - book->SetAttribute("Book", entry->book.books[i]); - sEntry->InsertEndChild(book); + tinyxml2::XMLElement* book = bookRoot->InsertNewChildElement("Book"); + book->SetAttribute("Page", entry->book.books[i]); + bookRoot->InsertEndChild(book); } + sEntry->InsertEndChild(bookRoot); } @@ -426,13 +430,13 @@ void OTRExporter_Audio::WriteSampleXML(ZAudio* audio) { // There is no overload for size_t. MSVC and GCC are fine with `size` being cast // to size_t and passed in, but apple clang is not. - root->SetAttribute("SampleSize", (uint64_t)pair.second->data.size()); + root->SetAttribute("Size", (uint64_t)pair.second->data.size()); sample.InsertEndChild(root); std::string sampleDataPath = GetSampleDataStr(audio, pair.second); sampleDataPath = OTRExporter_DisplayList::GetPathToRes(res, sampleDataPath); - root->SetAttribute("SamplePath", sampleDataPath.c_str()); + root->SetAttribute("Path", sampleDataPath.c_str()); std::string basePath = GetSampleEntryStr(audio, pair.second); std::string fName = OTRExporter_DisplayList::GetPathToRes(res, basePath); @@ -444,8 +448,6 @@ void OTRExporter_Audio::WriteSampleXML(ZAudio* audio) { std::vector xmlData((printer.CStr()), printer.CStr() + printer.CStrSize() - 1); AddFile(fName, xmlData); - - MemoryStream* stream = new MemoryStream(); BinaryWriter sampleDataWriter = BinaryWriter(stream);