diff --git a/assets/yaml/us/rev1/ast_audio.yaml b/assets/yaml/us/rev1/ast_audio.yaml index 43d2af2b..1a595c90 100644 --- a/assets/yaml/us/rev1/ast_audio.yaml +++ b/assets/yaml/us/rev1/ast_audio.yaml @@ -1,8 +1,30 @@ -audio_seq: - { type: BLOB, offset: 0xDEA20, size: 0x3ACF0, symbol: gAudioSeq } - -audio_bank: - { type: BLOB, offset: 0x119710, size: 0x1E020, symbol: gAudioBank } +:config: + force: true + header: + code: + - '#include "sys.h"' + - '#include "sf64audio_provisional.h"' -audio_table: - { type: BLOB, offset: 0x137730, size: 0x73C580, symbol: gAudioTable } \ No newline at end of file +audio_setup: + type: NAUDIO:V1:AUDIO_SETUP + audio_seq: + size: 0x3ACF0 + offset: 0xDEA20 + audio_bank: + size: 0x1E020 + offset: 0x119710 + audio_table: + size: 0x73C580 + offset: 0x137730 + +audio_sample_bank_table: + { type: NAUDIO:V1:AUDIO_TABLE, format: SAMPLE, offset: 0xC4210, symbol: gSampleBankTableInit } + +audio_seq_table: + { type: NAUDIO:V1:AUDIO_TABLE, format: SEQUENCE, offset: 0xC4260, symbol: gSeqTableInit } + +audio_soundfont_table: + { type: NAUDIO:V1:AUDIO_TABLE, format: SOUNDFONT, offset: 0xC4690, symbol: gSoundFontTableInit } + +audio_seq_font_table: + { type: ARRAY, count: 283, array_type: u8, offset: 0xC48B0, symbol: gSeqFontTableInit } \ No newline at end of file diff --git a/include/sf64audio_provisional.h b/include/sf64audio_provisional.h index aa6dbe6c..9a81cb5d 100644 --- a/include/sf64audio_provisional.h +++ b/include/sf64audio_provisional.h @@ -840,8 +840,8 @@ typedef struct { typedef struct { /* 0x00 */ AudioTableBase base; - /* 0x10 */ AudioTableEntry entries[]; // (dynamic size) -} AudioTable; // size >= 0x20 + /* 0x10 */ AudioTableEntry* entries; // (dynamic size) +} AudioTable; // size >= 0x20 typedef struct SampleDma { /* 0x00 */ u8* ramAddr; @@ -1091,10 +1091,10 @@ bool AudioThread_ResetComplete(void); void AudioThread_ResetAudioHeap(s32); void AudioThread_Init(void); -extern AudioTable gSampleBankTableInit; -extern AudioTable gSeqTableInit; -extern AudioTable gSoundFontTableInit; -extern u8 gSeqFontTableInit[]; +// extern AudioTable gSampleBankTableInit; +// extern AudioTable gSeqTableInit; +// extern AudioTable gSoundFontTableInit; +// extern u8 gSeqFontTableInit[]; extern AudioSpec gAudioSpecs[]; extern s16 gSeqTicksPerBeat; diff --git a/src/audio/audio_load.c b/src/audio/audio_load.c index e08f62f3..a385da5d 100644 --- a/src/audio/audio_load.c +++ b/src/audio/audio_load.c @@ -390,11 +390,11 @@ void AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) { s32 fontId; s32 i; - seqId = AudioLoad_GetLoadTableIndex(SEQUENCE_TABLE, seqId); +// seqId = AudioLoad_GetLoadTableIndex(SEQUENCE_TABLE, seqId); AudioSeq_SequencePlayerDisable(&gSeqPlayers[playerIdx]); - index = *((u16*) gSeqFontTable + seqId); + index = BSWAP16(*((u16*) gSeqFontTable + seqId)); numFonts = gSeqFontTable[index++]; fontId = 0xFF; @@ -419,12 +419,12 @@ void AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) { void* AudioLoad_SyncLoadSeq(s32 seqId) { AudioTable* table = AudioLoad_GetLoadTable(SEQUENCE_TABLE); - s32 seqIdx = AudioLoad_GetLoadTableIndex(SEQUENCE_TABLE, seqId); - - return Audio_LoadBlob(gAudioSeq, table->entries[seqIdx].romAddr); + return ResourceGetDataByCrc((uint64_t) table->entries[seqId].romAddr); } void* AudioLoad_SyncLoadSampleBank(u32 sampleBankId, s32* outMedium) { + return NULL; + void* ramAddr; AudioTable* sampleBankTable = AudioLoad_GetLoadTable(2); s32 cachePolicy; @@ -433,7 +433,7 @@ void* AudioLoad_SyncLoadSampleBank(u32 sampleBankId, s32* outMedium) { sampleBankId = AudioLoad_GetLoadTableIndex(SAMPLE_TABLE, sampleBankId); gSampleFontLoadStatus[sampleBankId] = 2; - return Audio_LoadBlob(gAudioTable, sampleBankTable->entries[sampleBankId].romAddr); +// return Audio_LoadBlob(gAudioTable, sampleBankTable->entries[sampleBankId].romAddr); ramAddr = AudioLoad_SearchCaches(2, sampleBankId); if (ramAddr != NULL) { @@ -468,7 +468,7 @@ void* AudioLoad_SyncLoadFont(s32 fontId) { s32 didAllocate; SampleBankRelocInfo relocInfo; - fontId = AudioLoad_GetLoadTableIndex(FONT_TABLE, fontId); + // fontId = AudioLoad_GetLoadTableIndex(FONT_TABLE, fontId); sampleBankId1 = gSoundFontList[fontId].sampleBankId1; sampleBankId2 = gSoundFontList[fontId].sampleBankId2; @@ -522,13 +522,11 @@ void* AudioLoad_SyncLoad(u32 tableType, u32 id, s32* didAllocate) { switch (tableType) { case SEQUENCE_TABLE: gSeqLoadStatus[id] = LOAD_STATUS_COMPLETE; - - //ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_PERSISTENT, id); - return Audio_LoadBlob(gAudioSeq, table->entries[id].romAddr); + return ResourceGetDataByCrc((uint64_t) table->entries[id].romAddr); case FONT_TABLE: gFontLoadStatus[id] = LOAD_STATUS_COMPLETE; //ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_PERSISTENT, id); - return Audio_LoadFont(table->entries[id]); + return Audio_LoadFont(table->entries[id], id); case SAMPLE_TABLE: loadStatus = 0; break; @@ -613,7 +611,7 @@ void AudioLoad_RelocateFont(s32 fontId, uintptr_t fontBaseAddr, SampleBankRelocI // } AudioTable* table = AudioLoad_GetLoadTable(FONT_TABLE); printf("fontId: %d\n", fontId); - SoundFont* font = Audio_LoadFont(table->entries[fontId]); + SoundFont* font = Audio_LoadFont(table->entries[fontId], fontId); gSoundFontList[fontId] = *font; } @@ -713,16 +711,16 @@ void* AudioLoad_AsyncLoadInner(s32 tableType, s32 id, s32 nChunks, s32 retData, case SEQUENCE_TABLE: gSeqLoadStatus[id] = LOAD_STATUS_COMPLETE; osSendMesg(retQueue, OS_MESG_32(retData << 0x18), OS_MESG_NOBLOCK); - return Audio_LoadBlob(gAudioSeq, table->entries[id].romAddr); + return ResourceGetDataByCrc((uint64_t) table->entries[id].romAddr); case FONT_TABLE: gFontLoadStatus[id] = LOAD_STATUS_COMPLETE; printf("fontId: %d\n", id); osSendMesg(retQueue, OS_MESG_32(retData << 0x18), OS_MESG_NOBLOCK); - return Audio_LoadFont(table->entries[id]); + return Audio_LoadFont(table->entries[id], id); case SAMPLE_TABLE: gSampleFontLoadStatus[id] = LOAD_STATUS_COMPLETE; // LTODO: Validate this - return Audio_LoadSample(table->entries[id].romAddr, table->entries[id], id); +// return Audio_LoadSample(table->entries[id].romAddr, table->entries[id], id); return NULL; } @@ -873,10 +871,10 @@ void AudioLoad_Init(void) { gAudioResetStep = 1; AudioHeap_ResetStep(); - gSequenceTable = &gSeqTableInit; - gSoundFontTable = &gSoundFontTableInit; - gSampleBankTable = &gSampleBankTableInit; - gSeqFontTable = gSeqFontTableInit; + gSequenceTable = SEGMENTED_TO_VIRTUAL(gSeqTableInit); + gSoundFontTable = SEGMENTED_TO_VIRTUAL(gSoundFontTableInit); + gSampleBankTable = SEGMENTED_TO_VIRTUAL(gSampleBankTableInit); + gSeqFontTable = SEGMENTED_TO_VIRTUAL(gSeqFontTableInit); gNumSequences = gSequenceTable->base.numEntries; // AudioLoad_InitTable(gSequenceTable, LOAD_ASSET(gAudioSeq), gSequenceMedium); diff --git a/src/audio/audio_playback.c b/src/audio/audio_playback.c index 064052f4..6f9ef7a2 100644 --- a/src/audio/audio_playback.c +++ b/src/audio/audio_playback.c @@ -175,7 +175,7 @@ Instrument* Audio_GetInstrument(s32 fontId, s32 instId) { //fontId = 7; if(gSoundFontList[fontId].instruments == NULL){ - gSoundFontList[fontId] = *Audio_LoadFont(gSoundFontTable->entries[fontId]); + gSoundFontList[fontId] = *Audio_LoadFont(gSoundFontTable->entries[fontId], fontId); } if ((gFontLoadStatus[fontId] < 2) != 0) { @@ -199,7 +199,7 @@ Drum* Audio_GetDrum(s32 fontId, s32 drumId) { // LTODO: Remove this if(gSoundFontList[fontId].drums == NULL){ - gSoundFontList[fontId] = *Audio_LoadFont(gSoundFontTable->entries[fontId]); + gSoundFontList[fontId] = *Audio_LoadFont(gSoundFontTable->entries[fontId], fontId); } if ((gFontLoadStatus[fontId] < 2) != 0) { diff --git a/src/audio/audio_seqplayer.c b/src/audio/audio_seqplayer.c index b3c8d7ca..7832890b 100644 --- a/src/audio/audio_seqplayer.c +++ b/src/audio/audio_seqplayer.c @@ -1,5 +1,6 @@ #include "sys.h" #include "sf64audio_provisional.h" +#include "endianness.h" #define PORTAMENTO_IS_SPECIAL(x) ((x).mode & 0x80) #define PORTAMENTO_MODE(x) ((x).mode & ~0x80) @@ -1014,7 +1015,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { case 0xC6: cmd = AudioSeq_ScriptReadU8(state); - sp52 = ((u16*) gSeqFontTable)[seqPlayer->seqId]; + sp52 = BSWAP16(((u16*) gSeqFontTable)[seqPlayer->seqId]); loBits = gSeqFontTable[sp52]; cmd = gSeqFontTable[sp52 + loBits - cmd]; diff --git a/src/audio/audio_synthesis.c b/src/audio/audio_synthesis.c index 507719a3..f547eb86 100644 --- a/src/audio/audio_synthesis.c +++ b/src/audio/audio_synthesis.c @@ -669,9 +669,8 @@ Acmd* AudioSynth_Update(Acmd* aList, s32* cmdCount, s16* aiBufStart, s32 aiBufLe //if (gAudioBufferParams.ticksPerUpdate > 3 && gGameState != GSTATE_PLAY) return; aCmdPtr = aList; for (i = gAudioBufferParams.ticksPerUpdate; i > 0; i--) { - - AudioSeq_ProcessSequences(i - 1); - AudioSynth_SyncSampleStates(gAudioBufferParams.ticksPerUpdate - i); + AudioSeq_ProcessSequences(i - 1); + AudioSynth_SyncSampleStates(gAudioBufferParams.ticksPerUpdate - i); } aiBufPtr = aiBufStart; diff --git a/src/audio/audio_tables.c b/src/audio/audio_tables.c index 5b99609c..6d0336a2 100644 --- a/src/audio/audio_tables.c +++ b/src/audio/audio_tables.c @@ -1,6 +1,7 @@ #include "sys.h" #include "sf64audio_provisional.h" +#if 0 AudioTable gSampleBankTableInit = { { 4, 0, 0 }, { @@ -98,7 +99,7 @@ AudioTable gSoundFontTableInit = { // clang-format off -u8 gSeqFontTableInit[283] = { +u8 gSeqFontTableInitOriginal[283] = { // Offset into this table for sequence sound font list AS_BYTES(132), AS_BYTES(134), AS_BYTES(155), AS_BYTES(157), AS_BYTES(159), AS_BYTES(161), AS_BYTES(163), AS_BYTES(165), AS_BYTES(167), AS_BYTES(169), AS_BYTES(171), AS_BYTES(173), AS_BYTES(175), AS_BYTES(177), @@ -123,3 +124,5 @@ u8 gSeqFontTableInit[283] = { }; // clang-format on + +#endif \ No newline at end of file diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index 9b93d8c2..7f737ce3 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -17,6 +17,16 @@ #include "resource/importers/SkeletonFactory.h" #include "resource/importers/Vec3fFactory.h" #include "resource/importers/Vec3sFactory.h" + +#include "resource/importers/audio/AudioTableFactory.h" +#include "resource/importers/audio/BookFactory.h" +#include "resource/importers/audio/DrumFactory.h" +#include "resource/importers/audio/EnvelopeFactory.h" +#include "resource/importers/audio/InstrumentFactory.h" +#include "resource/importers/audio/LoopFactory.h" +#include "resource/importers/audio/SampleFactory.h" +#include "resource/importers/audio/SoundFontFactory.h" + #include "port/interpolation/FrameInterpolation.h" #include #include @@ -25,6 +35,7 @@ #include #include #include "audio/GameAudio.h" +#include "port/patches/DisplayListPatch.h" // #include "sf64audio_provisional.h" #include @@ -127,11 +138,36 @@ GameEngine::GameEngine() { loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Blob", static_cast(LUS::ResourceType::Blob), 0); + + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, + "AudioTable", static_cast(SF64::ResourceType::AudioTable), 0); + + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, + "AdpcmBook", static_cast(SF64::ResourceType::AdpcmBook), 0); + + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, + "Drum", static_cast(SF64::ResourceType::Drum), 0); + + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, + "Envelope", static_cast(SF64::ResourceType::Envelope), 0); + + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, + "Instrument", static_cast(SF64::ResourceType::Instrument), 0); + + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, + "AdpcmLoop", static_cast(SF64::ResourceType::AdpcmLoop), 0); + + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, + "Sample", static_cast(SF64::ResourceType::Sample), 1); + + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, + "SoundFont", static_cast(SF64::ResourceType::SoundFont), 0); } void GameEngine::Create() { const auto instance = Instance = new GameEngine(); instance->AudioInit(); + DisplayListPatch::Run(); GameUI::SetupGuiElements(); #if defined(__SWITCH__) || defined(__WIIU__) CVarRegisterInteger("gControlNav", 1); // always enable controller nav on switch/wii u diff --git a/src/port/patches/DisplayListPatch.cpp b/src/port/patches/DisplayListPatch.cpp new file mode 100644 index 00000000..75170e96 --- /dev/null +++ b/src/port/patches/DisplayListPatch.cpp @@ -0,0 +1,21 @@ +#include "DisplayListPatch.h" +#include + +std::unordered_map>> patches = { + // { ast_corneria_seg6_gfx_23420, { + // { 23, gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, 0x003C, 0x003C) } + // }} +}; + +void DisplayListPatch::Run() { + SPDLOG_INFO("Applying display list patches"); + + for(auto& entry : patches){ + auto data = (Gfx*) ResourceGetDataByName(entry.first); + for(auto& patch : entry.second){ + data[patch.first] = patch.second; + } + + SPDLOG_INFO("{} patched successfully!", entry.first); + } +} \ No newline at end of file diff --git a/src/port/patches/DisplayListPatch.h b/src/port/patches/DisplayListPatch.h new file mode 100644 index 00000000..ae469ce6 --- /dev/null +++ b/src/port/patches/DisplayListPatch.h @@ -0,0 +1,5 @@ +#pragma once +class DisplayListPatch { +public: + static void Run(); +}; diff --git a/src/port/resource/importers/audio/AudioTableFactory.cpp b/src/port/resource/importers/audio/AudioTableFactory.cpp new file mode 100644 index 00000000..a2798a2e --- /dev/null +++ b/src/port/resource/importers/audio/AudioTableFactory.cpp @@ -0,0 +1,38 @@ +#include "AudioTableFactory.h" +#include "port/resource/type/audio/AudioTable.h" +#include "../ResourceUtil.h" + +namespace SF64 { +std::shared_ptr ResourceFactoryBinaryAudioTableV0::ReadResource(std::shared_ptr file) { + if (!FileHasValidFormatAndReader(file)) { + return nullptr; + } + + auto table = std::make_shared(file->InitData); + auto reader = std::get>(file->Reader); + + int16_t med = reader->ReadInt16(); + uint32_t addr = reader->ReadUInt32(); + uint32_t count = reader->ReadUInt32(); + + for(size_t i = 0; i < count; i++){ + uint64_t crc = reader->ReadUInt64(); + uint32_t size = reader->ReadUInt32(); + int8_t medium = reader->ReadInt8(); + int8_t policy = reader->ReadInt8(); + int16_t sd1 = reader->ReadInt16(); + int16_t sd2 = reader->ReadInt16(); + int16_t sd3 = reader->ReadInt16(); + + table->mEntries.push_back({ + (uintptr_t) crc, + size, medium, policy, sd1, sd2, sd3 + }); + } + + table->mTable.base = { (int16_t)count, med, addr }; + table->mTable.entries = table->mEntries.data(); + + return table; +} +} // namespace LUS diff --git a/src/port/resource/importers/audio/AudioTableFactory.h b/src/port/resource/importers/audio/AudioTableFactory.h new file mode 100644 index 00000000..e27cbd79 --- /dev/null +++ b/src/port/resource/importers/audio/AudioTableFactory.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Resource.h" +#include "ResourceFactoryBinary.h" + +namespace SF64 { +class ResourceFactoryBinaryAudioTableV0 : public Ship::ResourceFactoryBinary { + public: + std::shared_ptr ReadResource(std::shared_ptr file) override; +}; +}; // namespace LUS diff --git a/src/port/resource/importers/audio/BookFactory.cpp b/src/port/resource/importers/audio/BookFactory.cpp new file mode 100644 index 00000000..88d05548 --- /dev/null +++ b/src/port/resource/importers/audio/BookFactory.cpp @@ -0,0 +1,24 @@ +#include "BookFactory.h" +#include "port/resource/type/audio/AdpcmBook.h" + +namespace SF64 { +std::shared_ptr ResourceFactoryBinaryAdpcmBookV0::ReadResource(std::shared_ptr file) { + if (!FileHasValidFormatAndReader(file)) { + return nullptr; + } + + auto book = std::make_shared(file->InitData); + auto reader = std::get>(file->Reader); + + book->mBook.order = reader->ReadUInt32(); + book->mBook.numPredictors = reader->ReadUInt32(); + uint32_t count = reader->ReadUInt32(); + + for(size_t i = 0; i < count; i++){ + book->mPages.push_back(reader->ReadInt16()); + } + + book->mBook.book = book->mPages.data(); + return book; +} +} // namespace LUS diff --git a/src/port/resource/importers/audio/BookFactory.h b/src/port/resource/importers/audio/BookFactory.h new file mode 100644 index 00000000..0207cd81 --- /dev/null +++ b/src/port/resource/importers/audio/BookFactory.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Resource.h" +#include "ResourceFactoryBinary.h" + +namespace SF64 { +class ResourceFactoryBinaryAdpcmBookV0 : public Ship::ResourceFactoryBinary { + public: + std::shared_ptr ReadResource(std::shared_ptr file) override; +}; +}; // namespace LUS diff --git a/src/port/resource/importers/audio/DrumFactory.cpp b/src/port/resource/importers/audio/DrumFactory.cpp new file mode 100644 index 00000000..ca53d468 --- /dev/null +++ b/src/port/resource/importers/audio/DrumFactory.cpp @@ -0,0 +1,24 @@ +#include "DrumFactory.h" +#include "../ResourceUtil.h" +#include "port/resource/type/audio/Drum.h" + +namespace SF64 { +std::shared_ptr ResourceFactoryBinaryDrumV0::ReadResource(std::shared_ptr file) { + if (!FileHasValidFormatAndReader(file)) { + return nullptr; + } + + auto drum = std::make_shared(file->InitData); + auto reader = std::get>(file->Reader); + + drum->mDrum.adsrDecayIndex = reader->ReadUByte(); + drum->mDrum.pan = reader->ReadUByte(); + drum->mDrum.isRelocated = reader->ReadUByte(); + drum->mDrum.tunedSample.sample = LoadChild(reader->ReadUInt64()); + drum->mDrum.tunedSample.tuning = reader->ReadFloat(); + drum->mDrum.envelope = LoadChild(reader->ReadUInt64()); + drum->mDrum.isRelocated = 1; + + return drum; +} +} // namespace LUS diff --git a/src/port/resource/importers/audio/DrumFactory.h b/src/port/resource/importers/audio/DrumFactory.h new file mode 100644 index 00000000..8b63febb --- /dev/null +++ b/src/port/resource/importers/audio/DrumFactory.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Resource.h" +#include "ResourceFactoryBinary.h" + +namespace SF64 { +class ResourceFactoryBinaryDrumV0 : public Ship::ResourceFactoryBinary { + public: + std::shared_ptr ReadResource(std::shared_ptr file) override; +}; +}; // namespace LUS diff --git a/src/port/resource/importers/audio/EnvelopeFactory.cpp b/src/port/resource/importers/audio/EnvelopeFactory.cpp new file mode 100644 index 00000000..1a3dfc60 --- /dev/null +++ b/src/port/resource/importers/audio/EnvelopeFactory.cpp @@ -0,0 +1,20 @@ +#include "EnvelopeFactory.h" +#include "port/resource/type/audio/Envelope.h" + +namespace SF64 { +std::shared_ptr ResourceFactoryBinaryEnvelopeV0::ReadResource(std::shared_ptr file) { + if (!FileHasValidFormatAndReader(file)) { + return nullptr; + } + + auto envelope = std::make_shared(file->InitData); + auto reader = std::get>(file->Reader); + + uint32_t count = reader->ReadUInt32(); + for(size_t i = 0; i < count; i++){ + envelope->mPoints.push_back({ reader->ReadInt16(), reader->ReadInt16() }); + } + + return envelope; +} +} // namespace LUS diff --git a/src/port/resource/importers/audio/EnvelopeFactory.h b/src/port/resource/importers/audio/EnvelopeFactory.h new file mode 100644 index 00000000..41107a4c --- /dev/null +++ b/src/port/resource/importers/audio/EnvelopeFactory.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Resource.h" +#include "ResourceFactoryBinary.h" + +namespace SF64 { +class ResourceFactoryBinaryEnvelopeV0 : public Ship::ResourceFactoryBinary { + public: + std::shared_ptr ReadResource(std::shared_ptr file) override; +}; +}; // namespace LUS diff --git a/src/port/resource/importers/audio/InstrumentFactory.cpp b/src/port/resource/importers/audio/InstrumentFactory.cpp new file mode 100644 index 00000000..357ef0c6 --- /dev/null +++ b/src/port/resource/importers/audio/InstrumentFactory.cpp @@ -0,0 +1,29 @@ +#include "InstrumentFactory.h" +#include "../ResourceUtil.h" +#include "port/resource/type/audio/Instrument.h" + +namespace SF64 { +std::shared_ptr ResourceFactoryBinaryInstrumentV0::ReadResource(std::shared_ptr file) { + if (!FileHasValidFormatAndReader(file)) { + return nullptr; + } + + auto instrument = std::make_shared(file->InitData); + auto reader = std::get>(file->Reader); + + instrument->mInstrument.isRelocated = reader->ReadUByte(); + instrument->mInstrument.normalRangeLo = reader->ReadUByte(); + instrument->mInstrument.normalRangeHi = reader->ReadUByte(); + instrument->mInstrument.adsrDecayIndex = reader->ReadUByte(); + instrument->mInstrument.envelope = LoadChild(reader->ReadUInt64()); + instrument->mInstrument.lowPitchTunedSample.sample = LoadChild(reader->ReadUInt64()); + instrument->mInstrument.lowPitchTunedSample.tuning = reader->ReadFloat(); + instrument->mInstrument.normalPitchTunedSample.sample = LoadChild(reader->ReadUInt64()); + instrument->mInstrument.normalPitchTunedSample.tuning = reader->ReadFloat(); + instrument->mInstrument.highPitchTunedSample.sample = LoadChild(reader->ReadUInt64()); + instrument->mInstrument.highPitchTunedSample.tuning = reader->ReadFloat(); + instrument->mInstrument.isRelocated = 1; + + return instrument; +} +} // namespace LUS diff --git a/src/port/resource/importers/audio/InstrumentFactory.h b/src/port/resource/importers/audio/InstrumentFactory.h new file mode 100644 index 00000000..ed99a5f2 --- /dev/null +++ b/src/port/resource/importers/audio/InstrumentFactory.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Resource.h" +#include "ResourceFactoryBinary.h" + +namespace SF64 { +class ResourceFactoryBinaryInstrumentV0 : public Ship::ResourceFactoryBinary { + public: + std::shared_ptr ReadResource(std::shared_ptr file) override; +}; +}; // namespace LUS diff --git a/src/port/resource/importers/audio/LoopFactory.cpp b/src/port/resource/importers/audio/LoopFactory.cpp new file mode 100644 index 00000000..f2dfca35 --- /dev/null +++ b/src/port/resource/importers/audio/LoopFactory.cpp @@ -0,0 +1,24 @@ +#include "LoopFactory.h" +#include "port/resource/type/audio/AdpcmLoop.h" + +namespace SF64 { +std::shared_ptr ResourceFactoryBinaryAdpcmLoopV0::ReadResource(std::shared_ptr file) { + if (!FileHasValidFormatAndReader(file)) { + return nullptr; + } + + auto loop = std::make_shared(file->InitData); + auto reader = std::get>(file->Reader); + + loop->mLoop.start = reader->ReadUInt32(); + loop->mLoop.end = reader->ReadUInt32(); + loop->mLoop.count = reader->ReadUInt32(); + if(loop->mLoop.count != 0){ + for(size_t i = 0; i < 16; i++){ + loop->mLoop.predictorState[i] = reader->ReadInt16(); + } + } + + return loop; +} +} // namespace LUS diff --git a/src/port/resource/importers/audio/LoopFactory.h b/src/port/resource/importers/audio/LoopFactory.h new file mode 100644 index 00000000..b244249e --- /dev/null +++ b/src/port/resource/importers/audio/LoopFactory.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Resource.h" +#include "ResourceFactoryBinary.h" + +namespace SF64 { +class ResourceFactoryBinaryAdpcmLoopV0 : public Ship::ResourceFactoryBinary { + public: + std::shared_ptr ReadResource(std::shared_ptr file) override; +}; +}; // namespace LUS diff --git a/src/port/resource/importers/audio/SampleFactory.cpp b/src/port/resource/importers/audio/SampleFactory.cpp new file mode 100644 index 00000000..ff89b227 --- /dev/null +++ b/src/port/resource/importers/audio/SampleFactory.cpp @@ -0,0 +1,28 @@ +#include "SampleFactory.h" +#include "../ResourceUtil.h" +#include "port/resource/type/audio/Sample.h" + +namespace SF64 { +std::shared_ptr ResourceFactoryBinarySampleV1::ReadResource(std::shared_ptr file) { + if (!FileHasValidFormatAndReader(file)) { + return nullptr; + } + + auto sample = std::make_shared(file->InitData); + auto reader = std::get>(file->Reader); + + sample->mSample.codec = reader->ReadUInt32(); + sample->mSample.medium = reader->ReadUInt32(); + sample->mSample.unk = reader->ReadUInt32(); + sample->mSample.size = reader->ReadUInt32(); + sample->mSample.loop = LoadChild(reader->ReadUInt64()); + sample->mSample.book = LoadChild(reader->ReadUInt64()); + sample->mSample.sampleAddr = new uint8_t[sample->mSample.size]; + reader->Read((char*) sample->mSample.sampleAddr, sample->mSample.size); + + sample->mSample.medium = 0; + sample->mSample.isRelocated = 1; + + return sample; +} +} // namespace LUS diff --git a/src/port/resource/importers/audio/SampleFactory.h b/src/port/resource/importers/audio/SampleFactory.h new file mode 100644 index 00000000..7a92fd1f --- /dev/null +++ b/src/port/resource/importers/audio/SampleFactory.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Resource.h" +#include "ResourceFactoryBinary.h" + +namespace SF64 { +class ResourceFactoryBinarySampleV1 : public Ship::ResourceFactoryBinary { + public: + std::shared_ptr ReadResource(std::shared_ptr file) override; +}; +}; // namespace LUS diff --git a/src/port/resource/importers/audio/SoundFontFactory.cpp b/src/port/resource/importers/audio/SoundFontFactory.cpp new file mode 100644 index 00000000..431f9410 --- /dev/null +++ b/src/port/resource/importers/audio/SoundFontFactory.cpp @@ -0,0 +1,32 @@ +#include "SoundFontFactory.h" +#include "../ResourceUtil.h" +#include "port/resource/type/audio/SoundFont.h" + +namespace SF64 { +std::shared_ptr ResourceFactoryBinarySoundFontV0::ReadResource(std::shared_ptr file) { + if (!FileHasValidFormatAndReader(file)) { + return nullptr; + } + + auto font = std::make_shared(file->InitData); + auto reader = std::get>(file->Reader); + + font->mFont.numInstruments = reader->ReadUByte(); + font->mFont.numDrums = reader->ReadUByte(); + font->mFont.sampleBankId1 = reader->ReadUByte(); + font->mFont.sampleBankId2 = reader->ReadUByte(); + + for(size_t i = 0; i < font->mFont.numInstruments; i++){ + font->mInstruments.push_back(LoadChild(reader->ReadUInt64())); + } + + for(size_t i = 0; i < font->mFont.numDrums; i++){ + font->mDrums.push_back(LoadChild(reader->ReadUInt64())); + } + + font->mFont.instruments = font->mInstruments.data(); + font->mFont.drums = font->mDrums.data(); + + return font; +} +} // namespace LUS diff --git a/src/port/resource/importers/audio/SoundFontFactory.h b/src/port/resource/importers/audio/SoundFontFactory.h new file mode 100644 index 00000000..04823a55 --- /dev/null +++ b/src/port/resource/importers/audio/SoundFontFactory.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Resource.h" +#include "ResourceFactoryBinary.h" + +namespace SF64 { +class ResourceFactoryBinarySoundFontV0 : public Ship::ResourceFactoryBinary { + public: + std::shared_ptr ReadResource(std::shared_ptr file) override; +}; +}; // namespace LUS diff --git a/src/port/resource/loaders/AudioLoader.cpp b/src/port/resource/loaders/AudioLoader.cpp index db1345dc..156d067b 100644 --- a/src/port/resource/loaders/AudioLoader.cpp +++ b/src/port/resource/loaders/AudioLoader.cpp @@ -6,8 +6,12 @@ #include #include #include -#include "test.c" +#ifdef OTR_AUDIO +extern "C" SoundFont* Audio_LoadFont(AudioTableEntry entry, uint32_t fontId) { + return (SoundFont*) ResourceGetDataByCrc((uint64_t) gSoundFontTable->entries[fontId].romAddr); +} +#else namespace fs = std::filesystem; std::unordered_map gAudioCache; @@ -56,7 +60,7 @@ EnvelopePoint* Audio_LoadEnvelope(uint32_t addr) { return envelopes; } -extern "C" SoundFont* Audio_LoadFont(AudioTableEntry entry) { +extern "C" SoundFont* Audio_LoadFont(AudioTableEntry entry, uint32_t fontId) { auto reader = Audio_MakeReader(gAudioBank, entry.romAddr); if(gAudioCache.contains(entry.romAddr)){ @@ -212,4 +216,5 @@ extern "C" Drum* Audio_LoadDrum(uint32_t addr, AudioTableEntry entry, uint32_t s drum->envelope = Audio_LoadEnvelope(entry.romAddr + reader.ReadUInt32()); return drum; -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/src/port/resource/loaders/AudioLoader.h b/src/port/resource/loaders/AudioLoader.h index 00d4178f..052d6875 100644 --- a/src/port/resource/loaders/AudioLoader.h +++ b/src/port/resource/loaders/AudioLoader.h @@ -3,18 +3,23 @@ #include #include "sf64audio_provisional.h" +#define OTR_AUDIO 1 + #ifdef __cplusplus extern "C" { #endif +#ifdef OTR_AUDIO +SoundFont* Audio_LoadFont(AudioTableEntry entry, uint32_t fontId); +#else char* Audio_LoadBlob(const char* resource, u32 offset); AdpcmBook* Audio_LoadBook(uint32_t addr); AdpcmLoop* Audio_LoadLoop(uint32_t addr); Instrument* Audio_LoadInstrument(uint32_t addr, AudioTableEntry entry, uint32_t sampleBankID); Drum* Audio_LoadDrum(uint32_t addr, AudioTableEntry entry, uint32_t sampleBankID); Sample* Audio_LoadSample(uint32_t addr, AudioTableEntry entry, uint32_t sampleBankID); -SoundFont* Audio_LoadFont(AudioTableEntry entry); - +SoundFont* Audio_LoadFont(AudioTableEntry entry, uint32_t fontId); +#endif #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/src/port/resource/type/ResourceType.h b/src/port/resource/type/ResourceType.h index c751281e..fdcc9103 100644 --- a/src/port/resource/type/ResourceType.h +++ b/src/port/resource/type/ResourceType.h @@ -17,5 +17,19 @@ enum class ResourceType { Vec3f = 0x56433346, // VC3F Vec3s = 0x56433353, // VC3S GenericArray = 0x47415252, // GARR + + // NAudio v0 + Bank = 0x42414E4B, // BANK + Sample = 0x41554643, // AIFC + Sequence = 0x53455143, // SEQC + + // NAudio v1 + SoundFont = 0x53464E54, // SFNT + Drum = 0x4452554D, // DRUM + Instrument = 0x494E5354, // INST + AdpcmLoop = 0x4150434C, // APCL + AdpcmBook = 0x41504342, // APCB + Envelope = 0x45564C50, // EVLP + AudioTable = 0x4154424C // ATBL }; } // namespace SOH diff --git a/src/port/resource/type/audio/AdpcmBook.cpp b/src/port/resource/type/audio/AdpcmBook.cpp new file mode 100644 index 00000000..517d08a1 --- /dev/null +++ b/src/port/resource/type/audio/AdpcmBook.cpp @@ -0,0 +1,11 @@ +#include "AdpcmBook.h" + +namespace SF64 { +AdpcmBookData* AdpcmBook::GetPointer() { + return &mBook; +} + +size_t AdpcmBook::GetPointerSize() { + return sizeof(AdpcmBookData) + sizeof(int16_t) * mPages.size(); +} +} \ No newline at end of file diff --git a/src/port/resource/type/audio/AdpcmBook.h b/src/port/resource/type/audio/AdpcmBook.h new file mode 100644 index 00000000..45b7cc2f --- /dev/null +++ b/src/port/resource/type/audio/AdpcmBook.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include + +namespace SF64 { +struct AdpcmBookData { + /* 0x00 */ int32_t order; + /* 0x04 */ int32_t numPredictors; + /* 0x08 */ int16_t* book; +}; + +class AdpcmBook : public Ship::Resource { + public: + using Resource::Resource; + + AdpcmBook() : Resource(std::shared_ptr()) {} + + AdpcmBookData* GetPointer(); + size_t GetPointerSize(); + + AdpcmBookData mBook; + std::vector mPages; +}; +} \ No newline at end of file diff --git a/src/port/resource/type/audio/AdpcmLoop.cpp b/src/port/resource/type/audio/AdpcmLoop.cpp new file mode 100644 index 00000000..cddac277 --- /dev/null +++ b/src/port/resource/type/audio/AdpcmLoop.cpp @@ -0,0 +1,11 @@ +#include "AdpcmLoop.h" + +namespace SF64 { +AdpcmLoopData* AdpcmLoop::GetPointer() { + return &mLoop; +} + +size_t AdpcmLoop::GetPointerSize() { + return sizeof(AdpcmLoopData); +} +} \ No newline at end of file diff --git a/src/port/resource/type/audio/AdpcmLoop.h b/src/port/resource/type/audio/AdpcmLoop.h new file mode 100644 index 00000000..85650754 --- /dev/null +++ b/src/port/resource/type/audio/AdpcmLoop.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include + +namespace SF64 { +struct AdpcmLoopData { + /* 0x00 */ uint32_t start; + /* 0x04 */ uint32_t end; + /* 0x08 */ uint32_t count; + /* 0x10 */ int16_t predictorState[16]; // only exists if count != 0. 8-byte aligned +}; + +class AdpcmLoop : public Ship::Resource { + public: + using Resource::Resource; + + AdpcmLoop() : Resource(std::shared_ptr()) {} + + AdpcmLoopData* GetPointer(); + size_t GetPointerSize(); + + AdpcmLoopData mLoop; +}; +} \ No newline at end of file diff --git a/src/port/resource/type/audio/AudioContext.h b/src/port/resource/type/audio/AudioContext.h new file mode 100644 index 00000000..a6851b2e --- /dev/null +++ b/src/port/resource/type/audio/AudioContext.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include "Sample.h" + +namespace SF64 { +struct TunedSample { + SampleData* sample; + float tuning; +}; + +enum class AudioTableType { + SAMPLE_TABLE, + SEQ_TABLE, + FONT_TABLE +}; +} \ No newline at end of file diff --git a/src/port/resource/type/audio/AudioTable.cpp b/src/port/resource/type/audio/AudioTable.cpp new file mode 100644 index 00000000..a072604e --- /dev/null +++ b/src/port/resource/type/audio/AudioTable.cpp @@ -0,0 +1,11 @@ +#include "AudioTable.h" + +namespace SF64 { +AudioTableData* AudioTable::GetPointer() { + return &mTable; +} + +size_t AudioTable::GetPointerSize() { + return sizeof(AudioTableData); +} +} \ No newline at end of file diff --git a/src/port/resource/type/audio/AudioTable.h b/src/port/resource/type/audio/AudioTable.h new file mode 100644 index 00000000..42fe8e29 --- /dev/null +++ b/src/port/resource/type/audio/AudioTable.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include + +namespace SF64 { +struct AudioTableBase { + /* 0x00 */ int16_t numEntries; + /* 0x02 */ int16_t unkMediumParam; + /* 0x04 */ uintptr_t romAddr; + /* 0x08 */ char pad[8]; +}; + +struct AudioTableEntry { + /* 0x00 */ uintptr_t romAddr; + /* 0x04 */ uint32_t size; + /* 0x08 */ int8_t medium; + /* 0x09 */ int8_t cachePolicy; + /* 0x0A */ int16_t shortData1; + /* 0x0C */ int16_t shortData2; + /* 0x0E */ int16_t shortData3; +}; // size = 0x10 + +struct AudioTableData { + /* 0x00 */ AudioTableBase base; + /* 0x10 */ AudioTableEntry* entries; +}; + +class AudioTable : public Ship::Resource { + public: + using Resource::Resource; + + AudioTable() : Resource(std::shared_ptr()) {} + + AudioTableData* GetPointer(); + size_t GetPointerSize(); + + AudioTableData mTable; + std::vector mEntries; +}; +} \ No newline at end of file diff --git a/src/port/resource/type/audio/Drum.cpp b/src/port/resource/type/audio/Drum.cpp new file mode 100644 index 00000000..df1ce8bf --- /dev/null +++ b/src/port/resource/type/audio/Drum.cpp @@ -0,0 +1,11 @@ +#include "Drum.h" + +namespace SF64 { +DrumData* Drum::GetPointer() { + return &mDrum; +} + +size_t Drum::GetPointerSize() { + return sizeof(DrumData); +} +} \ No newline at end of file diff --git a/src/port/resource/type/audio/Drum.h b/src/port/resource/type/audio/Drum.h new file mode 100644 index 00000000..44966cd8 --- /dev/null +++ b/src/port/resource/type/audio/Drum.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include "Envelope.h" +#include "AudioContext.h" + +namespace SF64 { +struct DrumData { + uint8_t adsrDecayIndex; + uint8_t pan; + uint8_t isRelocated; + TunedSample tunedSample; + EnvelopePointData* envelope; +}; + +class Drum : public Ship::Resource { + public: + using Resource::Resource; + + Drum() : Resource(std::shared_ptr()) {} + + DrumData* GetPointer(); + size_t GetPointerSize(); + + DrumData mDrum; +}; +} \ No newline at end of file diff --git a/src/port/resource/type/audio/Envelope.cpp b/src/port/resource/type/audio/Envelope.cpp new file mode 100644 index 00000000..3418d3af --- /dev/null +++ b/src/port/resource/type/audio/Envelope.cpp @@ -0,0 +1,11 @@ +#include "Envelope.h" + +namespace SF64 { +EnvelopePointData* Envelope::GetPointer() { + return mPoints.data(); +} + +size_t Envelope::GetPointerSize() { + return sizeof(EnvelopePointData) * mPoints.size(); +} +} \ No newline at end of file diff --git a/src/port/resource/type/audio/Envelope.h b/src/port/resource/type/audio/Envelope.h new file mode 100644 index 00000000..b2086cae --- /dev/null +++ b/src/port/resource/type/audio/Envelope.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +namespace SF64 { + +struct EnvelopePointData { + int16_t delay; + int16_t arg; +}; + +class Envelope : public Ship::Resource { + public: + using Resource::Resource; + + Envelope() : Resource(std::shared_ptr()) {} + + EnvelopePointData* GetPointer(); + size_t GetPointerSize(); + + std::vector mPoints; +}; +} \ No newline at end of file diff --git a/src/port/resource/type/audio/Instrument.cpp b/src/port/resource/type/audio/Instrument.cpp new file mode 100644 index 00000000..dbd0eb9e --- /dev/null +++ b/src/port/resource/type/audio/Instrument.cpp @@ -0,0 +1,11 @@ +#include "Instrument.h" + +namespace SF64 { +InstrumentData* Instrument::GetPointer() { + return &mInstrument; +} + +size_t Instrument::GetPointerSize() { + return sizeof(InstrumentData); +} +} \ No newline at end of file diff --git a/src/port/resource/type/audio/Instrument.h b/src/port/resource/type/audio/Instrument.h new file mode 100644 index 00000000..40b00391 --- /dev/null +++ b/src/port/resource/type/audio/Instrument.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include "Envelope.h" +#include "AudioContext.h" + +namespace SF64 { +struct InstrumentData { + uint8_t isRelocated; + uint8_t normalRangeLo; + uint8_t normalRangeHi; + uint8_t adsrDecayIndex; + EnvelopePointData* envelope; + TunedSample lowPitchTunedSample; + TunedSample normalPitchTunedSample; + TunedSample highPitchTunedSample; +}; + +class Instrument : public Ship::Resource { + public: + using Resource::Resource; + + Instrument() : Resource(std::shared_ptr()) {} + + InstrumentData* GetPointer(); + size_t GetPointerSize(); + + InstrumentData mInstrument; +}; +} \ No newline at end of file diff --git a/src/port/resource/type/audio/Sample.cpp b/src/port/resource/type/audio/Sample.cpp new file mode 100644 index 00000000..b8e514df --- /dev/null +++ b/src/port/resource/type/audio/Sample.cpp @@ -0,0 +1,11 @@ +#include "Sample.h" + +namespace SF64 { +SampleData* Sample::GetPointer() { + return &mSample; +} + +size_t Sample::GetPointerSize() { + return sizeof(mSample); +} +} \ No newline at end of file diff --git a/src/port/resource/type/audio/Sample.h b/src/port/resource/type/audio/Sample.h new file mode 100644 index 00000000..80c50cd7 --- /dev/null +++ b/src/port/resource/type/audio/Sample.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include +#include "Envelope.h" +#include "AdpcmLoop.h" +#include "AdpcmBook.h" + +namespace SF64 { +struct SampleData { + uint32_t codec : 4; + uint32_t medium : 2; + uint32_t unk : 1; + uint32_t isRelocated : 1; + uint32_t size : 24; + uint8_t* sampleAddr; + AdpcmLoopData* loop; + AdpcmBookData* book; +}; + +class Sample : public Ship::Resource { + public: + using Resource::Resource; + + Sample() : Resource(std::shared_ptr()) {} + + SampleData* GetPointer(); + size_t GetPointerSize(); + + SampleData mSample; +}; +} \ No newline at end of file diff --git a/src/port/resource/type/audio/SoundFont.cpp b/src/port/resource/type/audio/SoundFont.cpp new file mode 100644 index 00000000..01356f3e --- /dev/null +++ b/src/port/resource/type/audio/SoundFont.cpp @@ -0,0 +1,11 @@ +#include "SoundFont.h" + +namespace SF64 { +SoundFontData* SoundFont::GetPointer() { + return &mFont; +} + +size_t SoundFont::GetPointerSize() { + return sizeof(SoundFontData); +} +} \ No newline at end of file diff --git a/src/port/resource/type/audio/SoundFont.h b/src/port/resource/type/audio/SoundFont.h new file mode 100644 index 00000000..2801e254 --- /dev/null +++ b/src/port/resource/type/audio/SoundFont.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include "Instrument.h" +#include "Drum.h" + +namespace SF64 { +struct SoundFontData { + /* 0x00 */ uint8_t numInstruments; + /* 0x01 */ uint8_t numDrums; + /* 0x02 */ uint8_t sampleBankId1; + /* 0x03 */ uint8_t sampleBankId2; + /* 0x04 */ InstrumentData** instruments; + /* 0x08 */ DrumData** drums; +}; + +class SoundFont : public Ship::Resource { + public: + using Resource::Resource; + + SoundFont() : Resource(std::shared_ptr()) {} + + SoundFontData* GetPointer(); + size_t GetPointerSize(); + + SoundFontData mFont; + std::vector mInstruments; + std::vector mDrums; +}; +} \ No newline at end of file