From 630c814f0cf5d47be7082ae80a5a08251d6cc854 Mon Sep 17 00:00:00 2001 From: louist103 <35883445+louist103@users.noreply.github.com> Date: Wed, 30 Apr 2025 21:34:15 -0400 Subject: [PATCH] Format and fix mixer for Windows --- soh/soh/OTRGlobals.cpp | 4 +- soh/soh/mixer.c | 3 +- .../resource/importer/AudioSampleFactory.cpp | 3 +- .../resource/importer/AudioSampleFactory.h | 20 +-- .../resource/importer/AudioSequenceFactory.h | 16 +-- .../resource/importer/AudioSoundFontFactory.h | 32 ++--- soh/soh/resource/type/AudioSample.cpp | 24 ++-- soh/soh/resource/type/AudioSample.h | 96 ++++++------- soh/soh/resource/type/AudioSequence.cpp | 20 +-- soh/soh/resource/type/AudioSequence.h | 38 ++--- soh/soh/resource/type/AudioSoundFont.cpp | 36 ++--- soh/soh/resource/type/AudioSoundFont.h | 136 +++++++++--------- soh/src/code/audio_load.c | 4 +- soh/src/code/audio_synthesis.c | 39 +++-- 14 files changed, 234 insertions(+), 237 deletions(-) diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 0d40d670c..2bdcabfb5 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -418,12 +418,12 @@ void OTRGlobals::Initialize() { RESOURCE_FORMAT_BINARY, "AudioSoundFont", static_cast(SOH::ResourceType::SOH_AudioSoundFont), 2); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_XML, - "SoundFont", static_cast(SOH::ResourceType::SOH_AudioSoundFont), 0); + "SoundFont", static_cast(SOH::ResourceType::SOH_AudioSoundFont), 0); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "AudioSequence", static_cast(SOH::ResourceType::SOH_AudioSequence), 2); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_XML, - "Sequence", static_cast(SOH::ResourceType::SOH_AudioSequence), 0); + "Sequence", static_cast(SOH::ResourceType::SOH_AudioSequence), 0); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Background", static_cast(SOH::ResourceType::SOH_Background), 0); diff --git a/soh/soh/mixer.c b/soh/soh/mixer.c index d01a9bede..1646d1a07 100644 --- a/soh/soh/mixer.c +++ b/soh/soh/mixer.c @@ -16,7 +16,6 @@ #define ROUND_UP_8(v) (((v) + 7) & ~7) #define ROUND_DOWN_16(v) ((v) & ~0xf) - #define DMEM_BUF_SIZE (0x1000 - 0x3C0 - 0x40) #define BUF_U8(a) (rspa.buf.as_u8 + ((a)-0x3C0)) #define BUF_S16(a) (rspa.buf.as_s16 + ((a)-0x3C0) / sizeof(int16_t)) @@ -38,7 +37,7 @@ static struct { uint16_t filter_count; int16_t filter[8]; - __attribute__((aligned(16))) union { + union { int16_t as_s16[DMEM_BUF_SIZE / sizeof(int16_t)]; uint8_t as_u8[DMEM_BUF_SIZE]; } buf; diff --git a/soh/soh/resource/importer/AudioSampleFactory.cpp b/soh/soh/resource/importer/AudioSampleFactory.cpp index 99f2e558e..88b94bcd8 100644 --- a/soh/soh/resource/importer/AudioSampleFactory.cpp +++ b/soh/soh/resource/importer/AudioSampleFactory.cpp @@ -346,8 +346,7 @@ uint8_t ResourceFactoryXMLAudioSampleV0::CodecStrToInt(const char* str, const ch return CODEC_S16; } else { char buff[2048]; - snprintf(buff, 2048, - "Invalid codec in %s. Got %s, expected ADPCM, S8, S16MEM, ADPCMSMALL, REVERB, S16.", file, + snprintf(buff, 2048, "Invalid codec in %s. Got %s, expected ADPCM, S8, S16MEM, ADPCMSMALL, REVERB, S16.", file, str); throw std::runtime_error(buff); } diff --git a/soh/soh/resource/importer/AudioSampleFactory.h b/soh/soh/resource/importer/AudioSampleFactory.h index 665abff0a..6b738a768 100644 --- a/soh/soh/resource/importer/AudioSampleFactory.h +++ b/soh/soh/resource/importer/AudioSampleFactory.h @@ -6,18 +6,18 @@ namespace SOH { class ResourceFactoryBinaryAudioSampleV2 final : public Ship::ResourceFactoryBinary { - public: - std::shared_ptr ReadResource(std::shared_ptr file, - std::shared_ptr initData) override; - }; + public: + std::shared_ptr ReadResource(std::shared_ptr file, + std::shared_ptr initData) override; +}; class ResourceFactoryXMLAudioSampleV0 final : public Ship::ResourceFactoryXML { - public: - std::shared_ptr ReadResource(std::shared_ptr file, - std::shared_ptr initData) override; + public: + std::shared_ptr ReadResource(std::shared_ptr file, + std::shared_ptr initData) override; - private: - static uint8_t CodecStrToInt(const char* str, const char* file); - }; + private: + static uint8_t CodecStrToInt(const char* str, const char* file); +}; } // namespace SOH diff --git a/soh/soh/resource/importer/AudioSequenceFactory.h b/soh/soh/resource/importer/AudioSequenceFactory.h index dc479418e..a3d6080eb 100644 --- a/soh/soh/resource/importer/AudioSequenceFactory.h +++ b/soh/soh/resource/importer/AudioSequenceFactory.h @@ -6,15 +6,15 @@ namespace SOH { class ResourceFactoryBinaryAudioSequenceV2 final : public Ship::ResourceFactoryBinary { - public: - std::shared_ptr ReadResource(std::shared_ptr file, - std::shared_ptr initData) override; - }; + public: + std::shared_ptr ReadResource(std::shared_ptr file, + std::shared_ptr initData) override; +}; class ResourceFactoryXMLAudioSequenceV0 final : public Ship::ResourceFactoryXML { - public: - std::shared_ptr ReadResource(std::shared_ptr file, - std::shared_ptr initData) override; - }; + public: + std::shared_ptr ReadResource(std::shared_ptr file, + std::shared_ptr initData) override; +}; } // namespace SOH diff --git a/soh/soh/resource/importer/AudioSoundFontFactory.h b/soh/soh/resource/importer/AudioSoundFontFactory.h index fa2f7b615..70a73822e 100644 --- a/soh/soh/resource/importer/AudioSoundFontFactory.h +++ b/soh/soh/resource/importer/AudioSoundFontFactory.h @@ -7,24 +7,24 @@ namespace SOH { class ResourceFactoryBinaryAudioSoundFontV2 final : public Ship::ResourceFactoryBinary { - public: - std::shared_ptr ReadResource(std::shared_ptr file, - std::shared_ptr initData) override; - }; + public: + std::shared_ptr ReadResource(std::shared_ptr file, + std::shared_ptr initData) override; +}; class ResourceFactoryXMLSoundFontV0 final : public Ship::ResourceFactoryXML { - public: - std::shared_ptr ReadResource(std::shared_ptr file, - std::shared_ptr initData) override; - static int8_t MediumStrToInt(const char* str, const char* file); - static int8_t CachePolicyToInt(const char* str, const char* file); + public: + std::shared_ptr ReadResource(std::shared_ptr file, + std::shared_ptr initData) override; + static int8_t MediumStrToInt(const char* str, const char* file); + static int8_t CachePolicyToInt(const char* str, const char* file); - private: - void ParseDrums(AudioSoundFont* soundFont, tinyxml2::XMLElement* element); - void ParseInstruments(AudioSoundFont* soundFont, tinyxml2::XMLElement* element); - void ParseSfxTable(AudioSoundFont* soundFont, tinyxml2::XMLElement* element); - std::vector ParseEnvelopes(AudioSoundFont* soundFont, tinyxml2::XMLElement* element, - unsigned int* count); - }; + private: + void ParseDrums(AudioSoundFont* soundFont, tinyxml2::XMLElement* element); + void ParseInstruments(AudioSoundFont* soundFont, tinyxml2::XMLElement* element); + void ParseSfxTable(AudioSoundFont* soundFont, tinyxml2::XMLElement* element); + std::vector ParseEnvelopes(AudioSoundFont* soundFont, tinyxml2::XMLElement* element, + unsigned int* count); +}; } // namespace SOH diff --git a/soh/soh/resource/type/AudioSample.cpp b/soh/soh/resource/type/AudioSample.cpp index 17effa130..b4a539757 100644 --- a/soh/soh/resource/type/AudioSample.cpp +++ b/soh/soh/resource/type/AudioSample.cpp @@ -1,19 +1,19 @@ #include "AudioSample.h" namespace SOH { - AudioSample::~AudioSample() { - if (sample.book != nullptr && sample.book->book != nullptr) { - delete[] sample.book->book; - } - if (sample.sampleAddr != nullptr) { - delete[] sample.sampleAddr; - } +AudioSample::~AudioSample() { + if (sample.book != nullptr && sample.book->book != nullptr) { + delete[] sample.book->book; } - Sample* AudioSample::GetPointer() { - return &sample; + if (sample.sampleAddr != nullptr) { + delete[] sample.sampleAddr; } +} +Sample* AudioSample::GetPointer() { + return &sample; +} - size_t AudioSample::GetPointerSize() { - return sizeof(Sample); - } +size_t AudioSample::GetPointerSize() { + return sizeof(Sample); +} } // namespace SOH \ No newline at end of file diff --git a/soh/soh/resource/type/AudioSample.h b/soh/soh/resource/type/AudioSample.h index 77399b485..84e623781 100644 --- a/soh/soh/resource/type/AudioSample.h +++ b/soh/soh/resource/type/AudioSample.h @@ -5,56 +5,56 @@ #include namespace SOH { - typedef struct { - /* 0x00 */ u32 start; - /* 0x04 */ u32 end; - /* 0x08 */ u32 count; - /* 0x0C */ char unk_0C[0x4]; - /* 0x10 */ s16 state[16]; // only exists if count != 0. 8-byte aligned - } AdpcmLoop; // size = 0x30 (or 0x10) +typedef struct { + /* 0x00 */ u32 start; + /* 0x04 */ u32 end; + /* 0x08 */ u32 count; + /* 0x0C */ char unk_0C[0x4]; + /* 0x10 */ s16 state[16]; // only exists if count != 0. 8-byte aligned +} AdpcmLoop; // size = 0x30 (or 0x10) - typedef struct { - /* 0x00 */ s32 order; - /* 0x04 */ s32 npredictors; - /* 0x08 */ s16* book; // size 8 * order * npredictors. 8-byte aligned - } AdpcmBook; // s +typedef struct { + /* 0x00 */ s32 order; + /* 0x04 */ s32 npredictors; + /* 0x08 */ s16* book; // size 8 * order * npredictors. 8-byte aligned +} AdpcmBook; // s - typedef struct Sample { - union { - struct { - ///* 0x0 */ u32 unk_0 : 1; - /* 0x0 */ u32 codec : 4; // The state of compression or decompression, See `SampleCodec` - /* 0x0 */ u32 medium : 2; // Medium where sample is currently stored. See `SampleMedium` - /* 0x0 */ u32 unk_bit26 : 1; - /* 0x0 */ u32 isRelocated : 1; // Has the sample header been relocated (offsets to pointers) - }; - u32 asU32; +typedef struct Sample { + union { + struct { + ///* 0x0 */ u32 unk_0 : 1; + /* 0x0 */ u32 codec : 4; // The state of compression or decompression, See `SampleCodec` + /* 0x0 */ u32 medium : 2; // Medium where sample is currently stored. See `SampleMedium` + /* 0x0 */ u32 unk_bit26 : 1; + /* 0x0 */ u32 isRelocated : 1; // Has the sample header been relocated (offsets to pointers) }; - /* 0x1 */ u32 size; // Size of the sample - u32 fileSize; - /* 0x4 */ u8* sampleAddr; // Raw sample data. Offset from the start of the sample bank or absolute address to either - // rom or ram - /* 0x8 */ AdpcmLoop* - loop; // Adpcm loop parameters used by the sample. Offset from the start of the sound font / pointer to ram - /* 0xC */ AdpcmBook* - book; // Adpcm book parameters used by the sample. Offset from the start of the sound font / pointer to ram - } Sample; // size = 0x10 - - class AudioSample : public Ship::Resource { - public: - using Resource::Resource; - - AudioSample() : Resource(std::shared_ptr()) { - } - ~AudioSample(); - - Sample* GetPointer(); - size_t GetPointerSize(); - - Sample sample; - AdpcmLoop loop; - AdpcmBook book; - // Only applies to streamed audio - float tuning = -1.0f; + u32 asU32; }; + /* 0x1 */ u32 size; // Size of the sample + u32 fileSize; + /* 0x4 */ u8* sampleAddr; // Raw sample data. Offset from the start of the sample bank or absolute address to either + // rom or ram + /* 0x8 */ AdpcmLoop* + loop; // Adpcm loop parameters used by the sample. Offset from the start of the sound font / pointer to ram + /* 0xC */ AdpcmBook* + book; // Adpcm book parameters used by the sample. Offset from the start of the sound font / pointer to ram +} Sample; // size = 0x10 + +class AudioSample : public Ship::Resource { + public: + using Resource::Resource; + + AudioSample() : Resource(std::shared_ptr()) { + } + ~AudioSample(); + + Sample* GetPointer(); + size_t GetPointerSize(); + + Sample sample; + AdpcmLoop loop; + AdpcmBook book; + // Only applies to streamed audio + float tuning = -1.0f; +}; }; // namespace SOH \ No newline at end of file diff --git a/soh/soh/resource/type/AudioSequence.cpp b/soh/soh/resource/type/AudioSequence.cpp index 1d84ee738..040fbf124 100644 --- a/soh/soh/resource/type/AudioSequence.cpp +++ b/soh/soh/resource/type/AudioSequence.cpp @@ -2,17 +2,17 @@ namespace SOH { - Sequence* AudioSequence::GetPointer() { - return &sequence; - } +Sequence* AudioSequence::GetPointer() { + return &sequence; +} - size_t AudioSequence::GetPointerSize() { - return sizeof(Sequence); - } +size_t AudioSequence::GetPointerSize() { + return sizeof(Sequence); +} - AudioSequence::~AudioSequence() { - delete[] sequence.seqData; - sequence.seqData = nullptr; - } +AudioSequence::~AudioSequence() { + delete[] sequence.seqData; + sequence.seqData = nullptr; +} } // namespace SOH \ No newline at end of file diff --git a/soh/soh/resource/type/AudioSequence.h b/soh/soh/resource/type/AudioSequence.h index 9ca59043f..b76645dee 100644 --- a/soh/soh/resource/type/AudioSequence.h +++ b/soh/soh/resource/type/AudioSequence.h @@ -5,27 +5,27 @@ namespace SOH { - typedef struct { - char* seqData; - uint32_t seqDataSize; - uint16_t seqNumber; - uint8_t medium; - uint8_t cachePolicy; - uint32_t numFonts; - uint8_t fonts[16]; - } Sequence; +typedef struct { + char* seqData; + uint32_t seqDataSize; + uint16_t seqNumber; + uint8_t medium; + uint8_t cachePolicy; + uint32_t numFonts; + uint8_t fonts[16]; +} Sequence; - class AudioSequence : public Ship::Resource { - public: - using Resource::Resource; +class AudioSequence : public Ship::Resource { + public: + using Resource::Resource; - AudioSequence() : Resource(std::shared_ptr()) { - } - ~AudioSequence(); + AudioSequence() : Resource(std::shared_ptr()) { + } + ~AudioSequence(); - Sequence* GetPointer(); - size_t GetPointerSize(); + Sequence* GetPointer(); + size_t GetPointerSize(); - Sequence sequence; - }; + Sequence sequence; +}; }; // namespace SOH \ No newline at end of file diff --git a/soh/soh/resource/type/AudioSoundFont.cpp b/soh/soh/resource/type/AudioSoundFont.cpp index a30df1567..da95bf574 100644 --- a/soh/soh/resource/type/AudioSoundFont.cpp +++ b/soh/soh/resource/type/AudioSoundFont.cpp @@ -2,27 +2,27 @@ namespace SOH { - AudioSoundFont::~AudioSoundFont() { - for (auto i : instrumentAddresses) { - if (i != nullptr) { - delete[] i->envelope; - delete i; - } - } - - for (auto d : drumAddresses) { - if (d != nullptr) { - delete[] d->envelope; - delete d; - } +AudioSoundFont::~AudioSoundFont() { + for (auto i : instrumentAddresses) { + if (i != nullptr) { + delete[] i->envelope; + delete i; } } - SoundFont* AudioSoundFont::GetPointer() { - return &soundFont; + for (auto d : drumAddresses) { + if (d != nullptr) { + delete[] d->envelope; + delete d; + } } +} - size_t AudioSoundFont::GetPointerSize() { - return sizeof(SoundFont); - } +SoundFont* AudioSoundFont::GetPointer() { + return &soundFont; +} + +size_t AudioSoundFont::GetPointerSize() { + return sizeof(SoundFont); +} } // namespace SOH \ No newline at end of file diff --git a/soh/soh/resource/type/AudioSoundFont.h b/soh/soh/resource/type/AudioSoundFont.h index 048b1ed29..e387ede5f 100644 --- a/soh/soh/resource/type/AudioSoundFont.h +++ b/soh/soh/resource/type/AudioSoundFont.h @@ -8,74 +8,74 @@ namespace SOH { - typedef struct { - /* 0x0 */ s16 delay; - /* 0x2 */ s16 arg; - } AdsrEnvelope; // size = 0x4 +typedef struct { + /* 0x0 */ s16 delay; + /* 0x2 */ s16 arg; +} AdsrEnvelope; // size = 0x4 - typedef struct { - /* 0x00 */ Sample* sample; - /* 0x04 */ union { - u32 tuningAsU32; - f32 tuning; // frequency scale factor - }; - } SoundFontSound; // size = 0x8 - - typedef struct { - /* 0x00 */ u8 loaded; - /* 0x01 */ u8 normalRangeLo; - /* 0x02 */ u8 normalRangeHi; - /* 0x03 */ u8 releaseRate; - /* 0x04 */ AdsrEnvelope* envelope; - /* 0x08 */ SoundFontSound lowNotesSound; - /* 0x10 */ SoundFontSound normalNotesSound; - /* 0x18 */ SoundFontSound highNotesSound; - } Instrument; // size = 0x20 - - typedef struct { - /* 0x00 */ u8 releaseRate; - /* 0x01 */ u8 pan; - /* 0x02 */ u8 loaded; - /* 0x04 */ SoundFontSound sound; - /* 0x14 */ AdsrEnvelope* envelope; - } Drum; // size = 0x14 - - typedef struct { - /* 0x00 */ u8 numInstruments; - /* 0x01 */ u8 numDrums; - /* 0x02 */ u8 sampleBankId1; - /* 0x03 */ u8 sampleBankId2; - /* 0x04 */ u16 numSfx; - /* 0x08 */ Instrument** instruments; - /* 0x0C */ Drum** drums; - /* 0x10 */ SoundFontSound* soundEffects; - s32 fntIndex; - } SoundFont; // size = 0x14 - - class AudioSoundFont : public Ship::Resource { - public: - using Resource::Resource; - - AudioSoundFont() : Resource(std::shared_ptr()) { - } - ~AudioSoundFont(); - - SoundFont* GetPointer(); - size_t GetPointerSize(); - - int8_t medium; - int8_t cachePolicy; - uint16_t data1; - uint16_t data2; - uint16_t data3; - - std::vector drumAddresses; - std::vector> drumEnvelopeArrays; - - std::vector instrumentAddresses; - - std::vector soundEffects; - - SoundFont soundFont; +typedef struct { + /* 0x00 */ Sample* sample; + /* 0x04 */ union { + u32 tuningAsU32; + f32 tuning; // frequency scale factor }; +} SoundFontSound; // size = 0x8 + +typedef struct { + /* 0x00 */ u8 loaded; + /* 0x01 */ u8 normalRangeLo; + /* 0x02 */ u8 normalRangeHi; + /* 0x03 */ u8 releaseRate; + /* 0x04 */ AdsrEnvelope* envelope; + /* 0x08 */ SoundFontSound lowNotesSound; + /* 0x10 */ SoundFontSound normalNotesSound; + /* 0x18 */ SoundFontSound highNotesSound; +} Instrument; // size = 0x20 + +typedef struct { + /* 0x00 */ u8 releaseRate; + /* 0x01 */ u8 pan; + /* 0x02 */ u8 loaded; + /* 0x04 */ SoundFontSound sound; + /* 0x14 */ AdsrEnvelope* envelope; +} Drum; // size = 0x14 + +typedef struct { + /* 0x00 */ u8 numInstruments; + /* 0x01 */ u8 numDrums; + /* 0x02 */ u8 sampleBankId1; + /* 0x03 */ u8 sampleBankId2; + /* 0x04 */ u16 numSfx; + /* 0x08 */ Instrument** instruments; + /* 0x0C */ Drum** drums; + /* 0x10 */ SoundFontSound* soundEffects; + s32 fntIndex; +} SoundFont; // size = 0x14 + +class AudioSoundFont : public Ship::Resource { + public: + using Resource::Resource; + + AudioSoundFont() : Resource(std::shared_ptr()) { + } + ~AudioSoundFont(); + + SoundFont* GetPointer(); + size_t GetPointerSize(); + + int8_t medium; + int8_t cachePolicy; + uint16_t data1; + uint16_t data2; + uint16_t data3; + + std::vector drumAddresses; + std::vector> drumEnvelopeArrays; + + std::vector instrumentAddresses; + + std::vector soundEffects; + + SoundFont soundFont; +}; }; // namespace SOH diff --git a/soh/src/code/audio_load.c b/soh/src/code/audio_load.c index 5ceb474fa..81f67f9c0 100644 --- a/soh/src/code/audio_load.c +++ b/soh/src/code/audio_load.c @@ -892,7 +892,7 @@ AudioTable* AudioLoad_GetLoadTable(s32 tableType) { } void AudioLoad_RelocateFont(s32 fontId, SoundFontData* mem, RelocInfo* relocInfo) { -return; + return; uintptr_t reloc; uintptr_t reloc2; Instrument* inst; @@ -1354,7 +1354,7 @@ void AudioLoad_Init(void* heap, size_t heapSize) { int customSeqListSize = 0; char** seqList = ResourceMgr_ListFiles("audio/sequences*", &seqListSize); char** customSeqList = ResourceMgr_ListFiles("custom/music/*", &customSeqListSize); - sequenceMapSize = (size_t)(seqListSize + customSeqListSize ); + sequenceMapSize = (size_t)(seqListSize + customSeqListSize); sequenceMap = malloc((sequenceMapSize + 0xF) * sizeof(char*)); gAudioContext.seqLoadStatus = malloc(sequenceMapSize); diff --git a/soh/src/code/audio_synthesis.c b/soh/src/code/audio_synthesis.c index a9f6b2f69..abd657e0d 100644 --- a/soh/src/code/audio_synthesis.c +++ b/soh/src/code/audio_synthesis.c @@ -853,27 +853,26 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS s5 = samplesLenAdjusted; goto skip; case CODEC_S16: - case CODEC_OPUS: - AudioSynth_ClearBuffer(cmd++, DMEM_UNCOMPRESSED_NOTE, - (samplesLenAdjusted + 16) * 2); - flags = A_CONTINUE; - skipBytes = 0; - size_t bytesToRead; - nSamplesProcessed += samplesLenAdjusted; + case CODEC_OPUS: + AudioSynth_ClearBuffer(cmd++, DMEM_UNCOMPRESSED_NOTE, (samplesLenAdjusted + 16) * 2); + flags = A_CONTINUE; + skipBytes = 0; + size_t bytesToRead; + nSamplesProcessed += samplesLenAdjusted; - if (((synthState->samplePosInt * 2) + (samplesLenAdjusted)*2) < audioFontSample->size) { - bytesToRead = (samplesLenAdjusted)*2; - } else { - bytesToRead = audioFontSample->size - (synthState->samplePosInt * 2); - } - // 2S2H [Port] [Custom audio] Handle decoding OPUS data - if (audioFontSample->codec == CODEC_OPUS) { - aOPUSdecImpl(sampleAddr, DMEM_UNCOMPRESSED_NOTE, bytesToRead, &synthState->opusFile, - synthState->samplePosInt, audioFontSample->fileSize); - } else { - aLoadBuffer(cmd++, sampleAddr + (synthState->samplePosInt * 2), DMEM_UNCOMPRESSED_NOTE, - bytesToRead); - } + if (((synthState->samplePosInt * 2) + (samplesLenAdjusted)*2) < audioFontSample->size) { + bytesToRead = (samplesLenAdjusted)*2; + } else { + bytesToRead = audioFontSample->size - (synthState->samplePosInt * 2); + } + // 2S2H [Port] [Custom audio] Handle decoding OPUS data + if (audioFontSample->codec == CODEC_OPUS) { + aOPUSdecImpl(sampleAddr, DMEM_UNCOMPRESSED_NOTE, bytesToRead, &synthState->opusFile, + synthState->samplePosInt, audioFontSample->fileSize); + } else { + aLoadBuffer(cmd++, sampleAddr + (synthState->samplePosInt * 2), DMEM_UNCOMPRESSED_NOTE, + bytesToRead); + } goto skip; case CODEC_REVERB: