Merge branch 'zapd_audio_support' into zelda64

This commit is contained in:
Kevin Alexis Contreras 2022-06-16 23:09:50 -05:00
commit bb90be6748
16 changed files with 127 additions and 59 deletions

View File

@ -30,7 +30,7 @@ void OTRExporter_Audio::WriteSampleEntryReference(ZAudio* audio, SampleEntry* en
void OTRExporter_Audio::WriteSampleEntry(SampleEntry* entry, BinaryWriter* writer) void OTRExporter_Audio::WriteSampleEntry(SampleEntry* entry, BinaryWriter* writer)
{ {
WriteHeader(nullptr, "", writer, Ship::ResourceType::AudioSample); WriteHeader(nullptr, "", writer, Ship::ResourceType::AudioSample, Ship::Version::Rachael);
writer->Write(entry->codec); writer->Write(entry->codec);
writer->Write(entry->medium); writer->Write(entry->medium);
@ -82,7 +82,7 @@ void OTRExporter_Audio::Save(ZResource* res, const fs::path& outPath, BinaryWrit
{ {
ZAudio* audio = (ZAudio*)res; ZAudio* audio = (ZAudio*)res;
WriteHeader(res, outPath, writer, Ship::ResourceType::Audio); WriteHeader(res, outPath, writer, Ship::ResourceType::Audio, Ship::Version::Rachael);
// Write Samples as individual files // Write Samples as individual files
for (auto pair : audio->samples) for (auto pair : audio->samples)
@ -115,7 +115,7 @@ void OTRExporter_Audio::Save(ZResource* res, const fs::path& outPath, BinaryWrit
MemoryStream* fntStream = new MemoryStream(); MemoryStream* fntStream = new MemoryStream();
BinaryWriter fntWriter = BinaryWriter(fntStream); BinaryWriter fntWriter = BinaryWriter(fntStream);
WriteHeader(nullptr, "", &fntWriter, Ship::ResourceType::AudioSoundFont); WriteHeader(nullptr, "", &fntWriter, Ship::ResourceType::AudioSoundFont, Ship::Version::Rachael);
fntWriter.Write((uint32_t)i); fntWriter.Write((uint32_t)i);
fntWriter.Write(audio->soundFontTable[i].medium); fntWriter.Write(audio->soundFontTable[i].medium);
@ -174,17 +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... WriteHeader(nullptr, "", &seqWriter, Ship::ResourceType::AudioSequence, Ship::Version::Rachael);
seqWriter.Write((uint32_t)seq.size());
seqWriter.Write(seq.data(), seq.size());
seqWriter.Write((uint8_t)i); 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()); seqWriter.Write((uint32_t)audio->fontIndices[i].size());
for (int k = 0; k < audio->fontIndices[i].size(); k++) for (int k = 0; k < audio->fontIndices[i].size(); k++)
seqWriter.Write((uint8_t)audio->fontIndices[i][k]); seqWriter.Write((uint8_t)audio->fontIndices[i][k]);
seqWriter.Write(seq.data(), seq.size());
std::string fName = OTRExporter_DisplayList::GetPathToRes(res, StringHelper::Sprintf("sequences/%s", audio->seqNames[i].c_str())); std::string fName = OTRExporter_DisplayList::GetPathToRes(res, StringHelper::Sprintf("sequences/%s", audio->seqNames[i].c_str()));
AddFile(fName, seqStream->ToVector()); AddFile(fName, seqStream->ToVector());
} }

View File

@ -1,7 +1,7 @@
#include "Exporter.h" #include "Exporter.h"
#include "VersionInfo.h" #include "VersionInfo.h"
void OTRExporter::WriteHeader(ZResource* res, const fs::path& outPath, BinaryWriter* writer, Ship::ResourceType resType) void OTRExporter::WriteHeader(ZResource* res, const fs::path& outPath, BinaryWriter* writer, Ship::ResourceType resType, Ship::Version resVersion)
{ {
writer->Write((uint8_t)Endianess::Little); // 0x00 writer->Write((uint8_t)Endianess::Little); // 0x00
writer->Write((uint8_t)0); // 0x01 writer->Write((uint8_t)0); // 0x01
@ -9,7 +9,8 @@ void OTRExporter::WriteHeader(ZResource* res, const fs::path& outPath, BinaryWri
writer->Write((uint8_t)0); // 0x03 writer->Write((uint8_t)0); // 0x03
writer->Write((uint32_t)resType); // 0x04 writer->Write((uint32_t)resType); // 0x04
writer->Write((uint32_t)MAJOR_VERSION); // 0x08 //writer->Write((uint32_t)MAJOR_VERSION); // 0x08
writer->Write((uint32_t)resVersion); // 0x08
writer->Write((uint64_t)0xDEADBEEFDEADBEEF); // id, 0x0C writer->Write((uint64_t)0xDEADBEEFDEADBEEF); // id, 0x0C
writer->Write((uint32_t)resourceVersions[resType]); // 0x10 writer->Write((uint32_t)resourceVersions[resType]); // 0x10
writer->Write((uint64_t)0); // ROM CRC, 0x14 writer->Write((uint64_t)0); // ROM CRC, 0x14

View File

@ -4,9 +4,10 @@
//#include "OTRExporter.h" //#include "OTRExporter.h"
#include <Utils/BinaryWriter.h> #include <Utils/BinaryWriter.h>
#include <Resource.h> #include <Resource.h>
#include "VersionInfo.h"
class OTRExporter : public ZResourceExporter class OTRExporter : public ZResourceExporter
{ {
protected: protected:
static void WriteHeader(ZResource* res, const fs::path& outPath, BinaryWriter* writer, Ship::ResourceType resType); static void WriteHeader(ZResource* res, const fs::path& outPath, BinaryWriter* writer, Ship::ResourceType resType, Ship::Version resVersion = MAJOR_VERSION);
}; };

View File

@ -344,7 +344,6 @@ void ZAudio::ParseRawData()
//int gSequenceTableOffset = 0x1386A0; //int gSequenceTableOffset = 0x1386A0;
//int gSampleBankTableOffset = 0x138D90; //int gSampleBankTableOffset = 0x138D90;
//int gSequenceFontTableOffset = 0x1384E0; //int gSequenceFontTableOffset = 0x1384E0;
// NTSC 1.0 // NTSC 1.0
//int gSoundFontTableOffset = 0x1026A0; //int gSoundFontTableOffset = 0x1026A0;
//int gSequenceTableOffset = 0x102AD0; //int gSequenceTableOffset = 0x102AD0;

View File

@ -2,7 +2,30 @@
namespace Ship namespace Ship
{ {
void AudioSampleV1::ParseFileBinary(BinaryReader* reader, Resource* res) void AudioSequenceV2::ParseFileBinary(BinaryReader* reader, Resource* res)
{
AudioSequence* seq = (AudioSequence*)res;
ResourceFile::ParseFileBinary(reader, res);
int seqDataSize = reader->ReadInt32();
seq->seqData.reserve(seqDataSize);
for (int i = 0; i < seqDataSize; i++)
seq->seqData.push_back(reader->ReadUByte());
seq->seqNumber = reader->ReadUByte();
seq->medium = reader->ReadUByte();
seq->cachePolicy = reader->ReadUByte();
int numFonts = reader->ReadInt32();
for (int i = 0; i < numFonts; i++)
seq->fonts.push_back(reader->ReadUByte());
}
void AudioSampleV2::ParseFileBinary(BinaryReader* reader, Resource* res)
{ {
AudioSample* entry = (AudioSample*)res; AudioSample* entry = (AudioSample*)res;
@ -15,7 +38,7 @@ namespace Ship
int dataSize = reader->ReadInt32(); int dataSize = reader->ReadInt32();
for (uint32_t i = 0; i < dataSize; i++) for (int i = 0; i < dataSize; i++)
entry->data.push_back(reader->ReadUByte()); entry->data.push_back(reader->ReadUByte());
entry->loop.start = reader->ReadUInt32(); entry->loop.start = reader->ReadUInt32();
@ -24,7 +47,7 @@ namespace Ship
int loopStateCnt = reader->ReadUInt32(); int loopStateCnt = reader->ReadUInt32();
for (uint32_t i = 0; i < loopStateCnt; i++) for (int i = 0; i < loopStateCnt; i++)
entry->loop.states.push_back(reader->ReadInt16()); entry->loop.states.push_back(reader->ReadInt16());
entry->book.order = reader->ReadInt32(); entry->book.order = reader->ReadInt32();
@ -32,11 +55,11 @@ namespace Ship
int bookSize = reader->ReadInt32(); int bookSize = reader->ReadInt32();
for (uint32_t i = 0; i < bookSize; i++) for (int i = 0; i < bookSize; i++)
entry->book.books.push_back(reader->ReadInt16()); entry->book.books.push_back(reader->ReadInt16());
} }
void AudioSoundFontV1::ParseFileBinary(BinaryReader* reader, Resource* res) void AudioSoundFontV2::ParseFileBinary(BinaryReader* reader, Resource* res)
{ {
AudioSoundFont* soundFont = (AudioSoundFont*)res; AudioSoundFont* soundFont = (AudioSoundFont*)res;
@ -137,7 +160,7 @@ namespace Ship
} }
} }
std::vector<AdsrEnvelope*> AudioSoundFontV1::ReadEnvelopeData(BinaryReader* reader) std::vector<AdsrEnvelope*> AudioSoundFontV2::ReadEnvelopeData(BinaryReader* reader)
{ {
std::vector<AdsrEnvelope*> envelopes; std::vector<AdsrEnvelope*> envelopes;
@ -155,7 +178,7 @@ namespace Ship
return envelopes; return envelopes;
} }
void AudioV1::ParseFileBinary(BinaryReader* reader, Resource* res) void AudioV2::ParseFileBinary(BinaryReader* reader, Resource* res)
{ {
Audio* audio = (Audio*)res; Audio* audio = (Audio*)res;

View File

@ -57,26 +57,43 @@ namespace Ship
SoundFontEntry* highNotesSound = nullptr; SoundFontEntry* highNotesSound = nullptr;
}; };
class AudioSoundFontV1 : public ResourceFile class AudioSequenceV2 : public ResourceFile
{ {
public: public:
void ParseFileBinary(BinaryReader* reader, Resource* res) override; void ParseFileBinary(BinaryReader* reader, Resource* res) override;
static std::vector<AdsrEnvelope*> ReadEnvelopeData(BinaryReader* reader); static std::vector<AdsrEnvelope*> ReadEnvelopeData(BinaryReader* reader);
}; };
class AudioSampleV1 : public ResourceFile class AudioSoundFontV2 : public ResourceFile
{ {
public: public:
void ParseFileBinary(BinaryReader* reader, Resource* res) override; void ParseFileBinary(BinaryReader* reader, Resource* res) override;
static std::vector<AdsrEnvelope*> ReadEnvelopeData(BinaryReader* reader);
}; };
class AudioV1 : public ResourceFile class AudioSampleV2 : public ResourceFile
{ {
public: public:
void ParseFileBinary(BinaryReader* reader, Resource* res) override; void ParseFileBinary(BinaryReader* reader, Resource* res) override;
}; };
struct AudioSoundFont : public Resource class AudioV2 : public ResourceFile
{
public:
void ParseFileBinary(BinaryReader* reader, Resource* res) override;
};
class AudioSequence : public Resource
{
public:
std::vector<char> seqData;
uint8_t seqNumber;
uint8_t medium;
uint8_t cachePolicy;
std::vector<uint8_t> fonts;
};
class AudioSoundFont : public Resource
{ {
public: public:
uint32_t ptr; uint32_t ptr;
@ -110,10 +127,5 @@ namespace Ship
class Audio : public Resource class Audio : public Resource
{ {
public: public:
//std::vector<AudioTableEntry> soundFontTable;
//std::vector<AudioTableEntry> sequenceTable;
//std::vector<AudioTableEntry> sampleBankTable;
//std::vector<char*> sequences;
//std::vector<SampleEntry*> samples;
}; };
} }

View File

@ -9,9 +9,9 @@ namespace Ship
switch (version) switch (version)
{ {
case Version::Roy: case Version::Rachael:
{ {
AudioV1 audioFac = AudioV1(); AudioV2 audioFac = AudioV2();
audioFac.ParseFileBinary(reader, audio); audioFac.ParseFileBinary(reader, audio);
} }
break; break;
@ -30,10 +30,9 @@ namespace Ship
switch (version) switch (version)
{ {
case Version::Deckard: // OTRTODO: Remove this line after we merge in that refactor case Version::Rachael:
case Version::Roy:
{ {
AudioSampleV1 audioSampleFac = AudioSampleV1(); AudioSampleV2 audioSampleFac = AudioSampleV2();
audioSampleFac.ParseFileBinary(reader, audioSample); audioSampleFac.ParseFileBinary(reader, audioSample);
} }
break; break;
@ -52,10 +51,9 @@ namespace Ship
switch (version) switch (version)
{ {
case Version::Deckard: // OTRTODO: Remove this line after we merge in that refactor case Version::Rachael:
case Version::Roy:
{ {
AudioSoundFontV1 audioSFFac = AudioSoundFontV1(); AudioSoundFontV2 audioSFFac = AudioSoundFontV2();
audioSFFac.ParseFileBinary(reader, audioSF); audioSFFac.ParseFileBinary(reader, audioSF);
} }
break; break;
@ -66,4 +64,25 @@ namespace Ship
return audioSF; return audioSF;
} }
AudioSequence* AudioSequenceFactory::ReadAudioSequence(BinaryReader* reader)
{
AudioSequence* audioSeq = new AudioSequence();
Version version = (Version)reader->ReadUInt32();
switch (version)
{
case Version::Rachael:
{
AudioSequenceV2 audioSeqFac = AudioSequenceV2();
audioSeqFac.ParseFileBinary(reader, audioSeq);
}
break;
default:
// VERSION NOT SUPPORTED
break;
}
return audioSeq;
}
}; };

View File

@ -20,4 +20,10 @@ namespace Ship
public: public:
static AudioSoundFont* ReadAudioSoundFont(BinaryReader* reader); static AudioSoundFont* ReadAudioSoundFont(BinaryReader* reader);
}; };
class AudioSequenceFactory
{
public:
static AudioSequence* ReadAudioSequence(BinaryReader* reader);
};
} }

View File

@ -29,9 +29,9 @@ namespace Ship
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
reader->ReadByte(); reader->ReadByte();
// OTRTODO: Setup the binaryreader to use the resource's endianess // OTRTODO: Setup the binaryreader to use the resource's endianess
ResourceType resourceType = (ResourceType)reader->ReadUInt32(); ResourceType resourceType = (ResourceType)reader->ReadUInt32();
Resource* result = nullptr; Resource* result = nullptr;
@ -94,6 +94,9 @@ namespace Ship
case ResourceType::AudioSoundFont: case ResourceType::AudioSoundFont:
result = AudioSoundFontFactory::ReadAudioSoundFont(reader.get()); result = AudioSoundFontFactory::ReadAudioSoundFont(reader.get());
break; break;
case ResourceType::AudioSequence:
result = AudioSequenceFactory::ReadAudioSequence(reader.get());
break;
default: default:
// RESOURCE TYPE NOT SUPPORTED // RESOURCE TYPE NOT SUPPORTED
break; break;

View File

@ -30,9 +30,10 @@ namespace Ship
Array = 0x4F415252, // OARR Array = 0x4F415252, // OARR
Text = 0x4F545854, // OTXT Text = 0x4F545854, // OTXT
Blob = 0x4F424C42, // OBLB Blob = 0x4F424C42, // OBLB
Audio = 'OAUD', Audio = 0x4F415544, // OAUD
AudioSample = 'OSMP', AudioSample = 0x4F534D50, // OSMP
AudioSoundFont = 'OSFT', AudioSoundFont = 0x4F534654, // OSFT
AudioSequence = 0x4F534551, // OSEQ
}; };
enum class DataType enum class DataType

View File

@ -113,7 +113,6 @@
<Sequence Name="108_Timed_Minigame"/> <Sequence Name="108_Timed_Minigame"/>
<Sequence Name="109_Cutscene_Effects"/> <Sequence Name="109_Cutscene_Effects"/>
</Sequences> </Sequences>
<Samples Bank="0"> <Samples Bank="0">
<Sample Name="Bird Chirp 1"> <Sample Name="Bird Chirp 1">
<Offset Version="MQDebug" At="0"/> <Offset Version="MQDebug" At="0"/>
@ -1432,7 +1431,6 @@
<Offset Version="MQDebug" At="0"/> <Offset Version="MQDebug" At="0"/>
</Sample> </Sample>
</Samples> </Samples>
<Samples Bank="3"> <Samples Bank="3">
<Sample Name="Low Rumbling"> <Sample Name="Low Rumbling">
<Offset Version="MQDebug" At="0"/> <Offset Version="MQDebug" At="0"/>
@ -1552,4 +1550,4 @@
<Soundfont Name="21_Zoras_Domain" Index="21"/> <Soundfont Name="21_Zoras_Domain" Index="21"/>
</Audio> </Audio>
</File> </File>
</Root> </Root>

View File

@ -125,7 +125,8 @@ typedef struct {
/* 0x08 */ s16 book[1]; // size 8 * order * npredictors. 8-byte aligned /* 0x08 */ s16 book[1]; // size 8 * order * npredictors. 8-byte aligned
} AdpcmBook; // size >= 0x8 } AdpcmBook; // size >= 0x8
typedef struct { typedef struct
{
union { union {
struct { struct {
/* 0x00 */ u32 codec : 4; /* 0x00 */ u32 codec : 4;

View File

@ -568,21 +568,20 @@ extern "C" Vtx* ResourceMgr_LoadVtxByName(const char* path)
extern "C" SequenceData ResourceMgr_LoadSeqByName(const char* path) extern "C" SequenceData ResourceMgr_LoadSeqByName(const char* path)
{ {
auto file = OTRGlobals::Instance->context->GetResourceManager()->LoadFile(path).get(); auto file = std::static_pointer_cast<Ship::AudioSequence>(OTRGlobals::Instance->context->GetResourceManager()
->LoadResource(path));
char* data = file->buffer.get();
SequenceData seqData; SequenceData seqData;
seqData.seqNumber = data[1]; seqData.seqNumber = file->seqNumber;
seqData.medium = data[2]; seqData.medium = file->medium;
seqData.cachePolicy = data[3]; seqData.cachePolicy = file->cachePolicy;
seqData.numFonts = data[4]; seqData.numFonts = file->fonts.size();
for (int i = 0; i < seqData.numFonts; i++) for (int i = 0; i < seqData.numFonts; i++)
seqData.fonts[i] = data[5 + i]; seqData.fonts[i] = file->fonts[i];
seqData.seqData = &data[5 + seqData.numFonts]; seqData.seqData = file->seqData.data();
seqData.seqDataSize = file->dwBufferSize - 5 - seqData.numFonts; seqData.seqDataSize = file->seqData.size();
return seqData; return seqData;
} }
@ -785,7 +784,9 @@ extern "C" SoundFont* ResourceMgr_LoadAudioSoundFont(const char* path) {
} }
soundFontC->instruments[i] = inst; soundFontC->instruments[i] = inst;
} else { }
else
{
soundFontC->instruments[i] = nullptr; soundFontC->instruments[i] = nullptr;
} }
} }

View File

@ -76,7 +76,8 @@ void* sUnusedHandler = NULL;
s32 gAudioContextInitalized = false; s32 gAudioContextInitalized = false;
char* sequenceMap[512]; char* sequenceMap[256];
char* fontMap[256];
uintptr_t fontStart; uintptr_t fontStart;
uint32_t fontOffsets[8192]; uint32_t fontOffsets[8192];
@ -389,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--;
} }
@ -609,6 +611,7 @@ s32 AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) {
} }
seqData = AudioLoad_SyncLoadSeq(seqId); seqData = AudioLoad_SyncLoadSeq(seqId);
if (seqData == NULL) { if (seqData == NULL) {
return 0; return 0;
} }
@ -897,7 +900,6 @@ void AudioLoad_RelocateFont(s32 fontId, SoundFontData* mem, RelocInfo* relocInfo
SoundFontSound* sfx; SoundFontSound* sfx;
s32 i; s32 i;
SoundFont* sf = NULL; SoundFont* sf = NULL;
s32 numDrums = 0; s32 numDrums = 0;
s32 numInstruments = 0; s32 numInstruments = 0;
s32 numSfx = 0; s32 numSfx = 0;

View File

@ -356,6 +356,7 @@ Instrument* Audio_GetInstrumentInner(s32 fontId, s32 instId) {
} }
return inst; return inst;
} }

View File

@ -5,7 +5,6 @@
extern bool gUseLegacySD; extern bool gUseLegacySD;
extern char* sequenceMap[256]; extern char* sequenceMap[256];
char* fontMap[256];
#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)