diff options
Diffstat (limited to 'src/audio/lib')
| -rw-r--r-- | src/audio/lib/effects.c | 42 | ||||
| -rw-r--r-- | src/audio/lib/heap.c | 49 | ||||
| -rw-r--r-- | src/audio/lib/load.c | 19 | ||||
| -rw-r--r-- | src/audio/lib/playback.c | 42 | ||||
| -rw-r--r-- | src/audio/lib/seqplayer.c | 154 | ||||
| -rw-r--r-- | src/audio/lib/synthesis.c | 71 | ||||
| -rw-r--r-- | src/audio/lib/thread.c | 458 |
7 files changed, 416 insertions, 419 deletions
diff --git a/src/audio/lib/effects.c b/src/audio/lib/effects.c index 8de03887e..bbfcaf61a 100644 --- a/src/audio/lib/effects.c +++ b/src/audio/lib/effects.c @@ -113,8 +113,8 @@ f32 Audio_GetVibratoFreqScale(VibratoState* vib) { static f32 D_80130510 = 0.0f; static s32 D_80130514 = 0; f32 pitchChange; - f32 extent; - f32 invExtent; + f32 depth; + f32 invDepth; f32 result; f32 temp; SequenceChannel* channel = vib->channel; @@ -127,17 +127,17 @@ f32 Audio_GetVibratoFreqScale(VibratoState* vib) { //! @bug this probably meant to compare with gAudioCtx.sequenceChannelNone. //! -1 isn't used as a channel pointer anywhere else. if (channel != ((SequenceChannel*)(-1))) { - if (vib->extentChangeTimer) { - if (vib->extentChangeTimer == 1) { - vib->extent = (s32)channel->vibratoExtentTarget; + if (vib->depthChangeTimer) { + if (vib->depthChangeTimer == 1) { + vib->depth = (s32)channel->vibratoDepthTarget; } else { - vib->extent += ((s32)channel->vibratoExtentTarget - vib->extent) / (s32)vib->extentChangeTimer; + vib->depth += ((s32)channel->vibratoDepthTarget - vib->depth) / (s32)vib->depthChangeTimer; } - vib->extentChangeTimer--; - } else if (channel->vibratoExtentTarget != (s32)vib->extent) { - if ((vib->extentChangeTimer = channel->vibratoExtentChangeDelay) == 0) { - vib->extent = (s32)channel->vibratoExtentTarget; + vib->depthChangeTimer--; + } else if (channel->vibratoDepthTarget != (s32)vib->depth) { + if ((vib->depthChangeTimer = channel->vibratoDepthChangeDelay) == 0) { + vib->depth = (s32)channel->vibratoDepthTarget; } } @@ -156,16 +156,16 @@ f32 Audio_GetVibratoFreqScale(VibratoState* vib) { } } - if (vib->extent == 0.0f) { + if (vib->depth == 0.0f) { return 1.0f; } pitchChange = Audio_GetVibratoPitchChange(vib) + 32768.0f; - temp = vib->extent / 4096.0f; - extent = temp + 1.0f; - invExtent = 1.0f / extent; + temp = vib->depth / 4096.0f; + depth = temp + 1.0f; + invDepth = 1.0f / depth; - result = 1.0f / ((extent - invExtent) * pitchChange / 65536.0f + invExtent); + result = 1.0f / ((depth - invDepth) * pitchChange / 65536.0f + invDepth); D_80130510 += result; D_80130514++; @@ -190,16 +190,16 @@ void Audio_NoteVibratoInit(Note* note) { vib = ¬e->playbackState.vibratoState; - vib->active = 1; + vib->active = true; vib->time = 0; + vib->curve = gWaveSamples[2]; // gSineWaveSample[0..63] - vib->curve = gWaveSamples[2]; vib->channel = note->playbackState.parentLayer->channel; channel = vib->channel; - if ((vib->extentChangeTimer = channel->vibratoExtentChangeDelay) == 0) { - vib->extent = (s32)channel->vibratoExtentTarget; + if ((vib->depthChangeTimer = channel->vibratoDepthChangeDelay) == 0) { + vib->depth = (s32)channel->vibratoDepthTarget; } else { - vib->extent = (s32)channel->vibratoExtentStart; + vib->depth = (s32)channel->vibratoDepthStart; } if ((vib->rateChangeTimer = channel->vibratoRateChangeDelay) == 0) { @@ -264,7 +264,7 @@ f32 Audio_AdsrUpdate(AdsrState* adsr) { break; default: - adsr->delay *= gAudioCtx.audioBufferParameters.updatesPerFrameScaled; + adsr->delay *= gAudioCtx.audioBufferParameters.ticksPerUpdateScaled; if (adsr->delay == 0) { adsr->delay = 1; } diff --git a/src/audio/lib/heap.c b/src/audio/lib/heap.c index 899cf912b..dcb027d49 100644 --- a/src/audio/lib/heap.c +++ b/src/audio/lib/heap.c @@ -11,12 +11,10 @@ void AudioHeap_DiscardSampleBank(s32 sampleBankId); void AudioHeap_DiscardSampleBanks(void); /** - * Effectively scales `updatesPerFrameInv` by the reciprocal of `scaleInv` - * `updatesPerFrameInvScaled` is just `updatesPerFrameInv` scaled down by a factor of 256.0f - * i.e. (256.0f * `updatesPerFrameInvScaled`) is just `updatesPerFrameInv` + * Effectively scales `ticksPerUpdateInv` by the reciprocal of `scaleInv` */ f32 AudioHeap_CalculateAdsrDecay(f32 scaleInv) { - return (256.0f * gAudioCtx.audioBufferParameters.updatesPerFrameInvScaled) / scaleInv; + return (256.0f * gAudioCtx.audioBufferParameters.ticksPerUpdateInvScaled) / scaleInv; } /** @@ -96,7 +94,7 @@ void AudioHeap_ReleaseNotesForFont(s32 fontId) { if (playbackState->fontId == fontId) { if ((playbackState->priority != 0) && (playbackState->adsr.action.s.state == ADSR_STATE_DECAY)) { playbackState->priority = 1; - playbackState->adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; + playbackState->adsr.fadeOutVel = gAudioCtx.audioBufferParameters.ticksPerUpdateInv; playbackState->adsr.action.s.release = true; } } @@ -793,7 +791,7 @@ s32 AudioHeap_ResetStep(void) { if (gAudioCtx.notes[i].noteSubEu.bitField0.enabled && gAudioCtx.notes[i].playbackState.adsr.action.s.state != ADSR_STATE_DISABLED) { gAudioCtx.notes[i].playbackState.adsr.fadeOutVel = - gAudioCtx.audioBufferParameters.updatesPerFrameInv; + gAudioCtx.audioBufferParameters.ticksPerUpdateInv; gAudioCtx.notes[i].playbackState.adsr.action.s.release = true; } } @@ -853,7 +851,7 @@ void AudioHeap_Init(void) { s32 i; s32 j; s32 pad2; - AudioSpec* spec = &gAudioSpecs[gAudioCtx.audioResetSpecIdToLoad]; // Audio Specifications + AudioSpec* spec = &gAudioSpecs[gAudioCtx.specId]; // Audio Specifications gAudioCtx.sampleDmaCount = 0; @@ -865,17 +863,17 @@ void AudioHeap_Init(void) { ALIGN16(gAudioCtx.audioBufferParameters.samplingFrequency / gAudioCtx.refreshRate); gAudioCtx.audioBufferParameters.minAiBufferLength = gAudioCtx.audioBufferParameters.samplesPerFrameTarget - 0x10; gAudioCtx.audioBufferParameters.maxAiBufferLength = gAudioCtx.audioBufferParameters.samplesPerFrameTarget + 0x10; - gAudioCtx.audioBufferParameters.updatesPerFrame = + gAudioCtx.audioBufferParameters.ticksPerUpdate = ((gAudioCtx.audioBufferParameters.samplesPerFrameTarget + 0x10) / 0xD0) + 1; - gAudioCtx.audioBufferParameters.samplesPerUpdate = - (gAudioCtx.audioBufferParameters.samplesPerFrameTarget / gAudioCtx.audioBufferParameters.updatesPerFrame) & ~7; - gAudioCtx.audioBufferParameters.samplesPerUpdateMax = gAudioCtx.audioBufferParameters.samplesPerUpdate + 8; - gAudioCtx.audioBufferParameters.samplesPerUpdateMin = gAudioCtx.audioBufferParameters.samplesPerUpdate - 8; + gAudioCtx.audioBufferParameters.samplesPerTick = + (gAudioCtx.audioBufferParameters.samplesPerFrameTarget / gAudioCtx.audioBufferParameters.ticksPerUpdate) & ~7; + gAudioCtx.audioBufferParameters.samplesPerTickMax = gAudioCtx.audioBufferParameters.samplesPerTick + 8; + gAudioCtx.audioBufferParameters.samplesPerTickMin = gAudioCtx.audioBufferParameters.samplesPerTick - 8; gAudioCtx.audioBufferParameters.resampleRate = 32000.0f / (s32)gAudioCtx.audioBufferParameters.samplingFrequency; - gAudioCtx.audioBufferParameters.updatesPerFrameInvScaled = - (1.0f / 256.0f) / gAudioCtx.audioBufferParameters.updatesPerFrame; - gAudioCtx.audioBufferParameters.updatesPerFrameScaled = gAudioCtx.audioBufferParameters.updatesPerFrame / 4.0f; - gAudioCtx.audioBufferParameters.updatesPerFrameInv = 1.0f / gAudioCtx.audioBufferParameters.updatesPerFrame; + gAudioCtx.audioBufferParameters.ticksPerUpdateInvScaled = + (1.0f / 256.0f) / gAudioCtx.audioBufferParameters.ticksPerUpdate; + gAudioCtx.audioBufferParameters.ticksPerUpdateScaled = gAudioCtx.audioBufferParameters.ticksPerUpdate / 4.0f; + gAudioCtx.audioBufferParameters.ticksPerUpdateInv = 1.0f / gAudioCtx.audioBufferParameters.ticksPerUpdate; // SampleDma buffer size gAudioCtx.sampleDmaBufSize1 = spec->sampleDmaBufSize1; @@ -887,19 +885,22 @@ void AudioHeap_Init(void) { gAudioCtx.audioBufferParameters.numSequencePlayers = 4; } gAudioCtx.unk_2 = spec->unk_14; - gAudioCtx.tempoInternalToExternal = - (u32)(gAudioCtx.audioBufferParameters.updatesPerFrame * 2880000.0f / gTatumsPerBeat / gAudioCtx.unk_2960); + + // (ticks / min) + // 60 * 1000 is a conversion from milliseconds to minutes + gAudioCtx.maxTempo = (u32)(gAudioCtx.audioBufferParameters.ticksPerUpdate * (f32)(60 * 1000 * SEQTICKS_PER_BEAT) / + gTempoData.seqTicksPerBeat / gAudioCtx.maxTempoTvTypeFactors); gAudioCtx.unk_2870 = gAudioCtx.refreshRate; - gAudioCtx.unk_2870 *= gAudioCtx.audioBufferParameters.updatesPerFrame; + gAudioCtx.unk_2870 *= gAudioCtx.audioBufferParameters.ticksPerUpdate; gAudioCtx.unk_2870 /= gAudioCtx.audioBufferParameters.aiSamplingFrequency; - gAudioCtx.unk_2870 /= gAudioCtx.tempoInternalToExternal; + gAudioCtx.unk_2870 /= gAudioCtx.maxTempo; gAudioCtx.audioBufferParameters.specUnk4 = spec->unk_04; gAudioCtx.audioBufferParameters.samplesPerFrameTarget *= gAudioCtx.audioBufferParameters.specUnk4; gAudioCtx.audioBufferParameters.maxAiBufferLength *= gAudioCtx.audioBufferParameters.specUnk4; gAudioCtx.audioBufferParameters.minAiBufferLength *= gAudioCtx.audioBufferParameters.specUnk4; - gAudioCtx.audioBufferParameters.updatesPerFrame *= gAudioCtx.audioBufferParameters.specUnk4; + gAudioCtx.audioBufferParameters.ticksPerUpdate *= gAudioCtx.audioBufferParameters.specUnk4; if (gAudioCtx.audioBufferParameters.specUnk4 >= 2) { gAudioCtx.audioBufferParameters.maxAiBufferLength -= 0x10; @@ -907,7 +908,7 @@ void AudioHeap_Init(void) { // Determine the length of the buffer for storing the audio command list passed to the rsp audio microcode gAudioCtx.maxAudioCmds = - gAudioCtx.numNotes * 0x10 * gAudioCtx.audioBufferParameters.updatesPerFrame + spec->numReverbs * 0x18 + 0x140; + gAudioCtx.numNotes * 0x10 * gAudioCtx.audioBufferParameters.ticksPerUpdate + spec->numReverbs * 0x18 + 0x140; // Calculate sizes for various caches on the audio heap persistentSize = @@ -949,7 +950,7 @@ void AudioHeap_Init(void) { gAudioCtx.notes = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, gAudioCtx.numNotes * sizeof(Note)); Audio_NoteInitAll(); Audio_InitNoteFreeList(); - gAudioCtx.noteSubsEu = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, gAudioCtx.audioBufferParameters.updatesPerFrame * + gAudioCtx.noteSubsEu = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, gAudioCtx.audioBufferParameters.ticksPerUpdate * gAudioCtx.numNotes * sizeof(NoteSubEu)); // Initialize audio binary interface command list buffers for (i = 0; i != 2; i++) { @@ -1011,7 +1012,7 @@ void AudioHeap_Init(void) { reverb->unk_34 = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, sizeof(RESAMPLE_STATE)); reverb->unk_38 = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, sizeof(RESAMPLE_STATE)); reverb->unk_3C = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, sizeof(RESAMPLE_STATE)); - for (j = 0; j < gAudioCtx.audioBufferParameters.updatesPerFrame; j++) { + for (j = 0; j < gAudioCtx.audioBufferParameters.ticksPerUpdate; j++) { ramAddr = AudioHeap_AllocZeroedAttemptExternal(&gAudioCtx.miscPool, DMEM_2CH_SIZE); reverb->items[0][j].toDownsampleLeft = ramAddr; reverb->items[0][j].toDownsampleRight = ramAddr + DMEM_1CH_SIZE / SAMPLE_SIZE; diff --git a/src/audio/lib/load.c b/src/audio/lib/load.c index b7b674a23..c542c8062 100644 --- a/src/audio/lib/load.c +++ b/src/audio/lib/load.c @@ -1126,7 +1126,7 @@ void AudioLoad_Init(void* heap, u32 heapSize) { void* ramAddr; s32 i; - D_801755D0 = NULL; + gAudioCustomUpdateFunction = NULL; gAudioCtx.resetTimer = 0; { @@ -1138,25 +1138,26 @@ void AudioLoad_Init(void* heap, u32 heapSize) { } } + // 1000 is a conversion from seconds to milliseconds switch (osTvType) { case OS_TV_PAL: - gAudioCtx.unk_2960 = 20.03042f; - gAudioCtx.refreshRate = 50; + gAudioCtx.maxTempoTvTypeFactors = 1000 * REFRESH_RATE_DEVIATION_PAL / REFRESH_RATE_PAL; + gAudioCtx.refreshRate = REFRESH_RATE_PAL; break; case OS_TV_MPAL: - gAudioCtx.unk_2960 = 16.546f; - gAudioCtx.refreshRate = 60; + gAudioCtx.maxTempoTvTypeFactors = 1000 * REFRESH_RATE_DEVIATION_MPAL / REFRESH_RATE_MPAL; + gAudioCtx.refreshRate = REFRESH_RATE_MPAL; break; case OS_TV_NTSC: default: - gAudioCtx.unk_2960 = 16.713f; - gAudioCtx.refreshRate = 60; + gAudioCtx.maxTempoTvTypeFactors = 1000 * REFRESH_RATE_DEVIATION_NTSC / REFRESH_RATE_NTSC; + gAudioCtx.refreshRate = REFRESH_RATE_NTSC; break; } - Audio_InitMesgQueues(); + AudioThread_InitMesgQueues(); for (i = 0; i < 3; i++) { gAudioCtx.aiBufLengths[i] = 0xA0; @@ -1209,7 +1210,7 @@ void AudioLoad_Init(void* heap, u32 heapSize) { gAudioCtx.numSequences = gAudioCtx.sequenceTable->numEntries; - gAudioCtx.audioResetSpecIdToLoad = 0; + gAudioCtx.specId = 0; gAudioCtx.resetStatus = 1; // Set reset to immediately initialize the audio heap AudioHeap_ResetStep(); diff --git a/src/audio/lib/playback.c b/src/audio/lib/playback.c index 87e2f792c..9c1b8126e 100644 --- a/src/audio/lib/playback.c +++ b/src/audio/lib/playback.c @@ -100,8 +100,8 @@ void Audio_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* attrs) { sub->gain = attrs->gain; sub->filter = attrs->filter; - sub->unk_07 = attrs->unk_14; - sub->unk_0E = attrs->unk_16; + sub->combFilterSize = attrs->combFilterSize; + sub->combFilterGain = attrs->combFilterGain; sub->reverbVol = reverbVol; } @@ -174,7 +174,7 @@ void Audio_ProcessNotes(void) { if (note != playbackState->parentLayer->note && playbackState->unk_04 == 0) { playbackState->adsr.action.s.release = true; - playbackState->adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; + playbackState->adsr.fadeOutVel = gAudioCtx.audioBufferParameters.ticksPerUpdateInv; playbackState->priority = 1; playbackState->unk_04 = 2; goto out; @@ -256,8 +256,8 @@ void Audio_ProcessNotes(void) { subAttrs.stereo = attrs->stereo; subAttrs.gain = attrs->gain; subAttrs.filter = attrs->filter; - subAttrs.unk_14 = attrs->unk_4; - subAttrs.unk_16 = attrs->unk_6; + subAttrs.combFilterSize = attrs->combFilterSize; + subAttrs.combFilterGain = attrs->combFilterGain; bookOffset = noteSubEu->bitField1.bookOffset; } else { SequenceLayer* layer = playbackState->parentLayer; @@ -271,11 +271,11 @@ void Audio_ProcessNotes(void) { } else { subAttrs.stereo = layer->stereo; } - subAttrs.reverbVol = channel->reverb; + subAttrs.reverbVol = channel->targetReverbVol; subAttrs.gain = channel->gain; subAttrs.filter = channel->filter; - subAttrs.unk_14 = channel->unk_0F; - subAttrs.unk_16 = channel->unk_20; + subAttrs.combFilterSize = channel->combFilterSize; + subAttrs.combFilterGain = channel->combFilterGain; bookOffset = channel->bookOffset & 0x7; if (channel->seqPlayer->muted && (channel->muteBehavior & MUTE_BEHAVIOR_3)) { @@ -433,7 +433,7 @@ s32 Audio_SetFontInstrument(s32 instrumentType, s32 fontId, s32 index, void* val void Audio_SeqLayerDecayRelease(SequenceLayer* layer, s32 target) { Note* note; NoteAttributes* attrs; - SequenceChannel* chan; + SequenceChannel* channel; s32 i; if (layer == NO_LAYER) { @@ -456,7 +456,7 @@ void Audio_SeqLayerDecayRelease(SequenceLayer* layer, s32 target) { if (note->playbackState.parentLayer != layer) { if (note->playbackState.parentLayer == NO_LAYER && note->playbackState.wantedParentLayer == NO_LAYER && note->playbackState.prevParentLayer == layer && target != ADSR_STATE_DECAY) { - note->playbackState.adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; + note->playbackState.adsr.fadeOutVel = gAudioCtx.audioBufferParameters.ticksPerUpdateInv; note->playbackState.adsr.action.s.release = true; } return; @@ -468,10 +468,10 @@ void Audio_SeqLayerDecayRelease(SequenceLayer* layer, s32 target) { attrs->pan = layer->notePan; if (layer->channel != NULL) { - chan = layer->channel; - attrs->reverb = chan->reverb; - attrs->gain = chan->gain; - attrs->filter = chan->filter; + channel = layer->channel; + attrs->reverb = channel->targetReverbVol; + attrs->gain = channel->gain; + attrs->filter = channel->filter; if (attrs->filter != NULL) { for (i = 0; i < 8; i++) { @@ -480,18 +480,18 @@ void Audio_SeqLayerDecayRelease(SequenceLayer* layer, s32 target) { attrs->filter = attrs->filterBuf; } - attrs->unk_6 = chan->unk_20; - attrs->unk_4 = chan->unk_0F; - if (chan->seqPlayer->muted && (chan->muteBehavior & MUTE_BEHAVIOR_3)) { + attrs->combFilterGain = channel->combFilterGain; + attrs->combFilterSize = channel->combFilterSize; + if (channel->seqPlayer->muted && (channel->muteBehavior & MUTE_BEHAVIOR_3)) { note->noteSubEu.bitField0.finished = true; } if (layer->stereo.asByte == 0) { - attrs->stereo = chan->stereo; + attrs->stereo = channel->stereo; } else { attrs->stereo = layer->stereo; } - note->playbackState.priority = chan->someOtherPriority; + note->playbackState.priority = channel->someOtherPriority; } else { attrs->stereo = layer->stereo; note->playbackState.priority = 1; @@ -500,7 +500,7 @@ void Audio_SeqLayerDecayRelease(SequenceLayer* layer, s32 target) { note->playbackState.prevParentLayer = note->playbackState.parentLayer; note->playbackState.parentLayer = NO_LAYER; if (target == ADSR_STATE_RELEASE) { - note->playbackState.adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; + note->playbackState.adsr.fadeOutVel = gAudioCtx.audioBufferParameters.ticksPerUpdateInv; note->playbackState.adsr.action.s.release = true; note->playbackState.unk_04 = 2; } else { @@ -805,7 +805,7 @@ void Audio_NoteReleaseAndTakeOwnership(Note* note, SequenceLayer* layer) { note->playbackState.wantedParentLayer = layer; note->playbackState.priority = layer->channel->notePriority; - note->playbackState.adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; + note->playbackState.adsr.fadeOutVel = gAudioCtx.audioBufferParameters.ticksPerUpdateInv; note->playbackState.adsr.action.s.release = true; } diff --git a/src/audio/lib/seqplayer.c b/src/audio/lib/seqplayer.c index 008bedea6..620f7a453 100644 --- a/src/audio/lib/seqplayer.c +++ b/src/audio/lib/seqplayer.c @@ -259,7 +259,7 @@ void AudioSeq_InitSequenceChannel(SequenceChannel* channel) { channel->enabled = false; channel->finished = false; channel->stopScript = false; - channel->stopSomething2 = false; + channel->muted = false; channel->hasInstrument = false; channel->stereoHeadsetEffects = false; channel->transposition = 0; @@ -274,7 +274,7 @@ void AudioSeq_InitSequenceChannel(SequenceChannel* channel) { channel->gateTimeRandomVariance = 0; channel->noteUnused = NULL; channel->reverbIndex = 0; - channel->reverb = 0; + channel->targetReverbVol = 0; channel->gain = 0; channel->notePriority = 3; channel->someOtherPriority = 1; @@ -284,20 +284,20 @@ void AudioSeq_InitSequenceChannel(SequenceChannel* channel) { channel->adsr.sustain = 0; channel->vibratoRateTarget = 0x800; channel->vibratoRateStart = 0x800; - channel->vibratoExtentTarget = 0; - channel->vibratoExtentStart = 0; + channel->vibratoDepthTarget = 0; + channel->vibratoDepthStart = 0; channel->vibratoRateChangeDelay = 0; - channel->vibratoExtentChangeDelay = 0; + channel->vibratoDepthChangeDelay = 0; channel->vibratoDelay = 0; channel->filter = NULL; - channel->unk_20 = 0; - channel->unk_0F = 0; + channel->combFilterGain = 0; + channel->combFilterSize = 0; channel->volume = 1.0f; channel->volumeScale = 1.0f; channel->freqScale = 1.0f; - for (i = 0; i < ARRAY_COUNT(channel->soundScriptIO); i++) { - channel->soundScriptIO[i] = SEQ_IO_VAL_NONE; + for (i = 0; i < ARRAY_COUNT(channel->seqScriptIO); i++) { + channel->seqScriptIO[i] = SEQ_IO_VAL_NONE; } channel->unused = false; @@ -326,7 +326,7 @@ s32 AudioSeq_SeqChannelSetLayer(SequenceChannel* channel, s32 layerIndex) { layer->adsr.decayIndex = 0; layer->enabled = true; layer->finished = false; - layer->stopSomething = false; + layer->muted = false; layer->continuousNotes = false; layer->bit3 = false; layer->ignoreDrumPan = false; @@ -530,9 +530,9 @@ void AudioSeq_SeqLayerProcessScript(SequenceLayer* layer) { if (layer->delay > 1) { layer->delay--; - if (!layer->stopSomething && layer->delay <= layer->gateDelay) { + if (!layer->muted && (layer->delay <= layer->gateDelay)) { Audio_SeqLayerNoteDecay(layer); - layer->stopSomething = true; + layer->muted = true; } return; } @@ -555,7 +555,7 @@ void AudioSeq_SeqLayerProcessScript(SequenceLayer* layer) { AudioSeq_SeqLayerProcessScriptStep5(layer, cmd); } - if (layer->stopSomething == true) { + if (layer->muted == true) { if ((layer->note != NULL) || layer->continuousNotes) { Audio_SeqLayerNoteDecay(layer); } @@ -579,9 +579,9 @@ void AudioSeq_SeqLayerProcessScriptStep1(SequenceLayer* layer) { s32 AudioSeq_SeqLayerProcessScriptStep5(SequenceLayer* layer, s32 sameTunedSample) { Note* note; - if (!layer->stopSomething && layer->tunedSample != NULL && - layer->tunedSample->sample->codec == CODEC_S16_INMEMORY && layer->tunedSample->sample->medium != MEDIUM_RAM) { - layer->stopSomething = true; + if (!layer->muted && (layer->tunedSample != NULL) && (layer->tunedSample->sample->codec == CODEC_S16_INMEMORY) && + (layer->tunedSample->sample->medium != MEDIUM_RAM)) { + layer->muted = true; return PROCESS_SCRIPT_END; } @@ -812,7 +812,7 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) { drum = Audio_GetDrum(channel->fontId, semitone); if (drum == NULL) { - layer->stopSomething = true; + layer->muted = true; layer->delay2 = layer->delay; return PROCESS_SCRIPT_END; } @@ -834,7 +834,7 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) { soundEffect = Audio_GetSoundEffect(channel->fontId, sfxId); if (soundEffect == NULL) { - layer->stopSomething = true; + layer->muted = true; layer->delay2 = layer->delay + 1; return PROCESS_SCRIPT_END; } @@ -850,7 +850,7 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) { layer->semitone = semitone; if (semitone >= 0x80) { - layer->stopSomething = true; + layer->muted = true; return PROCESS_SCRIPT_END; } @@ -903,12 +903,12 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) { portamento->extent = (freqScale2 / freqScale) - 1.0f; if (PORTAMENTO_IS_SPECIAL(*portamento)) { - speed = seqPlayer->tempo * 0x8000 / gAudioCtx.tempoInternalToExternal; + speed = seqPlayer->tempo * 0x8000 / gAudioCtx.maxTempo; if (layer->delay != 0) { speed = speed * 0x100 / (layer->delay * layer->portamentoTime); } } else { - speed = 0x20000 / (layer->portamentoTime * gAudioCtx.audioBufferParameters.updatesPerFrame); + speed = 0x20000 / (layer->portamentoTime * gAudioCtx.audioBufferParameters.ticksPerUpdate); } if (speed >= 0x7FFF) { @@ -964,7 +964,7 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) { // (It's a bit unclear if 'portamento' has actually always been // set when this is reached...) if (PORTAMENTO_IS_SPECIAL(*portamento)) { - speed2 = seqPlayer->tempo * 0x8000 / gAudioCtx.tempoInternalToExternal; + speed2 = seqPlayer->tempo * 0x8000 / gAudioCtx.maxTempo; speed2 = speed2 * 0x100 / (layer->delay * layer->portamentoTime); if (speed2 >= 0x7FFF) { speed2 = 0x7FFF; @@ -989,12 +989,12 @@ s32 AudioSeq_SeqLayerProcessScriptStep3(SequenceLayer* layer, s32 cmd) { if (cmd == 0xC0) { layer->delay = AudioSeq_ScriptReadCompressedU16(state); - layer->stopSomething = true; + layer->muted = true; layer->bit1 = false; return PROCESS_SCRIPT_END; } - layer->stopSomething = false; + layer->muted = false; if (channel->largeNotes == true) { switch (cmd & 0xC0) { @@ -1078,13 +1078,13 @@ s32 AudioSeq_SeqLayerProcessScriptStep3(SequenceLayer* layer, s32 cmd) { } if ((seqPlayer->muted && (channel->muteBehavior & (MUTE_BEHAVIOR_STOP_NOTES | MUTE_BEHAVIOR_4))) || - channel->stopSomething2) { - layer->stopSomething = true; + channel->muted) { + layer->muted = true; return PROCESS_SCRIPT_END; } if (seqPlayer->skipTicks != 0) { - layer->stopSomething = true; + layer->muted = true; return PROCESS_SCRIPT_END; } @@ -1329,9 +1329,9 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { case 0xD8: cmd = (u8)cmdArgs[0]; - channel->vibratoExtentTarget = cmd * 8; - channel->vibratoExtentStart = 0; - channel->vibratoExtentChangeDelay = 0; + channel->vibratoDepthTarget = cmd * 8; + channel->vibratoDepthStart = 0; + channel->vibratoDepthChangeDelay = 0; break; case 0xD7: @@ -1343,11 +1343,11 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { case 0xE2: cmd = (u8)cmdArgs[0]; - channel->vibratoExtentStart = cmd * 8; + channel->vibratoDepthStart = cmd * 8; cmd = (u8)cmdArgs[1]; - channel->vibratoExtentTarget = cmd * 8; + channel->vibratoDepthTarget = cmd * 8; cmd = (u8)cmdArgs[2]; - channel->vibratoExtentChangeDelay = cmd * 16; + channel->vibratoDepthChangeDelay = cmd * 16; break; case 0xE1: @@ -1366,7 +1366,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { case 0xD4: cmd = (u8)cmdArgs[0]; - channel->reverb = cmd; + channel->targetReverbVol = cmd; break; case 0xC6: @@ -1483,7 +1483,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { data += 4; channel->newPan = data[-3]; channel->panChannelWeight = data[-2]; - channel->reverb = data[-1]; + channel->targetReverbVol = data[-1]; channel->reverbIndex = data[0]; //! @bug: Not marking reverb state as changed channel->changes.s.pan = true; @@ -1497,16 +1497,16 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { channel->transposition = (s8)AudioSeq_ScriptReadU8(scriptState); channel->newPan = AudioSeq_ScriptReadU8(scriptState); channel->panChannelWeight = AudioSeq_ScriptReadU8(scriptState); - channel->reverb = AudioSeq_ScriptReadU8(scriptState); + channel->targetReverbVol = AudioSeq_ScriptReadU8(scriptState); channel->reverbIndex = AudioSeq_ScriptReadU8(scriptState); //! @bug: Not marking reverb state as changed channel->changes.s.pan = true; break; case 0xEC: - channel->vibratoExtentTarget = 0; - channel->vibratoExtentStart = 0; - channel->vibratoExtentChangeDelay = 0; + channel->vibratoDepthTarget = 0; + channel->vibratoDepthStart = 0; + channel->vibratoDepthChangeDelay = 0; channel->vibratoRateTarget = 0; channel->vibratoRateStart = 0; channel->vibratoRateChangeDelay = 0; @@ -1515,8 +1515,8 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { channel->adsr.sustain = 0; channel->velocityRandomVariance = 0; channel->gateTimeRandomVariance = 0; - channel->unk_0F = 0; - channel->unk_20 = 0; + channel->combFilterSize = 0; + channel->combFilterGain = 0; channel->bookOffset = 0; channel->freqScale = 1.0f; break; @@ -1578,7 +1578,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { break; case 0xBD: - temp2 = Audio_NextRandom(); + temp2 = AudioThread_NextRandom(); channel->unk_22 = (cmdArgs[0] == 0) ? (temp2 & 0xFFFF) : (temp2 % cmdArgs[0]); channel->unk_22 += cmdArgs[1]; temp2 = (channel->unk_22 / 0x100) + 0x80; @@ -1595,8 +1595,8 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { break; case 0xBB: - channel->unk_0F = cmdArgs[0]; - channel->unk_20 = cmdArgs[1]; + channel->combFilterSize = cmdArgs[0]; + channel->combFilterGain = cmdArgs[1]; break; case 0xBC: @@ -1642,7 +1642,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { break; case 0x70: - channel->soundScriptIO[lowBits] = scriptState->value; + channel->seqScriptIO[lowBits] = scriptState->value; break; case 0x78: @@ -1664,26 +1664,26 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { case 0x10: if (lowBits < 8) { - channel->soundScriptIO[lowBits] = SEQ_IO_VAL_NONE; - if (AudioLoad_SlowLoadSample(channel->fontId, scriptState->value, - &channel->soundScriptIO[lowBits]) == -1) {} + channel->seqScriptIO[lowBits] = SEQ_IO_VAL_NONE; + if (AudioLoad_SlowLoadSample(channel->fontId, scriptState->value, &channel->seqScriptIO[lowBits]) == + -1) {} } else { lowBits -= 8; - channel->soundScriptIO[lowBits] = SEQ_IO_VAL_NONE; + channel->seqScriptIO[lowBits] = SEQ_IO_VAL_NONE; if (AudioLoad_SlowLoadSample(channel->fontId, channel->unk_22 + 0x100, - &channel->soundScriptIO[lowBits]) == -1) {} + &channel->seqScriptIO[lowBits]) == -1) {} } break; case 0x60: - scriptState->value = channel->soundScriptIO[lowBits]; + scriptState->value = channel->seqScriptIO[lowBits]; if (lowBits < 2) { - channel->soundScriptIO[lowBits] = SEQ_IO_VAL_NONE; + channel->seqScriptIO[lowBits] = SEQ_IO_VAL_NONE; } break; case 0x50: - scriptState->value -= channel->soundScriptIO[lowBits]; + scriptState->value -= channel->seqScriptIO[lowBits]; break; case 0x20: @@ -1693,12 +1693,12 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { case 0x30: cmd = AudioSeq_ScriptReadU8(scriptState); - seqPlayer->channels[lowBits]->soundScriptIO[cmd] = scriptState->value; + seqPlayer->channels[lowBits]->seqScriptIO[cmd] = scriptState->value; break; case 0x40: cmd = AudioSeq_ScriptReadU8(scriptState); - scriptState->value = seqPlayer->channels[lowBits]->soundScriptIO[cmd]; + scriptState->value = seqPlayer->channels[lowBits]->seqScriptIO[cmd]; break; } } @@ -1743,14 +1743,18 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { } seqPlayer->scriptCounter++; - seqPlayer->tempoAcc += seqPlayer->tempo; - seqPlayer->tempoAcc += (s16)seqPlayer->unk_0C; - if (seqPlayer->tempoAcc < gAudioCtx.tempoInternalToExternal) { + // Apply the tempo by controlling the number of updates run on the .seq script. + // Processing the .seq script every possible update will result in a tempo = maxTempo + // Processing the .seq script a fraction of the updates will result in a `tempo = fraction * maxTempo` + // where `fraction = (tempo + tempoChange) / maxTempo` + // This algorithm uses `tempoAcc` to discretize `(tempo + tempoChange) / maxTempo` + seqPlayer->tempoAcc += seqPlayer->tempo; + seqPlayer->tempoAcc += (s16)seqPlayer->tempoChange; + if (seqPlayer->tempoAcc < gAudioCtx.maxTempo) { return; } - - seqPlayer->tempoAcc -= (u16)gAudioCtx.tempoInternalToExternal; + seqPlayer->tempoAcc -= (u16)gAudioCtx.maxTempo; if (seqPlayer->stopScript == true) { return; @@ -1810,9 +1814,9 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { break; case 0xDD: - seqPlayer->tempo = AudioSeq_ScriptReadU8(seqScript) * TATUMS_PER_BEAT; - if (seqPlayer->tempo > gAudioCtx.tempoInternalToExternal) { - seqPlayer->tempo = (u16)gAudioCtx.tempoInternalToExternal; + seqPlayer->tempo = AudioSeq_ScriptReadU8(seqScript) * SEQTICKS_PER_BEAT; + if (seqPlayer->tempo > gAudioCtx.maxTempo) { + seqPlayer->tempo = (u16)gAudioCtx.maxTempo; } if ((s16)seqPlayer->tempo <= 0) { @@ -1821,7 +1825,7 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { break; case 0xDC: - seqPlayer->unk_0C = (s8)AudioSeq_ScriptReadU8(seqScript) * TATUMS_PER_BEAT; + seqPlayer->tempoChange = (s8)AudioSeq_ScriptReadU8(seqScript) * SEQTICKS_PER_BEAT; break; case 0xDA: @@ -1982,17 +1986,17 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { break; case 0x50: - seqScript->value -= seqPlayer->soundScriptIO[cmdLowBits]; + seqScript->value -= seqPlayer->seqScriptIO[cmdLowBits]; break; case 0x70: - seqPlayer->soundScriptIO[cmdLowBits] = seqScript->value; + seqPlayer->seqScriptIO[cmdLowBits] = seqScript->value; break; case 0x80: - seqScript->value = seqPlayer->soundScriptIO[cmdLowBits]; + seqScript->value = seqPlayer->seqScriptIO[cmdLowBits]; if (cmdLowBits < 2) { - seqPlayer->soundScriptIO[cmdLowBits] = SEQ_IO_VAL_NONE; + seqPlayer->seqScriptIO[cmdLowBits] = SEQ_IO_VAL_NONE; } break; @@ -2014,14 +2018,14 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { cmd = AudioSeq_ScriptReadU8(seqScript); temp = AudioSeq_ScriptReadS16(seqScript); data2 = &seqPlayer->seqData[temp]; - AudioLoad_SlowLoadSeq(cmd, data2, &seqPlayer->soundScriptIO[cmdLowBits]); + AudioLoad_SlowLoadSeq(cmd, data2, &seqPlayer->seqScriptIO[cmdLowBits]); break; case 0x60: cmd = AudioSeq_ScriptReadU8(seqScript); value = cmd; temp = AudioSeq_ScriptReadU8(seqScript); - AudioLoad_ScriptLoad(value, temp, &seqPlayer->soundScriptIO[cmdLowBits]); + AudioLoad_ScriptLoad(value, temp, &seqPlayer->seqScriptIO[cmdLowBits]); break; } } @@ -2038,7 +2042,7 @@ void AudioSeq_ProcessSequences(s32 arg0) { SequencePlayer* seqPlayer; u32 i; - gAudioCtx.noteSubEuOffset = (gAudioCtx.audioBufferParameters.updatesPerFrame - arg0 - 1) * gAudioCtx.numNotes; + gAudioCtx.noteSubEuOffset = (gAudioCtx.audioBufferParameters.ticksPerUpdate - arg0 - 1) * gAudioCtx.numNotes; for (i = 0; i < (u32)gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { seqPlayer = &gAudioCtx.seqPlayers[i]; @@ -2069,8 +2073,8 @@ void AudioSeq_ResetSequencePlayer(SequencePlayer* seqPlayer) { seqPlayer->fadeTimer = 0; seqPlayer->fadeTimerUnkEu = 0; seqPlayer->tempoAcc = 0; - seqPlayer->tempo = 120 * TATUMS_PER_BEAT; // 120 BPM - seqPlayer->unk_0C = 0; + seqPlayer->tempo = 120 * SEQTICKS_PER_BEAT; // 120 BPM + seqPlayer->tempoChange = 0; seqPlayer->transposition = 0; seqPlayer->noteAllocPolicy = 0; seqPlayer->shortNoteVelocityTable = gDefaultShortNoteVelocityTable; @@ -2122,8 +2126,8 @@ void AudioSeq_InitSequencePlayer(SequencePlayer* seqPlayer) { seqPlayer->seqDmaInProgress = false; seqPlayer->applyBend = false; - for (j = 0; j < ARRAY_COUNT(seqPlayer->soundScriptIO); j++) { - seqPlayer->soundScriptIO[j] = SEQ_IO_VAL_NONE; + for (j = 0; j < ARRAY_COUNT(seqPlayer->seqScriptIO); j++) { + seqPlayer->seqScriptIO[j] = SEQ_IO_VAL_NONE; } seqPlayer->muteBehavior = MUTE_BEHAVIOR_SOFTEN | MUTE_BEHAVIOR_STOP_NOTES; diff --git a/src/audio/lib/synthesis.c b/src/audio/lib/synthesis.c index 51b2c2e5a..321bd79a5 100644 --- a/src/audio/lib/synthesis.c +++ b/src/audio/lib/synthesis.c @@ -5,7 +5,7 @@ #define DMEM_TEMP 0x3C0 #define DMEM_UNCOMPRESSED_NOTE 0x580 #define DMEM_HAAS_TEMP 0x5C0 -#define DMEM_SCRATCH2 0x760 // = DMEM_TEMP + DMEM_2CH_SIZE + a bit more +#define DMEM_COMB_TEMP 0x760 // = DMEM_TEMP + DMEM_2CH_SIZE + a bit more #define DMEM_COMPRESSED_ADPCM_DATA 0x940 // = DMEM_LEFT_CH #define DMEM_LEFT_CH 0x940 #define DMEM_RIGHT_CH 0xAE0 @@ -38,14 +38,14 @@ u32 sEnvMixerOp = _SHIFTL(A_ENVMIXER, 24, 8); // Store the left dry channel in a temp space to be delayed to produce the haas effect u32 sEnvMixerLeftHaasDmemDests = - MK_CMD(DMEM_HAAS_TEMP >> 4, DMEM_RIGHT_CH >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4); + AUDIO_MK_CMD(DMEM_HAAS_TEMP >> 4, DMEM_RIGHT_CH >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4); // Store the right dry channel in a temp space to be delayed to produce the haas effect u32 sEnvMixerRightHaasDmemDests = - MK_CMD(DMEM_LEFT_CH >> 4, DMEM_HAAS_TEMP >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4); + AUDIO_MK_CMD(DMEM_LEFT_CH >> 4, DMEM_HAAS_TEMP >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4); u32 sEnvMixerDefaultDmemDests = - MK_CMD(DMEM_LEFT_CH >> 4, DMEM_RIGHT_CH >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4); + AUDIO_MK_CMD(DMEM_LEFT_CH >> 4, DMEM_RIGHT_CH >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4); u16 D_801304B0[] = { 0x7FFF, 0xD001, 0x3FFF, 0xF001, 0x5FFF, 0x9001, 0x7FFF, 0x8001, @@ -158,32 +158,32 @@ Acmd* AudioSynth_Update(Acmd* cmdStart, s32* cmdCnt, s16* aiStart, s32 aiBufLen) SynthesisReverb* reverb; cmdP = cmdStart; - for (i = gAudioCtx.audioBufferParameters.updatesPerFrame; i > 0; i--) { + for (i = gAudioCtx.audioBufferParameters.ticksPerUpdate; i > 0; i--) { AudioSeq_ProcessSequences(i - 1); - func_800DB03C(gAudioCtx.audioBufferParameters.updatesPerFrame - i); + func_800DB03C(gAudioCtx.audioBufferParameters.ticksPerUpdate - i); } aiBufP = aiStart; gAudioCtx.curLoadedBook = NULL; - for (i = gAudioCtx.audioBufferParameters.updatesPerFrame; i > 0; i--) { + for (i = gAudioCtx.audioBufferParameters.ticksPerUpdate; i > 0; i--) { if (i == 1) { chunkLen = aiBufLen; - } else if ((aiBufLen / i) >= gAudioCtx.audioBufferParameters.samplesPerUpdateMax) { - chunkLen = gAudioCtx.audioBufferParameters.samplesPerUpdateMax; - } else if (gAudioCtx.audioBufferParameters.samplesPerUpdateMin >= (aiBufLen / i)) { - chunkLen = gAudioCtx.audioBufferParameters.samplesPerUpdateMin; + } else if ((aiBufLen / i) >= gAudioCtx.audioBufferParameters.samplesPerTickMax) { + chunkLen = gAudioCtx.audioBufferParameters.samplesPerTickMax; + } else if (gAudioCtx.audioBufferParameters.samplesPerTickMin >= (aiBufLen / i)) { + chunkLen = gAudioCtx.audioBufferParameters.samplesPerTickMin; } else { - chunkLen = gAudioCtx.audioBufferParameters.samplesPerUpdate; + chunkLen = gAudioCtx.audioBufferParameters.samplesPerTick; } for (j = 0; j < gAudioCtx.numSynthesisReverbs; j++) { if (gAudioCtx.synthesisReverbs[j].useReverb) { - AudioSynth_InitNextRingBuf(chunkLen, gAudioCtx.audioBufferParameters.updatesPerFrame - i, j); + AudioSynth_InitNextRingBuf(chunkLen, gAudioCtx.audioBufferParameters.ticksPerUpdate - i, j); } } - cmdP = AudioSynth_DoOneAudioUpdate(aiBufP, chunkLen, cmdP, gAudioCtx.audioBufferParameters.updatesPerFrame - i); + cmdP = AudioSynth_DoOneAudioUpdate(aiBufP, chunkLen, cmdP, gAudioCtx.audioBufferParameters.ticksPerUpdate - i); aiBufLen -= chunkLen; aiBufP += 2 * chunkLen; } @@ -203,7 +203,7 @@ void func_800DB2C0(s32 updateIndex, s32 noteIndex) { NoteSubEu* noteSubEu; s32 i; - for (i = updateIndex + 1; i < gAudioCtx.audioBufferParameters.updatesPerFrame; i++) { + for (i = updateIndex + 1; i < gAudioCtx.audioBufferParameters.ticksPerUpdate; i++) { noteSubEu = &gAudioCtx.noteSubsEu[(gAudioCtx.numNotes * i) + noteIndex]; if (!noteSubEu->bitField0.needsInit) { noteSubEu->bitField0.enabled = false; @@ -717,7 +717,7 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS s32 frameIndex; s32 skipBytes; s32 temp_v1_6; - void* buf; + s16* combFilterState; s32 nSamplesToDecode; u32 sampleAddr; u32 samplesLenFixedPoint; @@ -740,12 +740,12 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS s32 resampledTempLen; u16 sampleDmemBeforeResampling; s32 sampleDataOffset; - s32 thing; + s32 combFilterDmem; s32 s5; Note* note; u32 numSamplesToLoad; - u16 unk7; - u16 unkE; + u16 combFilterSize; + u16 combFilterGain; s16* filter; s32 bookOffset; s32 finished; @@ -769,7 +769,7 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS synthState->prevHaasEffectRightDelaySize = 0; synthState->reverbVol = noteSubEu->reverbVol; synthState->numParts = 0; - synthState->unk_1A = 1; + synthState->combFilterNeedsInit = true; note->noteSubEu.bitField0.finished = false; finished = false; } @@ -1089,23 +1089,26 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS AudioSynth_LoadFilterBuffer(cmd++, flags, DMEM_TEMP, synthState->synthesisBuffers->mixEnvelopeState); } - unk7 = noteSubEu->unk_07; - unkE = noteSubEu->unk_0E; - buf = synthState->synthesisBuffers->unkState; - if (unk7 != 0 && noteSubEu->unk_0E != 0) { - AudioSynth_DMemMove(cmd++, DMEM_TEMP, DMEM_SCRATCH2, aiBufLen * SAMPLE_SIZE); - thing = DMEM_SCRATCH2 - unk7; - if (synthState->unk_1A != 0) { - AudioSynth_ClearBuffer(cmd++, thing, unk7); - synthState->unk_1A = 0; + // Apply the comb filter to the mono-signal by taking the signal with a small temporal offset, + // and adding it back to itself + combFilterSize = noteSubEu->combFilterSize; + combFilterGain = noteSubEu->combFilterGain; + combFilterState = synthState->synthesisBuffers->combFilterState; + if ((combFilterSize != 0) && (noteSubEu->combFilterGain != 0)) { + AudioSynth_DMemMove(cmd++, DMEM_TEMP, DMEM_COMB_TEMP, aiBufLen * SAMPLE_SIZE); + combFilterDmem = DMEM_COMB_TEMP - combFilterSize; + if (synthState->combFilterNeedsInit) { + AudioSynth_ClearBuffer(cmd++, combFilterDmem, combFilterSize); + synthState->combFilterNeedsInit = false; } else { - AudioSynth_LoadBuffer(cmd++, thing, unk7, buf); + AudioSynth_LoadBuffer(cmd++, combFilterDmem, combFilterSize, combFilterState); } - AudioSynth_SaveBuffer(cmd++, DMEM_TEMP + (aiBufLen * SAMPLE_SIZE) - unk7, unk7, buf); - AudioSynth_Mix(cmd++, (aiBufLen * (s32)SAMPLE_SIZE) >> 4, unkE, DMEM_SCRATCH2, thing); - AudioSynth_DMemMove(cmd++, thing, DMEM_TEMP, aiBufLen * SAMPLE_SIZE); + AudioSynth_SaveBuffer(cmd++, DMEM_TEMP + (aiBufLen * SAMPLE_SIZE) - combFilterSize, combFilterSize, + combFilterState); + AudioSynth_Mix(cmd++, (aiBufLen * (s32)SAMPLE_SIZE) >> 4, combFilterGain, DMEM_COMB_TEMP, combFilterDmem); + AudioSynth_DMemMove(cmd++, combFilterDmem, DMEM_TEMP, aiBufLen * SAMPLE_SIZE); } else { - synthState->unk_1A = 1; + synthState->combFilterNeedsInit = true; } if ((noteSubEu->haasEffectLeftDelaySize != 0) || (synthState->prevHaasEffectLeftDelaySize != 0)) { diff --git a/src/audio/lib/thread.c b/src/audio/lib/thread.c index 53cd7d246..22afc33fd 100644 --- a/src/audio/lib/thread.c +++ b/src/audio/lib/thread.c @@ -3,42 +3,23 @@ #define SAMPLES_TO_OVERPRODUCE 0x10 #define EXTRA_BUFFERED_AI_SAMPLES_TARGET 0x80 -typedef enum { - CHAN_UPD_UNK_0, // 0 - CHAN_UPD_VOL_SCALE, // 1 - CHAN_UPD_VOL, // 2 - CHAN_UPD_PAN_SIGNED, // 3 - CHAN_UPD_FREQ_SCALE, // 4 - CHAN_UPD_REVERB, // 5 - CHAN_UPD_SCRIPT_IO, // 6 - CHAN_UPD_PAN_UNSIGNED, // 7 - CHAN_UPD_STOP_SOMETHING2, // 8 - CHAN_UPD_MUTE_BEHAVE, // 9 - CHAN_UPD_VIBE_X8, // 10 - CHAN_UPD_VIBE_X32, // 11 - CHAN_UPD_UNK_0F, // 12 - CHAN_UPD_UNK_20, // 13 - CHAN_UPD_STEREO // 14 -} ChannelUpdateType; - -void func_800E6300(SequenceChannel* channel, AudioCmd* cmd); -void func_800E59AC(s32 playerIdx, s32 fadeTimer); -void Audio_InitMesgQueues(void); -AudioTask* func_800E5000(void); -void Audio_ProcessCmds(u32); -void func_800E6128(SequencePlayer* seqPlayer, AudioCmd* cmd); -void func_800E5958(s32 playerIdx, s32 fadeTimer); -s32 func_800E66C0(s32 arg0); +AudioTask* AudioThread_UpdateImpl(void); +void AudioThread_SetFadeInTimer(s32 seqPlayerIndex, s32 fadeTimer); +void AudioThread_SetFadeOutTimer(s32 seqPlayerIndex, s32 fadeTimer); +void AudioThread_ProcessCmds(u32); +void AudioThread_ProcessSeqPlayerCmd(SequencePlayer* seqPlayer, AudioCmd* cmd); +void AudioThread_ProcessChannelCmd(SequenceChannel* channel, AudioCmd* cmd); +s32 func_800E66C0(s32 flags); // AudioMgr_Retrace -AudioTask* func_800E4FE0(void) { - return func_800E5000(); +AudioTask* AudioThread_Update(void) { + return AudioThread_UpdateImpl(); } /** * This is Audio_Update for the audio thread */ -AudioTask* func_800E5000(void) { +AudioTask* AudioThread_UpdateImpl(void) { static s32 sMaxAbiCmdCnt = 0x80; static AudioTask* sWaitingAudioTask = NULL; u32 samplesRemainingInAi; @@ -55,8 +36,8 @@ AudioTask* func_800E5000(void) { gAudioCtx.totalTaskCount++; if (gAudioCtx.totalTaskCount % (gAudioCtx.audioBufferParameters.specUnk4) != 0) { - if (D_801755D0 != NULL) { - D_801755D0(); + if (gAudioCustomUpdateFunction != NULL) { + gAudioCustomUpdateFunction(); } if ((gAudioCtx.totalTaskCount % gAudioCtx.audioBufferParameters.specUnk4) + 1 == @@ -82,8 +63,8 @@ AudioTask* func_800E5000(void) { } } - if (D_801755D0 != NULL) { - D_801755D0(); + if (gAudioCustomUpdateFunction != NULL) { + gAudioCustomUpdateFunction(); } sp5C = gAudioCtx.curAudioFrameDmaCount; @@ -114,7 +95,7 @@ AudioTask* func_800E5000(void) { if (gAudioCtx.resetStatus != 0) { if (AudioHeap_ResetStep() == 0) { if (gAudioCtx.resetStatus == 0) { - osSendMesg(gAudioCtx.audioResetQueueP, (OSMesg)(u32)gAudioCtx.audioResetSpecIdToLoad, OS_MESG_NOBLOCK); + osSendMesg(gAudioCtx.audioResetQueueP, (OSMesg)(u32)gAudioCtx.specId, OS_MESG_NOBLOCK); } sWaitingAudioTask = NULL; @@ -151,13 +132,13 @@ AudioTask* func_800E5000(void) { j = 0; if (gAudioCtx.resetStatus == 0) { // msg = 0000RREE R = read pos, E = End Pos - while (osRecvMesg(gAudioCtx.cmdProcQueueP, (OSMesg*)&sp4C, OS_MESG_NOBLOCK) != -1) { + while (osRecvMesg(gAudioCtx.threadCmdProcQueueP, (OSMesg*)&sp4C, OS_MESG_NOBLOCK) != -1) { if (1) {} - Audio_ProcessCmds(sp4C); + AudioThread_ProcessCmds(sp4C); j++; } - if ((j == 0) && (gAudioCtx.cmdQueueFinished)) { - Audio_ScheduleProcessCmds(); + if ((j == 0) && (gAudioCtx.threadCmdQueueFinished)) { + AudioThread_ScheduleProcessCmds(); } } @@ -169,9 +150,9 @@ AudioTask* func_800E5000(void) { gAudioCtx.audioRandom = gAudioCtx.audioRandom + gAudioCtx.aiBuffers[index][gAudioCtx.totalTaskCount & 0xFF]; // gWaveSamples[8] interprets compiled assembly code as s16 samples as a way to generate sound with noise. - // Start with the address of func_800E4FE0, and offset it by a random number between 0 - 0xFFF0 + // Start with the address of AudioThread_Update, and offset it by a random number between 0 - 0xFFF0 // Use the resulting address as the starting address to interpret an array of samples i.e. `s16 samples[]` - gWaveSamples[8] = (s16*)(((u8*)func_800E4FE0) + (gAudioCtx.audioRandom & 0xFFF0)); + gWaveSamples[8] = (s16*)((u8*)AudioThread_Update + (gAudioCtx.audioRandom & 0xFFF0)); index = gAudioCtx.rspTaskIndex; gAudioCtx.curTask->msgQueue = NULL; @@ -208,63 +189,57 @@ AudioTask* func_800E5000(void) { } } -#define ACMD_SND_MDE ((u32)0xF0000000) -#define ACMD_MUTE ((u32)0xF1000000) - -void func_800E5584(AudioCmd* cmd) { +void AudioThread_ProcessGlobalCmd(AudioCmd* cmd) { s32 i; - s32 pad; - s32 pad2; - u32 temp_a1_5; - u32 temp_t7; + s32 pad[3]; + u32 flags; switch (cmd->op) { - case 0x81: + case AUDIOCMD_OP_GLOBAL_SYNC_LOAD_SEQ_PARTS: AudioLoad_SyncLoadSeqParts(cmd->arg1, cmd->arg2); break; - case 0x82: + case AUDIOCMD_OP_GLOBAL_INIT_SEQPLAYER: AudioLoad_SyncInitSeqPlayer(cmd->arg0, cmd->arg1, cmd->arg2); - func_800E59AC(cmd->arg0, cmd->asInt); + AudioThread_SetFadeInTimer(cmd->arg0, cmd->asInt); break; - case 0x85: + case AUDIOCMD_OP_GLOBAL_INIT_SEQPLAYER_SKIP_TICKS: AudioLoad_SyncInitSeqPlayerSkipTicks(cmd->arg0, cmd->arg1, cmd->asInt); break; - case 0x83: + case AUDIOCMD_OP_GLOBAL_DISABLE_SEQPLAYER: if (gAudioCtx.seqPlayers[cmd->arg0].enabled) { if (cmd->asInt == 0) { AudioSeq_SequencePlayerDisableAsFinished(&gAudioCtx.seqPlayers[cmd->arg0]); } else { - func_800E5958(cmd->arg0, cmd->asInt); + AudioThread_SetFadeOutTimer(cmd->arg0, cmd->asInt); } } break; - case 0xF0: + case AUDIOCMD_OP_GLOBAL_SET_SOUND_MODE: gAudioCtx.soundMode = cmd->asUInt; break; - case 0xF1: + case AUDIOCMD_OP_GLOBAL_MUTE: for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[i]; - seqPlayer->muted = 1; - seqPlayer->recalculateVolume = 1; + seqPlayer->muted = true; + seqPlayer->recalculateVolume = true; } break; - case 0xF2: + case AUDIOCMD_OP_GLOBAL_UNMUTE: if (cmd->asUInt == 1) { for (i = 0; i < gAudioCtx.numNotes; i++) { Note* note = &gAudioCtx.notes[i]; NoteSubEu* subEu = ¬e->noteSubEu; - if (subEu->bitField0.enabled && note->playbackState.unk_04 == 0) { - if (note->playbackState.parentLayer->channel->muteBehavior & MUTE_BEHAVIOR_3) { - subEu->bitField0.finished = true; - } + if (subEu->bitField0.enabled && (note->playbackState.unk_04 == 0) && + (note->playbackState.parentLayer->channel->muteBehavior & MUTE_BEHAVIOR_3)) { + subEu->bitField0.finished = true; } } } @@ -272,53 +247,53 @@ void func_800E5584(AudioCmd* cmd) { for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[i]; - seqPlayer->muted = 0; - seqPlayer->recalculateVolume = 1; + seqPlayer->muted = false; + seqPlayer->recalculateVolume = true; } break; - case 0xF3: + case AUDIOCMD_OP_GLOBAL_SYNC_LOAD_INSTRUMENT: AudioLoad_SyncLoadInstrument(cmd->arg0, cmd->arg1, cmd->arg2); break; - case 0xF4: + case AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_SAMPLE_BANK: AudioLoad_AsyncLoadSampleBank(cmd->arg0, cmd->arg1, cmd->arg2, &gAudioCtx.externalLoadQueue); break; - case 0xF5: + case AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_FONT: AudioLoad_AsyncLoadFont(cmd->arg0, cmd->arg1, cmd->arg2, &gAudioCtx.externalLoadQueue); break; - case 0xFC: + case AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_SEQ: AudioLoad_AsyncLoadSeq(cmd->arg0, cmd->arg1, cmd->arg2, &gAudioCtx.externalLoadQueue); break; - case 0xF6: + case AUDIOCMD_OP_GLOBAL_DISCARD_SEQ_FONTS: AudioLoad_DiscardSeqFonts(cmd->arg1); break; - case 0x90: - gAudioCtx.unk_5BDC[cmd->arg0] = cmd->asUShort; + case AUDIOCMD_OP_GLOBAL_SET_CHANNEL_MASK: + gAudioCtx.threadCmdChannelMask[cmd->arg0] = cmd->asUShort; break; - case 0xF9: + case AUDIOCMD_OP_GLOBAL_RESET_AUDIO_HEAP: gAudioCtx.resetStatus = 5; - gAudioCtx.audioResetSpecIdToLoad = cmd->asUInt; + gAudioCtx.specId = cmd->asUInt; break; - case 0xFB: - D_801755D0 = (void (*)(void))cmd->asUInt; + case AUDIOCMD_OP_GLOBAL_SET_CUSTOM_UPDATE_FUNCTION: + gAudioCustomUpdateFunction = (AudioCustomUpdateFunction)cmd->asUInt; break; - case 0xE0: - case 0xE1: - case 0xE2: - Audio_SetFontInstrument(cmd->op - 0xE0, cmd->arg0, cmd->arg1, cmd->data); + case AUDIOCMD_OP_GLOBAL_SET_DRUM_FONT: + case AUDIOCMD_OP_GLOBAL_SET_SFX_FONT: + case AUDIOCMD_OP_GLOBAL_SET_INSTRUMENT_FONT: + Audio_SetFontInstrument(cmd->op - AUDIOCMD_OP_GLOBAL_SET_DRUM_FONT, cmd->arg0, cmd->arg1, cmd->data); break; - case 0xFE: - temp_t7 = cmd->asUInt; - if (temp_t7 == 1) { + case AUDIOCMD_OP_GLOBAL_DISABLE_ALL_SEQPLAYERS: + flags = cmd->asUInt; + if (flags == 1) { for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[i]; @@ -327,10 +302,10 @@ void func_800E5584(AudioCmd* cmd) { } } } - func_800E66C0(temp_t7); + func_800E66C0(flags); break; - case 0xE3: + case AUDIOCMD_OP_GLOBAL_POP_PERSISTENT_CACHE: AudioHeap_PopPersistentCache(cmd->asInt); break; @@ -339,9 +314,8 @@ void func_800E5584(AudioCmd* cmd) { } } -// SetFadeOutTimer -void func_800E5958(s32 playerIdx, s32 fadeTimer) { - SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[playerIdx]; +void AudioThread_SetFadeOutTimer(s32 seqPlayerIndex, s32 fadeTimer) { + SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[seqPlayerIndex]; if (fadeTimer == 0) { fadeTimer = 1; @@ -352,12 +326,11 @@ void func_800E5958(s32 playerIdx, s32 fadeTimer) { seqPlayer->fadeTimer = fadeTimer; } -// SetFadeInTimer -void func_800E59AC(s32 playerIdx, s32 fadeTimer) { +void AudioThread_SetFadeInTimer(s32 seqPlayerIndex, s32 fadeTimer) { SequencePlayer* seqPlayer; if (fadeTimer != 0) { - seqPlayer = &gAudioCtx.seqPlayers[playerIdx]; + seqPlayer = &gAudioCtx.seqPlayers[seqPlayerIndex]; seqPlayer->state = 1; seqPlayer->fadeTimerUnkEu = fadeTimer; seqPlayer->fadeTimer = fadeTimer; @@ -366,63 +339,67 @@ void func_800E59AC(s32 playerIdx, s32 fadeTimer) { } } -void Audio_InitMesgQueuesInternal(void) { - gAudioCtx.cmdWrPos = 0; - gAudioCtx.cmdRdPos = 0; - gAudioCtx.cmdQueueFinished = 0; +void AudioThread_InitMesgQueuesImpl(void) { + gAudioCtx.threadCmdWritePos = 0; + gAudioCtx.threadCmdReadPos = 0; + gAudioCtx.threadCmdQueueFinished = false; + gAudioCtx.taskStartQueueP = &gAudioCtx.taskStartQueue; - gAudioCtx.cmdProcQueueP = &gAudioCtx.cmdProcQueue; + gAudioCtx.threadCmdProcQueueP = &gAudioCtx.threadCmdProcQueue; gAudioCtx.audioResetQueueP = &gAudioCtx.audioResetQueue; + osCreateMesgQueue(gAudioCtx.taskStartQueueP, gAudioCtx.taskStartMsgBuf, ARRAY_COUNT(gAudioCtx.taskStartMsgBuf)); - osCreateMesgQueue(gAudioCtx.cmdProcQueueP, gAudioCtx.cmdProcMsgBuf, ARRAY_COUNT(gAudioCtx.cmdProcMsgBuf)); + osCreateMesgQueue(gAudioCtx.threadCmdProcQueueP, gAudioCtx.threadCmdProcMsgBuf, + ARRAY_COUNT(gAudioCtx.threadCmdProcMsgBuf)); osCreateMesgQueue(gAudioCtx.audioResetQueueP, gAudioCtx.audioResetMsgBuf, ARRAY_COUNT(gAudioCtx.audioResetMsgBuf)); } -void Audio_QueueCmd(u32 opArgs, void** data) { - AudioCmd* cmd = &gAudioCtx.cmdBuf[gAudioCtx.cmdWrPos & 0xFF]; +void AudioThread_QueueCmd(u32 opArgs, void** data) { + AudioCmd* cmd = &gAudioCtx.threadCmdBuf[gAudioCtx.threadCmdWritePos & 0xFF]; cmd->opArgs = opArgs; cmd->data = *data; - gAudioCtx.cmdWrPos++; + gAudioCtx.threadCmdWritePos++; - if (gAudioCtx.cmdWrPos == gAudioCtx.cmdRdPos) { - gAudioCtx.cmdWrPos--; + if (gAudioCtx.threadCmdWritePos == gAudioCtx.threadCmdReadPos) { + gAudioCtx.threadCmdWritePos--; } } -void Audio_QueueCmdF32(u32 opArgs, f32 data) { - Audio_QueueCmd(opArgs, (void**)&data); +void AudioThread_QueueCmdF32(u32 opArgs, f32 data) { + AudioThread_QueueCmd(opArgs, (void**)&data); } -void Audio_QueueCmdS32(u32 opArgs, s32 data) { - Audio_QueueCmd(opArgs, (void**)&data); +void AudioThread_QueueCmdS32(u32 opArgs, s32 data) { + AudioThread_QueueCmd(opArgs, (void**)&data); } -void Audio_QueueCmdS8(u32 opArgs, s8 data) { +void AudioThread_QueueCmdS8(u32 opArgs, s8 data) { u32 uData = data << 0x18; - Audio_QueueCmd(opArgs, (void**)&uData); + AudioThread_QueueCmd(opArgs, (void**)&uData); } -void Audio_QueueCmdU16(u32 opArgs, u16 data) { +void AudioThread_QueueCmdU16(u32 opArgs, u16 data) { u32 uData = data << 0x10; - Audio_QueueCmd(opArgs, (void**)&uData); + AudioThread_QueueCmd(opArgs, (void**)&uData); } -s32 Audio_ScheduleProcessCmds(void) { +s32 AudioThread_ScheduleProcessCmds(void) { static s32 D_801304E8 = 0; s32 ret; - if (D_801304E8 < (u8)((gAudioCtx.cmdWrPos - gAudioCtx.cmdRdPos) + 0x100)) { - D_801304E8 = (u8)((gAudioCtx.cmdWrPos - gAudioCtx.cmdRdPos) + 0x100); + if (D_801304E8 < (u8)((gAudioCtx.threadCmdWritePos - gAudioCtx.threadCmdReadPos) + 0x100)) { + D_801304E8 = (u8)((gAudioCtx.threadCmdWritePos - gAudioCtx.threadCmdReadPos) + 0x100); } - ret = osSendMesg(gAudioCtx.cmdProcQueueP, - (OSMesg)(((gAudioCtx.cmdRdPos & 0xFF) << 8) | (gAudioCtx.cmdWrPos & 0xFF)), OS_MESG_NOBLOCK); + ret = osSendMesg(gAudioCtx.threadCmdProcQueueP, + (OSMesg)(((gAudioCtx.threadCmdReadPos & 0xFF) << 8) | (gAudioCtx.threadCmdWritePos & 0xFF)), + OS_MESG_NOBLOCK); if (ret != -1) { - gAudioCtx.cmdRdPos = gAudioCtx.cmdWrPos; + gAudioCtx.threadCmdReadPos = gAudioCtx.threadCmdWritePos; ret = 0; } else { return -1; @@ -431,72 +408,72 @@ s32 Audio_ScheduleProcessCmds(void) { return ret; } -void Audio_ResetCmdQueue(void) { - gAudioCtx.cmdQueueFinished = 0; - gAudioCtx.cmdRdPos = gAudioCtx.cmdWrPos; +void AudioThread_ResetCmdQueue(void) { + gAudioCtx.threadCmdQueueFinished = false; + gAudioCtx.threadCmdReadPos = gAudioCtx.threadCmdWritePos; } -void Audio_ProcessCmd(AudioCmd* cmd) { +void AudioThread_ProcessCmd(AudioCmd* cmd) { SequencePlayer* seqPlayer; - u16 phi_v0; - s32 i; + u16 threadCmdChannelMask; + s32 channelIndex; if ((cmd->op & 0xF0) == 0xF0) { - func_800E5584(cmd); + AudioThread_ProcessGlobalCmd(cmd); return; } if (cmd->arg0 < gAudioCtx.audioBufferParameters.numSequencePlayers) { seqPlayer = &gAudioCtx.seqPlayers[cmd->arg0]; if (cmd->op & 0x80) { - func_800E5584(cmd); + AudioThread_ProcessGlobalCmd(cmd); return; } if (cmd->op & 0x40) { - func_800E6128(seqPlayer, cmd); + AudioThread_ProcessSeqPlayerCmd(seqPlayer, cmd); return; } - if (cmd->arg1 < 0x10) { - func_800E6300(seqPlayer->channels[cmd->arg1], cmd); + if (cmd->arg1 < SEQ_NUM_CHANNELS) { + AudioThread_ProcessChannelCmd(seqPlayer->channels[cmd->arg1], cmd); return; } - if (cmd->arg1 == 0xFF) { - phi_v0 = gAudioCtx.unk_5BDC[cmd->arg0]; - for (i = 0; i < 16; i++) { - if (phi_v0 & 1) { - func_800E6300(seqPlayer->channels[i], cmd); + if (cmd->arg1 == AUDIOCMD_ALL_CHANNELS) { + threadCmdChannelMask = gAudioCtx.threadCmdChannelMask[cmd->arg0]; + for (channelIndex = 0; channelIndex < SEQ_NUM_CHANNELS; channelIndex++) { + if (threadCmdChannelMask & 1) { + AudioThread_ProcessChannelCmd(seqPlayer->channels[channelIndex], cmd); } - phi_v0 = phi_v0 >> 1; + threadCmdChannelMask = threadCmdChannelMask >> 1; } } } } -void Audio_ProcessCmds(u32 msg) { - static u8 curCmdRdPos = 0; +void AudioThread_ProcessCmds(u32 msg) { + static u8 sCurCmdRdPos = 0; AudioCmd* cmd; u8 endPos; - if (!gAudioCtx.cmdQueueFinished) { - curCmdRdPos = msg >> 8; + if (!gAudioCtx.threadCmdQueueFinished) { + sCurCmdRdPos = msg >> 8; } while (true) { endPos = msg & 0xFF; - if (curCmdRdPos == endPos) { - gAudioCtx.cmdQueueFinished = 0; + if (sCurCmdRdPos == endPos) { + gAudioCtx.threadCmdQueueFinished = false; return; } - cmd = &gAudioCtx.cmdBuf[curCmdRdPos++ & 0xFF]; - if (cmd->op == 0xF8) { - gAudioCtx.cmdQueueFinished = 1; + cmd = &gAudioCtx.threadCmdBuf[sCurCmdRdPos++ & 0xFF]; + if (cmd->op == AUDIOCMD_OP_GLOBAL_STOP_AUDIOCMDS) { + gAudioCtx.threadCmdQueueFinished = true; return; } - Audio_ProcessCmd(cmd); - cmd->op = 0; + AudioThread_ProcessCmd(cmd); + cmd->op = AUDIOCMD_OP_NOOP; } } @@ -511,8 +488,8 @@ u32 func_800E5E20(u32* out) { return sp1C >> 0x18; } -u8* func_800E5E84(s32 arg0, u32* arg1) { - return AudioLoad_GetFontsForSequence(arg0, arg1); +u8* AudioThread_GetFontsForSequence(s32 seqId, u32* outNumFonts) { + return AudioLoad_GetFontsForSequence(seqId, outNumFonts); } void Audio_GetSampleBankIdsOfFont(s32 fontId, u32* sampleBankId1, u32* sampleBankId2) { @@ -522,11 +499,11 @@ void Audio_GetSampleBankIdsOfFont(s32 fontId, u32* sampleBankId1, u32* sampleBan s32 func_800E5EDC(void) { s32 pad; - s32 sp18; + s32 specId; - if (osRecvMesg(gAudioCtx.audioResetQueueP, (OSMesg*)&sp18, OS_MESG_NOBLOCK) == -1) { + if (osRecvMesg(gAudioCtx.audioResetQueueP, (OSMesg*)&specId, OS_MESG_NOBLOCK) == -1) { return 0; - } else if (gAudioCtx.audioResetSpecIdToLoad != sp18) { + } else if (gAudioCtx.specId != specId) { return -1; } else { return 1; @@ -540,7 +517,7 @@ void func_800E5F34(void) { // clang-format on } -s32 func_800E5F88(s32 resetPreloadID) { +s32 AudioThread_ResetAudioHeap(s32 specId) { s32 resetStatus; OSMesg msg; s32 pad; @@ -548,11 +525,11 @@ s32 func_800E5F88(s32 resetPreloadID) { func_800E5F34(); resetStatus = gAudioCtx.resetStatus; if (resetStatus != 0) { - Audio_ResetCmdQueue(); - if (gAudioCtx.audioResetSpecIdToLoad == resetPreloadID) { + AudioThread_ResetCmdQueue(); + if (gAudioCtx.specId == specId) { return -2; } else if (resetStatus > 2) { - gAudioCtx.audioResetSpecIdToLoad = resetPreloadID; + gAudioCtx.specId = specId; return -3; } else { osRecvMesg(gAudioCtx.audioResetQueueP, &msg, OS_MESG_BLOCK); @@ -560,81 +537,81 @@ s32 func_800E5F88(s32 resetPreloadID) { } func_800E5F34(); - Audio_QueueCmdS32(0xF9000000, resetPreloadID); + AUDIOCMD_GLOBAL_RESET_AUDIO_HEAP(specId); - return Audio_ScheduleProcessCmds(); + return AudioThread_ScheduleProcessCmds(); } -void Audio_PreNMIInternal(void) { +void AudioThread_PreNMIInternal(void) { gAudioCtx.resetTimer = 1; if (gAudioContextInitialized) { - func_800E5F88(0); + AudioThread_ResetAudioHeap(0); gAudioCtx.resetStatus = 0; } } -s8 func_800E6070(s32 playerIdx, s32 channelIdx, s32 scriptIdx) { - SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[playerIdx]; +s8 AudioThread_GetChannelIO(s32 seqPlayerIndex, s32 channelIndex, s32 ioPort) { + SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[seqPlayerIndex]; SequenceChannel* channel; if (seqPlayer->enabled) { - channel = seqPlayer->channels[channelIdx]; - return channel->soundScriptIO[scriptIdx]; + channel = seqPlayer->channels[channelIndex]; + return channel->seqScriptIO[ioPort]; } else { - return -1; + return SEQ_IO_VAL_NONE; } } -s8 func_800E60C4(s32 playerIdx, s32 port) { - return gAudioCtx.seqPlayers[playerIdx].soundScriptIO[port]; +s8 AudioThread_GetSeqPlayerIO(s32 seqPlayerIndex, s32 ioPort) { + return gAudioCtx.seqPlayers[seqPlayerIndex].seqScriptIO[ioPort]; } -void Audio_InitExternalPool(void* ramAddr, u32 size) { +void AudioThread_InitExternalPool(void* ramAddr, u32 size) { AudioHeap_InitPool(&gAudioCtx.externalPool, ramAddr, size); } -void Audio_DestroyExternalPool(void) { +void AudioThread_ResetExternalPool(void) { gAudioCtx.externalPool.startRamAddr = NULL; } -void func_800E6128(SequencePlayer* seqPlayer, AudioCmd* cmd) { +void AudioThread_ProcessSeqPlayerCmd(SequencePlayer* seqPlayer, AudioCmd* cmd) { f32 fadeVolume; switch (cmd->op) { - case 0x41: + case AUDIOCMD_OP_SEQPLAYER_FADE_VOLUME_SCALE: if (seqPlayer->fadeVolumeScale != cmd->asFloat) { seqPlayer->fadeVolumeScale = cmd->asFloat; - seqPlayer->recalculateVolume = 1; + seqPlayer->recalculateVolume = true; } break; - case 0x47: - seqPlayer->tempo = cmd->asInt * 0x30; + case AUDIOCMD_OP_SEQPLAYER_SET_TEMPO: + seqPlayer->tempo = cmd->asInt * SEQTICKS_PER_BEAT; break; - case 0x49: - seqPlayer->unk_0C = cmd->asInt * 0x30; + case AUDIOCMD_OP_SEQPLAYER_CHANGE_TEMPO: + seqPlayer->tempoChange = cmd->asInt * SEQTICKS_PER_BEAT; break; - case 0x4E: - seqPlayer->unk_0C = cmd->asInt; + case AUDIOCMD_OP_SEQPLAYER_CHANGE_TEMPO_SEQTICKS: + seqPlayer->tempoChange = cmd->asInt; break; - case 0x48: + case AUDIOCMD_OP_SEQPLAYER_SET_TRANSPOSITION: seqPlayer->transposition = cmd->asSbyte; break; - case 0x46: - seqPlayer->soundScriptIO[cmd->arg2] = cmd->asSbyte; + case AUDIOCMD_OP_SEQPLAYER_SET_IO: + seqPlayer->seqScriptIO[cmd->arg2] = cmd->asSbyte; break; - case 0x4A: + case AUDIOCMD_OP_SEQPLAYER_FADE_TO_SET_VOLUME: fadeVolume = (s32)cmd->arg1 / 127.0f; - goto block_11; + goto apply_fade; - case 0x4B: + case AUDIOCMD_OP_SEQPLAYER_FADE_TO_SCALED_VOLUME: fadeVolume = ((s32)cmd->arg1 / 100.0f) * seqPlayer->fadeVolume; - block_11: + apply_fade: if (seqPlayer->state != 2) { seqPlayer->volume = seqPlayer->fadeVolume; if (cmd->asInt == 0) { @@ -649,7 +626,7 @@ void func_800E6128(SequencePlayer* seqPlayer, AudioCmd* cmd) { } break; - case 0x4C: + case AUDIOCMD_OP_SEQPLAYER_RESET_VOLUME: if (seqPlayer->state != 2) { if (cmd->asInt == 0) { seqPlayer->fadeVolume = seqPlayer->volume; @@ -663,7 +640,7 @@ void func_800E6128(SequencePlayer* seqPlayer, AudioCmd* cmd) { } break; - case 0x4D: + case AUDIOCMD_OP_SEQPLAYER_SET_BEND: seqPlayer->bend = cmd->asFloat; if (seqPlayer->bend == 1.0f) { seqPlayer->applyBend = false; @@ -677,82 +654,83 @@ void func_800E6128(SequencePlayer* seqPlayer, AudioCmd* cmd) { } } -void func_800E6300(SequenceChannel* channel, AudioCmd* cmd) { +void AudioThread_ProcessChannelCmd(SequenceChannel* channel, AudioCmd* cmd) { switch (cmd->op) { - case CHAN_UPD_VOL_SCALE: + case AUDIOCMD_OP_CHANNEL_SET_VOL_SCALE: if (channel->volumeScale != cmd->asFloat) { channel->volumeScale = cmd->asFloat; - channel->changes.s.volume = 1; + channel->changes.s.volume = true; } break; - case CHAN_UPD_VOL: + case AUDIOCMD_OP_CHANNEL_SET_VOL: if (channel->volume != cmd->asFloat) { channel->volume = cmd->asFloat; - channel->changes.s.volume = 1; + channel->changes.s.volume = true; } break; - case CHAN_UPD_PAN_SIGNED: + case AUDIOCMD_OP_CHANNEL_SET_PAN: if (channel->newPan != cmd->asSbyte) { channel->newPan = cmd->asSbyte; - channel->changes.s.pan = 1; + channel->changes.s.pan = true; } break; - case CHAN_UPD_PAN_UNSIGNED: + case AUDIOCMD_OP_CHANNEL_SET_PAN_WEIGHT: + //! @bug: Should compare `asSbyte` to `panChannelWeight` if (channel->newPan != cmd->asSbyte) { channel->panChannelWeight = cmd->asSbyte; - channel->changes.s.pan = 1; + channel->changes.s.pan = true; } break; - case CHAN_UPD_FREQ_SCALE: + case AUDIOCMD_OP_CHANNEL_SET_FREQ_SCALE: if (channel->freqScale != cmd->asFloat) { channel->freqScale = cmd->asFloat; - channel->changes.s.freqScale = 1; + channel->changes.s.freqScale = true; } break; - case CHAN_UPD_REVERB: - if (channel->reverb != cmd->asSbyte) { - channel->reverb = cmd->asSbyte; + case AUDIOCMD_OP_CHANNEL_SET_REVERB_VOLUME: + if (channel->targetReverbVol != cmd->asSbyte) { + channel->targetReverbVol = cmd->asSbyte; } break; - case CHAN_UPD_SCRIPT_IO: - if (cmd->arg2 < 8) { - channel->soundScriptIO[cmd->arg2] = cmd->asSbyte; + case AUDIOCMD_OP_CHANNEL_SET_IO: + if (cmd->arg2 < ARRAY_COUNT(channel->seqScriptIO)) { + channel->seqScriptIO[cmd->arg2] = cmd->asSbyte; } break; - case CHAN_UPD_STOP_SOMETHING2: - channel->stopSomething2 = cmd->asSbyte; + case AUDIOCMD_OP_CHANNEL_SET_MUTE: + channel->muted = cmd->asSbyte; break; - case CHAN_UPD_MUTE_BEHAVE: + case AUDIOCMD_OP_CHANNEL_SET_MUTE_BEHAVIOR: channel->muteBehavior = cmd->asSbyte; break; - case CHAN_UPD_VIBE_X8: - channel->vibratoExtentTarget = cmd->asUbyte * 8; - channel->vibratoExtentChangeDelay = 1; + case AUDIOCMD_OP_CHANNEL_SET_VIBRATO_DEPTH: + channel->vibratoDepthTarget = cmd->asUbyte * 8; + channel->vibratoDepthChangeDelay = 1; break; - case CHAN_UPD_VIBE_X32: + case AUDIOCMD_OP_CHANNEL_SET_VIBRATO_RATE: channel->vibratoRateTarget = cmd->asUbyte * 32; channel->vibratoRateChangeDelay = 1; break; - case CHAN_UPD_UNK_0F: - channel->unk_0F = cmd->asUbyte; + case AUDIOCMD_OP_CHANNEL_SET_COMB_FILTER_SIZE: + channel->combFilterSize = cmd->asUbyte; break; - case CHAN_UPD_UNK_20: - channel->unk_20 = cmd->asUShort; + case AUDIOCMD_OP_CHANNEL_SET_COMB_FILTER_GAIN: + channel->combFilterGain = cmd->asUShort; break; - case CHAN_UPD_STEREO: + case AUDIOCMD_OP_CHANNEL_SET_STEREO: channel->stereo.asByte = cmd->asUbyte; break; @@ -761,24 +739,33 @@ void func_800E6300(SequenceChannel* channel, AudioCmd* cmd) { } } -void func_800E64B0(s32 arg0, s32 arg1, s32 arg2) { - Audio_QueueCmdS32(((arg0 & 0xFF) << 0x10) | 0xFA000000 | ((arg1 & 0xFF) << 8) | (arg2 & 0xFF), 1); +/** + * Call an audio-thread command that has no code to process it. Unused. + */ +void AudioThread_Noop1Cmd(s32 arg0, s32 arg1, s32 arg2) { + AUDIOCMD_GLOBAL_NOOP_1(arg0, arg1, arg2, 1); } -void func_800E64F8(void) { - Audio_QueueCmdS32(0xFA000000, 0); +/** + * Call an audio-thread command that has no code to process it. Unused. + */ +void AudioThread_Noop1CmdZeroed(void) { + AUDIOCMD_GLOBAL_NOOP_1(0, 0, 0, 0); } -void func_800E651C(u32 arg0, s32 arg1) { - Audio_QueueCmdS32((arg1 & 0xFF) | 0xFD000000, arg0); +/** + * Call an audio-thread command that has no code to process it. Unused. + */ +void AudioThread_Noop2Cmd(u32 arg0, s32 arg1) { + AUDIOCMD_GLOBAL_NOOP_2(0, 0, arg1, arg0); } -void Audio_WaitForAudioTask(void) { +void AudioThread_WaitForAudioTask(void) { osRecvMesg(gAudioCtx.taskStartQueueP, NULL, OS_MESG_NOBLOCK); osRecvMesg(gAudioCtx.taskStartQueueP, NULL, OS_MESG_BLOCK); } -s32 func_800E6590(s32 playerIdx, s32 arg1, s32 arg2) { +s32 func_800E6590(s32 seqPlayerIndex, s32 channelIndex, s32 layerIndex) { SequencePlayer* seqPlayer; SequenceLayer* layer; Note* note; @@ -786,9 +773,9 @@ s32 func_800E6590(s32 playerIdx, s32 arg1, s32 arg2) { s32 loopEnd; s32 samplePos; - seqPlayer = &gAudioCtx.seqPlayers[playerIdx]; - if (seqPlayer->enabled && seqPlayer->channels[arg1]->enabled) { - layer = seqPlayer->channels[arg1]->layers[arg2]; + seqPlayer = &gAudioCtx.seqPlayers[seqPlayerIndex]; + if (seqPlayer->enabled && seqPlayer->channels[channelIndex]->enabled) { + layer = seqPlayer->channels[channelIndex]->layers[layerIndex]; if (layer == NULL) { return 0; } @@ -826,7 +813,7 @@ void func_800E66A0(void) { func_800E66C0(2); } -s32 func_800E66C0(s32 arg0) { +s32 func_800E66C0(s32 flags) { s32 phi_v1; NotePlaybackState* playbackState; NoteSubEu* noteSubEu; @@ -841,7 +828,7 @@ s32 func_800E66C0(s32 arg0) { if (note->noteSubEu.bitField0.enabled) { noteSubEu = ¬e->noteSubEu; if (playbackState->adsr.action.s.state != 0) { - if (arg0 >= 2) { + if (flags >= 2) { tunedSample = noteSubEu->tunedSample; if (tunedSample == NULL || noteSubEu->bitField1.isSyntheticWave) { continue; @@ -852,8 +839,8 @@ s32 func_800E66C0(s32 arg0) { } phi_v1++; - if ((arg0 & 1) == 1) { - playbackState->adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; + if ((flags & 1) == 1) { + playbackState->adsr.fadeOutVel = gAudioCtx.audioBufferParameters.ticksPerUpdateInv; playbackState->adsr.action.s.release = 1; } } @@ -862,14 +849,15 @@ s32 func_800E66C0(s32 arg0) { return phi_v1; } -u32 Audio_NextRandom(void) { - static u32 audRand = 0x12345678; +u32 AudioThread_NextRandom(void) { + static u32 sAudioRandom = 0x12345678; + + sAudioRandom = ((osGetCount() + 0x1234567) * (sAudioRandom + gAudioCtx.totalTaskCount)); + sAudioRandom += gAudioCtx.audioRandom; - audRand = ((osGetCount() + 0x1234567) * (audRand + gAudioCtx.totalTaskCount)); - audRand += gAudioCtx.audioRandom; - return audRand; + return sAudioRandom; } -void Audio_InitMesgQueues(void) { - Audio_InitMesgQueuesInternal(); +void AudioThread_InitMesgQueues(void) { + AudioThread_InitMesgQueuesImpl(); } |
