diff --git a/include/variables.h b/include/variables.h index 2e39bdf97e..f947ef989d 100644 --- a/include/variables.h +++ b/include/variables.h @@ -121,7 +121,7 @@ extern u8 gDefaultShortNoteGateTimeTable[16]; extern EnvelopePoint gDefaultEnvelope[4]; extern NoteSubEu gZeroNoteSub; extern NoteSubEu gDefaultNoteSub; -extern u16 gHeadsetPanQuantization[64]; +extern u16 gHaasEffectDelaySizes[64]; extern s16 D_8012FBA8[]; extern f32 gHeadsetPanVolume[128]; extern f32 gStereoPanVolume[128]; diff --git a/include/z64audio.h b/include/z64audio.h index 4c09eae546..9d86bdd1bb 100644 --- a/include/z64audio.h +++ b/include/z64audio.h @@ -484,19 +484,19 @@ typedef struct SequenceLayer { } SequenceLayer; // size = 0x80 typedef struct { - /* 0x0000 */ s16 adpcmdecState[0x10]; - /* 0x0020 */ s16 finalResampleState[0x10]; - /* 0x0040 */ s16 mixEnvelopeState[0x28]; - /* 0x0090 */ s16 panResampleState[0x10]; - /* 0x00B0 */ s16 panSamplesBuffer[0x20]; - /* 0x00F0 */ s16 dummyResampleState[0x10]; -} NoteSynthesisBuffers; // size = 0x110 + /* 0x000 */ s16 adpcmdecState[16]; + /* 0x020 */ s16 finalResampleState[16]; + /* 0x040 */ s16 mixEnvelopeState[32]; + /* 0x080 */ s16 unusedState[16]; + /* 0x0A0 */ s16 haasEffectDelayState[32]; + /* 0x0E0 */ s16 unkState[128]; +} NoteSynthesisBuffers; // size = 0x1E0 typedef struct { /* 0x00 */ u8 restart; /* 0x01 */ u8 sampleDmaIndex; - /* 0x02 */ u8 prevHeadsetPanRight; - /* 0x03 */ u8 prevHeadsetPanLeft; + /* 0x02 */ u8 prevHaasEffectLeftDelaySize; + /* 0x03 */ u8 prevHaasEffectRightDelaySize; /* 0x04 */ u8 reverbVol; /* 0x05 */ u8 numParts; /* 0x06 */ u16 samplePosFrac; @@ -559,11 +559,11 @@ typedef struct { /* 0x01 */ u8 bookOffset : 2; /* 0x01 */ u8 isSyntheticWave : 1; /* 0x01 */ u8 hasTwoParts : 1; - /* 0x01 */ u8 usesHeadsetPanEffects2 : 1; + /* 0x01 */ u8 useHaasEffect : 1; } bitField1; /* 0x02 */ u8 gain; // Increases volume by a multiplicative scaling factor. Represented as a UQ4.4 number - /* 0x03 */ u8 headsetPanRight; - /* 0x04 */ u8 headsetPanLeft; + /* 0x03 */ u8 haasEffectLeftDelaySize; + /* 0x04 */ u8 haasEffectRightDelaySize; /* 0x05 */ u8 reverbVol; /* 0x06 */ u8 harmonicIndexCurAndPrev; // bits 3..2 store curHarmonicIndex, bits 1..0 store prevHarmonicIndex /* 0x07 */ u8 unk_07; diff --git a/src/code/audio_data.c b/src/code/audio_data.c index 7aec374940..10ddc4601e 100644 --- a/src/code/audio_data.c +++ b/src/code/audio_data.c @@ -556,7 +556,7 @@ NoteSubEu gDefaultNoteSub = { { 1, 1, 0, 0, 0, 0, 0, 0 }, { 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -u16 gHeadsetPanQuantization[64] = { +u16 gHaasEffectDelaySizes[64] = { 30 * SAMPLE_SIZE, 29 * SAMPLE_SIZE, 28 * SAMPLE_SIZE, diff --git a/src/code/audio_playback.c b/src/code/audio_playback.c index 571a3a0c45..87ad945a65 100644 --- a/src/code/audio_playback.c +++ b/src/code/audio_playback.c @@ -1,8 +1,9 @@ #include "global.h" void Audio_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* attrs) { - f32 volRight, volLeft; - s32 smallPanIndex; + f32 volLeft; + f32 volRight; + s32 halfPanIndex; u64 pad; u8 strongLeft; u8 strongRight; @@ -31,22 +32,22 @@ void Audio_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* attrs) { sub->bitField0.stereoHeadsetEffects = stereoData.stereoHeadsetEffects; sub->bitField0.usesHeadsetPanEffects = stereoData.usesHeadsetPanEffects; if (stereoHeadsetEffects && (gAudioContext.soundMode == SOUNDMODE_HEADSET)) { - smallPanIndex = pan >> 1; - if (smallPanIndex > 0x3F) { - smallPanIndex = 0x3F; + halfPanIndex = pan >> 1; + if (halfPanIndex > 0x3F) { + halfPanIndex = 0x3F; } - sub->headsetPanLeft = gHeadsetPanQuantization[smallPanIndex]; - sub->headsetPanRight = gHeadsetPanQuantization[0x3F - smallPanIndex]; - sub->bitField1.usesHeadsetPanEffects2 = true; + sub->haasEffectRightDelaySize = gHaasEffectDelaySizes[halfPanIndex]; + sub->haasEffectLeftDelaySize = gHaasEffectDelaySizes[0x3F - halfPanIndex]; + sub->bitField1.useHaasEffect = true; volLeft = gHeadsetPanVolume[pan]; volRight = gHeadsetPanVolume[0x7F - pan]; } else if (stereoHeadsetEffects && (gAudioContext.soundMode == SOUNDMODE_STEREO)) { strongLeft = strongRight = 0; - sub->headsetPanRight = 0; - sub->headsetPanLeft = 0; - sub->bitField1.usesHeadsetPanEffects2 = false; + sub->haasEffectLeftDelaySize = 0; + sub->haasEffectRightDelaySize = 0; + sub->bitField1.useHaasEffect = false; volLeft = gStereoPanVolume[pan]; volRight = gStereoPanVolume[0x7F - pan]; @@ -945,6 +946,7 @@ void Audio_NoteInitAll(void) { note->playbackState.portamento.speed = 0; note->playbackState.stereoHeadsetEffects = false; note->startSamplePos = 0; - note->synthesisState.synthesisBuffers = AudioHeap_AllocDmaMemory(&gAudioContext.miscPool, 0x1E0); + note->synthesisState.synthesisBuffers = + AudioHeap_AllocDmaMemory(&gAudioContext.miscPool, sizeof(NoteSynthesisBuffers)); } } diff --git a/src/code/audio_synthesis.c b/src/code/audio_synthesis.c index 851ae56d9b..a00c57ffae 100644 --- a/src/code/audio_synthesis.c +++ b/src/code/audio_synthesis.c @@ -4,7 +4,7 @@ // DMEM Addresses for the RSP #define DMEM_TEMP 0x3C0 #define DMEM_UNCOMPRESSED_NOTE 0x580 -#define DMEM_NOTE_PAN_TEMP 0x5C0 +#define DMEM_HAAS_TEMP 0x5C0 #define DMEM_SCRATCH2 0x760 // = DMEM_TEMP + DMEM_2CH_SIZE + a bit more #define DMEM_COMPRESSED_ADPCM_DATA 0x940 // = DMEM_LEFT_CH #define DMEM_LEFT_CH 0x940 @@ -14,6 +14,12 @@ #define DMEM_WET_LEFT_CH 0xC80 #define DMEM_WET_RIGHT_CH 0xE20 // = DMEM_WET_LEFT_CH + DMEM_1CH_SIZE +typedef enum { + /* 0 */ HAAS_EFFECT_DELAY_NONE, + /* 1 */ HAAS_EFFECT_DELAY_LEFT, // Delay left channel so that right channel is heard first + /* 2 */ HAAS_EFFECT_DELAY_RIGHT // Delay right channel so that left channel is heard first +} HaasEffectDelaySide; + Acmd* AudioSynth_LoadRingBufferPart(Acmd* cmd, u16 dmem, u16 startPos, s32 size, SynthesisReverb* reverb); Acmd* AudioSynth_SaveBufferOffset(Acmd* cmd, u16 dmem, u16 offset, s32 size, s16* buf); Acmd* AudioSynth_SaveRingBufferPart(Acmd* cmd, u16 dmem, u16 startPos, s32 size, SynthesisReverb* reverb); @@ -21,17 +27,25 @@ Acmd* AudioSynth_DoOneAudioUpdate(s16* aiBuf, s32 aiBufLen, Acmd* cmd, s32 updat Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisState* synthState, s16* aiBuf, s32 aiBufLen, Acmd* cmd, s32 updateIndex); Acmd* AudioSynth_LoadWaveSamples(Acmd* cmd, NoteSubEu* noteSubEu, NoteSynthesisState* synthState, s32 numSamplesToLoad); -Acmd* AudioSynth_NoteApplyHeadsetPanEffects(Acmd* cmd, NoteSubEu* noteSubEu, NoteSynthesisState* synthState, s32 bufLen, - s32 flags, s32 side); +Acmd* AudioSynth_ApplyHaasEffect(Acmd* cmd, NoteSubEu* noteSubEu, NoteSynthesisState* synthState, s32 size, s32 flags, + s32 haasEffectDelaySide); Acmd* AudioSynth_ProcessEnvelope(Acmd* cmd, NoteSubEu* noteSubEu, NoteSynthesisState* synthState, s32 aiBufLen, - u16 inBuf, s32 headsetPanSettings, s32 flags); + u16 dmemSrc, s32 haasEffectDelaySide, s32 flags); Acmd* AudioSynth_FinalResample(Acmd* cmd, NoteSynthesisState* synthState, s32 size, u16 pitch, u16 inpDmem, s32 resampleFlags); -u32 D_801304A0 = _SHIFTL(A_ENVMIXER, 24, 8); -u32 D_801304A4 = MK_CMD(DMEM_NOTE_PAN_TEMP >> 4, DMEM_RIGHT_CH >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4); -u32 D_801304A8 = MK_CMD(DMEM_LEFT_CH >> 4, DMEM_NOTE_PAN_TEMP >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4); -u32 D_801304AC = MK_CMD(DMEM_LEFT_CH >> 4, DMEM_RIGHT_CH >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4); +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); + +// 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); + +u32 sEnvMixerDefaultDmemDests = + 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, @@ -723,7 +737,7 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS s32 nParts; s32 curPart; s32 sampleDataStartPad; - s32 side; + s32 haasEffectDelaySide; s32 resampledTempLen; u16 sampleDmemBeforeResampling; s32 sampleDataOffset; @@ -752,8 +766,8 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS synthState->samplePosFrac = 0; synthState->curVolLeft = 0; synthState->curVolRight = 0; - synthState->prevHeadsetPanRight = 0; - synthState->prevHeadsetPanLeft = 0; + synthState->prevHaasEffectLeftDelaySize = 0; + synthState->prevHaasEffectRightDelaySize = 0; synthState->reverbVol = noteSubEu->reverbVol; synthState->numParts = 0; synthState->unk_1A = 1; @@ -1078,7 +1092,7 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS unk7 = noteSubEu->unk_07; unkE = noteSubEu->unk_0E; - buf = &synthState->synthesisBuffers->panSamplesBuffer[0x18]; + 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; @@ -1095,21 +1109,24 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS synthState->unk_1A = 1; } - if (noteSubEu->headsetPanRight != 0 || synthState->prevHeadsetPanRight != 0) { - side = 1; - } else if (noteSubEu->headsetPanLeft != 0 || synthState->prevHeadsetPanLeft != 0) { - side = 2; + if ((noteSubEu->haasEffectLeftDelaySize != 0) || (synthState->prevHaasEffectLeftDelaySize != 0)) { + haasEffectDelaySide = HAAS_EFFECT_DELAY_LEFT; + } else if ((noteSubEu->haasEffectRightDelaySize != 0) || (synthState->prevHaasEffectRightDelaySize != 0)) { + haasEffectDelaySide = HAAS_EFFECT_DELAY_RIGHT; } else { - side = 0; + haasEffectDelaySide = HAAS_EFFECT_DELAY_NONE; } - cmd = AudioSynth_ProcessEnvelope(cmd, noteSubEu, synthState, aiBufLen, DMEM_TEMP, side, flags); - if (noteSubEu->bitField1.usesHeadsetPanEffects2) { + + cmd = AudioSynth_ProcessEnvelope(cmd, noteSubEu, synthState, aiBufLen, DMEM_TEMP, haasEffectDelaySide, flags); + + if (noteSubEu->bitField1.useHaasEffect) { if (!(flags & A_INIT)) { flags = A_CONTINUE; } - cmd = - AudioSynth_NoteApplyHeadsetPanEffects(cmd, noteSubEu, synthState, aiBufLen * (s32)SAMPLE_SIZE, flags, side); + cmd = AudioSynth_ApplyHaasEffect(cmd, noteSubEu, synthState, aiBufLen * (s32)SAMPLE_SIZE, flags, + haasEffectDelaySide); } + return cmd; } @@ -1125,8 +1142,8 @@ Acmd* AudioSynth_FinalResample(Acmd* cmd, NoteSynthesisState* synthState, s32 si } Acmd* AudioSynth_ProcessEnvelope(Acmd* cmd, NoteSubEu* noteSubEu, NoteSynthesisState* synthState, s32 aiBufLen, - u16 inBuf, s32 headsetPanSettings, s32 flags) { - u32 phi_a1; + u16 dmemSrc, s32 haasEffectDelaySide, s32 flags) { + u32 dmemDests; u16 curVolLeft; u16 targetVolLeft; s32 phi_t1; @@ -1171,30 +1188,36 @@ Acmd* AudioSynth_ProcessEnvelope(Acmd* cmd, NoteSubEu* noteSubEu, NoteSynthesisS synthState->curVolLeft = curVolLeft + (rampLeft * (aiBufLen >> 3)); synthState->curVolRight = curVolRight + (rampRight * (aiBufLen >> 3)); - if (noteSubEu->bitField1.usesHeadsetPanEffects2) { - AudioSynth_ClearBuffer(cmd++, DMEM_NOTE_PAN_TEMP, DMEM_1CH_SIZE); + if (noteSubEu->bitField1.useHaasEffect) { + AudioSynth_ClearBuffer(cmd++, DMEM_HAAS_TEMP, DMEM_1CH_SIZE); AudioSynth_EnvSetup1(cmd++, phi_t1 * 2, rampReverb, rampLeft, rampRight); AudioSynth_EnvSetup2(cmd++, curVolLeft, curVolRight); - switch (headsetPanSettings) { - case 1: - phi_a1 = D_801304A4; + + switch (haasEffectDelaySide) { + case HAAS_EFFECT_DELAY_LEFT: + // Store the left dry channel in a temp space to be delayed to produce the haas effect + dmemDests = sEnvMixerLeftHaasDmemDests; break; - case 2: - phi_a1 = D_801304A8; + + case HAAS_EFFECT_DELAY_RIGHT: + // Store the right dry channel in a temp space to be delayed to produce the haas effect + dmemDests = sEnvMixerRightHaasDmemDests; break; - default: - phi_a1 = D_801304AC; + + default: // HAAS_EFFECT_DELAY_NONE + dmemDests = sEnvMixerDefaultDmemDests; break; } } else { aEnvSetup1(cmd++, phi_t1 * 2, rampReverb, rampLeft, rampRight); aEnvSetup2(cmd++, curVolLeft, curVolRight); - phi_a1 = D_801304AC; + dmemDests = sEnvMixerDefaultDmemDests; } - aEnvMixer(cmd++, inBuf, aiBufLen, (sourceReverbVol & 0x80) >> 7, noteSubEu->bitField0.stereoHeadsetEffects, + aEnvMixer(cmd++, dmemSrc, aiBufLen, (sourceReverbVol & 0x80) >> 7, noteSubEu->bitField0.stereoHeadsetEffects, noteSubEu->bitField0.usesHeadsetPanEffects, noteSubEu->bitField0.stereoStrongRight, - noteSubEu->bitField0.stereoStrongLeft, phi_a1, D_801304A0); + noteSubEu->bitField0.stereoStrongLeft, dmemDests, sEnvMixerOp); + return cmd; } @@ -1242,61 +1265,75 @@ Acmd* AudioSynth_LoadWaveSamples(Acmd* cmd, NoteSubEu* noteSubEu, NoteSynthesisS return cmd; } -Acmd* AudioSynth_NoteApplyHeadsetPanEffects(Acmd* cmd, NoteSubEu* noteSubEu, NoteSynthesisState* synthState, s32 bufLen, - s32 flags, s32 side) { - u16 dest; +/** + * The Haas Effect gives directionality to sound by appling a small (< 35ms) delay to either the left or right channel. + * The delay is small enough that the sound is still perceived as one sound, but the channel that is not delayed will + * reach our ear first and give a sense of directionality. The sound is directed towards the opposite side of the delay. + */ +Acmd* AudioSynth_ApplyHaasEffect(Acmd* cmd, NoteSubEu* noteSubEu, NoteSynthesisState* synthState, s32 size, s32 flags, + s32 haasEffectDelaySide) { + u16 dmemDest; u16 pitch; - u8 prevPanShift; - u8 panShift; + u8 prevHaasEffectDelaySize; + u8 haasEffectDelaySize; - switch (side) { - case 1: - dest = DMEM_LEFT_CH; - panShift = noteSubEu->headsetPanRight; - prevPanShift = synthState->prevHeadsetPanRight; - synthState->prevHeadsetPanLeft = 0; - synthState->prevHeadsetPanRight = panShift; + switch (haasEffectDelaySide) { + case HAAS_EFFECT_DELAY_LEFT: + // Delay the sample on the left channel + // This allows the right channel to be heard first + dmemDest = DMEM_LEFT_CH; + haasEffectDelaySize = noteSubEu->haasEffectLeftDelaySize; + prevHaasEffectDelaySize = synthState->prevHaasEffectLeftDelaySize; + synthState->prevHaasEffectRightDelaySize = 0; + synthState->prevHaasEffectLeftDelaySize = haasEffectDelaySize; break; - case 2: - dest = DMEM_RIGHT_CH; - panShift = noteSubEu->headsetPanLeft; - prevPanShift = synthState->prevHeadsetPanLeft; - synthState->prevHeadsetPanLeft = panShift; - synthState->prevHeadsetPanRight = 0; + + case HAAS_EFFECT_DELAY_RIGHT: + // Delay the sample on the right channel + // This allows the left channel to be heard first + dmemDest = DMEM_RIGHT_CH; + haasEffectDelaySize = noteSubEu->haasEffectRightDelaySize; + prevHaasEffectDelaySize = synthState->prevHaasEffectRightDelaySize; + synthState->prevHaasEffectRightDelaySize = haasEffectDelaySize; + synthState->prevHaasEffectLeftDelaySize = 0; break; - default: + + default: // HAAS_EFFECT_DELAY_NONE return cmd; } if (flags != A_INIT) { - // Slightly adjust the sample rate in order to fit a change in pan shift - if (panShift != prevPanShift) { - pitch = (((bufLen << 0xF) / 2) - 1) / ((bufLen + panShift - prevPanShift - 2) / 2); - aSetBuffer(cmd++, 0, DMEM_NOTE_PAN_TEMP, DMEM_TEMP, bufLen + panShift - prevPanShift); + // Slightly adjust the sample rate in order to fit a change in sample delay + if (haasEffectDelaySize != prevHaasEffectDelaySize) { + pitch = (((size << 0xF) / 2) - 1) / ((size + haasEffectDelaySize - prevHaasEffectDelaySize - 2) / 2); + aSetBuffer(cmd++, 0, DMEM_HAAS_TEMP, DMEM_TEMP, size + haasEffectDelaySize - prevHaasEffectDelaySize); aResampleZoh(cmd++, pitch, 0); } else { - aDMEMMove(cmd++, DMEM_NOTE_PAN_TEMP, DMEM_TEMP, bufLen); + aDMEMMove(cmd++, DMEM_HAAS_TEMP, DMEM_TEMP, size); } - if (prevPanShift != 0) { - aLoadBuffer(cmd++, &synthState->synthesisBuffers->panResampleState[0x8], DMEM_NOTE_PAN_TEMP, - ALIGN16(prevPanShift)); - aDMEMMove(cmd++, DMEM_TEMP, DMEM_NOTE_PAN_TEMP + prevPanShift, bufLen + panShift - prevPanShift); + if (prevHaasEffectDelaySize != 0) { + aLoadBuffer(cmd++, synthState->synthesisBuffers->haasEffectDelayState, DMEM_HAAS_TEMP, + ALIGN16(prevHaasEffectDelaySize)); + aDMEMMove(cmd++, DMEM_TEMP, DMEM_HAAS_TEMP + prevHaasEffectDelaySize, + size + haasEffectDelaySize - prevHaasEffectDelaySize); } else { - aDMEMMove(cmd++, DMEM_TEMP, DMEM_NOTE_PAN_TEMP, bufLen + panShift); + aDMEMMove(cmd++, DMEM_TEMP, DMEM_HAAS_TEMP, size + haasEffectDelaySize); } } else { - // Just shift right - aDMEMMove(cmd++, DMEM_NOTE_PAN_TEMP, DMEM_TEMP, bufLen); - aClearBuffer(cmd++, DMEM_NOTE_PAN_TEMP, panShift); - aDMEMMove(cmd++, DMEM_TEMP, DMEM_NOTE_PAN_TEMP + panShift, bufLen); + // Just apply a delay directly + aDMEMMove(cmd++, DMEM_HAAS_TEMP, DMEM_TEMP, size); + aClearBuffer(cmd++, DMEM_HAAS_TEMP, haasEffectDelaySize); + aDMEMMove(cmd++, DMEM_TEMP, DMEM_HAAS_TEMP + haasEffectDelaySize, size); } - if (panShift) { + if (haasEffectDelaySize) { // != 0 // Save excessive samples for next iteration - aSaveBuffer(cmd++, DMEM_NOTE_PAN_TEMP + bufLen, &synthState->synthesisBuffers->panResampleState[0x8], - ALIGN16(panShift)); + aSaveBuffer(cmd++, DMEM_HAAS_TEMP + size, synthState->synthesisBuffers->haasEffectDelayState, + ALIGN16(haasEffectDelaySize)); } - aAddMixer(cmd++, ALIGN64(bufLen), DMEM_NOTE_PAN_TEMP, dest, 0x7FFF); + + aAddMixer(cmd++, ALIGN64(size), DMEM_HAAS_TEMP, dmemDest, 0x7FFF); + return cmd; }