mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-11-29 21:02:18 -05:00
Updated zapd_audio_support on zelda64
This commit is contained in:
commit
8b63cf93d8
@ -6,7 +6,7 @@
|
|||||||
#include <Utils/File.h>
|
#include <Utils/File.h>
|
||||||
#include "DisplayListExporter.h"
|
#include "DisplayListExporter.h"
|
||||||
|
|
||||||
void OTRExporter_Audio::WriteSampleEntryReference(SampleEntry* entry, std::map<uint32_t, SampleEntry*> samples, BinaryWriter* writer)
|
void OTRExporter_Audio::WriteSampleEntryReference(ZAudio* audio, SampleEntry* entry, std::map<uint32_t, SampleEntry*> samples, BinaryWriter* writer)
|
||||||
{
|
{
|
||||||
writer->Write((uint8_t)(entry != nullptr ? 1 : 0));
|
writer->Write((uint8_t)(entry != nullptr ? 1 : 0));
|
||||||
|
|
||||||
@ -21,7 +21,17 @@ void OTRExporter_Audio::WriteSampleEntryReference(SampleEntry* entry, std::map<u
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writer->Write(addr);
|
if (entry != nullptr)
|
||||||
|
{
|
||||||
|
if (audio->sampleOffsets[entry->bankId].find(entry->sampleDataOffset) != audio->sampleOffsets[entry->bankId].end())
|
||||||
|
{
|
||||||
|
writer->Write(StringHelper::Sprintf("audio/samples/%s", audio->sampleOffsets[entry->bankId][entry->sampleDataOffset].c_str()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
writer->Write(entry->fileName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
writer->Write("");
|
||||||
}
|
}
|
||||||
|
|
||||||
void OTRExporter_Audio::WriteSampleEntry(SampleEntry* entry, BinaryWriter* writer)
|
void OTRExporter_Audio::WriteSampleEntry(SampleEntry* entry, BinaryWriter* writer)
|
||||||
@ -52,13 +62,13 @@ void OTRExporter_Audio::WriteSampleEntry(SampleEntry* entry, BinaryWriter* write
|
|||||||
writer->Write((entry->book.books[i]));
|
writer->Write((entry->book.books[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void OTRExporter_Audio::WriteSoundFontEntry(SoundFontEntry* entry, std::map<uint32_t, SampleEntry*> samples, BinaryWriter* writer)
|
void OTRExporter_Audio::WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, std::map<uint32_t, SampleEntry*> samples, BinaryWriter* writer)
|
||||||
{
|
{
|
||||||
writer->Write((uint8_t)(entry != nullptr ? 1 : 0));
|
writer->Write((uint8_t)(entry != nullptr ? 1 : 0));
|
||||||
|
|
||||||
if (entry != nullptr)
|
if (entry != nullptr)
|
||||||
{
|
{
|
||||||
WriteSampleEntryReference(entry->sampleEntry, samples, writer);
|
WriteSampleEntryReference(audio, entry->sampleEntry, samples, writer);
|
||||||
writer->Write(entry->tuning);
|
writer->Write(entry->tuning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,21 +96,21 @@ void OTRExporter_Audio::Save(ZResource* res, const fs::path& outPath, BinaryWrit
|
|||||||
MemoryStream* sampleStream = new MemoryStream();
|
MemoryStream* sampleStream = new MemoryStream();
|
||||||
BinaryWriter sampleWriter = BinaryWriter(sampleStream);
|
BinaryWriter sampleWriter = BinaryWriter(sampleStream);
|
||||||
|
|
||||||
|
writer->Write((uint32_t)pair.first);
|
||||||
WriteSampleEntry(pair.second, &sampleWriter);
|
WriteSampleEntry(pair.second, &sampleWriter);
|
||||||
|
|
||||||
std::string fName = OTRExporter_DisplayList::GetPathToRes(res, StringHelper::Sprintf("samples/sample_%08X", pair.first));
|
std::string basePath = "";
|
||||||
|
|
||||||
|
if (audio->sampleOffsets[pair.second->bankId].find(pair.second->sampleDataOffset) != audio->sampleOffsets[pair.second->bankId].end())
|
||||||
|
basePath = StringHelper::Sprintf("samples/%s", audio->sampleOffsets[pair.second->bankId][pair.second->sampleDataOffset].c_str());
|
||||||
|
else
|
||||||
|
basePath = StringHelper::Sprintf("samples/sample_%08X", pair.first);
|
||||||
|
|
||||||
|
std::string fName = OTRExporter_DisplayList::GetPathToRes(res, basePath);
|
||||||
AddFile(fName, sampleStream->ToVector());
|
AddFile(fName, sampleStream->ToVector());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the samplebank table
|
|
||||||
//writer->Write((uint32_t)audio->sampleBankTable.size());
|
|
||||||
//for (size_t i = 0; i < audio->sampleBankTable.size(); i++)
|
|
||||||
//{
|
|
||||||
//}
|
|
||||||
|
|
||||||
// Write the soundfont table
|
// Write the soundfont table
|
||||||
//writer->Write((uint32_t)audio->soundFontTable.size());
|
|
||||||
|
|
||||||
for (size_t i = 0; i < audio->soundFontTable.size(); i++)
|
for (size_t i = 0; i < audio->soundFontTable.size(); i++)
|
||||||
{
|
{
|
||||||
MemoryStream* fntStream = new MemoryStream();
|
MemoryStream* fntStream = new MemoryStream();
|
||||||
@ -108,6 +118,7 @@ void OTRExporter_Audio::Save(ZResource* res, const fs::path& outPath, BinaryWrit
|
|||||||
|
|
||||||
WriteHeader(nullptr, "", &fntWriter, Ship::ResourceType::AudioSoundFont);
|
WriteHeader(nullptr, "", &fntWriter, Ship::ResourceType::AudioSoundFont);
|
||||||
|
|
||||||
|
fntWriter.Write((uint32_t)i);
|
||||||
fntWriter.Write(audio->soundFontTable[i].medium);
|
fntWriter.Write(audio->soundFontTable[i].medium);
|
||||||
fntWriter.Write(audio->soundFontTable[i].cachePolicy);
|
fntWriter.Write(audio->soundFontTable[i].cachePolicy);
|
||||||
fntWriter.Write(audio->soundFontTable[i].data1);
|
fntWriter.Write(audio->soundFontTable[i].data1);
|
||||||
@ -126,7 +137,7 @@ void OTRExporter_Audio::Save(ZResource* res, const fs::path& outPath, BinaryWrit
|
|||||||
|
|
||||||
WriteEnvData(audio->soundFontTable[i].drums[k].env, &fntWriter);
|
WriteEnvData(audio->soundFontTable[i].drums[k].env, &fntWriter);
|
||||||
|
|
||||||
WriteSampleEntryReference(audio->soundFontTable[i].drums[k].sample, audio->samples, &fntWriter);
|
WriteSampleEntryReference(audio, audio->soundFontTable[i].drums[k].sample, audio->samples, &fntWriter);
|
||||||
fntWriter.Write(audio->soundFontTable[i].drums[k].tuning);
|
fntWriter.Write(audio->soundFontTable[i].drums[k].tuning);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,14 +152,14 @@ void OTRExporter_Audio::Save(ZResource* res, const fs::path& outPath, BinaryWrit
|
|||||||
|
|
||||||
WriteEnvData(audio->soundFontTable[i].instruments[k].env, &fntWriter);
|
WriteEnvData(audio->soundFontTable[i].instruments[k].env, &fntWriter);
|
||||||
|
|
||||||
WriteSoundFontEntry(audio->soundFontTable[i].instruments[k].lowNotesSound, audio->samples, &fntWriter);
|
WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].lowNotesSound, audio->samples, &fntWriter);
|
||||||
WriteSoundFontEntry(audio->soundFontTable[i].instruments[k].normalNotesSound, audio->samples, &fntWriter);
|
WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].normalNotesSound, audio->samples, &fntWriter);
|
||||||
WriteSoundFontEntry(audio->soundFontTable[i].instruments[k].highNotesSound, 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++)
|
for (size_t k = 0; k < audio->soundFontTable[i].soundEffects.size(); k++)
|
||||||
{
|
{
|
||||||
WriteSoundFontEntry(audio->soundFontTable[i].soundEffects[k], audio->samples, &fntWriter);
|
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/font_%02X", i));
|
||||||
@ -163,12 +174,18 @@ void OTRExporter_Audio::Save(ZResource* res, const fs::path& outPath, BinaryWrit
|
|||||||
MemoryStream* seqStream = new MemoryStream();
|
MemoryStream* seqStream = new MemoryStream();
|
||||||
BinaryWriter seqWriter = BinaryWriter(seqStream);
|
BinaryWriter seqWriter = BinaryWriter(seqStream);
|
||||||
|
|
||||||
|
seqWriter.Write((uint8_t)0); // Version 0 of format...
|
||||||
|
seqWriter.Write((uint8_t)i);
|
||||||
seqWriter.Write((uint8_t)audio->sequenceTable[i].medium);
|
seqWriter.Write((uint8_t)audio->sequenceTable[i].medium);
|
||||||
seqWriter.Write((uint8_t)audio->sequenceTable[i].cachePolicy);
|
seqWriter.Write((uint8_t)audio->sequenceTable[i].cachePolicy);
|
||||||
|
seqWriter.Write((uint8_t)audio->fontIndices[i].size());
|
||||||
|
|
||||||
|
for (int k = 0; k < audio->fontIndices[i].size(); k++)
|
||||||
|
seqWriter.Write((uint8_t)audio->fontIndices[i][k]);
|
||||||
|
|
||||||
seqWriter.Write(seq.data(), seq.size());
|
seqWriter.Write(seq.data(), seq.size());
|
||||||
|
|
||||||
std::string fName = OTRExporter_DisplayList::GetPathToRes(res, StringHelper::Sprintf("sequences/seq_%02X", i));
|
std::string fName = OTRExporter_DisplayList::GetPathToRes(res, StringHelper::Sprintf("sequences/%s", audio->seqNames[i].c_str()));
|
||||||
AddFile(fName, seqStream->ToVector());
|
AddFile(fName, seqStream->ToVector());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,8 @@ class OTRExporter_Audio : public OTRExporter
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void WriteSampleEntry(SampleEntry* entry, BinaryWriter* writer);
|
void WriteSampleEntry(SampleEntry* entry, BinaryWriter* writer);
|
||||||
void WriteSampleEntryReference(SampleEntry* entry, std::map<uint32_t, SampleEntry*> samples, BinaryWriter* writer);
|
void WriteSampleEntryReference(ZAudio* audio, SampleEntry* entry, std::map<uint32_t, SampleEntry*> samples, BinaryWriter* writer);
|
||||||
void WriteSoundFontEntry(SoundFontEntry* entry, std::map<uint32_t, SampleEntry*> samples, BinaryWriter* writer);
|
void WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, std::map<uint32_t, SampleEntry*> samples, BinaryWriter* writer);
|
||||||
void WriteEnvData(std::vector<AdsrEnvelope*> envelopes, BinaryWriter* writer);
|
void WriteEnvData(std::vector<AdsrEnvelope*> envelopes, BinaryWriter* writer);
|
||||||
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
|
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
|
||||||
};
|
};
|
@ -13,6 +13,54 @@ ZAudio::ZAudio(ZFile* nParent) : ZResource(nParent)
|
|||||||
{
|
{
|
||||||
//RegisterRequiredAttribute("CodeOffset");
|
//RegisterRequiredAttribute("CodeOffset");
|
||||||
//RegisterOptionalAttribute("LangOffset", "0");
|
//RegisterOptionalAttribute("LangOffset", "0");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZAudio::ParseXML(tinyxml2::XMLElement* reader)
|
||||||
|
{
|
||||||
|
ZResource::ParseXML(reader);
|
||||||
|
|
||||||
|
auto t = reader->Name();
|
||||||
|
|
||||||
|
auto child = reader->FirstChildElement();
|
||||||
|
|
||||||
|
while (child != nullptr)
|
||||||
|
{
|
||||||
|
int bp = 0;
|
||||||
|
if (std::string(child->Value()) == "Sequences")
|
||||||
|
{
|
||||||
|
auto seqChild = child->FirstChildElement();
|
||||||
|
|
||||||
|
while (seqChild != nullptr)
|
||||||
|
{
|
||||||
|
if (std::string(seqChild->Value()) == "Sequence")
|
||||||
|
{
|
||||||
|
seqNames.push_back(seqChild->Attribute("Name"));
|
||||||
|
}
|
||||||
|
|
||||||
|
seqChild = seqChild->NextSiblingElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::string(child->Value()) == "Samples")
|
||||||
|
{
|
||||||
|
int bankId = child->IntAttribute("Bank", 0);
|
||||||
|
auto sampChild = child->FirstChildElement();
|
||||||
|
|
||||||
|
while (sampChild != nullptr)
|
||||||
|
{
|
||||||
|
if (std::string(sampChild->Value()) == "Sample")
|
||||||
|
{
|
||||||
|
auto atStr = sampChild->FirstChildElement()->Attribute("At");
|
||||||
|
sampleOffsets[bankId][StringHelper::StrToL(atStr, 16)] = sampChild->Attribute("Name");
|
||||||
|
}
|
||||||
|
|
||||||
|
sampChild = sampChild->NextSiblingElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
child = child->NextSiblingElement();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZAudio::DecodeADPCMSample(SampleEntry* sample)
|
void ZAudio::DecodeADPCMSample(SampleEntry* sample)
|
||||||
@ -26,9 +74,6 @@ std::vector<AdsrEnvelope*> ZAudio::ParseEnvelopeData(std::vector<uint8_t> audioB
|
|||||||
{
|
{
|
||||||
std::vector<AdsrEnvelope*> result;
|
std::vector<AdsrEnvelope*> result;
|
||||||
|
|
||||||
//bool process = true;
|
|
||||||
|
|
||||||
//for (int i = 0; i < 4; i++)
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
AdsrEnvelope* env = new AdsrEnvelope();
|
AdsrEnvelope* env = new AdsrEnvelope();
|
||||||
@ -49,13 +94,13 @@ std::vector<AdsrEnvelope*> ZAudio::ParseEnvelopeData(std::vector<uint8_t> audioB
|
|||||||
|
|
||||||
SoundFontEntry* ZAudio::ParseSoundFontEntry(std::vector<uint8_t> audioBank,
|
SoundFontEntry* ZAudio::ParseSoundFontEntry(std::vector<uint8_t> audioBank,
|
||||||
std::vector<uint8_t> audioTable,
|
std::vector<uint8_t> audioTable,
|
||||||
AudioTableEntry audioSampleBankEntry,
|
AudioTableEntry audioSampleBankEntry, int bankIndex,
|
||||||
int soundFontOffset,
|
int soundFontOffset,
|
||||||
int baseOffset)
|
int baseOffset)
|
||||||
{
|
{
|
||||||
SoundFontEntry* soundFont = new SoundFontEntry();
|
SoundFontEntry* soundFont = new SoundFontEntry();
|
||||||
soundFont->sampleEntry = ParseSampleEntry(
|
soundFont->sampleEntry = ParseSampleEntry(
|
||||||
audioBank, audioTable, audioSampleBankEntry,
|
audioBank, audioTable, audioSampleBankEntry, bankIndex,
|
||||||
BitConverter::ToInt32BE(audioBank, soundFontOffset + 0) + baseOffset, baseOffset);
|
BitConverter::ToInt32BE(audioBank, soundFontOffset + 0) + baseOffset, baseOffset);
|
||||||
soundFont->tuning = BitConverter::ToFloatBE(audioBank, soundFontOffset + 4);
|
soundFont->tuning = BitConverter::ToFloatBE(audioBank, soundFontOffset + 4);
|
||||||
|
|
||||||
@ -64,7 +109,7 @@ SoundFontEntry* ZAudio::ParseSoundFontEntry(std::vector<uint8_t> audioBank,
|
|||||||
|
|
||||||
SampleEntry* ZAudio::ParseSampleEntry(std::vector<uint8_t> audioBank,
|
SampleEntry* ZAudio::ParseSampleEntry(std::vector<uint8_t> audioBank,
|
||||||
std::vector<uint8_t> audioTable,
|
std::vector<uint8_t> audioTable,
|
||||||
AudioTableEntry audioSampleBankEntry,
|
AudioTableEntry audioSampleBankEntry, int bankIndex,
|
||||||
int sampleOffset,
|
int sampleOffset,
|
||||||
int baseOffset)
|
int baseOffset)
|
||||||
{
|
{
|
||||||
@ -74,6 +119,8 @@ SampleEntry* ZAudio::ParseSampleEntry(std::vector<uint8_t> audioBank,
|
|||||||
{
|
{
|
||||||
SampleEntry* sample = new SampleEntry();
|
SampleEntry* sample = new SampleEntry();
|
||||||
|
|
||||||
|
sample->bankId = bankIndex;
|
||||||
|
|
||||||
int sampleSize = BitConverter::ToInt32BE(audioBank, sampleOffset + 0) & 0x00FFFFFF;
|
int sampleSize = BitConverter::ToInt32BE(audioBank, sampleOffset + 0) & 0x00FFFFFF;
|
||||||
int loopOffset = BitConverter::ToInt32BE(audioBank, sampleOffset + 8) + baseOffset;
|
int loopOffset = BitConverter::ToInt32BE(audioBank, sampleOffset + 8) + baseOffset;
|
||||||
int bookOffset = BitConverter::ToInt32BE(audioBank, sampleOffset + 12) + baseOffset;
|
int bookOffset = BitConverter::ToInt32BE(audioBank, sampleOffset + 12) + baseOffset;
|
||||||
@ -111,6 +158,9 @@ SampleEntry* ZAudio::ParseSampleEntry(std::vector<uint8_t> audioBank,
|
|||||||
BitConverter::ToInt16BE(audioBank, bookOffset + 8 + (i * 2)));
|
BitConverter::ToInt16BE(audioBank, bookOffset + 8 + (i * 2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sample->sampleDataOffset = sampleDataOffset;
|
||||||
|
sample->fileName = StringHelper::Sprintf("audio/samples/sample_%08X", sampleOffset);
|
||||||
|
|
||||||
samples[sampleOffset] = sample;
|
samples[sampleOffset] = sample;
|
||||||
|
|
||||||
return sample;
|
return sample;
|
||||||
@ -173,15 +223,13 @@ void ZAudio::ParseSoundFont(std::vector<uint8_t> codeData, std::vector<uint8_t>
|
|||||||
{
|
{
|
||||||
samplePtr += ptr;
|
samplePtr += ptr;
|
||||||
|
|
||||||
drum.sample = ParseSampleEntry(codeData, audioTable, audioSampleBank[sampleBankId1],
|
drum.sample = ParseSampleEntry(codeData, audioTable, audioSampleBank[sampleBankId1], sampleBankId1,
|
||||||
BitConverter::ToInt32BE(codeData, samplePtr + 4) + ptr, ptr);
|
BitConverter::ToInt32BE(codeData, samplePtr + 4) + ptr, ptr);
|
||||||
|
|
||||||
drum.releaseRate = codeData[samplePtr + 0];
|
drum.releaseRate = codeData[samplePtr + 0];
|
||||||
drum.pan = codeData[samplePtr + 1];
|
drum.pan = codeData[samplePtr + 1];
|
||||||
drum.loaded = codeData[samplePtr + 2];
|
drum.loaded = codeData[samplePtr + 2];
|
||||||
drum.tuning = BitConverter::ToFloatBE(codeData, samplePtr + 8);
|
drum.tuning = BitConverter::ToFloatBE(codeData, samplePtr + 8);
|
||||||
|
|
||||||
//int sampleDefOffset = BitConverter::ToInt32BE(codeData, samplePtr + 4);
|
|
||||||
drum.env = ParseEnvelopeData(codeData, audioTable, BitConverter::ToInt32BE(codeData, samplePtr + 12) + ptr, ptr);
|
drum.env = ParseEnvelopeData(codeData, audioTable, BitConverter::ToInt32BE(codeData, samplePtr + 12) + ptr, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +242,7 @@ void ZAudio::ParseSoundFont(std::vector<uint8_t> codeData, std::vector<uint8_t>
|
|||||||
for (int i = 0; i < numSfx; i++)
|
for (int i = 0; i < numSfx; i++)
|
||||||
{
|
{
|
||||||
SoundFontEntry* sfx;
|
SoundFontEntry* sfx;
|
||||||
sfx = ParseSoundFontEntry(codeData, audioTable, audioSampleBank[sampleBankId1],
|
sfx = ParseSoundFontEntry(codeData, audioTable, audioSampleBank[sampleBankId1], sampleBankId1,
|
||||||
currentOffset, ptr);
|
currentOffset, ptr);
|
||||||
entry.soundEffects.push_back(sfx);
|
entry.soundEffects.push_back(sfx);
|
||||||
|
|
||||||
@ -221,16 +269,16 @@ void ZAudio::ParseSoundFont(std::vector<uint8_t> codeData, std::vector<uint8_t>
|
|||||||
|
|
||||||
if (BitConverter::ToInt32BE(codeData, currentOffset + 8) != 0)
|
if (BitConverter::ToInt32BE(codeData, currentOffset + 8) != 0)
|
||||||
instrument.lowNotesSound = ParseSoundFontEntry(
|
instrument.lowNotesSound = ParseSoundFontEntry(
|
||||||
codeData, audioTable, audioSampleBank[sampleBankId1], currentOffset + 8, ptr);
|
codeData, audioTable, audioSampleBank[sampleBankId1], sampleBankId1, currentOffset + 8, ptr);
|
||||||
|
|
||||||
if (BitConverter::ToInt32BE(codeData, currentOffset + 16) != 0)
|
if (BitConverter::ToInt32BE(codeData, currentOffset + 16) != 0)
|
||||||
instrument.normalNotesSound = ParseSoundFontEntry(
|
instrument.normalNotesSound = ParseSoundFontEntry(
|
||||||
codeData, audioTable, audioSampleBank[sampleBankId1], currentOffset + 16, ptr);
|
codeData, audioTable, audioSampleBank[sampleBankId1], sampleBankId1, currentOffset + 16, ptr);
|
||||||
|
|
||||||
if (BitConverter::ToInt32BE(codeData, currentOffset + 24) != 0 &&
|
if (BitConverter::ToInt32BE(codeData, currentOffset + 24) != 0 &&
|
||||||
instrument.normalRangeHi != 0x7F)
|
instrument.normalRangeHi != 0x7F)
|
||||||
instrument.highNotesSound = ParseSoundFontEntry(
|
instrument.highNotesSound = ParseSoundFontEntry(
|
||||||
codeData, audioTable, audioSampleBank[sampleBankId1], currentOffset + 24, ptr);
|
codeData, audioTable, audioSampleBank[sampleBankId1], sampleBankId1, currentOffset + 24, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.instruments.push_back(instrument);
|
entry.instruments.push_back(instrument);
|
||||||
@ -261,23 +309,57 @@ void ZAudio::ParseRawData()
|
|||||||
else
|
else
|
||||||
audioBankData = Globals::Instance->GetBaseromFile(Globals::Instance->baseRomPath.string() + "Audiobank");
|
audioBankData = Globals::Instance->GetBaseromFile(Globals::Instance->baseRomPath.string() + "Audiobank");
|
||||||
|
|
||||||
|
|
||||||
if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory)
|
if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory)
|
||||||
audioSeqData = Globals::Instance->GetBaseromFile("Audioseq");
|
audioSeqData = Globals::Instance->GetBaseromFile("Audioseq");
|
||||||
else
|
else
|
||||||
audioSeqData = Globals::Instance->GetBaseromFile(Globals::Instance->baseRomPath.string() +
|
audioSeqData = Globals::Instance->GetBaseromFile(Globals::Instance->baseRomPath.string() +
|
||||||
"Audioseq");
|
"Audioseq");
|
||||||
|
|
||||||
|
//codeData = File::ReadAllBytes("baserom/code_ntsc");
|
||||||
|
//audioTableData = File::ReadAllBytes("baserom/Audiotable_ntsc");
|
||||||
|
//audioSeqData = File::ReadAllBytes("baserom/Audioseq_ntsc");
|
||||||
|
//audioBankData = File::ReadAllBytes("baserom/Audiobank_ntsc");
|
||||||
|
|
||||||
// TABLE PARSING
|
// TABLE PARSING
|
||||||
|
|
||||||
|
// GC PAL
|
||||||
//int gSoundFontTableOffset = 0x138270; // OTRTODO: Make this an XML Param
|
//int gSoundFontTableOffset = 0x138270; // OTRTODO: Make this an XML Param
|
||||||
//int gSequenceTableOffset = 0x1386A0; // OTRTODO: Make this an XML Param
|
//int gSequenceTableOffset = 0x1386A0; // OTRTODO: Make this an XML Param
|
||||||
//int gSampleBankTableOffset = 0x138D90; // OTRTODO: Make this an XML Param
|
//int gSampleBankTableOffset = 0x138D90; // OTRTODO: Make this an XML Param
|
||||||
|
//int gSequenceFontTableOffset = 0x1384E0; // OTRTODO: Make this an XML Param
|
||||||
|
|
||||||
|
// NMQ DBG ROM
|
||||||
int gSoundFontTableOffset = 0x138290; // OTRTODO: Make this an XML Param
|
int gSoundFontTableOffset = 0x138290; // OTRTODO: Make this an XML Param
|
||||||
int gSequenceTableOffset = 0x1386C0; // OTRTODO: Make this an XML Param
|
int gSequenceTableOffset = 0x1386C0; // OTRTODO: Make this an XML Param
|
||||||
int gSampleBankTableOffset = 0x138DB0; // OTRTODO: Make this an XML Param
|
int gSampleBankTableOffset = 0x138DB0; // OTRTODO: Make this an XML Param
|
||||||
|
int gSequenceFontTableOffset = 0x138500; // OTRTODO: Make this an XML Param
|
||||||
|
|
||||||
|
// NTSC 1.0
|
||||||
|
//int gSoundFontTableOffset = 0x1026A0; // OTRTODO: Make this an XML Param
|
||||||
|
//int gSequenceTableOffset = 0x102AD0; // OTRTODO: Make this an XML Param
|
||||||
|
//int gSampleBankTableOffset = 0x1031C0; // OTRTODO: Make this an XML Param
|
||||||
|
//int gSequenceFontTableOffset = 0x102910; // OTRTODO: Make this an XML Param
|
||||||
|
|
||||||
soundFontTable = ParseAudioTable(codeData, gSoundFontTableOffset);
|
soundFontTable = ParseAudioTable(codeData, gSoundFontTableOffset);
|
||||||
sequenceTable = ParseAudioTable(codeData, gSequenceTableOffset);
|
sequenceTable = ParseAudioTable(codeData, gSequenceTableOffset);
|
||||||
sampleBankTable = ParseAudioTable(codeData, gSampleBankTableOffset);
|
sampleBankTable = ParseAudioTable(codeData, gSampleBankTableOffset);
|
||||||
// int gSequenceFontTableOffset = 0x1384E0; // OTRTODO: Make this an XML Param
|
|
||||||
|
// SEQEUNCE FONT TABLE PARSING
|
||||||
|
for (int i = 0; i < sequenceTable.size(); i++)
|
||||||
|
{
|
||||||
|
uint16_t idx = BitConverter::ToUInt16BE(codeData, gSequenceFontTableOffset + (i * 2));
|
||||||
|
uint8_t numFonts = codeData[gSequenceFontTableOffset + (idx++)];
|
||||||
|
std::vector<uint32_t> fontIds;
|
||||||
|
|
||||||
|
for (int j = 0; j < numFonts; j++)
|
||||||
|
{
|
||||||
|
uint8_t fontId = codeData[gSequenceFontTableOffset + (idx++)];
|
||||||
|
fontIds.push_back(fontId);
|
||||||
|
}
|
||||||
|
|
||||||
|
fontIndices.push_back(fontIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// SAMPLE/FONT PARSING
|
// SAMPLE/FONT PARSING
|
||||||
@ -286,13 +368,6 @@ void ZAudio::ParseRawData()
|
|||||||
ParseSoundFont(audioBankData, audioTableData, sampleBankTable, soundFontTable[i]);
|
ParseSoundFont(audioBankData, audioTableData, sampleBankTable, soundFontTable[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// SOUNDBANK PARSING
|
|
||||||
/*for (int i = 0; i < sampleBankTable.size(); i++)
|
|
||||||
{
|
|
||||||
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// SEQUENCE PARSING
|
// SEQUENCE PARSING
|
||||||
for (int i = 0; i < sequenceTable.size(); i++)
|
for (int i = 0; i < sequenceTable.size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -21,12 +21,14 @@ struct AdpcmLoop
|
|||||||
/* 0x00 */ uint32_t start;
|
/* 0x00 */ uint32_t start;
|
||||||
/* 0x04 */ uint32_t end;
|
/* 0x04 */ uint32_t end;
|
||||||
/* 0x08 */ uint32_t count;
|
/* 0x08 */ uint32_t count;
|
||||||
///* 0x10 */ int16_t state[16]; // only exists if count != 0. 8-byte aligned
|
|
||||||
/* 0x10 */ std::vector<int16_t> states;
|
/* 0x10 */ std::vector<int16_t> states;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SampleEntry
|
struct SampleEntry
|
||||||
{
|
{
|
||||||
|
std::string fileName;
|
||||||
|
uint8_t bankId;
|
||||||
|
uint32_t sampleDataOffset;
|
||||||
uint8_t codec;
|
uint8_t codec;
|
||||||
uint8_t medium;
|
uint8_t medium;
|
||||||
uint8_t unk_bit26;
|
uint8_t unk_bit26;
|
||||||
@ -51,7 +53,6 @@ struct DrumEntry
|
|||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
float tuning;
|
float tuning;
|
||||||
std::vector<AdsrEnvelope*> env;
|
std::vector<AdsrEnvelope*> env;
|
||||||
//AdsrEnvelope* env = nullptr;
|
|
||||||
SampleEntry* sample = nullptr;
|
SampleEntry* sample = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -63,7 +64,6 @@ struct InstrumentEntry
|
|||||||
uint8_t normalRangeHi;
|
uint8_t normalRangeHi;
|
||||||
uint8_t releaseRate;
|
uint8_t releaseRate;
|
||||||
std::vector<AdsrEnvelope*> env;
|
std::vector<AdsrEnvelope*> env;
|
||||||
//AdsrEnvelope* env = nullptr;
|
|
||||||
SoundFontEntry* lowNotesSound = nullptr;
|
SoundFontEntry* lowNotesSound = nullptr;
|
||||||
SoundFontEntry* normalNotesSound = nullptr;
|
SoundFontEntry* normalNotesSound = nullptr;
|
||||||
SoundFontEntry* highNotesSound = nullptr;
|
SoundFontEntry* highNotesSound = nullptr;
|
||||||
@ -92,21 +92,26 @@ public:
|
|||||||
std::vector<AudioTableEntry> sampleBankTable;
|
std::vector<AudioTableEntry> sampleBankTable;
|
||||||
std::vector<std::vector<char>> sequences;
|
std::vector<std::vector<char>> sequences;
|
||||||
std::map<uint32_t, SampleEntry*> samples;
|
std::map<uint32_t, SampleEntry*> samples;
|
||||||
|
std::vector<std::vector<uint32_t>> fontIndices;
|
||||||
|
std::vector<std::string> seqNames;
|
||||||
|
std::map<uint32_t, std::map<uint32_t, std::string>> sampleOffsets;
|
||||||
|
|
||||||
ZAudio(ZFile* nParent);
|
ZAudio(ZFile* nParent);
|
||||||
|
|
||||||
|
void ParseXML(tinyxml2::XMLElement* reader) override;
|
||||||
|
|
||||||
void DecodeADPCMSample(SampleEntry* sample);
|
void DecodeADPCMSample(SampleEntry* sample);
|
||||||
std::vector<AdsrEnvelope*> ParseEnvelopeData(std::vector<uint8_t> audioBank, std::vector<uint8_t> audioTable,
|
std::vector<AdsrEnvelope*> ParseEnvelopeData(std::vector<uint8_t> audioBank, std::vector<uint8_t> audioTable,
|
||||||
int envelopeOffset, int baseOffset);
|
int envelopeOffset, int baseOffset);
|
||||||
|
|
||||||
SoundFontEntry* ParseSoundFontEntry(std::vector<uint8_t> audioBank,
|
SoundFontEntry* ParseSoundFontEntry(std::vector<uint8_t> audioBank,
|
||||||
std::vector<uint8_t> audioTable,
|
std::vector<uint8_t> audioTable,
|
||||||
AudioTableEntry audioSampleBankEntry,
|
AudioTableEntry audioSampleBankEntry, int bankIndex,
|
||||||
int soundFontOffset,
|
int soundFontOffset,
|
||||||
int baseOffset);
|
int baseOffset);
|
||||||
|
|
||||||
SampleEntry* ParseSampleEntry(std::vector<uint8_t> audioBank, std::vector<uint8_t> audioTable,
|
SampleEntry* ParseSampleEntry(std::vector<uint8_t> audioBank, std::vector<uint8_t> audioTable,
|
||||||
AudioTableEntry audioSampleBankEntry,
|
AudioTableEntry audioSampleBankEntry, int bankIndex,
|
||||||
int sampleOffset, int baseOffset);
|
int sampleOffset, int baseOffset);
|
||||||
|
|
||||||
std::vector<AudioTableEntry> ParseAudioTable(std::vector<uint8_t> codeData, int baseOffset);
|
std::vector<AudioTableEntry> ParseAudioTable(std::vector<uint8_t> codeData, int baseOffset);
|
||||||
|
@ -100,12 +100,15 @@ void ZResource::ParseXML(tinyxml2::XMLElement* reader)
|
|||||||
attrs = attrs->Next();
|
attrs = attrs->Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Globals::Instance->otrMode)
|
||||||
|
{
|
||||||
if (!canHaveInner && !reader->NoChildren())
|
if (!canHaveInner && !reader->NoChildren())
|
||||||
{
|
{
|
||||||
std::string errorHeader = StringHelper::Sprintf(
|
std::string errorHeader = StringHelper::Sprintf(
|
||||||
"resource '%s' with inner element/child detected", reader->Name());
|
"resource '%s' with inner element/child detected", reader->Name());
|
||||||
HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, "");
|
HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, "");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto& attr : registeredAttributes)
|
for (const auto& attr : registeredAttributes)
|
||||||
{
|
{
|
||||||
@ -121,7 +124,6 @@ void ZResource::ParseXML(tinyxml2::XMLElement* reader)
|
|||||||
|
|
||||||
name = registeredAttributes.at("Name").value;
|
name = registeredAttributes.at("Name").value;
|
||||||
|
|
||||||
|
|
||||||
// Disable this check for OTR file generation for now since it takes up a considerable amount of CPU time
|
// Disable this check for OTR file generation for now since it takes up a considerable amount of CPU time
|
||||||
if (!Globals::Instance->otrMode)
|
if (!Globals::Instance->otrMode)
|
||||||
{
|
{
|
||||||
|
@ -42,6 +42,7 @@ namespace Ship
|
|||||||
|
|
||||||
ResourceFile::ParseFileBinary(reader, res);
|
ResourceFile::ParseFileBinary(reader, res);
|
||||||
|
|
||||||
|
soundFont->id = reader->ReadInt32();
|
||||||
soundFont->medium = reader->ReadByte();
|
soundFont->medium = reader->ReadByte();
|
||||||
soundFont->cachePolicy = reader->ReadByte();
|
soundFont->cachePolicy = reader->ReadByte();
|
||||||
soundFont->data1 = reader->ReadInt16();
|
soundFont->data1 = reader->ReadInt16();
|
||||||
@ -62,7 +63,7 @@ namespace Ship
|
|||||||
drum.env = ReadEnvelopeData(reader);
|
drum.env = ReadEnvelopeData(reader);
|
||||||
|
|
||||||
bool hasSample = reader->ReadByte();
|
bool hasSample = reader->ReadByte();
|
||||||
drum.offset = reader->ReadInt32();
|
drum.sampleFileName = reader->ReadString();
|
||||||
drum.tuning = reader->ReadSingle();
|
drum.tuning = reader->ReadSingle();
|
||||||
|
|
||||||
soundFont->drums.push_back(drum);
|
soundFont->drums.push_back(drum);
|
||||||
@ -87,7 +88,7 @@ namespace Ship
|
|||||||
{
|
{
|
||||||
entry.lowNotesSound = new SoundFontEntry();
|
entry.lowNotesSound = new SoundFontEntry();
|
||||||
bool hasSampleRef = reader->ReadByte();
|
bool hasSampleRef = reader->ReadByte();
|
||||||
entry.lowNotesSound->sampleOffset = reader->ReadInt32();
|
entry.lowNotesSound->sampleFileName = reader->ReadString();
|
||||||
entry.lowNotesSound->tuning = reader->ReadSingle();
|
entry.lowNotesSound->tuning = reader->ReadSingle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,7 +100,7 @@ namespace Ship
|
|||||||
{
|
{
|
||||||
entry.normalNotesSound = new SoundFontEntry();
|
entry.normalNotesSound = new SoundFontEntry();
|
||||||
bool hasSampleRef = reader->ReadByte();
|
bool hasSampleRef = reader->ReadByte();
|
||||||
entry.normalNotesSound->sampleOffset = reader->ReadInt32();
|
entry.normalNotesSound->sampleFileName = reader->ReadString();
|
||||||
entry.normalNotesSound->tuning = reader->ReadSingle();
|
entry.normalNotesSound->tuning = reader->ReadSingle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,7 +112,7 @@ namespace Ship
|
|||||||
{
|
{
|
||||||
entry.highNotesSound = new SoundFontEntry();
|
entry.highNotesSound = new SoundFontEntry();
|
||||||
bool hasSampleRef = reader->ReadByte();
|
bool hasSampleRef = reader->ReadByte();
|
||||||
entry.highNotesSound->sampleOffset = reader->ReadInt32();
|
entry.highNotesSound->sampleFileName = reader->ReadString();
|
||||||
entry.highNotesSound->tuning = reader->ReadSingle();
|
entry.highNotesSound->tuning = reader->ReadSingle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,7 +129,7 @@ namespace Ship
|
|||||||
if (hasSFEntry)
|
if (hasSFEntry)
|
||||||
{
|
{
|
||||||
bool hasSampleRef = reader->ReadByte();
|
bool hasSampleRef = reader->ReadByte();
|
||||||
entry->sampleOffset = reader->ReadInt32();
|
entry->sampleFileName = reader->ReadString();
|
||||||
entry->tuning = reader->ReadSingle();
|
entry->tuning = reader->ReadSingle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,10 +160,5 @@ namespace Ship
|
|||||||
Audio* audio = (Audio*)res;
|
Audio* audio = (Audio*)res;
|
||||||
|
|
||||||
ResourceFile::ParseFileBinary(reader, res);
|
ResourceFile::ParseFileBinary(reader, res);
|
||||||
|
|
||||||
//int sampleCnt = reader->ReadInt32();
|
|
||||||
|
|
||||||
//for (size_t i = 0; i < sampleCnt; i++)
|
|
||||||
//audio->samples.push_back(ReadSampleEntry(reader));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "Resource.h"
|
#include "Resource.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace Ship
|
namespace Ship
|
||||||
{
|
{
|
||||||
@ -24,14 +25,12 @@ namespace Ship
|
|||||||
/* 0x00 */ uint32_t start;
|
/* 0x00 */ uint32_t start;
|
||||||
/* 0x04 */ uint32_t end;
|
/* 0x04 */ uint32_t end;
|
||||||
/* 0x08 */ uint32_t count;
|
/* 0x08 */ uint32_t count;
|
||||||
///* 0x10 */ int16_t state[16]; // only exists if count != 0. 8-byte aligned
|
|
||||||
/* 0x10 */ std::vector<int16_t> states;
|
/* 0x10 */ std::vector<int16_t> states;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SoundFontEntry
|
struct SoundFontEntry
|
||||||
{
|
{
|
||||||
//SampleEntry* sampleEntry = nullptr;
|
std::string sampleFileName;
|
||||||
uint32_t sampleOffset;
|
|
||||||
float tuning;
|
float tuning;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -40,10 +39,9 @@ namespace Ship
|
|||||||
uint8_t releaseRate;
|
uint8_t releaseRate;
|
||||||
uint8_t pan;
|
uint8_t pan;
|
||||||
uint8_t loaded;
|
uint8_t loaded;
|
||||||
uint32_t offset;
|
std::string sampleFileName;
|
||||||
float tuning;
|
float tuning;
|
||||||
std::vector<AdsrEnvelope*> env;
|
std::vector<AdsrEnvelope*> env;
|
||||||
//SampleEntry* sample = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InstrumentEntry
|
struct InstrumentEntry
|
||||||
@ -83,6 +81,7 @@ namespace Ship
|
|||||||
public:
|
public:
|
||||||
uint32_t ptr;
|
uint32_t ptr;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
|
uint32_t id;
|
||||||
uint8_t medium;
|
uint8_t medium;
|
||||||
uint8_t cachePolicy;
|
uint8_t cachePolicy;
|
||||||
uint16_t data1;
|
uint16_t data1;
|
||||||
@ -97,6 +96,7 @@ namespace Ship
|
|||||||
class AudioSample : public Resource
|
class AudioSample : public Resource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
uint32_t originalOffset;
|
||||||
uint8_t codec;
|
uint8_t codec;
|
||||||
uint8_t medium;
|
uint8_t medium;
|
||||||
uint8_t unk_bit26;
|
uint8_t unk_bit26;
|
||||||
@ -115,6 +115,5 @@ namespace Ship
|
|||||||
//std::vector<AudioTableEntry> sampleBankTable;
|
//std::vector<AudioTableEntry> sampleBankTable;
|
||||||
//std::vector<char*> sequences;
|
//std::vector<char*> sequences;
|
||||||
//std::vector<SampleEntry*> samples;
|
//std::vector<SampleEntry*> samples;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -12,10 +12,10 @@ namespace Ship
|
|||||||
{
|
{
|
||||||
enum class ResourceType
|
enum class ResourceType
|
||||||
{
|
{
|
||||||
Archive = 0x4F415243, // OARC
|
Archive = 0x4F415243, // OARC (UNUSED)
|
||||||
Model = 0x4F4D444C, // OMDL
|
Model = 0x4F4D444C, // OMDL (WIP)
|
||||||
Texture = 0x4F544558, // OTEX
|
Texture = 0x4F544558, // OTEX
|
||||||
Material = 0x4F4D4154, // OMAT
|
Material = 0x4F4D4154, // OMAT (WIP)
|
||||||
Animation = 0x4F414E4D, // OANM
|
Animation = 0x4F414E4D, // OANM
|
||||||
PlayerAnimation = 0x4F50414D, // OPAM
|
PlayerAnimation = 0x4F50414D, // OPAM
|
||||||
DisplayList = 0x4F444C54, // ODLT
|
DisplayList = 0x4F444C54, // ODLT
|
||||||
|
@ -339,6 +339,18 @@ namespace Ship {
|
|||||||
return LoadedList;
|
return LoadedList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<std::vector<std::string>> ResourceMgr::ListFiles(std::string SearchMask)
|
||||||
|
{
|
||||||
|
auto result = std::make_shared<std::vector<std::string>>();
|
||||||
|
auto fileList = OTR->ListFiles(SearchMask);
|
||||||
|
|
||||||
|
for (DWORD i = 0; i < fileList.size(); i++) {
|
||||||
|
result->push_back(fileList[i].cFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void ResourceMgr::InvalidateResourceCache() {
|
void ResourceMgr::InvalidateResourceCache() {
|
||||||
ResourceCache.clear();
|
ResourceCache.clear();
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ namespace Ship
|
|||||||
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> CacheDirectory(const std::string& SearchMask);
|
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> CacheDirectory(const std::string& SearchMask);
|
||||||
std::shared_ptr<std::vector<std::shared_ptr<ResourcePromise>>> CacheDirectoryAsync(const std::string& SearchMask);
|
std::shared_ptr<std::vector<std::shared_ptr<ResourcePromise>>> CacheDirectoryAsync(const std::string& SearchMask);
|
||||||
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> DirtyDirectory(std::string SearchMask);
|
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> DirtyDirectory(std::string SearchMask);
|
||||||
|
std::shared_ptr<std::vector<std::string>> ListFiles(std::string SearchMask);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void Start();
|
void Start();
|
||||||
|
@ -64,8 +64,6 @@ namespace SohImGui {
|
|||||||
bool p_open = false;
|
bool p_open = false;
|
||||||
bool needs_save = false;
|
bool needs_save = false;
|
||||||
std::vector<const char*> CustomTexts;
|
std::vector<const char*> CustomTexts;
|
||||||
int SelectedLanguage = CVar_GetS32("gLanguages", 0); //Default Language to 0=English 1=German 2=French
|
|
||||||
int SelectedHUD = CVar_GetS32("gHudColors", 1); //Default colors to GameCube.
|
|
||||||
ImVec4 hearts_colors;
|
ImVec4 hearts_colors;
|
||||||
ImVec4 hearts_dd_colors;
|
ImVec4 hearts_dd_colors;
|
||||||
ImVec4 a_btn_colors;
|
ImVec4 a_btn_colors;
|
||||||
|
@ -30,8 +30,8 @@ namespace Ship {
|
|||||||
WAVEFORMATEX desired;
|
WAVEFORMATEX desired;
|
||||||
desired.wFormatTag = WAVE_FORMAT_PCM;
|
desired.wFormatTag = WAVE_FORMAT_PCM;
|
||||||
desired.nChannels = 2;
|
desired.nChannels = 2;
|
||||||
desired.nSamplesPerSec = 32000;
|
desired.nSamplesPerSec = 44000; // OTRTODO
|
||||||
desired.nAvgBytesPerSec = 32000 * 2 * 2;
|
desired.nAvgBytesPerSec = 44000 * 2 * 2; // OTRTODO
|
||||||
desired.nBlockAlign = 4;
|
desired.nBlockAlign = 4;
|
||||||
desired.wBitsPerSample = 16;
|
desired.wBitsPerSample = 16;
|
||||||
desired.cbSize = 0;
|
desired.cbSize = 0;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
|||||||
<Root>
|
<Root>
|
||||||
<File Name="code" OutName="audio" RangeStart="0x0" RangeEnd="0x12CBB0">
|
<File Name="code" OutName="audio" RangeStart="0x0" RangeEnd="0x12CBB0">
|
||||||
<Audio Name="audio" Offset="0x00"/>
|
<Audio Name="audio" Offset="0x00">
|
||||||
|
</Audio>
|
||||||
</File>
|
</File>
|
||||||
</Root>
|
</Root>
|
||||||
|
@ -18,11 +18,6 @@
|
|||||||
#define _AudiotableSegmentRomStart "Audiotable"
|
#define _AudiotableSegmentRomStart "Audiotable"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define _icon_item_gameover_staticSegmentRomStart 0
|
|
||||||
#define _icon_item_gameover_staticSegmentRomEnd 0
|
|
||||||
#define _icon_item_staticSegmentRomStart 0
|
#define _icon_item_staticSegmentRomStart 0
|
||||||
#define _icon_item_staticSegmentRomEnd 0
|
#define _icon_item_staticSegmentRomEnd 0
|
||||||
#define _map_i_staticSegmentRomStart 0
|
#define _map_i_staticSegmentRomStart 0
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
#if defined(_WIN64) || defined(__x86_64__)
|
#if defined(_WIN64) || defined(__x86_64__)
|
||||||
#define _SOH64
|
#define _SOH64
|
||||||
#define AUDIO_HEAP_SIZE 0x70000
|
#define AUDIO_HEAP_SIZE 0xF0000
|
||||||
#else
|
#else
|
||||||
#define AUDIO_HEAP_SIZE 0x38000
|
#define AUDIO_HEAP_SIZE 0x38000
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,6 +18,10 @@
|
|||||||
|
|
||||||
#define AIBUF_LEN 0x580
|
#define AIBUF_LEN 0x580
|
||||||
|
|
||||||
|
#define CALC_RESAMPLE_FREQ(sampleRate) ((float)sampleRate / (s32)gAudioContext.audioBufferParameters.frequency)
|
||||||
|
|
||||||
|
extern bool gUseLegacySD;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* 0 */ ADSR_STATE_DISABLED,
|
/* 0 */ ADSR_STATE_DISABLED,
|
||||||
/* 1 */ ADSR_STATE_INITIAL,
|
/* 1 */ ADSR_STATE_INITIAL,
|
||||||
@ -136,6 +140,8 @@ typedef struct
|
|||||||
/* 0x04 */ u8* sampleAddr;
|
/* 0x04 */ u8* sampleAddr;
|
||||||
/* 0x08 */ AdpcmLoop* loop;
|
/* 0x08 */ AdpcmLoop* loop;
|
||||||
/* 0x0C */ AdpcmBook* book;
|
/* 0x0C */ AdpcmBook* book;
|
||||||
|
u32 sampleRateMagicValue; // For wav samples only...
|
||||||
|
s32 sampleRate; // For wav samples only...
|
||||||
} SoundFontSample; // size = 0x10
|
} SoundFontSample; // size = 0x10
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -1062,6 +1068,16 @@ typedef enum {
|
|||||||
/* -1 */ OCARINA_NOTE_INVALID = 0xFF
|
/* -1 */ OCARINA_NOTE_INVALID = 0xFF
|
||||||
} OcarinaNoteIdx;
|
} OcarinaNoteIdx;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char* seqData;
|
||||||
|
int32_t seqDataSize;
|
||||||
|
uint8_t seqNumber;
|
||||||
|
uint8_t medium;
|
||||||
|
uint8_t cachePolicy;
|
||||||
|
int32_t numFonts;
|
||||||
|
uint8_t fonts[16];
|
||||||
|
} SequenceData;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
<PlatformToolset>v142</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<EnableASAN>true</EnableASAN>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
@ -59,6 +59,7 @@ extern "C" void AudioPlayer_Play(const uint8_t* buf, uint32_t len);
|
|||||||
extern "C" int AudioPlayer_Buffered(void);
|
extern "C" int AudioPlayer_Buffered(void);
|
||||||
extern "C" int AudioPlayer_GetDesiredBuffered(void);
|
extern "C" int AudioPlayer_GetDesiredBuffered(void);
|
||||||
extern "C" void ResourceMgr_CacheDirectory(const char* resName);
|
extern "C" void ResourceMgr_CacheDirectory(const char* resName);
|
||||||
|
extern "C" SequenceData ResourceMgr_LoadSeqByName(const char* path);
|
||||||
|
|
||||||
// C->C++ Bridge
|
// C->C++ Bridge
|
||||||
extern "C" void OTRAudio_Init()
|
extern "C" void OTRAudio_Init()
|
||||||
@ -198,11 +199,16 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
|
|||||||
//AudioMgr_ThreadEntry(&gAudioMgr);
|
//AudioMgr_ThreadEntry(&gAudioMgr);
|
||||||
// 528 and 544 relate to 60 fps at 32 kHz 32000/60 = 533.333..
|
// 528 and 544 relate to 60 fps at 32 kHz 32000/60 = 533.333..
|
||||||
// in an ideal world, one third of the calls should use num_samples=544 and two thirds num_samples=528
|
// in an ideal world, one third of the calls should use num_samples=544 and two thirds num_samples=528
|
||||||
#define SAMPLES_HIGH 560
|
//#define SAMPLES_HIGH 560
|
||||||
#define SAMPLES_LOW 528
|
//#define SAMPLES_LOW 528
|
||||||
// PAL values
|
// PAL values
|
||||||
//#define SAMPLES_HIGH 656
|
//#define SAMPLES_HIGH 656
|
||||||
//#define SAMPLES_LOW 624
|
//#define SAMPLES_LOW 624
|
||||||
|
|
||||||
|
// 44KHZ values
|
||||||
|
#define SAMPLES_HIGH 752
|
||||||
|
#define SAMPLES_LOW 720
|
||||||
|
|
||||||
#define AUDIO_FRAMES_PER_UPDATE (R_UPDATE_RATE > 0 ? R_UPDATE_RATE : 1 )
|
#define AUDIO_FRAMES_PER_UPDATE (R_UPDATE_RATE > 0 ? R_UPDATE_RATE : 1 )
|
||||||
#define NUM_AUDIO_CHANNELS 2
|
#define NUM_AUDIO_CHANNELS 2
|
||||||
int samples_left = AudioPlayer_Buffered();
|
int samples_left = AudioPlayer_Buffered();
|
||||||
@ -321,6 +327,22 @@ extern "C" void ResourceMgr_InvalidateCache() {
|
|||||||
OTRGlobals::Instance->context->GetResourceManager()->InvalidateResourceCache();
|
OTRGlobals::Instance->context->GetResourceManager()->InvalidateResourceCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OTRTODO: There is probably a more elegant way to go about this...
|
||||||
|
extern "C" char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize) {
|
||||||
|
auto lst = OTRGlobals::Instance->context->GetResourceManager()->ListFiles(searchMask);
|
||||||
|
char** result = (char**)malloc(lst->size() * sizeof(char*));
|
||||||
|
|
||||||
|
for (int i = 0; i < lst->size(); i++) {
|
||||||
|
char* str = (char*)malloc(lst.get()[0][i].size() + 1);
|
||||||
|
memcpy(str, lst.get()[0][i].data(), lst.get()[0][i].size());
|
||||||
|
str[lst.get()[0][i].size()] = '\0';
|
||||||
|
result[i] = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
*resultSize = lst->size();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" void ResourceMgr_LoadFile(const char* resName) {
|
extern "C" void ResourceMgr_LoadFile(const char* resName) {
|
||||||
OTRGlobals::Instance->context->GetResourceManager()->LoadResource(resName);
|
OTRGlobals::Instance->context->GetResourceManager()->LoadResource(resName);
|
||||||
@ -545,35 +567,52 @@ extern "C" Vtx* ResourceMgr_LoadVtxByName(const char* path)
|
|||||||
return (Vtx*)res->vertices.data();
|
return (Vtx*)res->vertices.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" char* ResourceMgr_LoadSeqByID(int seqID)
|
extern "C" SequenceData ResourceMgr_LoadSeqByID(int seqID) {
|
||||||
{
|
|
||||||
|
if (seqID == 0xFF) {
|
||||||
|
SequenceData sDat;
|
||||||
|
sDat.numFonts = 0;
|
||||||
|
|
||||||
|
return sDat;
|
||||||
|
}
|
||||||
|
|
||||||
std::string fmtStr = "audio/sequences/seq_%02X";
|
std::string fmtStr = "audio/sequences/seq_%02X";
|
||||||
return OTRGlobals::Instance->context->GetResourceManager()->LoadFile(StringHelper::Sprintf(fmtStr.c_str(), seqID)).get()->buffer.get();
|
return ResourceMgr_LoadSeqByName(StringHelper::Sprintf(fmtStr.c_str(), seqID).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int ResourceMgr_GetSeqSizeByID(int seqID)
|
extern "C" SequenceData ResourceMgr_LoadSeqByName(const char* path) {
|
||||||
{
|
auto file = OTRGlobals::Instance->context->GetResourceManager()->LoadFile(path).get();
|
||||||
return OTRGlobals::Instance->context->GetResourceManager()
|
|
||||||
->LoadFile(StringHelper::Sprintf("audio/sequences/seq_%02X", seqID))
|
char* data = file->buffer.get();
|
||||||
.get()
|
|
||||||
->dwBufferSize;
|
SequenceData seqData;
|
||||||
|
seqData.seqNumber = data[1];
|
||||||
|
seqData.medium = data[2];
|
||||||
|
seqData.cachePolicy = data[3];
|
||||||
|
seqData.numFonts = data[4];
|
||||||
|
|
||||||
|
for (int i = 0; i < seqData.numFonts; i++)
|
||||||
|
seqData.fonts[i] = data[5 + i];
|
||||||
|
|
||||||
|
seqData.seqData = &data[5 + seqData.numFonts];
|
||||||
|
seqData.seqDataSize = file->dwBufferSize - 5 - seqData.numFonts;
|
||||||
|
|
||||||
|
return seqData;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, SoundFontSample*> cachedCustomSFs;
|
std::map<std::string, SoundFontSample*> cachedCustomSFs;
|
||||||
|
|
||||||
extern "C" SoundFontSample* ResourceMgr_LoadAudioSample(int romOffset)
|
extern "C" SoundFontSample* ResourceMgr_LoadAudioSample(const char* path) {
|
||||||
{
|
//auto str = StringHelper::Sprintf("audio/samples/sample_%08X", romOffset);
|
||||||
auto str = StringHelper::Sprintf("audio/samples/sample_%08X", romOffset);
|
|
||||||
|
|
||||||
if (cachedCustomSFs.find(str) != cachedCustomSFs.end())
|
if (std::string(path) == "")
|
||||||
return cachedCustomSFs[str];
|
return nullptr;
|
||||||
|
|
||||||
if (romOffset == 0x14f0) {
|
if (cachedCustomSFs.find(path) != cachedCustomSFs.end())
|
||||||
int bp = 0;
|
return cachedCustomSFs[path];
|
||||||
}
|
|
||||||
|
|
||||||
// Check if our file is actually a wav...
|
// Check if our file is actually a wav...
|
||||||
auto sampleRaw = OTRGlobals::Instance->context->GetResourceManager()->LoadFile(str);
|
auto sampleRaw = OTRGlobals::Instance->context->GetResourceManager()->LoadFile(path);
|
||||||
uint32_t* strem = (uint32_t*)sampleRaw->buffer.get();
|
uint32_t* strem = (uint32_t*)sampleRaw->buffer.get();
|
||||||
uint8_t* strem2 = (uint8_t*)strem;
|
uint8_t* strem2 = (uint8_t*)strem;
|
||||||
|
|
||||||
@ -587,6 +626,8 @@ extern "C" SoundFontSample* ResourceMgr_LoadAudioSample(int romOffset)
|
|||||||
|
|
||||||
*strem++; // fmt
|
*strem++; // fmt
|
||||||
int fmtChunkSize = *strem++;
|
int fmtChunkSize = *strem++;
|
||||||
|
*strem++; // wFormatTag + wChannels
|
||||||
|
int32_t sampleRate = *strem++; // dwSamplesPerSec
|
||||||
// OTRTODO: Make sure wav format is what the audio driver wants!
|
// OTRTODO: Make sure wav format is what the audio driver wants!
|
||||||
|
|
||||||
strem = (uint32_t*)&strem2[0x0C + fmtChunkSize + 8 + 4];
|
strem = (uint32_t*)&strem2[0x0C + fmtChunkSize + 8 + 4];
|
||||||
@ -597,26 +638,25 @@ extern "C" SoundFontSample* ResourceMgr_LoadAudioSample(int romOffset)
|
|||||||
// OTRTODO: Grab loop data from wav
|
// OTRTODO: Grab loop data from wav
|
||||||
sampleC->loop = (AdpcmLoop*)malloc(sizeof(AdpcmLoop));
|
sampleC->loop = (AdpcmLoop*)malloc(sizeof(AdpcmLoop));
|
||||||
sampleC->loop->start = 0;
|
sampleC->loop->start = 0;
|
||||||
sampleC->loop->end = sampleC->size / 2;
|
sampleC->loop->end = sampleC->size / 2; // OTRTODO: This calculation is probably incorrect... Sometimes it goes past the sample, sometimes it stops too early...
|
||||||
sampleC->loop->count = 0;
|
sampleC->loop->count = 0;
|
||||||
|
sampleC->sampleRateMagicValue = 'RIFF';
|
||||||
|
sampleC->sampleRate = sampleRate;
|
||||||
|
|
||||||
cachedCustomSFs[str] = sampleC;
|
cachedCustomSFs[path] = sampleC;
|
||||||
return sampleC;
|
return sampleC;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto sample = std::static_pointer_cast<Ship::AudioSample>(OTRGlobals::Instance->context->GetResourceManager()->LoadResource(str));
|
auto sample = std::static_pointer_cast<Ship::AudioSample>(
|
||||||
|
OTRGlobals::Instance->context->GetResourceManager()->LoadResource(path));
|
||||||
|
|
||||||
if (sample == nullptr)
|
if (sample == nullptr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (sample->cachedGameAsset != nullptr)
|
if (sample->cachedGameAsset != nullptr) {
|
||||||
{
|
|
||||||
SoundFontSample* sampleC = (SoundFontSample*)sample->cachedGameAsset;
|
SoundFontSample* sampleC = (SoundFontSample*)sample->cachedGameAsset;
|
||||||
|
|
||||||
return (SoundFontSample*)sample->cachedGameAsset;
|
return (SoundFontSample*)sample->cachedGameAsset;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
SoundFontSample* sampleC = (SoundFontSample*)malloc(sizeof(SoundFontSample));
|
SoundFontSample* sampleC = (SoundFontSample*)malloc(sizeof(SoundFontSample));
|
||||||
|
|
||||||
sampleC->sampleAddr = sample->data.data();
|
sampleC->sampleAddr = sample->data.data();
|
||||||
@ -692,7 +732,7 @@ extern "C" SoundFont* ResourceMgr_LoadAudioSoundFont(int fontIndex) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drum->sound.sample = ResourceMgr_LoadAudioSample(soundFont->drums[i].offset);
|
drum->sound.sample = ResourceMgr_LoadAudioSample(soundFont->drums[i].sampleFileName.c_str());
|
||||||
drum->sound.tuning = soundFont->drums[i].tuning;
|
drum->sound.tuning = soundFont->drums[i].tuning;
|
||||||
|
|
||||||
soundFontC->drums[i] = drum;
|
soundFontC->drums[i] = drum;
|
||||||
@ -726,7 +766,7 @@ extern "C" SoundFont* ResourceMgr_LoadAudioSoundFont(int fontIndex) {
|
|||||||
if (soundFont->instruments[i].lowNotesSound != nullptr)
|
if (soundFont->instruments[i].lowNotesSound != nullptr)
|
||||||
{
|
{
|
||||||
inst->lowNotesSound.sample =
|
inst->lowNotesSound.sample =
|
||||||
ResourceMgr_LoadAudioSample(soundFont->instruments[i].lowNotesSound->sampleOffset);
|
ResourceMgr_LoadAudioSample(soundFont->instruments[i].lowNotesSound->sampleFileName.c_str());
|
||||||
inst->lowNotesSound.tuning = soundFont->instruments[i].lowNotesSound->tuning;
|
inst->lowNotesSound.tuning = soundFont->instruments[i].lowNotesSound->tuning;
|
||||||
} else {
|
} else {
|
||||||
inst->lowNotesSound.sample = NULL;
|
inst->lowNotesSound.sample = NULL;
|
||||||
@ -735,7 +775,7 @@ extern "C" SoundFont* ResourceMgr_LoadAudioSoundFont(int fontIndex) {
|
|||||||
|
|
||||||
if (soundFont->instruments[i].normalNotesSound != nullptr) {
|
if (soundFont->instruments[i].normalNotesSound != nullptr) {
|
||||||
inst->normalNotesSound.sample =
|
inst->normalNotesSound.sample =
|
||||||
ResourceMgr_LoadAudioSample(soundFont->instruments[i].normalNotesSound->sampleOffset);
|
ResourceMgr_LoadAudioSample(soundFont->instruments[i].normalNotesSound->sampleFileName.c_str());
|
||||||
inst->normalNotesSound.tuning = soundFont->instruments[i].normalNotesSound->tuning;
|
inst->normalNotesSound.tuning = soundFont->instruments[i].normalNotesSound->tuning;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -745,7 +785,7 @@ extern "C" SoundFont* ResourceMgr_LoadAudioSoundFont(int fontIndex) {
|
|||||||
|
|
||||||
if (soundFont->instruments[i].highNotesSound != nullptr) {
|
if (soundFont->instruments[i].highNotesSound != nullptr) {
|
||||||
inst->highNotesSound.sample =
|
inst->highNotesSound.sample =
|
||||||
ResourceMgr_LoadAudioSample(soundFont->instruments[i].highNotesSound->sampleOffset);
|
ResourceMgr_LoadAudioSample(soundFont->instruments[i].highNotesSound->sampleFileName.c_str());
|
||||||
inst->highNotesSound.tuning = soundFont->instruments[i].highNotesSound->tuning;
|
inst->highNotesSound.tuning = soundFont->instruments[i].highNotesSound->tuning;
|
||||||
} else {
|
} else {
|
||||||
inst->highNotesSound.sample = NULL;
|
inst->highNotesSound.sample = NULL;
|
||||||
@ -763,7 +803,7 @@ extern "C" SoundFont* ResourceMgr_LoadAudioSoundFont(int fontIndex) {
|
|||||||
|
|
||||||
for (int i = 0; i < soundFont->soundEffects.size(); i++)
|
for (int i = 0; i < soundFont->soundEffects.size(); i++)
|
||||||
{
|
{
|
||||||
soundFontC->soundEffects[i].sample = ResourceMgr_LoadAudioSample(soundFont->soundEffects[i]->sampleOffset);
|
soundFontC->soundEffects[i].sample = ResourceMgr_LoadAudioSample(soundFont->soundEffects[i]->sampleFileName.c_str());
|
||||||
soundFontC->soundEffects[i].tuning = soundFont->soundEffects[i]->tuning;
|
soundFontC->soundEffects[i].tuning = soundFont->soundEffects[i]->tuning;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ uint16_t OTRGetPixelDepth(float x, float y);
|
|||||||
int32_t OTRGetLastScancode();
|
int32_t OTRGetLastScancode();
|
||||||
uint32_t ResourceMgr_GetGameVersion();
|
uint32_t ResourceMgr_GetGameVersion();
|
||||||
void ResourceMgr_CacheDirectory(const char* resName);
|
void ResourceMgr_CacheDirectory(const char* resName);
|
||||||
|
char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize);
|
||||||
void ResourceMgr_LoadFile(const char* resName);
|
void ResourceMgr_LoadFile(const char* resName);
|
||||||
char* ResourceMgr_LoadFileFromDisk(const char* filePath);
|
char* ResourceMgr_LoadFileFromDisk(const char* filePath);
|
||||||
char* ResourceMgr_LoadJPEG(char* data, int dataSize);
|
char* ResourceMgr_LoadJPEG(char* data, int dataSize);
|
||||||
@ -49,6 +50,10 @@ Gfx* ResourceMgr_PatchGfxByName(const char* path, int size);
|
|||||||
char* ResourceMgr_LoadArrayByNameAsVec3s(const char* path);
|
char* ResourceMgr_LoadArrayByNameAsVec3s(const char* path);
|
||||||
Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc);
|
Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc);
|
||||||
Vtx* ResourceMgr_LoadVtxByName(const char* path);
|
Vtx* ResourceMgr_LoadVtxByName(const char* path);
|
||||||
|
SoundFont* ResourceMgr_LoadAudioSoundFont(int fontIndex);
|
||||||
|
SequenceData ResourceMgr_LoadSeqByID(int seqID);
|
||||||
|
SequenceData ResourceMgr_LoadSeqByName(const char* path);
|
||||||
|
SoundFontSample* ResourceMgr_LoadAudioSample(const char* path);
|
||||||
CollisionHeader* ResourceMgr_LoadColByName(const char* path);
|
CollisionHeader* ResourceMgr_LoadColByName(const char* path);
|
||||||
uint64_t GetPerfCounter();
|
uint64_t GetPerfCounter();
|
||||||
struct SkeletonHeader* ResourceMgr_LoadSkeletonByName(const char* path);
|
struct SkeletonHeader* ResourceMgr_LoadSkeletonByName(const char* path);
|
||||||
@ -76,10 +81,6 @@ int AudioPlayer_GetDesiredBuffered(void);
|
|||||||
void AudioPlayer_Play(const uint8_t* buf, uint32_t len);
|
void AudioPlayer_Play(const uint8_t* buf, uint32_t len);
|
||||||
void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples);
|
void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples);
|
||||||
int Controller_ShouldRumble(size_t i);
|
int Controller_ShouldRumble(size_t i);
|
||||||
char* ResourceMgr_LoadSeqByID(int seqID);
|
|
||||||
int ResourceMgr_GetSeqSizeByID(int seqID);
|
|
||||||
SoundFont* ResourceMgr_LoadAudioSoundFont(int fontIndex);
|
|
||||||
SoundFontSample* ResourceMgr_LoadAudioSample(int romOffset);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1875,7 +1875,9 @@ AudioTable gSampleBankTable = { 0x0007,
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// OTRTODO: Implement This in OTR File
|
#if 0
|
||||||
|
u8 gSequenceFontTable[1] = { 0 };
|
||||||
|
#else
|
||||||
u8 gSequenceFontTable[0x1C0] = {
|
u8 gSequenceFontTable[0x1C0] = {
|
||||||
0xDC,
|
0xDC,
|
||||||
0x00,
|
0x00,
|
||||||
@ -2111,3 +2113,4 @@ u8 gSequenceFontTable[0x1C0] = {
|
|||||||
0x03, 0x01, 0x1F, 0x01, 0x20, 0x01, 0x20, 0x01, 0x09, 0x01, 0x21, 0x01, 0x22, 0x01, 0x21, 0x01, 0x09, 0x01, 0x20,
|
0x03, 0x01, 0x1F, 0x01, 0x20, 0x01, 0x20, 0x01, 0x09, 0x01, 0x21, 0x01, 0x22, 0x01, 0x21, 0x01, 0x09, 0x01, 0x20,
|
||||||
0x01, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x01, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
};
|
};
|
||||||
|
#endif
|
@ -544,16 +544,10 @@ u8 gDefaultShortNoteGateTimeTable[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
AdsrEnvelope gDefaultEnvelope[] = {
|
AdsrEnvelope gDefaultEnvelope[] = {
|
||||||
// OTRTODO: Byteswapped manually for quick audio support.
|
|
||||||
{ 0x0100, 0x007D },
|
{ 0x0100, 0x007D },
|
||||||
{ 0xE803, 0x007D },
|
{ 0xE803, 0x007D },
|
||||||
{ 0xFFFF, 0x0000 },
|
{ 0xFFFF, 0x0000 },
|
||||||
{ 0x0000, 0x0000 },
|
{ 0x0000, 0x0000 },
|
||||||
/* { 1, 32000 },
|
|
||||||
{ 1000, 32000 },
|
|
||||||
{ -1, 0 },
|
|
||||||
{ 0, 0 },
|
|
||||||
*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NoteSubEu gZeroNoteSub = { 0 };
|
NoteSubEu gZeroNoteSub = { 0 };
|
||||||
|
@ -70,23 +70,24 @@ ReverbSettings D_80133420[][3] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// OTRTODO
|
||||||
AudioSpec gAudioSpecs[18] = {
|
AudioSpec gAudioSpecs[18] = {
|
||||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x4000, 0x2880, 0, 0, 0 },
|
{ 44000, 1, 24, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x4000, 0x2880, 0, 0, 0 },
|
||||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[1], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
{ 44000, 1, 24, 4, 0, 0, 2, D_80133420[1], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
{ 44000, 1, 24, 4, 0, 0, 2, D_80133420[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||||
{ 32000, 1, 23, 4, 0, 0, 2, D_80133420[4], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
{ 44000, 1, 23, 4, 0, 0, 2, D_80133420[4], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||||
{ 32000, 1, 23, 4, 0, 0, 2, D_80133420[5], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
{ 44000, 1, 23, 4, 0, 0, 2, D_80133420[5], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[6], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
{ 44000, 1, 24, 4, 0, 0, 2, D_80133420[6], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[7], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
{ 44000, 1, 24, 4, 0, 0, 2, D_80133420[7], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||||
{ 32000, 1, 23, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
{ 44000, 1, 23, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[9], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
{ 44000, 1, 24, 4, 0, 0, 2, D_80133420[9], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||||
{ 32000, 1, 23, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
{ 44000, 1, 23, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||||
{ 32000, 1, 28, 3, 0, 0, 2, D_80133420[10], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x2800, 0x2880, 0, 0, 0 },
|
{ 44000, 1, 28, 3, 0, 0, 2, D_80133420[10], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x2800, 0x2880, 0, 0, 0 },
|
||||||
{ 32000, 1, 28, 3, 0, 0, 1, D_80133420[11], 0x300, 0x200, 0x7FFF, 0, 0x4800, 0, 0x4000, 0, 0, 0, 0 },
|
{ 44000, 1, 28, 3, 0, 0, 1, D_80133420[11], 0x300, 0x200, 0x7FFF, 0, 0x4800, 0, 0x4000, 0, 0, 0, 0 },
|
||||||
{ 32000, 1, 28, 3, 0, 0, 1, D_80133420[11], 0x300, 0x200, 0x7FFF, 0, 0, 0, 0x4000, 0x4800, 0, 0, 0 },
|
{ 44000, 1, 28, 3, 0, 0, 1, D_80133420[11], 0x300, 0x200, 0x7FFF, 0, 0, 0, 0x4000, 0x4800, 0, 0, 0 },
|
||||||
{ 32000, 1, 22, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
{ 44000, 1, 22, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||||
{ 32000, 1, 22, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
{ 44000, 1, 22, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||||
{ 32000, 1, 16, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
{ 44000, 1, 16, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||||
{ 22050, 1, 24, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
{ 22050, 1, 24, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3600, 0x2600, 0, 0, 0 },
|
{ 44000, 1, 24, 4, 0, 0, 2, D_80133420[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3600, 0x2600, 0, 0, 0 },
|
||||||
};
|
};
|
||||||
|
@ -76,6 +76,8 @@ void* sUnusedHandler = NULL;
|
|||||||
|
|
||||||
s32 gAudioContextInitalized = false;
|
s32 gAudioContextInitalized = false;
|
||||||
|
|
||||||
|
char* sequenceMap[512];
|
||||||
|
|
||||||
uintptr_t fontStart;
|
uintptr_t fontStart;
|
||||||
uint32_t fontOffsets[8192];
|
uint32_t fontOffsets[8192];
|
||||||
|
|
||||||
@ -388,6 +390,7 @@ SoundFontData* AudioLoad_SyncLoadSeqFonts(s32 seqId, u32* outDefaultFontId) {
|
|||||||
|
|
||||||
while (numFonts > 0) {
|
while (numFonts > 0) {
|
||||||
fontId = gAudioContext.sequenceFontTable[index++];
|
fontId = gAudioContext.sequenceFontTable[index++];
|
||||||
|
|
||||||
font = AudioLoad_SyncLoadFont(fontId);
|
font = AudioLoad_SyncLoadFont(fontId);
|
||||||
numFonts--;
|
numFonts--;
|
||||||
}
|
}
|
||||||
@ -480,6 +483,18 @@ void AudioLoad_AsyncLoadFont(s32 fontId, s32 arg1, s32 retData, OSMesgQueue* ret
|
|||||||
u8* AudioLoad_GetFontsForSequence(s32 seqId, u32* outNumFonts) {
|
u8* AudioLoad_GetFontsForSequence(s32 seqId, u32* outNumFonts) {
|
||||||
s32 index;
|
s32 index;
|
||||||
|
|
||||||
|
if (!gUseLegacySD)
|
||||||
|
{
|
||||||
|
if (seqId == 255)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
SequenceData sDat = ResourceMgr_LoadSeqByName(sequenceMap[seqId]);
|
||||||
|
|
||||||
|
if (sDat.numFonts == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return sDat.fonts;
|
||||||
|
} else {
|
||||||
index = ((u16*)gAudioContext.sequenceFontTable)[seqId];
|
index = ((u16*)gAudioContext.sequenceFontTable)[seqId];
|
||||||
|
|
||||||
*outNumFonts = gAudioContext.sequenceFontTable[index++];
|
*outNumFonts = gAudioContext.sequenceFontTable[index++];
|
||||||
@ -487,6 +502,7 @@ u8* AudioLoad_GetFontsForSequence(s32 seqId, u32* outNumFonts) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return &gAudioContext.sequenceFontTable[index];
|
return &gAudioContext.sequenceFontTable[index];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLoad_DiscardSeqFonts(s32 seqId) {
|
void AudioLoad_DiscardSeqFonts(s32 seqId) {
|
||||||
@ -569,17 +585,28 @@ s32 AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) {
|
|||||||
AudioSeq_SequencePlayerDisable(seqPlayer);
|
AudioSeq_SequencePlayerDisable(seqPlayer);
|
||||||
|
|
||||||
fontId = 0xFF;
|
fontId = 0xFF;
|
||||||
|
|
||||||
|
if (gUseLegacySD) {
|
||||||
index = ((u16*)gAudioContext.sequenceFontTable)[seqId];
|
index = ((u16*)gAudioContext.sequenceFontTable)[seqId];
|
||||||
numFonts = gAudioContext.sequenceFontTable[index++];
|
numFonts = gAudioContext.sequenceFontTable[index++];
|
||||||
|
|
||||||
while (numFonts > 0) {
|
while (numFonts > 0) {
|
||||||
fontId = gAudioContext.sequenceFontTable[index++];
|
fontId = gAudioContext.sequenceFontTable[index++];
|
||||||
|
|
||||||
// if (gUseLegacySD)
|
AudioLoad_SyncLoadFont(fontId); // NOTE: If this is commented out, then enemies will play child link sounds...
|
||||||
AudioLoad_SyncLoadFont(fontId);
|
|
||||||
|
|
||||||
numFonts--;
|
numFonts--;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
SequenceData seqData2 = ResourceMgr_LoadSeqByName(sequenceMap[seqId]);
|
||||||
|
|
||||||
|
for (int i = 0; i < seqData2.numFonts; i++)
|
||||||
|
{
|
||||||
|
fontId = seqData2.fonts[i];
|
||||||
|
AudioLoad_SyncLoadFont(fontId); // NOTE: If this is commented out, then enemies will play child link sounds...
|
||||||
|
numFonts--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
seqData = AudioLoad_SyncLoadSeq(seqId);
|
seqData = AudioLoad_SyncLoadSeq(seqId);
|
||||||
|
|
||||||
@ -660,7 +687,6 @@ SoundFontData* AudioLoad_SyncLoadFont(u32 fontId) {
|
|||||||
s32 didAllocate;
|
s32 didAllocate;
|
||||||
RelocInfo relocInfo;
|
RelocInfo relocInfo;
|
||||||
s32 realFontId = AudioLoad_GetRealTableIndex(FONT_TABLE, fontId);
|
s32 realFontId = AudioLoad_GetRealTableIndex(FONT_TABLE, fontId);
|
||||||
//s32 realFontId = fontId;
|
|
||||||
|
|
||||||
if (gAudioContext.fontLoadStatus[realFontId] == 1) {
|
if (gAudioContext.fontLoadStatus[realFontId] == 1) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -722,26 +748,20 @@ uintptr_t AudioLoad_SyncLoad(u32 tableType, u32 id, s32* didAllocate) {
|
|||||||
char* seqData = 0;
|
char* seqData = 0;
|
||||||
SoundFont* fnt;
|
SoundFont* fnt;
|
||||||
|
|
||||||
if (!gUseLegacySD && tableType == SEQUENCE_TABLE)
|
if (!gUseLegacySD && tableType == SEQUENCE_TABLE) {
|
||||||
{
|
SequenceData sData = ResourceMgr_LoadSeqByName(sequenceMap[id]);
|
||||||
seqData = ResourceMgr_LoadSeqByID(id);
|
seqData = sData.seqData;
|
||||||
size = ResourceMgr_GetSeqSizeByID(id);
|
size = sData.seqDataSize;
|
||||||
size -= 2;
|
medium = sData.medium;
|
||||||
medium = seqData[0];
|
cachePolicy = sData.cachePolicy;
|
||||||
cachePolicy = seqData[1];
|
|
||||||
romAddr = 0;
|
romAddr = 0;
|
||||||
seqData += 2;
|
} else if (!gUseLegacySD && tableType == FONT_TABLE) {
|
||||||
}
|
|
||||||
else if (!gUseLegacySD && tableType == FONT_TABLE)
|
|
||||||
{
|
|
||||||
fnt = ResourceMgr_LoadAudioSoundFont(id);
|
fnt = ResourceMgr_LoadAudioSoundFont(id);
|
||||||
size = sizeof(SoundFont);
|
size = sizeof(SoundFont);
|
||||||
medium = 2;
|
medium = 2;
|
||||||
cachePolicy = 0;
|
cachePolicy = 0;
|
||||||
romAddr = 0;
|
romAddr = 0;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
table = AudioLoad_GetLoadTable(tableType);
|
table = AudioLoad_GetLoadTable(tableType);
|
||||||
size = table->entries[realId].size;
|
size = table->entries[realId].size;
|
||||||
size = ALIGN16(size);
|
size = ALIGN16(size);
|
||||||
@ -1181,7 +1201,6 @@ s32 AudioLoad_AssertValidAddr(uintptr_t ramAddr, uintptr_t startAddr, size_t siz
|
|||||||
#define BASE_ROM_OFFSET(x) (uintptr_t)((uintptr_t)(x) + (uintptr_t)(romAddr))
|
#define BASE_ROM_OFFSET(x) (uintptr_t)((uintptr_t)(x) + (uintptr_t)(romAddr))
|
||||||
|
|
||||||
void AudioLoad_InitSwapFontSampleHeaders(SoundFontSample* sample, uintptr_t romAddr) {
|
void AudioLoad_InitSwapFontSampleHeaders(SoundFontSample* sample, uintptr_t romAddr) {
|
||||||
// OTRTODO: This will be removed when we actually extract the data.
|
|
||||||
size_t maxSoundFontSize = 0x3AA0; // soundFont 0 is the largest size at 0x3AA0
|
size_t maxSoundFontSize = 0x3AA0; // soundFont 0 is the largest size at 0x3AA0
|
||||||
AdpcmLoop* loop;
|
AdpcmLoop* loop;
|
||||||
AdpcmBook* book;
|
AdpcmBook* book;
|
||||||
@ -1390,12 +1409,21 @@ void AudioLoad_Init(void* heap, size_t heapSize) {
|
|||||||
uintptr_t bankStart = ResourceMgr_LoadFileRaw(_AudiobankSegmentRomStart);
|
uintptr_t bankStart = ResourceMgr_LoadFileRaw(_AudiobankSegmentRomStart);
|
||||||
uintptr_t tableStart = ResourceMgr_LoadFileRaw(_AudiotableSegmentRomStart);
|
uintptr_t tableStart = ResourceMgr_LoadFileRaw(_AudiotableSegmentRomStart);
|
||||||
|
|
||||||
|
// If we have the old audioseq files present (and this is a 32-bit build), use the legacy audio system
|
||||||
|
if (seqStart != NULL && bankStart != NULL && tableStart != NULL)
|
||||||
|
gUseLegacySD = true;
|
||||||
|
|
||||||
fontStart = bankStart;
|
fontStart = bankStart;
|
||||||
|
|
||||||
AudioLoad_InitTable(gAudioContext.sequenceTable, seqStart, 0);
|
AudioLoad_InitTable(gAudioContext.sequenceTable, seqStart, 0);
|
||||||
AudioLoad_InitTable(gAudioContext.soundFontTable, bankStart, 0);
|
AudioLoad_InitTable(gAudioContext.soundFontTable, bankStart, 0);
|
||||||
AudioLoad_InitTable(gAudioContext.sampleBankTable, tableStart, 0);
|
AudioLoad_InitTable(gAudioContext.sampleBankTable, tableStart, 0);
|
||||||
|
|
||||||
|
if (gUseLegacySD)
|
||||||
numFonts = gAudioContext.soundFontTable->numEntries;
|
numFonts = gAudioContext.soundFontTable->numEntries;
|
||||||
|
else
|
||||||
|
numFonts = 0x26; // OTRTODO: Count the number of soundfonts that are inside the OTR(s)
|
||||||
|
|
||||||
gAudioContext.soundFonts = AudioHeap_Alloc(&gAudioContext.audioInitPool, numFonts * sizeof(SoundFont));
|
gAudioContext.soundFonts = AudioHeap_Alloc(&gAudioContext.audioInitPool, numFonts * sizeof(SoundFont));
|
||||||
|
|
||||||
if (gUseLegacySD) {
|
if (gUseLegacySD) {
|
||||||
@ -1404,6 +1432,23 @@ void AudioLoad_Init(void* heap, size_t heapSize) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AudioLoad_InitSwapFont();
|
AudioLoad_InitSwapFont();
|
||||||
|
} else {
|
||||||
|
int seqListSize = 0;
|
||||||
|
char** seqList = ResourceMgr_ListFiles("audio/sequences*", &seqListSize);
|
||||||
|
|
||||||
|
for (int i = 0; i < seqListSize; i++)
|
||||||
|
{
|
||||||
|
SequenceData sDat = ResourceMgr_LoadSeqByName(seqList[i]);
|
||||||
|
|
||||||
|
char* str = malloc(strlen(seqList[i]) + 1);
|
||||||
|
strcpy(str, seqList[i]);
|
||||||
|
|
||||||
|
sequenceMap[sDat.seqNumber] = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(seqList);
|
||||||
|
|
||||||
|
int bp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (temp_v0_3 = AudioHeap_Alloc(&gAudioContext.audioInitPool, D_8014A6C4.permanentPoolSize), temp_v0_3 == NULL) {
|
if (temp_v0_3 = AudioHeap_Alloc(&gAudioContext.audioInitPool, D_8014A6C4.permanentPoolSize), temp_v0_3 == NULL) {
|
||||||
@ -1424,7 +1469,6 @@ void AudioLoad_InitSlowLoads(void) {
|
|||||||
s32 AudioLoad_SlowLoadSample(s32 fontId, s32 instId, s8* isDone) {
|
s32 AudioLoad_SlowLoadSample(s32 fontId, s32 instId, s8* isDone) {
|
||||||
SoundFontSample* sample;
|
SoundFontSample* sample;
|
||||||
AudioSlowLoad* slowLoad;
|
AudioSlowLoad* slowLoad;
|
||||||
|
|
||||||
sample = AudioLoad_GetFontSample(fontId, instId);
|
sample = AudioLoad_GetFontSample(fontId, instId);
|
||||||
if (sample == NULL) {
|
if (sample == NULL) {
|
||||||
*isDone = 0;
|
*isDone = 0;
|
||||||
@ -1596,11 +1640,13 @@ s32 AudioLoad_SlowLoadSeq(s32 seqId, u8* ramAddr, s8* isDone) {
|
|||||||
slowLoad->sample.sampleAddr = NULL;
|
slowLoad->sample.sampleAddr = NULL;
|
||||||
slowLoad->isDone = isDone;
|
slowLoad->isDone = isDone;
|
||||||
|
|
||||||
if (!gUseLegacySD) {
|
if (!gUseLegacySD)
|
||||||
char* seqData = ResourceMgr_LoadSeqByID(seqId);
|
{
|
||||||
size = ResourceMgr_GetSeqSizeByID(seqId) - 2;
|
SequenceData sData = ResourceMgr_LoadSeqByName(sequenceMap[seqId]);
|
||||||
slowLoad->curDevAddr = seqData + 2;
|
char* seqData = sData.seqData;
|
||||||
slowLoad->medium = seqData[0];
|
size = sData.seqDataSize;
|
||||||
|
slowLoad->curDevAddr = seqData;
|
||||||
|
slowLoad->medium = sData.medium;
|
||||||
} else {
|
} else {
|
||||||
size = seqTable->entries[seqId].size;
|
size = seqTable->entries[seqId].size;
|
||||||
size = ALIGN16(size);
|
size = ALIGN16(size);
|
||||||
@ -1825,41 +1871,22 @@ void AudioLoad_AsyncDmaUnkMedium(uintptr_t devAddr, uintptr_t ramAddr, size_t si
|
|||||||
#define RELOC(v, base) (reloc = (uintptr_t)((uintptr_t)(v) + (uintptr_t)(base)))
|
#define RELOC(v, base) (reloc = (uintptr_t)((uintptr_t)(v) + (uintptr_t)(base)))
|
||||||
|
|
||||||
void AudioLoad_RelocateSample(SoundFontSound* sound, SoundFontData* mem, RelocInfo* relocInfo, int fontId) {
|
void AudioLoad_RelocateSample(SoundFontSound* sound, SoundFontData* mem, RelocInfo* relocInfo, int fontId) {
|
||||||
// OTRTODO: This is hack to detect whether or not the sample has been relocated.
|
|
||||||
size_t maxSoundBankSize = 0x3EB2A0; // sample bank 0 is largest size at 0x3EB2A0
|
size_t maxSoundBankSize = 0x3EB2A0; // sample bank 0 is largest size at 0x3EB2A0
|
||||||
|
if (gUseLegacySD)
|
||||||
|
{
|
||||||
|
// NOTE: This is hack to detect whether or not the sample has been relocated.
|
||||||
if ((uintptr_t)mem <= maxSoundBankSize) {
|
if ((uintptr_t)mem <= maxSoundBankSize) {
|
||||||
// OTRTODO: This can be removed once we have properly byteswapped files on the disk.
|
|
||||||
assert("mem for sound font bank is too low.");
|
assert("mem for sound font bank is too low.");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SoundFontSample* sample;
|
SoundFontSample* sample;
|
||||||
void* reloc;
|
void* reloc;
|
||||||
|
|
||||||
// OTRTODO: Seems precarious to assume the RAM is never <= 0x3EB2A0, but it largely works.
|
// NOTE: Seems precarious to assume the RAM is never <= 0x3EB2A0, but it largely works.
|
||||||
if ((uintptr_t)sound->sample < maxSoundBankSize || !gUseLegacySD)
|
if ((uintptr_t)sound->sample < maxSoundBankSize || !gUseLegacySD) {
|
||||||
{
|
|
||||||
if (!gUseLegacySD) {
|
if (!gUseLegacySD) {
|
||||||
SoundFontSample* sample2 = sound;
|
SoundFontSample* sample2 = sound;
|
||||||
|
|
||||||
if (sample2->unk_bit25 != 1)
|
|
||||||
{
|
|
||||||
//if (sample2->size == 0x5CC8)
|
|
||||||
//{
|
|
||||||
// switch (sample2->medium) {
|
|
||||||
// case 0:
|
|
||||||
// sample2->medium = relocInfo->medium1;
|
|
||||||
// break;
|
|
||||||
// case 1:
|
|
||||||
// sample2->medium = relocInfo->medium2;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// sample2->unk_bit25 = 1;
|
|
||||||
// if (sample2->unk_bit26 && (sample2->medium != MEDIUM_RAM)) {
|
|
||||||
// // gAudioContext.usedSamples[gAudioContext.numUsedSamples++] = sample2;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
sample = sound->sample = RELOC(sound->sample, mem);
|
sample = sound->sample = RELOC(sound->sample, mem);
|
||||||
|
|
||||||
@ -2112,9 +2139,11 @@ s32 AudioLoad_GetSamplesForFont(s32 fontId, SoundFontSample** sampleSet) {
|
|||||||
void AudioLoad_AddUsedSample(SoundFontSound* sound) {
|
void AudioLoad_AddUsedSample(SoundFontSound* sound) {
|
||||||
SoundFontSample* sample = sound->sample;
|
SoundFontSample* sample = sound->sample;
|
||||||
|
|
||||||
|
if (sample != NULL) {
|
||||||
if ((sample->size != 0) && (sample->unk_bit26) && (sample->medium != MEDIUM_RAM)) {
|
if ((sample->size != 0) && (sample->unk_bit26) && (sample->medium != MEDIUM_RAM)) {
|
||||||
gAudioContext.usedSamples[gAudioContext.numUsedSamples++] = sample;
|
gAudioContext.usedSamples[gAudioContext.numUsedSamples++] = sample;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLoad_PreloadSamplesForFont(s32 fontId, s32 async, RelocInfo* relocInfo) {
|
void AudioLoad_PreloadSamplesForFont(s32 fontId, s32 async, RelocInfo* relocInfo) {
|
||||||
|
@ -286,7 +286,18 @@ void Audio_ProcessNotes(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
subAttrs.frequency *= playbackState->vibratoFreqScale * playbackState->portamentoFreqScale;
|
subAttrs.frequency *= playbackState->vibratoFreqScale * playbackState->portamentoFreqScale;
|
||||||
subAttrs.frequency *= gAudioContext.audioBufferParameters.resampleRate;
|
|
||||||
|
f32 resampRate = gAudioContext.audioBufferParameters.resampleRate;
|
||||||
|
|
||||||
|
if (!gUseLegacySD && !noteSubEu2->bitField1.isSyntheticWave && noteSubEu2->sound.soundFontSound != NULL &&
|
||||||
|
noteSubEu2->sound.soundFontSound->sample != NULL &&
|
||||||
|
noteSubEu2->sound.soundFontSound->sample->sampleRateMagicValue == 'RIFF') {
|
||||||
|
resampRate = CALC_RESAMPLE_FREQ(noteSubEu2->sound.soundFontSound->sample->sampleRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
subAttrs.frequency *= resampRate;
|
||||||
|
|
||||||
|
|
||||||
subAttrs.velocity *= scale;
|
subAttrs.velocity *= scale;
|
||||||
Audio_InitNoteSub(note, noteSubEu2, &subAttrs);
|
Audio_InitNoteSub(note, noteSubEu2, &subAttrs);
|
||||||
noteSubEu->bitField1.bookOffset = bookOffset;
|
noteSubEu->bitField1.bookOffset = bookOffset;
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
#include "ultra64.h"
|
#include "ultra64.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
|
extern bool gUseLegacySD;
|
||||||
|
extern char* sequenceMap[512];
|
||||||
|
|
||||||
#define PORTAMENTO_IS_SPECIAL(x) ((x).mode & 0x80)
|
#define PORTAMENTO_IS_SPECIAL(x) ((x).mode & 0x80)
|
||||||
#define PORTAMENTO_MODE(x) ((x).mode & ~0x80)
|
#define PORTAMENTO_MODE(x) ((x).mode & ~0x80)
|
||||||
#define PORTAMENTO_MODE_1 1
|
#define PORTAMENTO_MODE_1 1
|
||||||
@ -1060,9 +1063,14 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
|
|||||||
command = (u8)parameters[0];
|
command = (u8)parameters[0];
|
||||||
|
|
||||||
if (seqPlayer->defaultFont != 0xFF) {
|
if (seqPlayer->defaultFont != 0xFF) {
|
||||||
|
if (gUseLegacySD) {
|
||||||
offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId];
|
offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId];
|
||||||
lowBits = gAudioContext.sequenceFontTable[offset];
|
lowBits = gAudioContext.sequenceFontTable[offset];
|
||||||
command = gAudioContext.sequenceFontTable[offset + lowBits - result];
|
command = gAudioContext.sequenceFontTable[offset + lowBits - result];
|
||||||
|
} else {
|
||||||
|
SequenceData sDat = ResourceMgr_LoadSeqByName(sequenceMap[seqPlayer->seqId]);
|
||||||
|
command = sDat.fonts[sDat.numFonts - result - 1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, command)) {
|
if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, command)) {
|
||||||
@ -1171,9 +1179,14 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
|
|||||||
command = (u8)parameters[0];
|
command = (u8)parameters[0];
|
||||||
|
|
||||||
if (seqPlayer->defaultFont != 0xFF) {
|
if (seqPlayer->defaultFont != 0xFF) {
|
||||||
|
if (gUseLegacySD) {
|
||||||
offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId];
|
offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId];
|
||||||
lowBits = gAudioContext.sequenceFontTable[offset];
|
lowBits = gAudioContext.sequenceFontTable[offset];
|
||||||
command = gAudioContext.sequenceFontTable[offset + lowBits - result];
|
command = gAudioContext.sequenceFontTable[offset + lowBits - result];
|
||||||
|
} else {
|
||||||
|
SequenceData sDat = ResourceMgr_LoadSeqByName(sequenceMap[seqPlayer->seqId]);
|
||||||
|
command = sDat.fonts[sDat.numFonts - result - 1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, command)) {
|
if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, command)) {
|
||||||
@ -1330,14 +1343,12 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
|
|||||||
break;
|
break;
|
||||||
case 0xB2:
|
case 0xB2:
|
||||||
offset = (u16)parameters[0];
|
offset = (u16)parameters[0];
|
||||||
// OTRTODO: Byteswap added for quick audio
|
|
||||||
channel->unk_22 = BOMSWAP16(*(u16*)(seqPlayer->seqData + (uintptr_t)(offset + scriptState->value * 2)));
|
channel->unk_22 = BOMSWAP16(*(u16*)(seqPlayer->seqData + (uintptr_t)(offset + scriptState->value * 2)));
|
||||||
break;
|
break;
|
||||||
case 0xB4:
|
case 0xB4:
|
||||||
channel->dynTable = (void*)&seqPlayer->seqData[channel->unk_22];
|
channel->dynTable = (void*)&seqPlayer->seqData[channel->unk_22];
|
||||||
break;
|
break;
|
||||||
case 0xB5:
|
case 0xB5:
|
||||||
// OTRTODO: Byteswap added for quick audio
|
|
||||||
channel->unk_22 = BOMSWAP16(((u16*)(channel->dynTable))[scriptState->value]);
|
channel->unk_22 = BOMSWAP16(((u16*)(channel->dynTable))[scriptState->value]);
|
||||||
break;
|
break;
|
||||||
case 0xB6:
|
case 0xB6:
|
||||||
|
@ -561,6 +561,9 @@ Acmd* AudioSynth_DoOneAudioUpdate(s16* aiBuf, s32 aiBufLen, Acmd* cmd, s32 updat
|
|||||||
NoteSubEu* noteSubEu2;
|
NoteSubEu* noteSubEu2;
|
||||||
s32 unk14;
|
s32 unk14;
|
||||||
|
|
||||||
|
if (aiBufLen == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
t = gAudioContext.numNotes * updateIndex;
|
t = gAudioContext.numNotes * updateIndex;
|
||||||
count = 0;
|
count = 0;
|
||||||
if (gAudioContext.numSynthesisReverbs == 0) {
|
if (gAudioContext.numSynthesisReverbs == 0) {
|
||||||
|
@ -363,7 +363,11 @@ void Audio_ProcessSeqCmd(u32 cmd) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio_QueueSeqCmd(u32 cmd) {
|
extern f32 D_80130F24;
|
||||||
|
extern f32 D_80130F28;
|
||||||
|
|
||||||
|
void Audio_QueueSeqCmd(u32 cmd)
|
||||||
|
{
|
||||||
sAudioSeqCmds[sSeqCmdWrPos++] = cmd;
|
sAudioSeqCmds[sSeqCmdWrPos++] = cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2093,7 +2093,12 @@ void func_80075B44(GlobalContext* globalCtx) {
|
|||||||
case 7:
|
case 7:
|
||||||
Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_CRITTER_1 << 4 | NATURE_CHANNEL_CRITTER_3,
|
Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_CRITTER_1 << 4 | NATURE_CHANNEL_CRITTER_3,
|
||||||
CHANNEL_IO_PORT_1, 0);
|
CHANNEL_IO_PORT_1, 0);
|
||||||
if (globalCtx->envCtx.unk_EE[0] == 0 && globalCtx->envCtx.unk_F2[0] == 0) {
|
if (globalCtx->envCtx.unk_EE[0] == 0 && globalCtx->envCtx.unk_F2[0] == 0)
|
||||||
|
{
|
||||||
|
// OTRTODO: This is where corrupt audio happens. Commenting this out seems to not introduce any side effects?
|
||||||
|
// Further investigation is needed...
|
||||||
|
|
||||||
|
if (gUseLegacySD)
|
||||||
Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_CRITTER_4 << 4 | NATURE_CHANNEL_CRITTER_5,
|
Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_CRITTER_4 << 4 | NATURE_CHANNEL_CRITTER_5,
|
||||||
CHANNEL_IO_PORT_1, 1);
|
CHANNEL_IO_PORT_1, 1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user