Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions soh/include/z64audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ typedef struct {
/* 0x1C */ u16 unk_1C;
/* 0x1E */ u16 unk_1E;
struct OggOpusFile* opusFile; // Only for streamed opus audio
uintptr_t opusSampleAddr; // sample opusFile was opened for
} NoteSynthesisState; // size = 0x20

typedef struct {
Expand Down
1 change: 1 addition & 0 deletions soh/soh/mixer.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ struct OggOpusFile;

void aOPUSdecImpl(void* source_addr, uint16_t dest_addr, uint16_t nbytes, struct OggOpusFile** decState, int32_t pos,
uint32_t size);
void aOPUSFree(struct OggOpusFile* opusFile);

#define aSegment(pkt, s, b) \
do { \
Expand Down
3 changes: 2 additions & 1 deletion soh/src/code/audio_playback.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "global.h"
#include "soh/ResourceManagerHelpers.h"
#include "soh/mixer.h"

extern bool gUseLegacySD;

Expand Down Expand Up @@ -150,7 +151,6 @@ void Audio_NoteInit(Note* note) {
note->noteSubEu = gDefaultNoteSub;
}

extern void aOPUSFree(struct OggOpusFile* opusFile);
void Audio_NoteDisable(Note* note) {
if (note->noteSubEu.bitField0.needsInit == true) {
note->noteSubEu.bitField0.needsInit = false;
Expand All @@ -166,6 +166,7 @@ void Audio_NoteDisable(Note* note) {
if (note->synthesisState.opusFile != NULL) {
aOPUSFree(note->synthesisState.opusFile);
note->synthesisState.opusFile = NULL;
note->synthesisState.opusSampleAddr = 0;
}
}

Expand Down
7 changes: 7 additions & 0 deletions soh/src/code/audio_synthesis.c
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,13 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS

// 2S2H [Port] [Custom audio] Handle decoding OPUS data
if (audioFontSample->codec == CODEC_OPUS) {
// A note reused for another streamed sample keeps the decoder its predecessor opened,
// so the previous track carries on playing under the new note.
if (synthState->opusFile != NULL && synthState->opusSampleAddr != sampleAddr) {
aOPUSFree(synthState->opusFile);
synthState->opusFile = NULL;
}
synthState->opusSampleAddr = sampleAddr;
aOPUSdecImpl(sampleAddr, DMEM_UNCOMPRESSED_NOTE + s5, bytesToRead, &synthState->opusFile,
synthState->samplePosInt, audioFontSample->fileSize);
} else {
Expand Down
Loading