mirror of
https://github.com/izzy2lost/Torch.git
synced 2026-07-06 00:18:35 -07:00
Recreated audio export system to something more generic
This commit is contained in:
+34
-8
@@ -26,10 +26,6 @@
|
||||
#include "factories/AssetArrayFactory.h"
|
||||
#include "factories/ViewportFactory.h"
|
||||
|
||||
#include "factories/sm64/audio/BankFactory.h"
|
||||
#include "factories/sm64/audio/AudioHeaderFactory.h"
|
||||
#include "factories/sm64/audio/SampleFactory.h"
|
||||
#include "factories/sm64/audio/SequenceFactory.h"
|
||||
#include "factories/sm64/AnimationFactory.h"
|
||||
#include "factories/sm64/BehaviorScriptFactory.h"
|
||||
#include "factories/sm64/CollisionFactory.h"
|
||||
@@ -66,6 +62,21 @@
|
||||
#include "factories/sf64/ObjInitFactory.h"
|
||||
#include "factories/sf64/TriangleFactory.h"
|
||||
|
||||
#include "factories/naudio/v0/AudioHeaderFactory.h"
|
||||
#include "factories/naudio/v0/BankFactory.h"
|
||||
#include "factories/naudio/v0/SampleFactory.h"
|
||||
#include "factories/naudio/v0/SequenceFactory.h"
|
||||
|
||||
#include "factories/naudio/v1/AudioContext.h"
|
||||
#include "factories/naudio/v1/SoundFontFactory.h"
|
||||
#include "factories/naudio/v1/AudioTableFactory.h"
|
||||
#include "factories/naudio/v1/InstrumentFactory.h"
|
||||
#include "factories/naudio/v1/SampleFactory.h"
|
||||
#include "factories/naudio/v1/DrumFactory.h"
|
||||
#include "factories/naudio/v1/EnvelopeFactory.h"
|
||||
#include "factories/naudio/v1/LoopFactory.h"
|
||||
#include "factories/naudio/v1/BookFactory.h"
|
||||
|
||||
using namespace std::chrono;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
@@ -95,10 +106,6 @@ void Companion::Init(const ExportType type) {
|
||||
this->RegisterFactory("VP", std::make_shared<ViewportFactory>());
|
||||
|
||||
// SM64 specific
|
||||
this->RegisterFactory("SM64:AUDIO_HEADER", std::make_shared<AudioHeaderFactory>());
|
||||
this->RegisterFactory("SM64:SEQUENCE", std::make_shared<SequenceFactory>());
|
||||
this->RegisterFactory("SM64:SAMPLE", std::make_shared<SampleFactory>());
|
||||
this->RegisterFactory("SM64:BANK", std::make_shared<BankFactory>());
|
||||
this->RegisterFactory("SM64:DIALOG", std::make_shared<SM64::DialogFactory>());
|
||||
this->RegisterFactory("SM64:TEXT", std::make_shared<SM64::TextFactory>());
|
||||
this->RegisterFactory("SM64:DICTIONARY", std::make_shared<SM64::DictionaryFactory>());
|
||||
@@ -137,6 +144,22 @@ void Companion::Init(const ExportType type) {
|
||||
this->RegisterFactory("SF64:COLPOLY", std::make_shared<SF64::ColPolyFactory>());
|
||||
this->RegisterFactory("SF64:TRIANGLE", std::make_shared<SF64::TriangleFactory>());
|
||||
|
||||
// NAudio specific
|
||||
this->RegisterFactory("NAUDIO:V0:AUDIO_HEADER", std::make_shared<AudioHeaderFactory>());
|
||||
this->RegisterFactory("NAUDIO:V0:SEQUENCE", std::make_shared<SequenceFactory>());
|
||||
this->RegisterFactory("NAUDIO:V0:SAMPLE", std::make_shared<SampleFactory>());
|
||||
this->RegisterFactory("NAUDIO:V0:BANK", std::make_shared<BankFactory>());
|
||||
|
||||
this->RegisterFactory("NAUDIO:V1:AUDIO_SETUP", std::make_shared<AudioContextFactory>());
|
||||
this->RegisterFactory("NAUDIO:V1:AUDIO_TABLE", std::make_shared<AudioTableFactory>());
|
||||
this->RegisterFactory("NAUDIO:V1:SOUND_FONT", std::make_shared<SoundFontFactory>());
|
||||
this->RegisterFactory("NAUDIO:V1:INSTRUMENT", std::make_shared<InstrumentFactory>());
|
||||
this->RegisterFactory("NAUDIO:V1:DRUM", std::make_shared<DrumFactory>());
|
||||
this->RegisterFactory("NAUDIO:V1:SAMPLE", std::make_shared<NSampleFactory>());
|
||||
this->RegisterFactory("NAUDIO:V1:ENVELOPE", std::make_shared<EnvelopeFactory>());
|
||||
this->RegisterFactory("NAUDIO:V1:ADPCM_LOOP", std::make_shared<ADPCMLoopFactory>());
|
||||
this->RegisterFactory("NAUDIO:V1:ADPCM_BOOK", std::make_shared<ADPCMBookFactory>());
|
||||
|
||||
this->Process();
|
||||
}
|
||||
|
||||
@@ -1451,6 +1474,9 @@ std::optional<YAML::Node> Companion::AddAsset(YAML::Node asset) {
|
||||
} else {
|
||||
output = this->NormalizeAsset(typeId + "_" + Torch::to_hex(offset, false));
|
||||
}
|
||||
|
||||
std::replace(output.begin(), output.end(), ':', '_');
|
||||
|
||||
asset["autogen"] = true;
|
||||
asset["symbol"] = output;
|
||||
|
||||
|
||||
@@ -111,5 +111,7 @@ public:
|
||||
return std::nullopt;
|
||||
}
|
||||
private:
|
||||
virtual std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() = 0;
|
||||
virtual std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
@@ -15,9 +15,6 @@ enum class ResourceType {
|
||||
Array = 0x4F415252, // OARR
|
||||
Blob = 0x4F424C42, // OBLB
|
||||
Texture = 0x4F544558, // OTEX
|
||||
Bank = 0x42414E4B, // BANK
|
||||
Sample = 0x41554643, // AIFC
|
||||
Sequence = 0x53455143, // SEQC
|
||||
Lights = 0x46669697, // LGTS
|
||||
Vec3f = 0x56433346, // VC3F
|
||||
Vec3s = 0x56433353, // VC3S
|
||||
@@ -63,5 +60,18 @@ enum class ResourceType {
|
||||
ScriptCmd = 0x53434D44, // SCMD
|
||||
Hitbox = 0x48544258, // HTBX
|
||||
ObjectInit = 0x4F42494E, // OBIN
|
||||
|
||||
// NAudio v0
|
||||
Bank = 0x42414E4B, // BANK
|
||||
Sample = 0x41554643, // AIFC
|
||||
Sequence = 0x53455143, // SEQC
|
||||
|
||||
// NAudio v1
|
||||
SoundFont = 0x53464E54, // SFNT
|
||||
Drum = 0x4452554D, // DRUM
|
||||
Instrument = 0x494E5354, // INST
|
||||
AdpcmLoop = 0x4150434C, // APCL
|
||||
AdpcmBook = 0x41504342, // APCB
|
||||
Envelope = 0x45564C50, // EVLP
|
||||
};
|
||||
} // namespace LUS
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
#include "AudioContext.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "Companion.h"
|
||||
|
||||
std::unordered_map<AudioTableType, std::unordered_map<uint32_t, AudioTableEntry>> AudioContext::tables;
|
||||
std::unordered_map<AudioTableType, std::vector<uint8_t>> AudioContext::data;
|
||||
std::unordered_map<AudioTableType, AudioTableData> AudioContext::tableData;
|
||||
|
||||
std::optional<std::shared_ptr<IParsedData>> AudioContextFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
|
||||
auto seq = GetSafeNode<YAML::Node>(node, "audio_seq");
|
||||
auto seqSize = GetSafeNode<uint32_t>(seq, "size");
|
||||
auto seqOffset = GetSafeNode<uint32_t>(seq, "offset");
|
||||
|
||||
auto bank = GetSafeNode<YAML::Node>(node, "audio_bank");
|
||||
auto bankSize = GetSafeNode<uint32_t>(bank, "size");
|
||||
auto bankOffset = GetSafeNode<uint32_t>(bank, "offset");
|
||||
|
||||
auto table = GetSafeNode<YAML::Node>(node, "audio_table");
|
||||
auto tableSize = GetSafeNode<uint32_t>(table, "size");
|
||||
auto tableOffset = GetSafeNode<uint32_t>(table, "offset");
|
||||
|
||||
AudioContext::data[AudioTableType::SEQ_TABLE] = std::vector<uint8_t>(buffer.begin() + seqOffset, buffer.begin() + seqOffset + seqSize);
|
||||
AudioContext::data[AudioTableType::FONT_TABLE] = std::vector<uint8_t>(buffer.begin() + bankOffset, buffer.begin() + bankOffset + bankSize);
|
||||
AudioContext::data[AudioTableType::SAMPLE_TABLE] = std::vector<uint8_t>(buffer.begin() + tableOffset, buffer.begin() + tableOffset + tableSize);
|
||||
|
||||
SPDLOG_INFO("Sequence Table 0x{:X}", seqOffset);
|
||||
SPDLOG_INFO("Sound Font Table 0x{:X}", bankOffset);
|
||||
SPDLOG_INFO("Sample Bank Table 0x{:X}", tableOffset);
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
LUS::BinaryReader AudioContext::MakeReader(AudioTableType type, uint32_t offset) {
|
||||
auto entry = AudioContext::data[type];
|
||||
|
||||
LUS::BinaryReader reader(entry.data(), entry.size());
|
||||
reader.SetEndianness(Torch::Endianness::Big);
|
||||
reader.Seek(offset, LUS::SeekOffsetType::Start);
|
||||
|
||||
return reader;
|
||||
}
|
||||
|
||||
TunedSample AudioContext::LoadTunedSample(LUS::BinaryReader& reader, uint32_t parent, uint32_t sampleBankId) {
|
||||
auto sampleAddr = reader.ReadUInt32();
|
||||
auto tuning = reader.ReadFloat();
|
||||
|
||||
if(sampleAddr == 0){
|
||||
if(tuning != 0.0f){
|
||||
throw std::runtime_error("The provided tuned sample is invalid");
|
||||
}
|
||||
return { 0, 0, 0.0f };
|
||||
}
|
||||
|
||||
YAML::Node node;
|
||||
node["type"] = "NAUDIO:V1:SAMPLE";
|
||||
node["parent"] = parent;
|
||||
node["offset"] = parent + sampleAddr;
|
||||
node["sampleBankId"] = sampleBankId;
|
||||
Companion::Instance->AddAsset(node);
|
||||
|
||||
return { parent + sampleAddr, sampleBankId, tuning };
|
||||
}
|
||||
|
||||
uint64_t AudioContext::GetPathByAddr(uint32_t addr) {
|
||||
if(addr == 0){
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto dec = Companion::Instance->GetNodeByAddr(addr);
|
||||
if (dec.has_value()) {
|
||||
std::string path = std::get<0>(dec.value());
|
||||
uint64_t hash = CRC64(path.c_str());
|
||||
SPDLOG_INFO("Found path of 0x{:X} {}", addr, path);
|
||||
return hash;
|
||||
} else {
|
||||
throw std::runtime_error("Failed to find node by addr");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include "AudioTableFactory.h"
|
||||
#include "factories/naudio/v0/AudioHeaderFactory.h"
|
||||
#include "factories/BaseFactory.h"
|
||||
|
||||
struct TunedSample {
|
||||
uint32_t sample;
|
||||
uint32_t sampleBankId;
|
||||
float tuning;
|
||||
};
|
||||
|
||||
class AudioContext {
|
||||
public:
|
||||
static std::unordered_map<AudioTableType, std::unordered_map<uint32_t, AudioTableEntry>> tables;
|
||||
static std::unordered_map<AudioTableType, std::shared_ptr<AudioTableData>> tableData;
|
||||
static std::unordered_map<AudioTableType, std::vector<uint8_t>> data;
|
||||
|
||||
static LUS::BinaryReader MakeReader(AudioTableType type, uint32_t offset);
|
||||
static TunedSample LoadTunedSample(LUS::BinaryReader& reader, uint32_t parent, uint32_t sampleBankId);
|
||||
static uint64_t GetPathByAddr(uint32_t addr);
|
||||
};
|
||||
|
||||
class AudioContextFactory : public BaseFactory {
|
||||
public:
|
||||
std::optional<std::shared_ptr<IParsedData>> parse(std::vector<uint8_t>& buffer, YAML::Node& data) override;
|
||||
|
||||
inline std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() override {
|
||||
return {
|
||||
REGISTER(Header, AudioDummyExporter)
|
||||
REGISTER(Binary, AudioDummyExporter)
|
||||
REGISTER(Code, AudioDummyExporter)
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,131 @@
|
||||
#include "AudioTableFactory.h"
|
||||
#include "utils/Decompressor.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "AudioContext.h"
|
||||
#include "Companion.h"
|
||||
#include <iomanip>
|
||||
|
||||
#define INT2(c) std::dec << std::setfill(' ') << c
|
||||
#define HEX(c) "0x" << std::hex << std::setw(4) << std::setfill('0') << c
|
||||
#define ADDR(c) "0x" << std::hex << std::setw(5) << std::setfill('0') << c
|
||||
|
||||
static const std::unordered_map <std::string, AudioTableType> gTableTypes = {
|
||||
{ "SOUNDFONT", AudioTableType::FONT_TABLE },
|
||||
{ "SAMPLE", AudioTableType::SAMPLE_TABLE },
|
||||
{ "SEQUENCE", AudioTableType::SEQ_TABLE }
|
||||
};
|
||||
|
||||
ExportResult AudioTableHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
|
||||
const auto symbol = GetSafeNode(node, "symbol", entryName);
|
||||
|
||||
if(Companion::Instance->IsOTRMode()){
|
||||
write << "static const ALIGN_ASSET(2) char " << symbol << "[] = \"__OTR__" << (*replacement) << "\";\n\n";
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
write << "extern AudioTable " << symbol << ";\n";
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
ExportResult AudioTableCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
|
||||
const auto symbol = GetSafeNode(node, "symbol", entryName);
|
||||
const auto offset = GetSafeNode<uint32_t>(node, "offset");
|
||||
auto table = std::static_pointer_cast<AudioTableData>(raw);
|
||||
|
||||
if(table->type == AudioTableType::FONT_TABLE){
|
||||
write << "#define SOUNDFONT_ENTRY(offset, size, medium, cachePolicy, bank1, bank2, numInst, numDrums) { \\\n";
|
||||
write << fourSpaceTab << "offset, size, medium, cachePolicy, (((bank1) &0xFF) << 8) | ((bank2) &0xFF), \\\n";
|
||||
write << fourSpaceTab << fourSpaceTab << "(((numInst) &0xFF) << 8) | ((numDrums) &0xFF) \\\n}\n\n";
|
||||
}
|
||||
|
||||
write << "AudioTable " << symbol << " = {\n";
|
||||
write << fourSpaceTab << "{ " << table->entries.size() << ", " << table->medium << ", " << table->addr << " },\n";
|
||||
write << fourSpaceTab << "{ \n";
|
||||
|
||||
for(size_t i = 0; i < table->entries.size(); i++){
|
||||
auto &entry = table->entries[i];
|
||||
|
||||
if(table->type == AudioTableType::FONT_TABLE) {
|
||||
uint32_t numInstruments = (entry.shortData2 >> 8) & 0xFFu;
|
||||
uint32_t numDrums = entry.shortData2 & 0xFFu;
|
||||
uint32_t sampleBankId1 = (entry.shortData1 >> 8) & 0xFFu;
|
||||
uint32_t sampleBankId2 = entry.shortData1 & 0xFFu;
|
||||
|
||||
write << fourSpaceTab << fourSpaceTab << "SOUNDFONT_ENTRY(" << ADDR(entry.addr) << ", " << HEX(entry.size) << ", " << INT2((uint32_t) entry.medium) << ", " << INT2((uint32_t) entry.cachePolicy) << ", " << INT2(numInstruments) << ", " << INT2(numDrums) << ", " << INT2(sampleBankId1) << ", " << INT2(sampleBankId2) << "),\n" ;
|
||||
} else {
|
||||
write << fourSpaceTab << fourSpaceTab << "{ " << ADDR(entry.addr) << ", " << HEX(entry.size) << ", " << (uint32_t) entry.medium << ", " << (uint32_t) entry.cachePolicy << " },\n";
|
||||
}
|
||||
}
|
||||
|
||||
write << fourSpaceTab << "},\n";
|
||||
write << "};\n";
|
||||
|
||||
if (Companion::Instance->IsDebug()) {
|
||||
write << "// Count: " << table->entries.size() << "\n";
|
||||
}
|
||||
|
||||
return offset + 0x10 + (table->entries.size() * sizeof(AudioTableEntry));
|
||||
}
|
||||
|
||||
ExportResult AudioTableBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
|
||||
auto writer = LUS::BinaryWriter();
|
||||
// auto data = std::static_pointer_cast<AudioTableEntry>(raw)->mBuffer;
|
||||
|
||||
// WriteHeader(writer, Torch::ResourceType::Blob, 0);
|
||||
// writer.Write((uint32_t) data.size());
|
||||
// writer.Write((char*) data.data(), data.size());
|
||||
// writer.Finish(write);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::shared_ptr<IParsedData>> AudioTableFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
|
||||
// Parse table entry
|
||||
auto offset = GetSafeNode<uint32_t>(node, "offset");
|
||||
auto [_, segment] = Decompressor::AutoDecode(node, buffer);
|
||||
LUS::BinaryReader reader(segment.data, segment.size);
|
||||
reader.SetEndianness(Torch::Endianness::Big);
|
||||
|
||||
auto format = GetSafeNode<std::string>(node, "format");
|
||||
std::transform(format.begin(), format.end(), format.begin(), ::toupper);
|
||||
|
||||
if(!gTableTypes.contains(format)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto type = gTableTypes.at(format);
|
||||
auto count = reader.ReadInt16();
|
||||
auto bmedium = reader.ReadInt16();
|
||||
auto baddr = reader.ReadUInt32();
|
||||
reader.Read(0x8); // PAD
|
||||
|
||||
SPDLOG_INFO("count: {}", count);
|
||||
SPDLOG_INFO("medium: {}", bmedium);
|
||||
SPDLOG_INFO("addr: {}", baddr);
|
||||
|
||||
std::vector<AudioTableEntry> entries;
|
||||
for(size_t i = 0; i < count; i++){
|
||||
auto addr = reader.ReadUInt32();
|
||||
auto size = reader.ReadUInt32();
|
||||
auto medium = reader.ReadInt8();
|
||||
auto policy = reader.ReadInt8();
|
||||
auto sd1 = reader.ReadInt16();
|
||||
auto sd2 = reader.ReadInt16();
|
||||
auto sd3 = reader.ReadInt16();
|
||||
auto entry = AudioTableEntry { addr, size, medium, policy, sd1, sd2, sd3 };
|
||||
entries.push_back(entry);
|
||||
|
||||
if(type == AudioTableType::FONT_TABLE){
|
||||
YAML::Node font;
|
||||
font["type"] = "NAUDIO:V1:SOUND_FONT";
|
||||
font["offset"] = addr;
|
||||
Companion::Instance->AddAsset(font);
|
||||
}
|
||||
|
||||
AudioContext::tables[type][addr] = entry;
|
||||
}
|
||||
|
||||
auto table = std::make_shared<AudioTableData>(bmedium, offset, type, entries);
|
||||
AudioContext::tableData[type] = table;
|
||||
return table;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <factories/BaseFactory.h>
|
||||
|
||||
struct AudioTableEntry {
|
||||
uint32_t addr;
|
||||
uint32_t size;
|
||||
int8_t medium;
|
||||
int8_t cachePolicy;
|
||||
int16_t shortData1;
|
||||
int16_t shortData2;
|
||||
int16_t shortData3;
|
||||
};
|
||||
|
||||
enum class AudioTableType {
|
||||
SAMPLE_TABLE,
|
||||
SEQ_TABLE,
|
||||
FONT_TABLE
|
||||
};
|
||||
|
||||
class AudioTableData : public IParsedData {
|
||||
public:
|
||||
int16_t medium;
|
||||
uint32_t addr;
|
||||
AudioTableType type;
|
||||
std::vector<AudioTableEntry> entries;
|
||||
|
||||
AudioTableData(int16_t medium, uint32_t addr, AudioTableType type, std::vector<AudioTableEntry> entries) : medium(medium), addr(addr), type(type), entries(entries) {}
|
||||
};
|
||||
|
||||
class AudioTableHeaderExporter : public BaseExporter {
|
||||
ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
|
||||
};
|
||||
|
||||
class AudioTableBinaryExporter : public BaseExporter {
|
||||
ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
|
||||
};
|
||||
|
||||
class AudioTableCodeExporter : public BaseExporter {
|
||||
ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
|
||||
};
|
||||
|
||||
class AudioTableFactory : public BaseFactory {
|
||||
public:
|
||||
std::optional<std::shared_ptr<IParsedData>> parse(std::vector<uint8_t>& buffer, YAML::Node& data) override;
|
||||
inline std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() override {
|
||||
return {
|
||||
REGISTER(Header, AudioTableHeaderExporter)
|
||||
REGISTER(Binary, AudioTableBinaryExporter)
|
||||
REGISTER(Code, AudioTableCodeExporter)
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,58 @@
|
||||
#include "BookFactory.h"
|
||||
#include "utils/Decompressor.h"
|
||||
#include "Companion.h"
|
||||
|
||||
ExportResult ADPCMBookHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) {
|
||||
const auto symbol = GetSafeNode(node, "symbol", entryName);
|
||||
|
||||
if(Companion::Instance->IsOTRMode()){
|
||||
write << "static const ALIGN_ASSET(2) char " << symbol << "[] = \"__OTR__" << (*replacement) << "\";\n\n";
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
write << "extern AdpcmBook " << symbol << ";\n";
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
ExportResult ADPCMBookCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
ExportResult ADPCMBookBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
|
||||
auto writer = LUS::BinaryWriter();
|
||||
auto data = std::static_pointer_cast<ADPCMBookData>(raw);
|
||||
|
||||
WriteHeader(writer, Torch::ResourceType::AdpcmBook, 0);
|
||||
writer.Write(data->order);
|
||||
writer.Write(data->numPredictors);
|
||||
writer.Write((uint32_t) data->book.size());
|
||||
|
||||
for(auto& page : data->book){
|
||||
writer.Write(page);
|
||||
}
|
||||
|
||||
writer.Finish(write);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::shared_ptr<IParsedData>> ADPCMBookFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
|
||||
auto offset = GetSafeNode<uint32_t>(node, "offset");
|
||||
auto reader = AudioContext::MakeReader(AudioTableType::FONT_TABLE, offset);
|
||||
|
||||
auto book = std::make_shared<ADPCMBookData>();
|
||||
|
||||
book->order = reader.ReadInt32();
|
||||
book->numPredictors = reader.ReadInt32();
|
||||
size_t length = 8 * book->order * book->numPredictors;
|
||||
|
||||
if(length > 0x40){
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < length; i++){
|
||||
book->book.push_back(reader.ReadInt16());
|
||||
}
|
||||
|
||||
return book;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user