From 22ccdea772aafe65b7fa4160219246d32762c26a Mon Sep 17 00:00:00 2001 From: engineer124 Date: Wed, 1 Jun 2022 16:39:57 +1000 Subject: [PATCH 1/6] Sequence Instruction Documentation WIP --- src/code/audio_seqplayer.c | 537 ++++++++++++++++++++----------------- 1 file changed, 295 insertions(+), 242 deletions(-) diff --git a/src/code/audio_seqplayer.c b/src/code/audio_seqplayer.c index 566ce17f92c..87583b3c968 100644 --- a/src/code/audio_seqplayer.c +++ b/src/code/audio_seqplayer.c @@ -43,87 +43,87 @@ u8 AudioSeq_GetInstrument(SequenceChannel* channel, u8 instId, Instrument** inst (((sizeof(arg0Type) - 1) << 7) | ((sizeof(arg1Type) - 1) << 6) | ((sizeof(arg2Type) - 1) << 5) | 3) u8 sSeqInstructionArgsTable[] = { - CMD_ARGS_1(s16), // 0xB0 - CMD_ARGS_0(), // 0xB1 - CMD_ARGS_1(s16), // 0xB2 - CMD_ARGS_1(u8), // 0xB3 - CMD_ARGS_0(), // 0xB4 - CMD_ARGS_0(), // 0xB5 - CMD_ARGS_0(), // 0xB6 - CMD_ARGS_1(s16), // 0xB7 - CMD_ARGS_1(u8), // 0xB8 - CMD_ARGS_1(u8), // 0xB9 - CMD_ARGS_1(u8), // 0xBA - CMD_ARGS_2(u8, s16), // 0xBB - CMD_ARGS_1(s16), // 0xBC - CMD_ARGS_2(s16, s16), // 0xBD - CMD_ARGS_0(), // 0xBE - CMD_ARGS_0(), // 0xBF - CMD_ARGS_0(), // 0xC0 - CMD_ARGS_1(u8), // 0xC1 - CMD_ARGS_1(s16), // 0xC2 - CMD_ARGS_0(), // 0xC3 - CMD_ARGS_0(), // 0xC4 - CMD_ARGS_0(), // 0xC5 - CMD_ARGS_1(u8), // 0xC6 - CMD_ARGS_2(u8, s16), // 0xC7 - CMD_ARGS_1(u8), // 0xC8 - CMD_ARGS_1(u8), // 0xC9 - CMD_ARGS_1(u8), // 0xCA - CMD_ARGS_1(s16), // 0xCB - CMD_ARGS_1(u8), // 0xCC - CMD_ARGS_1(u8), // 0xCD - CMD_ARGS_1(s16), // 0xCE - CMD_ARGS_1(s16), // 0xCF - CMD_ARGS_1(u8), // 0xD0 - CMD_ARGS_1(u8), // 0xD1 - CMD_ARGS_1(u8), // 0xD2 - CMD_ARGS_1(u8), // 0xD3 - CMD_ARGS_1(u8), // 0xD4 - CMD_ARGS_1(u8), // 0xD5 - CMD_ARGS_1(u8), // 0xD6 - CMD_ARGS_1(u8), // 0xD7 - CMD_ARGS_1(u8), // 0xD8 - CMD_ARGS_1(u8), // 0xD9 - CMD_ARGS_1(s16), // 0xDA - CMD_ARGS_1(u8), // 0xDB - CMD_ARGS_1(u8), // 0xDC - CMD_ARGS_1(u8), // 0xDD - CMD_ARGS_1(s16), // 0xDE - CMD_ARGS_1(u8), // 0xDF - CMD_ARGS_1(u8), // 0xE0 - CMD_ARGS_3(u8, u8, u8), // 0xE1 - CMD_ARGS_3(u8, u8, u8), // 0xE2 - CMD_ARGS_1(u8), // 0xE3 - CMD_ARGS_0(), // 0xE4 - CMD_ARGS_1(u8), // 0xE5 - CMD_ARGS_1(u8), // 0xE6 - CMD_ARGS_1(s16), // 0xE7 - CMD_ARGS_3(u8, u8, u8), // 0xE8 - CMD_ARGS_1(u8), // 0xE9 - CMD_ARGS_0(), // 0xEA - CMD_ARGS_2(u8, u8), // 0xEB - CMD_ARGS_0(), // 0xEC - CMD_ARGS_1(u8), // 0xED - CMD_ARGS_1(u8), // 0xEE - CMD_ARGS_2(s16, u8), // 0xEF - CMD_ARGS_0(), // 0xF0 - CMD_ARGS_1(u8), // 0xF1 + CMD_ARGS_1(s16), // 0xB0 (`ldfilter(addr)`, channel: set filter) + CMD_ARGS_0(), // 0xB1 (`freefilter()`, channel: clear filter) + CMD_ARGS_1(s16), // 0xB2 (`ldseqtoptr(addr)`, channel: dynread sequence large) + CMD_ARGS_1(u8), // 0xB3 (`filter(u8)`, channel: load filter) + CMD_ARGS_0(), // 0xB4 (`ptrtodyntbl()`, channel: set dyntable large) + CMD_ARGS_0(), // 0xB5 (`dyntbltoptr()`, channel: read dyntable large) + CMD_ARGS_0(), // 0xB6 (`dyntblv()`, channel: read dyntable) + CMD_ARGS_1(s16), // 0xB7 (`randtoptr(u16)`, channel: random large) + CMD_ARGS_1(u8), // 0xB8 (`rand()`, channel: random value) + CMD_ARGS_1(u8), // 0xB9 (`randvel(u8)`, channel: set velocity random variance) + CMD_ARGS_1(u8), // 0xBA (`randgate(u8)`, channel: set gatetime random variance) + CMD_ARGS_2(u8, s16), // 0xBB (`unkbb(u8, u16)`, channel:) + CMD_ARGS_1(s16), // 0xBC (`ptradd(u16)`, channel: add large) + CMD_ARGS_2(s16, s16), // 0xBD (`randptr(u16, u16)`, channel: random range large) + CMD_ARGS_0(), // 0xBE () + CMD_ARGS_0(), // 0xBF () + CMD_ARGS_0(), // 0xC0 () + CMD_ARGS_1(u8), // 0xC1 (`instr(u8)`, channel: set instrument) + CMD_ARGS_1(s16), // 0xC2 (`dyntbl(addr)`, channel: set dyntable) + CMD_ARGS_0(), // 0xC3 (`short()`, channel: large notes off) + CMD_ARGS_0(), // 0xC4 (`noshort()`, channel: large notes on) + CMD_ARGS_0(), // 0xC5 (`dyntbllookup()`, channel: dyn set dyntable) + CMD_ARGS_1(u8), // 0xC6 (`font(u8)`, channel: set soundFont) + CMD_ARGS_2(u8, s16), // 0xC7 (`stseq(u8, addr)`, channel: write into sequence script) + CMD_ARGS_1(u8), // 0xC8 (`sub(u8)`, channel: subtract -> set value) + CMD_ARGS_1(u8), // 0xC9 (`and(u8)`, channel: `bit and` -> set value) + CMD_ARGS_1(u8), // 0xCA (`mutebhv(hex8)`, channel: set mute behavior) + CMD_ARGS_1(s16), // 0xCB (`ldseq(addr)`, channel: read sequence -> set value) + CMD_ARGS_1(u8), // 0xCC (`ldi(u8)`, channel: set value) + CMD_ARGS_1(u8), // 0xCD (`stopchan(u8)`, channel: disable channel) + CMD_ARGS_1(s16), // 0xCE (`ldptr(hex16)`, channel: ?? (load pointer?)) + CMD_ARGS_1(s16), // 0xCF (`stptrtoseq(addr)` channel: write large into sequence script) + CMD_ARGS_1(u8), // 0xD0 (`effects(u8)`, channel: stereo headset effects) + CMD_ARGS_1(u8), // 0xD1 (`notealloc(u8)`, channel: set note allocation policy) + CMD_ARGS_1(u8), // 0xD2 (`sustain(u8)`, channel: set sustain) + CMD_ARGS_1(u8), // 0xD3 (`bend(s8)`, channel: large bend pitch) + CMD_ARGS_1(u8), // 0xD4 (`reverb(u8)`, channel: set reverb) + CMD_ARGS_1(u8), // 0xD5 () + CMD_ARGS_1(u8), // 0xD6 () + CMD_ARGS_1(u8), // 0xD7 (`vibfreq(u8)`, channel: set vibrato rate) + CMD_ARGS_1(u8), // 0xD8 (`vibdepth(u8)`, channel: set vibrato extent) + CMD_ARGS_1(u8), // 0xD9 (`releaserate(u8)`, channel: set decay index) + CMD_ARGS_1(s16), // 0xDA (`env(addr)`, channel: set envelope) + CMD_ARGS_1(u8), // 0xDB (`transpose(s8)`, channel: transpose) + CMD_ARGS_1(u8), // 0xDC (`panweight(u8)`, channel: set pan mix) + CMD_ARGS_1(u8), // 0xDD (`pan(u8)`, channel: set pan) + CMD_ARGS_1(s16), // 0xDE (`freqscale(u16)`, channel: set freqscale) + CMD_ARGS_1(u8), // 0xDF (`vol(u8)`, channel: set volume) + CMD_ARGS_1(u8), // 0xE0 (`volexp(u8)`, channel: set volume scale) + CMD_ARGS_3(u8, u8, u8), // 0xE1 (`vibfreqgrad(u8, u8, u8)`, channel: set vibratorate linear) + CMD_ARGS_3(u8, u8, u8), // 0xE2 (`vibdepthgrad(u8, u8, u8)`, channel: set vibrato extent linear) + CMD_ARGS_1(u8), // 0xE3 (`vibdelay(u8)`, channel: set vibrato delay) + CMD_ARGS_0(), // 0xE4 (`dyncall()`, channel: dyncall) + CMD_ARGS_1(u8), // 0xE5 (`rvrbidx(u8)`, channel: set reverb index) + CMD_ARGS_1(u8), // 0xE6 (`samplbook(addr)`, channel: set book offset) + CMD_ARGS_1(s16), // 0xE7 (`ldparams(addr)`, channel: load parameters) + CMD_ARGS_3(u8, u8, u8), // 0xE8 (`params(u8, u8, u8, s8, s8, u8, u8, u8)`, channel set parameters) + CMD_ARGS_1(u8), // 0xE9 (`notepri(u8)`, channel: set note priority) + CMD_ARGS_0(), // 0xEA (`stop()`, channel: stop script) + CMD_ARGS_2(u8, u8), // 0xEB (`fontinstr()`, channel: set soundFont and instrument) + CMD_ARGS_0(), // 0xEC (``, channel: reset vibrato) + CMD_ARGS_1(u8), // 0xED (`gain(u8)`, channel: set hilo gain) + CMD_ARGS_1(u8), // 0xEE (`bendfine(s8)`, channel: small bend pitch) + CMD_ARGS_2(s16, u8), // 0xEF () + CMD_ARGS_0(), // 0xF0 (`freenotelist()`, channel: unreserve notes) + CMD_ARGS_1(u8), // 0xF1 (`allocnotelist(u8)`, channel: reserve notes) // Control flow instructions (>= 0xF2) can only have 0 or 1 args - CMD_ARGS_1(u8), // 0xF2 - CMD_ARGS_1(u8), // 0xF3 - CMD_ARGS_1(u8), // 0xF4 - CMD_ARGS_1(s16), // 0xF5 - CMD_ARGS_0(), // 0xF6 - CMD_ARGS_0(), // 0xF7 - CMD_ARGS_1(u8), // 0xF8 - CMD_ARGS_1(s16), // 0xF9 - CMD_ARGS_1(s16), // 0xFA - CMD_ARGS_1(s16), // 0xFB - CMD_ARGS_1(s16), // 0xFC - CMD_ARGS_0(), // 0xFD - CMD_ARGS_0(), // 0xFE - CMD_ARGS_0(), // 0xFF + CMD_ARGS_1(u8), // 0xF2 (`rbltz(reladdr8)`, branch relative if less than zero) + CMD_ARGS_1(u8), // 0xF3 (`rbeqz(reladdr8)`, branch relative if equal to zero) + CMD_ARGS_1(u8), // 0xF4 (`rjump(reladdr8)`, jump relative) + CMD_ARGS_1(s16), // 0xF5 (`bgez(addr)`, branch if greater than or equal to zero) + CMD_ARGS_0(), // 0xF6 (`break()`, break) + CMD_ARGS_0(), // 0xF7 (`loopend()`, loop end) + CMD_ARGS_1(u8), // 0xF8 (`loop(u8)`, loop) + CMD_ARGS_1(s16), // 0xF9 (`bltz(addr)`, branch if less than zero) + CMD_ARGS_1(s16), // 0xFA (`beqz(addr)`, branch if equal to zero) + CMD_ARGS_1(s16), // 0xFB (`jump()`, jump) + CMD_ARGS_1(s16), // 0xFC (`call(addr)`, call and jump to a function) + CMD_ARGS_0(), // 0xFD (`delay(var)`, delay n frames) + CMD_ARGS_0(), // 0xFE (`delay1()`, delay 1 frame) + CMD_ARGS_0(), // 0xFF (`end()`, end script) }; /** @@ -147,32 +147,36 @@ u16 AudioSeq_GetScriptControlFlowArgument(SeqScriptState* state, u8 cmd) { return cmdArg; } +/** + * Read and execute the control flow sequence instructions + * @return number of frames until next instruction. -1 signals termination + */ s32 AudioSeq_HandleScriptFlowControl(SequencePlayer* seqPlayer, SeqScriptState* state, s32 cmd, s32 cmdArg) { switch (cmd) { - case 0xFF: + case 0xFF: // `end()`, end script if (state->depth == 0) { return -1; } state->pc = state->stack[--state->depth]; break; - case 0xFD: + case 0xFD: // `delay(var)`, delay n frames return AudioSeq_ScriptReadCompressedU16(state); - case 0xFE: + case 0xFE: // `delay1()`, delay 1 frame return 1; - case 0xFC: + case 0xFC: // `call(addr)`, call and jump to a function state->stack[state->depth++] = state->pc; state->pc = seqPlayer->seqData + (u16)cmdArg; break; - case 0xF8: + case 0xF8: // `loop(u8)`, loop state->remLoopIters[state->depth] = cmdArg; state->stack[state->depth++] = state->pc; break; - case 0xF7: + case 0xF7: // `loopend()`, loop end state->remLoopIters[state->depth - 1]--; if (state->remLoopIters[state->depth - 1] != 0) { state->pc = state->stack[state->depth - 1]; @@ -181,14 +185,14 @@ s32 AudioSeq_HandleScriptFlowControl(SequencePlayer* seqPlayer, SeqScriptState* } break; - case 0xF6: + case 0xF6: // `break()`, break state->depth--; break; - case 0xF5: - case 0xF9: - case 0xFA: - case 0xFB: + case 0xF5: // `bgez(addr)`, branch if greater than or equal to zero + case 0xF9: // `bltz(addr)`, branch if less than zero + case 0xFA: // `beqz(addr)`, branch if equal to zero + case 0xFB: // `jump()`, jump if (cmd == 0xFA && state->value != 0) { break; } @@ -201,9 +205,9 @@ s32 AudioSeq_HandleScriptFlowControl(SequencePlayer* seqPlayer, SeqScriptState* state->pc = seqPlayer->seqData + (u16)cmdArg; break; - case 0xF2: - case 0xF3: - case 0xF4: + case 0xF2: // `rbltz(reladdr8)`, branch relative if less than zero + case 0xF3: // `rbeqz(reladdr8)`, branch relative if equal to zero + case 0xF4: // `rjump(reladdr8)`, jump relative if (cmd == 0xF3 && state->value != 0) { break; } @@ -585,9 +589,14 @@ s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer) { for (;;) { cmd = AudioSeq_ScriptReadU8(state); - if (cmd < 0xC1) { + + // Note Commands + // To be processed in AudioSeq_SeqLayerProcessScriptStep3 + if (cmd <= 0xC0) { return cmd; } + + // Control Flow Commands if (cmd >= 0xF2) { cmdArg = AudioSeq_GetScriptControlFlowArgument(state, cmd); @@ -599,8 +608,8 @@ s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer) { } switch (cmd) { - case 0xC1: // layer_setshortnotevelocity - case 0xCA: // layer_setpan + case 0xC1: // `shortvel(u8)`, layer: set short note velocity + case 0xCA: // `notepan(u8)`, layer: set pan tempByte = *(state->pc++); if (cmd == 0xC1) { @@ -610,8 +619,8 @@ s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer) { } break; - case 0xC9: // layer_setshortnotegatetime - case 0xC2: // layer_transpose; set transposition in semitones + case 0xC9: // `shortgate(u8)`, layer: set short note gatetime + case 0xC2: // `transpose(s8)`, layer: set transposition in semitones tempByte = *(state->pc++); if (cmd == 0xC9) { @@ -621,8 +630,8 @@ s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer) { } break; - case 0xC4: // layer_continuousnoteson - case 0xC5: // layer_continuousnotesoff + case 0xC4: // `legato()`, layer: continuous notes on + case 0xC5: // `nolegato()`, layer: continuous notes off if (cmd == 0xC4) { layer->continuousNotes = true; } else { @@ -632,19 +641,22 @@ s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer) { Audio_SeqLayerNoteDecay(layer); break; - case 0xC3: // layer_setshortnotedefaultdelay + case 0xC3: // `shortdelay(var)`, layer: set short note default delay sp3A = AudioSeq_ScriptReadCompressedU16(state); layer->shortNoteDefaultDelay = sp3A; break; - case 0xC6: // layer_setinstr + case 0xC6: // `instr(u8)`, layer: set instrument cmd = AudioSeq_ScriptReadU8(state); if (cmd >= 0x7E) { if (cmd == 0x7E) { + // Sfxs layer->instOrWave = 1; } else if (cmd == 0x7F) { + // Drums layer->instOrWave = 0; } else { + // Synthetic Wave layer->instOrWave = cmd; layer->instrument = NULL; } @@ -652,16 +664,16 @@ s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer) { if (cmd == 0xFF) { layer->adsr.decayIndex = 0; } - - break; - } - - if ((layer->instOrWave = AudioSeq_GetInstrument(channel, cmd, &layer->instrument, &layer->adsr)) == 0) { - layer->instOrWave = 0xFF; + } else { + // Instrument + if ((layer->instOrWave = AudioSeq_GetInstrument(channel, cmd, &layer->instrument, &layer->adsr)) == + 0) { + layer->instOrWave = 0xFF; + } } break; - case 0xC7: // layer_portamento + case 0xC7: // `portamento(hex8, u8, u8)`, layer: enable portamento layer->portamento.mode = AudioSeq_ScriptReadU8(state); cmd = AudioSeq_ScriptReadU8(state); @@ -685,39 +697,39 @@ s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer) { layer->portamentoTime = sp3A; break; - case 0xC8: // layer_disableportamento + case 0xC8: // `noportamento()`, layer: disable portamento layer->portamento.mode = 0; break; - case 0xCB: + case 0xCB: // `env(addr, u8)`, layer: set envelope and decay index sp3A = AudioSeq_ScriptReadS16(state); layer->adsr.envelope = (AdsrEnvelope*)(seqPlayer->seqData + sp3A); // fallthrough - case 0xCF: + case 0xCF: // `releaserate(u8)`, layer: set decay index layer->adsr.decayIndex = AudioSeq_ScriptReadU8(state); break; - case 0xCC: + case 0xCC: // `nodrumpan()`, layer: ignore drum pan layer->ignoreDrumPan = true; break; - case 0xCD: + case 0xCD: // `stereo(u8)`, layer: stereo effects layer->stereo.asByte = AudioSeq_ScriptReadU8(state); break; - case 0xCE: + case 0xCE: // `bendfine(s8)`, layer: bend pitch tempByte = AudioSeq_ScriptReadU8(state); layer->unk_34 = gBendPitchTwoSemitonesFrequencies[(tempByte + 0x80) & 0xFF]; break; default: switch (cmd & 0xF0) { - case 0xD0: // layer_setshortnotevelocityfromtable + case 0xD0: // `ldshortvel(bits:4)`, layer: set short note velocity from table sp3A = seqPlayer->shortNoteVelocityTable[cmd & 0xF]; layer->velocitySquare = (f32)(sp3A * sp3A) / 16129.0f; break; - case 0xE0: // layer_setshortnotegatetimefromtable + case 0xE0: // `ldshortgate(bits:4)`, layer: set short note gatetime from table layer->gateTime = (u8)seqPlayer->shortNoteGateTimeTable[cmd & 0xF]; break; } @@ -760,6 +772,7 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) { switch (instOrWave) { case 0: + // Drums semitone += channel->transposition + layer->transposition; layer->semitone = semitone; drum = Audio_GetDrum(channel->fontId, semitone); @@ -779,6 +792,7 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) { break; case 1: + // Sfxs layer->semitone = semitone; sfxId = (layer->transposition << 6) + semitone; sound = Audio_GetSfx(channel->fontId, sfxId); @@ -928,7 +942,7 @@ s32 AudioSeq_SeqLayerProcessScriptStep3(SequenceLayer* layer, s32 cmd) { s32 intDelta; f32 floatDelta; - if (cmd == 0xC0) { + if (cmd == 0xC0) { // `ldelay(var)`, layer: delay layer->delay = AudioSeq_ScriptReadCompressedU16(state); layer->stopSomething = true; layer->bit1 = false; @@ -938,21 +952,21 @@ s32 AudioSeq_SeqLayerProcessScriptStep3(SequenceLayer* layer, s32 cmd) { layer->stopSomething = false; if (channel->largeNotes == 1) { switch (cmd & 0xC0) { - case 0x00: + case 0x00: // `notedvg(bits:6, var, u8, u8)`, layer: large note 0 delay = AudioSeq_ScriptReadCompressedU16(state); velocity = *(state->pc++); layer->gateTime = *(state->pc++); layer->lastDelay = delay; break; - case 0x40: + case 0x40: // `notedv(bits:6, var, u8)`, layer: large note 1 delay = AudioSeq_ScriptReadCompressedU16(state); velocity = *(state->pc++); layer->gateTime = 0; layer->lastDelay = delay; break; - case 0x80: + case 0x80: // `notevg(bits:6, u8, u8)`, layer: large note 2 delay = layer->lastDelay; velocity = *(state->pc++); layer->gateTime = *(state->pc++); @@ -966,16 +980,16 @@ s32 AudioSeq_SeqLayerProcessScriptStep3(SequenceLayer* layer, s32 cmd) { cmd -= (cmd & 0xC0); } else { switch (cmd & 0xC0) { - case 0x00: + case 0x00: // `shortdvg(bits:6, var)`, layer: small note 0 delay = AudioSeq_ScriptReadCompressedU16(state); layer->lastDelay = delay; break; - case 0x40: + case 0x40: // `shortdv(bits:6)`, layer: small note 1 delay = layer->shortNoteDefaultDelay; break; - case 0x80: + case 0x80: // `shortvg(bits:6)`, layer: small note 2 delay = layer->lastDelay; break; } @@ -1051,18 +1065,24 @@ u8 AudioSeq_GetInstrument(SequenceChannel* channel, u8 instId, Instrument** inst void AudioSeq_SetInstrument(SequenceChannel* channel, u8 instId) { if (instId >= 0x80) { + // Synthetic Waves channel->instOrWave = instId; channel->instrument = NULL; } else if (instId == 0x7F) { + // Drums channel->instOrWave = 0; channel->instrument = (Instrument*)1; } else if (instId == 0x7E) { + // Sfxs channel->instOrWave = 1; channel->instrument = (Instrument*)2; - } else if ((channel->instOrWave = AudioSeq_GetInstrument(channel, instId, &channel->instrument, &channel->adsr)) == - 0) { - channel->hasInstrument = false; - return; + } else { + // Instruments + if ((channel->instOrWave = AudioSeq_GetInstrument(channel, instId, &channel->instrument, &channel->adsr)) == + 0) { + channel->hasInstrument = false; + return; + } } channel->hasInstrument = true; } @@ -1115,6 +1135,8 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { cmdArgs[i] = AudioSeq_ScriptReadS16(scriptState); } } + + // Control Flow Commands if (cmd >= 0xF2) { result = AudioSeq_HandleScriptFlowControl(seqPlayer, scriptState, cmd, cmdArgs[0]); @@ -1128,26 +1150,26 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { } } else { switch (cmd) { - case 0xEA: + case 0xEA: // `stop()`, channel: stop script channel->stopScript = true; goto exit_loop; - case 0xF1: + case 0xF1: // `allocnotelist(u8)`, channel: reserve notes Audio_NotePoolClear(&channel->notePool); cmd = (u8)cmdArgs[0]; Audio_NotePoolFill(&channel->notePool, cmd); break; - case 0xF0: + case 0xF0: // `freenotelist()`, channel: unreserve notes Audio_NotePoolClear(&channel->notePool); break; - case 0xC2: + case 0xC2: // `dyntbl(addr)`, channel: set dyntable offset = (u16)cmdArgs[0]; channel->dynTable = (void*)&seqPlayer->seqData[offset]; break; - case 0xC5: + case 0xC5: // `dyntbllookup()`, channel: dyn set dyntable if (scriptState->value != -1) { data = (*channel->dynTable)[scriptState->value]; @@ -1157,7 +1179,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { } break; - case 0xEB: + case 0xEB: // `fontinstr()`, channel: set soundFont and instrument result = (u8)cmdArgs[0]; cmd = (u8)cmdArgs[0]; @@ -1173,93 +1195,93 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { cmdArgs[0] = cmdArgs[1]; // fallthrough - case 0xC1: + case 0xC1: // `instr(u8)`, channel: set instrument cmd = (u8)cmdArgs[0]; AudioSeq_SetInstrument(channel, cmd); break; - case 0xC3: + case 0xC3: // `short()`, channel: large notes off channel->largeNotes = false; break; - case 0xC4: + case 0xC4: // `noshort()`, channel: large notes on channel->largeNotes = true; break; - case 0xDF: + case 0xDF: // `vol(u8)`, channel: set volume cmd = (u8)cmdArgs[0]; AudioSeq_SequenceChannelSetVolume(channel, cmd); channel->changes.s.volume = true; break; - case 0xE0: + case 0xE0: // `volexp(u8)`, channel: set volume scale cmd = (u8)cmdArgs[0]; channel->volumeScale = (f32)(s32)cmd / 128.0f; channel->changes.s.volume = true; break; - case 0xDE: + case 0xDE: // `freqscale(u16)`, channel: set freqscale offset = (u16)cmdArgs[0]; channel->freqScale = (f32)(s32)offset / 32768.0f; channel->changes.s.freqScale = true; break; - case 0xD3: + case 0xD3: // `bend(s8)`, channel: large bend pitch cmd = (u8)cmdArgs[0]; cmd += 0x80; channel->freqScale = gBendPitchOneOctaveFrequencies[cmd]; channel->changes.s.freqScale = true; break; - case 0xEE: + case 0xEE: // `bendfine(s8)`, channel: small bend pitch cmd = (u8)cmdArgs[0]; cmd += 0x80; channel->freqScale = gBendPitchTwoSemitonesFrequencies[cmd]; channel->changes.s.freqScale = true; break; - case 0xDD: + case 0xDD: // `pan(u8)`, channel: set pan cmd = (u8)cmdArgs[0]; channel->newPan = cmd; channel->changes.s.pan = true; break; - case 0xDC: + case 0xDC: // `panweight(u8)`, channel: set pan mix cmd = (u8)cmdArgs[0]; channel->panChannelWeight = cmd; channel->changes.s.pan = true; break; - case 0xDB: + case 0xDB: // `transpose(s8)`, channel: transpose signedParam = (s8)cmdArgs[0]; channel->transposition = signedParam; break; - case 0xDA: + case 0xDA: // `env(addr)`, channel: set envelope offset = (u16)cmdArgs[0]; channel->adsr.envelope = (AdsrEnvelope*)&seqPlayer->seqData[offset]; break; - case 0xD9: + case 0xD9: // `releaserate(u8)`, channel: set decay index cmd = (u8)cmdArgs[0]; channel->adsr.decayIndex = cmd; break; - case 0xD8: + case 0xD8: // `vibdepth(u8)`, channel: set vibrato extent cmd = (u8)cmdArgs[0]; channel->vibratoExtentTarget = cmd * 8; channel->vibratoExtentStart = 0; channel->vibratoExtentChangeDelay = 0; break; - case 0xD7: + case 0xD7: // `vibfreq(u8)`, channel: set vibrato rate cmd = (u8)cmdArgs[0]; channel->vibratoRateChangeDelay = 0; channel->vibratoRateTarget = cmd * 32; channel->vibratoRateStart = cmd * 32; break; - case 0xE2: + case 0xE2: // `vibdepthgrad(u8, u8, u8)`, channel: set vibrato extent linear cmd = (u8)cmdArgs[0]; channel->vibratoExtentStart = cmd * 8; cmd = (u8)cmdArgs[1]; @@ -1268,7 +1290,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { channel->vibratoExtentChangeDelay = cmd * 16; break; - case 0xE1: + case 0xE1: // `vibfreqgrad(u8, u8, u8)`, channel: set vibratorate linear cmd = (u8)cmdArgs[0]; channel->vibratoRateStart = cmd * 32; cmd = (u8)cmdArgs[1]; @@ -1277,17 +1299,17 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { channel->vibratoRateChangeDelay = cmd * 16; break; - case 0xE3: + case 0xE3: // `vibdelay(u8)`, channel: set vibrato delay cmd = (u8)cmdArgs[0]; channel->vibratoDelay = cmd * 16; break; - case 0xD4: + case 0xD4: // `reverb(u8)`, channel: set reverb cmd = (u8)cmdArgs[0]; channel->reverb = cmd; break; - case 0xC6: + case 0xC6: // `font(u8)`, channel: set soundFont result = (u8)cmdArgs[0]; cmd = (u8)cmdArgs[0]; @@ -1303,16 +1325,16 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { break; - case 0xC7: + case 0xC7: // `stseq(u8, addr)`, channel: write into sequence script cmd = (u8)cmdArgs[0]; offset = (u16)cmdArgs[1]; test = &seqPlayer->seqData[offset]; test[0] = (u8)scriptState->value + cmd; break; - case 0xC8: - case 0xCC: - case 0xC9: + case 0xC8: // `sub(u8)`, channel: subtract -> set value + case 0xCC: // `ldi(u8)`, channel: set value + case 0xC9: // `and(u8)`, channel: `bit and` -> set value signedParam = (s8)cmdArgs[0]; if (cmd == 0xC8) { @@ -1324,35 +1346,35 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { } break; - case 0xCD: + case 0xCD: // `stopchan(u8)`, channel: disable channel cmd = (u8)cmdArgs[0]; AudioSeq_SequenceChannelDisable(seqPlayer->channels[cmd]); break; - case 0xCA: + case 0xCA: // `mutebhv(hex8)`, channel: set mute behavior cmd = (u8)cmdArgs[0]; channel->muteBehavior = cmd; channel->changes.s.volume = true; break; - case 0xCB: + case 0xCB: // `ldseq(addr)`, channel: read sequence -> set value offset = (u16)cmdArgs[0]; scriptState->value = *(seqPlayer->seqData + (u32)(offset + scriptState->value)); break; - case 0xCE: + case 0xCE: // `ldptr(hex16)`, channel: ?? (load pointer?) offset = (u16)cmdArgs[0]; channel->unk_22 = offset; break; - case 0xCF: + case 0xCF: // `stptrtoseq(addr)` channel: write large into sequence script offset = (u16)cmdArgs[0]; test = &seqPlayer->seqData[offset]; test[0] = (channel->unk_22 >> 8) & 0xFF; test[1] = channel->unk_22 & 0xFF; break; - case 0xD0: + case 0xD0: // `effects(u8)`, channel: stereo headset effects cmd = (u8)cmdArgs[0]; if (cmd & 0x80) { channel->stereoHeadsetEffects = true; @@ -1362,22 +1384,22 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { channel->stereo.asByte = cmd & 0x7F; break; - case 0xD1: + case 0xD1: // `notealloc(u8)`, channel: set note allocation policy cmd = (u8)cmdArgs[0]; channel->noteAllocPolicy = cmd; break; - case 0xD2: + case 0xD2: // `sustain(u8)`, channel: set sustain cmd = (u8)cmdArgs[0]; channel->adsr.sustain = cmd; break; - case 0xE5: + case 0xE5: // `rvrbidx(u8)`, channel: set reverb index cmd = (u8)cmdArgs[0]; channel->reverbIndex = cmd; break; - case 0xE4: + case 0xE4: // `dyncall()`, channel: dyncall if (scriptState->value != -1) { data = (*channel->dynTable)[scriptState->value]; //! @bug: Missing a stack depth check here @@ -1387,12 +1409,12 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { } break; - case 0xE6: + case 0xE6: // `samplbook(addr)`, channel: set book offset cmd = (u8)cmdArgs[0]; channel->bookOffset = cmd; break; - case 0xE7: + case 0xE7: // `ldparams(addr)`, channel: load parameters offset = (u16)cmdArgs[0]; data = &seqPlayer->seqData[offset]; channel->muteBehavior = data[0]; @@ -1409,7 +1431,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { channel->changes.s.pan = true; break; - case 0xE8: + case 0xE8: // `params(u8, u8, u8, s8, s8, u8, u8, u8)`, channel set parameters channel->muteBehavior = cmdArgs[0]; channel->noteAllocPolicy = cmdArgs[1]; cmd = (u8)cmdArgs[2]; @@ -1423,7 +1445,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { channel->changes.s.pan = true; break; - case 0xEC: + case 0xEC: // ``, channel: reset vibrato channel->vibratoExtentTarget = 0; channel->vibratoExtentStart = 0; channel->vibratoExtentChangeDelay = 0; @@ -1441,25 +1463,26 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { channel->freqScale = 1.0f; break; - case 0xE9: + case 0xE9: // `notepri(u8)`, channel: set note priority AudioSeq_SetChannelPriorities(channel, (u8)cmdArgs[0]); break; - case 0xED: + case 0xED: // `gain(u8)`, channel: set hilo gain cmd = (u8)cmdArgs[0]; channel->unk_0C = cmd; break; - case 0xB0: + case 0xB0: // `ldfilter(addr)`, channel: set filter offset = (u16)cmdArgs[0]; data = seqPlayer->seqData + offset; channel->filter = (s16*)data; break; - case 0xB1: + case 0xB1: // `freefilter()`, channel: clear filter channel->filter = NULL; break; - case 0xB3: + + case 0xB3: // `filter(u8)`, channel: load filter cmd = cmdArgs[0]; if (channel->filter != NULL) { @@ -1469,34 +1492,34 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { } break; - case 0xB2: + case 0xB2: // `ldseqtoptr(addr)`, channel: dynread sequence large offset = (u16)cmdArgs[0]; channel->unk_22 = *(u16*)(seqPlayer->seqData + (u32)(offset + scriptState->value * 2)); break; - case 0xB4: + case 0xB4: // `ptrtodyntbl()`, channel: set dyntable large channel->dynTable = (void*)&seqPlayer->seqData[channel->unk_22]; break; - case 0xB5: + case 0xB5: // `dyntbltoptr()`, channel: read dyntable large channel->unk_22 = ((u16*)(channel->dynTable))[scriptState->value]; break; - case 0xB6: + case 0xB6: // `dyntblv()`, channel: read dyntable scriptState->value = (*channel->dynTable)[0][scriptState->value]; break; - case 0xB7: + case 0xB7: // `randtoptr(u16)`, channel: random large channel->unk_22 = (cmdArgs[0] == 0) ? gAudioContext.audioRandom & 0xFFFF : gAudioContext.audioRandom % cmdArgs[0]; break; - case 0xB8: + case 0xB8: // `rand()`, channel: random value scriptState->value = (cmdArgs[0] == 0) ? gAudioContext.audioRandom & 0xFFFF : gAudioContext.audioRandom % cmdArgs[0]; break; - case 0xBD: + case 0xBD: // `randptr(u16, u16)`, channel: random range large result = Audio_NextRandom(); channel->unk_22 = (cmdArgs[0] == 0) ? (u32)result & 0xFFFF : (u32)result % cmdArgs[0]; channel->unk_22 += cmdArgs[1]; @@ -1505,20 +1528,20 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { channel->unk_22 = (pad2 << 8) | param; break; - case 0xB9: + case 0xB9: // `randvel(u8)`, channel: set velocity random variance channel->velocityRandomVariance = cmdArgs[0]; break; - case 0xBA: + case 0xBA: // `randgate(u8)`, channel: set gatetime random variance channel->gateTimeRandomVariance = cmdArgs[0]; break; - case 0xBB: + case 0xBB: // `unkbb(u8, u16)`, channel: channel->unk_0F = cmdArgs[0]; channel->unk_20 = cmdArgs[1]; break; - case 0xBC: + case 0xBC: // `ptradd(u16)`, channel: add large channel->unk_22 += cmdArgs[0]; break; } @@ -1531,7 +1554,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { } switch (cmd & 0xF8) { - case 0x80: + case 0x80: // `testlayer(bits:3)`, channel: test layer is finished if (channel->layers[lowBits] != NULL) { scriptState->value = channel->layers[lowBits]->finished; } else { @@ -1539,18 +1562,18 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { } break; - case 0x88: + case 0x88: // `ldlayer(bits:3, addr)`, channel: set layer offset = AudioSeq_ScriptReadS16(scriptState); if (!AudioSeq_SeqChannelSetLayer(channel, lowBits)) { channel->layers[lowBits]->scriptState.pc = &seqPlayer->seqData[offset]; } break; - case 0x90: + case 0x90: // `dellayer(bits:3)`, channel: free layer AudioSeq_SeqLayerFree(channel, lowBits); break; - case 0x98: + case 0x98: // `dynldlayer(bits:3)`, channel: dynset layer if (scriptState->value != -1 && AudioSeq_SeqChannelSetLayer(channel, lowBits) != -1) { data = (*channel->dynTable)[scriptState->value]; offset = (data[0] << 8) + data[1]; @@ -1558,11 +1581,11 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { } break; - case 0x70: + case 0x70: // `stio(bits:3)`, channel: io write value channel->soundScriptIO[lowBits] = scriptState->value; break; - case 0x78: + case 0x78: // `rldlayer(bits:3, reladdr16)`, channel: set layer relative pad1 = AudioSeq_ScriptReadS16(scriptState); if (!AudioSeq_SeqChannelSetLayer(channel, lowBits)) { channel->layers[lowBits]->scriptState.pc = &scriptState->pc[pad1]; @@ -1573,11 +1596,11 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { lowBits = cmd & 0xF; switch (cmd & 0xF0) { - case 0x00: + case 0x00: // `cdelay(bits:4)`, channel: delay short channel->delay = lowBits; goto exit_loop; - case 0x10: + case 0x10: // `sample(bits:3, addr)`, channel: load sample if (lowBits < 8) { channel->soundScriptIO[lowBits] = -1; if (AudioLoad_SlowLoadSample(channel->fontId, scriptState->value, @@ -1594,28 +1617,28 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { } break; - case 0x60: + case 0x60: // `ldio(bits:4)`, channel: io read value scriptState->value = channel->soundScriptIO[lowBits]; if (lowBits < 2) { channel->soundScriptIO[lowBits] = -1; } break; - case 0x50: + case 0x50: // `subio(bits:4)`, channel: io read value subtract scriptState->value -= channel->soundScriptIO[lowBits]; break; - case 0x20: + case 0x20: // `ldchan(bits:4, addr)`, channel: start channel offset = AudioSeq_ScriptReadS16(scriptState); AudioSeq_SequenceChannelEnable(seqPlayer, lowBits, &seqPlayer->seqData[offset]); break; - case 0x30: + case 0x30: // `stcio(bits:4, u8)`, channel: io write value 2 cmd = AudioSeq_ScriptReadU8(scriptState); seqPlayer->channels[lowBits]->soundScriptIO[cmd] = scriptState->value; break; - case 0x40: + case 0x40: // `ldcio(bits:4, u8)`, channel: io read value 2 cmd = AudioSeq_ScriptReadU8(scriptState); scriptState->value = seqPlayer->channels[lowBits]->soundScriptIO[cmd]; break; @@ -1683,7 +1706,7 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { while (true) { command = AudioSeq_ScriptReadU8(seqScript); - // 0xF2 and above are "flow control" commands, including termination. + // Control Flow Commands if (command >= 0xF2) { s32 scriptHandled = AudioSeq_HandleScriptFlowControl( seqPlayer, seqScript, command, @@ -1699,7 +1722,7 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { } } else if (command >= 0xC0) { switch (command) { - case 0xF1: + case 0xF1: // `allocnotelist(u8)`, seqPlayer: reserve notes Audio_NotePoolClear(&seqPlayer->notePool); command = AudioSeq_ScriptReadU8(seqScript); Audio_NotePoolFill(&seqPlayer->notePool, command); @@ -1714,16 +1737,19 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { } if (dummy) {} break; - case 0xF0: + + case 0xF0: // `freenotelist()`, seqPlayer: unreserve notes Audio_NotePoolClear(&seqPlayer->notePool); break; - case 0xDF: + + case 0xDF: // `transpose(s8)`, seqPlayer: transpose seqPlayer->transposition = 0; - // Note: intentional fallthrough, also executes below command - case 0xDE: + // fallthrough + case 0xDE: // `rtranspose(s8)`, seqPlayer: transpose relative seqPlayer->transposition += (s8)AudioSeq_ScriptReadU8(seqScript); break; - case 0xDD: + + case 0xDD: // `tempo(u8)`, seqPlayer: set tempo seqPlayer->tempo = AudioSeq_ScriptReadU8(seqScript) * 48; if (seqPlayer->tempo > gAudioContext.tempoInternalToExternal) { seqPlayer->tempo = (u16)gAudioContext.tempoInternalToExternal; @@ -1732,10 +1758,12 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { seqPlayer->tempo = 1; } break; - case 0xDC: + + case 0xDC: // `tempochg(s8)`, seqPlayer: add tempo seqPlayer->unk_0C = (s8)AudioSeq_ScriptReadU8(seqScript) * 48; break; - case 0xDA: + + case 0xDA: // `volmode(s8)`, seqPlayer: change volume command = AudioSeq_ScriptReadU8(seqScript); temp = AudioSeq_ScriptReadS16(seqScript); switch (command) { @@ -1753,7 +1781,8 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { break; } break; - case 0xDB: + + case 0xDB: // `vol(u8)`, seqPlayer: set volume value = AudioSeq_ScriptReadU8(seqScript); switch (seqPlayer->state) { case 1: @@ -1773,27 +1802,34 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { break; } break; - case 0xD9: + + case 0xD9: // ``, seqPlayer: set volume scale seqPlayer->fadeVolumeScale = (s8)AudioSeq_ScriptReadU8(seqScript) / 127.0f; break; - case 0xD7: + + case 0xD7: // `initchan(hex16)`, seqPlayer: initialize channels temp = AudioSeq_ScriptReadS16(seqScript); AudioSeq_SequencePlayerSetupChannels(seqPlayer, temp); break; - case 0xD6: + + case 0xD6: // `freechan(hex16)`, seqPlayer: disable channels AudioSeq_ScriptReadS16(seqScript); break; - case 0xD5: + + case 0xD5: // `mutescale(s8)`, seqPlayer: set mute scale seqPlayer->muteVolumeScale = (s8)AudioSeq_ScriptReadU8(seqScript) / 127.0f; break; - case 0xD4: + + case 0xD4: // `mute()`, seqPlayer: mute seqPlayer->muted = true; break; - case 0xD3: + + case 0xD3: // `mutebhv(hex8)`, seqPlayer: set mute behavior seqPlayer->muteBehavior = AudioSeq_ScriptReadU8(seqScript); break; - case 0xD1: - case 0xD2: + + case 0xD1: // `ldshortgatearr(addr)`, seqPlayer: set short note gatetime table + case 0xD2: // `ldshortvelarr(addr)`, seqPlayer: set short note velocity table temp = AudioSeq_ScriptReadS16(seqScript); data3 = &seqPlayer->seqData[temp]; if (command == 0xD2) { @@ -1802,10 +1838,12 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { seqPlayer->shortNoteGateTimeTable = data3; } break; - case 0xD0: + + case 0xD0: // `notealloc(u8)`, seqPlayer: set note allocation policy seqPlayer->noteAllocPolicy = AudioSeq_ScriptReadU8(seqScript); break; - case 0xCE: + + case 0xCE: // `rand(u8)`, seqPlayer: random value command = AudioSeq_ScriptReadU8(seqScript); if (command == 0) { seqScript->value = (gAudioContext.audioRandom >> 2) & 0xFF; @@ -1813,7 +1851,8 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { seqScript->value = (gAudioContext.audioRandom >> 2) % command; } break; - case 0xCD: { + + case 0xCD: // `dyncall(addr)`, seqPlayer: dyncall temp = AudioSeq_ScriptReadS16(seqScript); if ((seqScript->value != -1) && (seqScript->depth != 3)) { @@ -1825,33 +1864,40 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { seqScript->pc = &seqPlayer->seqData[temp]; } break; - } - case 0xCC: + + case 0xCC: // `ldi(u8)`, seqPlayer: set value seqScript->value = AudioSeq_ScriptReadU8(seqScript); break; - case 0xC9: + + case 0xC9: // `and(u8)`, seqPlayer: `bit and` -> set value seqScript->value &= AudioSeq_ScriptReadU8(seqScript); break; - case 0xC8: + + case 0xC8: // `sub(u8)`, seqPlayer: subtract -> set value seqScript->value -= AudioSeq_ScriptReadU8(seqScript); break; - case 0xC7: + + case 0xC7: // `stseq(u8, addr)`, seqPlayer: write into sequence script command = AudioSeq_ScriptReadU8(seqScript); temp = AudioSeq_ScriptReadS16(seqScript); data2 = &seqPlayer->seqData[temp]; *data2 = (u8)seqScript->value + command; break; - case 0xC6: + + case 0xC6: // `stop()`, seqPlayer: stop script seqPlayer->stopScript = true; return; - case 0xC5: + + case 0xC5: // `scriptctr(u16)`, seqPlayer: set script counter seqPlayer->scriptCounter = (u16)AudioSeq_ScriptReadS16(seqScript); break; - case 0xEF: + + case 0xEF: // ``, seqPlayer: AudioSeq_ScriptReadS16(seqScript); AudioSeq_ScriptReadU8(seqScript); break; - case 0xC4: + + case 0xC4: // `runseq(u8, u8)`, seqPlayer: start sequence command = AudioSeq_ScriptReadU8(seqScript); if (command == 0xFF) { command = seqPlayer->playerIdx; @@ -1867,46 +1913,53 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { commandLow = command & 0x0F; switch (command & 0xF0) { - case 0x00: + case 0x00: // `testchan(bits:4)`, seqPlayer: test channel disabled seqScript->value = seqPlayer->channels[commandLow]->enabled ^ 1; break; - case 0x50: + + case 0x50: // `subio(bits:4)`, seqPlayer: io read value subtract seqScript->value -= seqPlayer->soundScriptIO[commandLow]; break; - case 0x70: + + case 0x70: // `stio(bits:4)`, seqPlayer: io write value seqPlayer->soundScriptIO[commandLow] = seqScript->value; break; - case 0x80: + + case 0x80: // `ldio(bits:4)`, seqPlayer: io read value seqScript->value = seqPlayer->soundScriptIO[commandLow]; if (commandLow < 2) { seqPlayer->soundScriptIO[commandLow] = -1; } break; - case 0x40: + + case 0x40: // `stopchan(bits:4)`, seqPlayer: disable channel AudioSeq_SequenceChannelDisable(seqPlayer->channels[commandLow]); break; - case 0x90: + + case 0x90: // `ldchan(bits:4, addr)`, seqPlayer: start channel temp = AudioSeq_ScriptReadS16(seqScript); AudioSeq_SequenceChannelEnable(seqPlayer, commandLow, (void*)&seqPlayer->seqData[temp]); break; - case 0xA0: + + case 0xA0: // `rldchan(bits:4, reladdr16)`, seqPlayer: start channel relative tempS = AudioSeq_ScriptReadS16(seqScript); AudioSeq_SequenceChannelEnable(seqPlayer, commandLow, (void*)&seqScript->pc[tempS]); break; - case 0xB0: + + case 0xB0: // `ldseq(bits:4, u8, addr)`, seqPlayer: load sequence command = AudioSeq_ScriptReadU8(seqScript); temp = AudioSeq_ScriptReadS16(seqScript); data2 = &seqPlayer->seqData[temp]; AudioLoad_SlowLoadSeq(command, data2, &seqPlayer->soundScriptIO[commandLow]); break; - case 0x60: { + + case 0x60: // `ldres(bits:4, u8, u8)`, seqPlayer: async load command = AudioSeq_ScriptReadU8(seqScript); value = command; temp = AudioSeq_ScriptReadU8(seqScript); AudioLoad_ScriptLoad(value, temp, &seqPlayer->soundScriptIO[commandLow]); break; - } } } } From e9eb79c556f1ddce798cef97a5423afc17a93fdc Mon Sep 17 00:00:00 2001 From: engineer124 Date: Wed, 1 Jun 2022 16:44:37 +1000 Subject: [PATCH 2/6] Undo spaces --- src/code/audio_seqplayer.c | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/src/code/audio_seqplayer.c b/src/code/audio_seqplayer.c index 87583b3c968..617bab602e6 100644 --- a/src/code/audio_seqplayer.c +++ b/src/code/audio_seqplayer.c @@ -1481,7 +1481,6 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { case 0xB1: // `freefilter()`, channel: clear filter channel->filter = NULL; break; - case 0xB3: // `filter(u8)`, channel: load filter cmd = cmdArgs[0]; @@ -1741,14 +1740,12 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { case 0xF0: // `freenotelist()`, seqPlayer: unreserve notes Audio_NotePoolClear(&seqPlayer->notePool); break; - case 0xDF: // `transpose(s8)`, seqPlayer: transpose seqPlayer->transposition = 0; // fallthrough case 0xDE: // `rtranspose(s8)`, seqPlayer: transpose relative seqPlayer->transposition += (s8)AudioSeq_ScriptReadU8(seqScript); break; - case 0xDD: // `tempo(u8)`, seqPlayer: set tempo seqPlayer->tempo = AudioSeq_ScriptReadU8(seqScript) * 48; if (seqPlayer->tempo > gAudioContext.tempoInternalToExternal) { @@ -1758,11 +1755,9 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { seqPlayer->tempo = 1; } break; - case 0xDC: // `tempochg(s8)`, seqPlayer: add tempo seqPlayer->unk_0C = (s8)AudioSeq_ScriptReadU8(seqScript) * 48; break; - case 0xDA: // `volmode(s8)`, seqPlayer: change volume command = AudioSeq_ScriptReadU8(seqScript); temp = AudioSeq_ScriptReadS16(seqScript); @@ -1781,7 +1776,6 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { break; } break; - case 0xDB: // `vol(u8)`, seqPlayer: set volume value = AudioSeq_ScriptReadU8(seqScript); switch (seqPlayer->state) { @@ -1802,32 +1796,25 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { break; } break; - case 0xD9: // ``, seqPlayer: set volume scale seqPlayer->fadeVolumeScale = (s8)AudioSeq_ScriptReadU8(seqScript) / 127.0f; break; - case 0xD7: // `initchan(hex16)`, seqPlayer: initialize channels temp = AudioSeq_ScriptReadS16(seqScript); AudioSeq_SequencePlayerSetupChannels(seqPlayer, temp); break; - case 0xD6: // `freechan(hex16)`, seqPlayer: disable channels AudioSeq_ScriptReadS16(seqScript); break; - case 0xD5: // `mutescale(s8)`, seqPlayer: set mute scale seqPlayer->muteVolumeScale = (s8)AudioSeq_ScriptReadU8(seqScript) / 127.0f; break; - case 0xD4: // `mute()`, seqPlayer: mute seqPlayer->muted = true; break; - case 0xD3: // `mutebhv(hex8)`, seqPlayer: set mute behavior seqPlayer->muteBehavior = AudioSeq_ScriptReadU8(seqScript); break; - case 0xD1: // `ldshortgatearr(addr)`, seqPlayer: set short note gatetime table case 0xD2: // `ldshortvelarr(addr)`, seqPlayer: set short note velocity table temp = AudioSeq_ScriptReadS16(seqScript); @@ -1838,11 +1825,9 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { seqPlayer->shortNoteGateTimeTable = data3; } break; - case 0xD0: // `notealloc(u8)`, seqPlayer: set note allocation policy seqPlayer->noteAllocPolicy = AudioSeq_ScriptReadU8(seqScript); break; - case 0xCE: // `rand(u8)`, seqPlayer: random value command = AudioSeq_ScriptReadU8(seqScript); if (command == 0) { @@ -1851,7 +1836,6 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { seqScript->value = (gAudioContext.audioRandom >> 2) % command; } break; - case 0xCD: // `dyncall(addr)`, seqPlayer: dyncall temp = AudioSeq_ScriptReadS16(seqScript); @@ -1864,39 +1848,31 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { seqScript->pc = &seqPlayer->seqData[temp]; } break; - case 0xCC: // `ldi(u8)`, seqPlayer: set value seqScript->value = AudioSeq_ScriptReadU8(seqScript); break; - case 0xC9: // `and(u8)`, seqPlayer: `bit and` -> set value seqScript->value &= AudioSeq_ScriptReadU8(seqScript); break; - case 0xC8: // `sub(u8)`, seqPlayer: subtract -> set value seqScript->value -= AudioSeq_ScriptReadU8(seqScript); break; - case 0xC7: // `stseq(u8, addr)`, seqPlayer: write into sequence script command = AudioSeq_ScriptReadU8(seqScript); temp = AudioSeq_ScriptReadS16(seqScript); data2 = &seqPlayer->seqData[temp]; *data2 = (u8)seqScript->value + command; break; - case 0xC6: // `stop()`, seqPlayer: stop script seqPlayer->stopScript = true; return; - case 0xC5: // `scriptctr(u16)`, seqPlayer: set script counter seqPlayer->scriptCounter = (u16)AudioSeq_ScriptReadS16(seqScript); break; - case 0xEF: // ``, seqPlayer: AudioSeq_ScriptReadS16(seqScript); AudioSeq_ScriptReadU8(seqScript); break; - case 0xC4: // `runseq(u8, u8)`, seqPlayer: start sequence command = AudioSeq_ScriptReadU8(seqScript); if (command == 0xFF) { @@ -1916,43 +1892,35 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { case 0x00: // `testchan(bits:4)`, seqPlayer: test channel disabled seqScript->value = seqPlayer->channels[commandLow]->enabled ^ 1; break; - case 0x50: // `subio(bits:4)`, seqPlayer: io read value subtract seqScript->value -= seqPlayer->soundScriptIO[commandLow]; break; - case 0x70: // `stio(bits:4)`, seqPlayer: io write value seqPlayer->soundScriptIO[commandLow] = seqScript->value; break; - case 0x80: // `ldio(bits:4)`, seqPlayer: io read value seqScript->value = seqPlayer->soundScriptIO[commandLow]; if (commandLow < 2) { seqPlayer->soundScriptIO[commandLow] = -1; } break; - case 0x40: // `stopchan(bits:4)`, seqPlayer: disable channel AudioSeq_SequenceChannelDisable(seqPlayer->channels[commandLow]); break; - case 0x90: // `ldchan(bits:4, addr)`, seqPlayer: start channel temp = AudioSeq_ScriptReadS16(seqScript); AudioSeq_SequenceChannelEnable(seqPlayer, commandLow, (void*)&seqPlayer->seqData[temp]); break; - case 0xA0: // `rldchan(bits:4, reladdr16)`, seqPlayer: start channel relative tempS = AudioSeq_ScriptReadS16(seqScript); AudioSeq_SequenceChannelEnable(seqPlayer, commandLow, (void*)&seqScript->pc[tempS]); break; - case 0xB0: // `ldseq(bits:4, u8, addr)`, seqPlayer: load sequence command = AudioSeq_ScriptReadU8(seqScript); temp = AudioSeq_ScriptReadS16(seqScript); data2 = &seqPlayer->seqData[temp]; AudioLoad_SlowLoadSeq(command, data2, &seqPlayer->soundScriptIO[commandLow]); break; - case 0x60: // `ldres(bits:4, u8, u8)`, seqPlayer: async load command = AudioSeq_ScriptReadU8(seqScript); value = command; From 980caf59e78d6018504effb1b6ee4c265f4c951e Mon Sep 17 00:00:00 2001 From: engineer124 Date: Wed, 1 Jun 2022 16:46:41 +1000 Subject: [PATCH 3/6] One more undo --- src/code/audio_seqplayer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/code/audio_seqplayer.c b/src/code/audio_seqplayer.c index 617bab602e6..ce62a44593a 100644 --- a/src/code/audio_seqplayer.c +++ b/src/code/audio_seqplayer.c @@ -1836,7 +1836,7 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { seqScript->value = (gAudioContext.audioRandom >> 2) % command; } break; - case 0xCD: // `dyncall(addr)`, seqPlayer: dyncall + case 0xCD: { // `dyncall(addr)`, seqPlayer: dyncall temp = AudioSeq_ScriptReadS16(seqScript); if ((seqScript->value != -1) && (seqScript->depth != 3)) { @@ -1848,6 +1848,7 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { seqScript->pc = &seqPlayer->seqData[temp]; } break; + } case 0xCC: // `ldi(u8)`, seqPlayer: set value seqScript->value = AudioSeq_ScriptReadU8(seqScript); break; From dda6a8cba3d3756f38435d350f57db14f29b112d Mon Sep 17 00:00:00 2001 From: engineer124 Date: Wed, 1 Jun 2022 16:48:25 +1000 Subject: [PATCH 4/6] Add file description --- src/code/audio_seqplayer.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/code/audio_seqplayer.c b/src/code/audio_seqplayer.c index ce62a44593a..52e45b15018 100644 --- a/src/code/audio_seqplayer.c +++ b/src/code/audio_seqplayer.c @@ -1,3 +1,19 @@ +/** + * @file audio_seqplayer.c + * + * Manages audio sequence players, interprets and executes the Music Macro Language for Sequences + * + * Music Macro Lanuage (MML): + * - A customized assembly language based on MIDI + * - All sequences are written in the MML + * - There are 3 different sets of instructions + * 1) Sequence Instructions + * 2) Channel Instructions + * 3) Layer Instruction + * - All three sets share a common pool of control flow instructions (>= 0xF2). + * Otherwise, each set of intructions have its own command interpreter + * + */ #include "ultra64.h" #include "global.h" From fb238470ff3252b757ee7d83b0267f8acbde7703 Mon Sep 17 00:00:00 2001 From: engineer124 Date: Wed, 1 Jun 2022 16:48:36 +1000 Subject: [PATCH 5/6] space --- src/code/audio_seqplayer.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/code/audio_seqplayer.c b/src/code/audio_seqplayer.c index 52e45b15018..aa9d7200f1d 100644 --- a/src/code/audio_seqplayer.c +++ b/src/code/audio_seqplayer.c @@ -12,7 +12,6 @@ * 3) Layer Instruction * - All three sets share a common pool of control flow instructions (>= 0xF2). * Otherwise, each set of intructions have its own command interpreter - * */ #include "ultra64.h" #include "global.h" From a80ee0e0a83770e79bcb52b730a505f772682f35 Mon Sep 17 00:00:00 2001 From: engineer124 Date: Wed, 1 Jun 2022 17:02:50 +1000 Subject: [PATCH 6/6] Final fixes --- src/code/audio_seqplayer.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/code/audio_seqplayer.c b/src/code/audio_seqplayer.c index aa9d7200f1d..3f0c2e8d122 100644 --- a/src/code/audio_seqplayer.c +++ b/src/code/audio_seqplayer.c @@ -66,7 +66,7 @@ u8 sSeqInstructionArgsTable[] = { CMD_ARGS_0(), // 0xB5 (`dyntbltoptr()`, channel: read dyntable large) CMD_ARGS_0(), // 0xB6 (`dyntblv()`, channel: read dyntable) CMD_ARGS_1(s16), // 0xB7 (`randtoptr(u16)`, channel: random large) - CMD_ARGS_1(u8), // 0xB8 (`rand()`, channel: random value) + CMD_ARGS_1(u8), // 0xB8 (`rand(u8)`, channel: random value) CMD_ARGS_1(u8), // 0xB9 (`randvel(u8)`, channel: set velocity random variance) CMD_ARGS_1(u8), // 0xBA (`randgate(u8)`, channel: set gatetime random variance) CMD_ARGS_2(u8, s16), // 0xBB (`unkbb(u8, u16)`, channel:) @@ -134,7 +134,7 @@ u8 sSeqInstructionArgsTable[] = { CMD_ARGS_1(u8), // 0xF8 (`loop(u8)`, loop) CMD_ARGS_1(s16), // 0xF9 (`bltz(addr)`, branch if less than zero) CMD_ARGS_1(s16), // 0xFA (`beqz(addr)`, branch if equal to zero) - CMD_ARGS_1(s16), // 0xFB (`jump()`, jump) + CMD_ARGS_1(s16), // 0xFB (`jump(addr)`, jump) CMD_ARGS_1(s16), // 0xFC (`call(addr)`, call and jump to a function) CMD_ARGS_0(), // 0xFD (`delay(var)`, delay n frames) CMD_ARGS_0(), // 0xFE (`delay1()`, delay 1 frame) @@ -207,7 +207,7 @@ s32 AudioSeq_HandleScriptFlowControl(SequencePlayer* seqPlayer, SeqScriptState* case 0xF5: // `bgez(addr)`, branch if greater than or equal to zero case 0xF9: // `bltz(addr)`, branch if less than zero case 0xFA: // `beqz(addr)`, branch if equal to zero - case 0xFB: // `jump()`, jump + case 0xFB: // `jump(addr)`, jump if (cmd == 0xFA && state->value != 0) { break; } @@ -1528,7 +1528,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { : gAudioContext.audioRandom % cmdArgs[0]; break; - case 0xB8: // `rand()`, channel: random value + case 0xB8: // `rand(u8)`, channel: random value scriptState->value = (cmdArgs[0] == 0) ? gAudioContext.audioRandom & 0xFFFF : gAudioContext.audioRandom % cmdArgs[0]; break; @@ -1751,7 +1751,6 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { } if (dummy) {} break; - case 0xF0: // `freenotelist()`, seqPlayer: unreserve notes Audio_NotePoolClear(&seqPlayer->notePool); break;