Document Audio Thread Commands (#1399)

* begin docs

* cleanup

* copy over progress

* cleanup

* small cleanup

* more docs, fill out cmds

* small touchup

* pan weight ganon comment

* fix specId

* seqcmd cleanup

* format

* small cleanup

* one more thing

* small feedback from MM

* partial PR

* some PR Suggestions

* small adjustments

* ticks, seqticks, frames, updates: term cleanup

* small fix

* PR Review

* PR Review

* PR Review

* rm param

* adjust comment

* update renamed functions

* format

---------

Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>
This commit is contained in:
engineer124
2024-02-01 10:25:23 +11:00
committed by GitHub
parent d65fb6ed28
commit a0d31dba68
25 changed files with 1393 additions and 842 deletions
+21 -21
View File
@@ -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 = &note->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;
}
+25 -24
View File
@@ -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;
+10 -9
View File
@@ -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();
+21 -21
View File
@@ -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;
}
+79 -75
View File
@@ -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;
+37 -34
View File
@@ -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)) {
+223 -235
View File
@@ -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 = &note->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 = &note->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;
audRand = ((osGetCount() + 0x1234567) * (audRand + gAudioCtx.totalTaskCount));
audRand += gAudioCtx.audioRandom;
return audRand;
sAudioRandom = ((osGetCount() + 0x1234567) * (sAudioRandom + gAudioCtx.totalTaskCount));
sAudioRandom += gAudioCtx.audioRandom;
return sAudioRandom;
}
void Audio_InitMesgQueues(void) {
Audio_InitMesgQueuesInternal();
void AudioThread_InitMesgQueues(void) {
AudioThread_InitMesgQueuesImpl();
}