-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Recreated audio export system to something more generic
- Loading branch information
Showing
33 changed files
with
1,144 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
}; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |
Oops, something went wrong.