audio docs

This commit is contained in:
Alejandro Javier Asenjo Nitti 2024-11-10 00:06:43 -03:00
parent 9fc4b2a796
commit 7d69a9a049
10 changed files with 991 additions and 718 deletions

View File

@ -9,6 +9,10 @@
#define TIME_IN_SECONDS(x) (x * 30);
#define CLAMP(x, min, max) ((x) < (min) ? (min) : (x) > (max) ? (max) : (x))
#define CLAMP_MAX(x, max) ((x) > (max) ? (max) : (x))
#define CLAMP_MIN(x, min) ((x) < (min) ? (min) : (x))
#define RAND_FLOAT(max) (Rand_ZeroOne()*(max))
#define RAND_INT(max) ((s32)(Rand_ZeroOne()*(max)))
#define RAND_FLOAT_CENTERED(width) ((Rand_ZeroOne()-0.5f)*(width))

View File

@ -612,7 +612,43 @@ typedef struct {
/* 0x0A */ u16 resampleRate;
/* 0x0C */ s16* waveSampleAddr;
} NoteSubEu; // size = 0x10
typedef struct {
struct {
/* 0x00 */ volatile u8 enabled : 1;
/* 0x00 */ u8 needsInit : 1;
/* 0x00 */ u8 finished : 1;
/* 0x00 */ u8 unused : 1;
/* 0x00 */ u8 strongRight : 1;
/* 0x00 */ u8 strongLeft : 1;
/* 0x00 */ u8 strongReverbRight : 1;
/* 0x00 */ u8 strongReverbLeft : 1;
} bitField0;
struct {
/* 0x01 */ u8 reverbIndex : 3;
/* 0x01 */ u8 bookOffset : 2;
/* 0x01 */ u8 isSyntheticWave : 1;
/* 0x01 */ u8 hasTwoParts : 1;
/* 0x01 */ u8 useHaasEffect : 1;
} bitField1;
/* 0x02 */ u8 gain; // Increases volume by a multiplicative scaling factor. Represented as a UQ4.4 number
/* 0x03 */ u8 haasEffectLeftDelaySize;
/* 0x04 */ u8 haasEffectRightDelaySize;
/* 0x05 */ u8 targetReverbVol;
/* 0x06 */ u8 harmonicIndexCurAndPrev; // bits 3..2 store curHarmonicIndex, bits 1..0 store prevHarmonicIndex
/* 0x07 */ u8 combFilterSize;
/* 0x08 */ u16 targetVolLeft;
/* 0x0A */ u16 targetVolRight;
/* 0x0C */ u16 frequencyFixedPoint;
/* 0x0E */ u16 combFilterGain;
union {
/* 0x10 */ TunedSample* tunedSample;
/* 0x10 */ s16* waveSampleAddr; // used for synthetic waves
};
/* 0x14 */ s16* filter;
/* 0x18 */ u8 unk_18;
/* 0x19 */ u8 surroundEffectIndex;
/* 0x1A */ u8 unk_1A[0x6];
} NoteSampleState; // size = 0x20
typedef struct Note {
/* 0x00 */ AudioListItem listItem;
/* 0x10 */ NoteSynthesisState synthesisState;
@ -1021,14 +1057,14 @@ typedef struct {
// audio_synthesis
void func_80008780(f32*, s32, f32*);
Acmd* func_80009B64(Acmd* aList, s32* cmdCount, s16* aiBufStart, s32 aiBufLen);
Acmd* AudioSynth_Update(Acmd* aList, s32* cmdCount, s16* aiBufStart, s32 aiBufLen);
// audio_effects
void func_800135A8(SequencePlayer* seqplayer);
void func_80013A18(Note* note);
void func_80013A84(Note* note);
void func_80013B6C(AdsrState* adsr, EnvelopePoint* envelope, s16* arg2);
f32 func_80013B90(AdsrState* adsr);
void Audio_SequencePlayerProcessSound(SequencePlayer* seqplayer);
void Audio_NoteVibratoUpdate(Note* note);
void Audio_NoteVibratoInit(Note* note);
void Audio_AdsrInit(AdsrState* adsr, EnvelopePoint* envelope, s16* arg2);
f32 Audio_AdsrUpdate(AdsrState* adsr);
// audio_heap
void AudioHeap_DiscardFont(s32 fontId);
@ -1058,29 +1094,29 @@ void AudioLoad_DiscardSeqFonts(s32 seqId);
s32 AudioLoad_SlowLoadSample(s32 fontId, u8 instId, s8* status);
// audio_playback
TunedSample* func_80011D10(Instrument* instrument, s32 arg1);
TunedSample* Audio_GetInstrumentTunedSample(Instrument* instrument, s32 semitone);
Instrument* Audio_GetInstrument(s32, s32);
Drum* Audio_GetDrum(s32, s32);
void func_80011F4C(Note* note);
void func_80011FA8(void);
void func_8001266C(SequenceLayer* layer);
void func_800127B0(Note* note, SequenceLayer* layer);
void func_80012864(NotePool* pool);
void func_800128B4(void);
void func_80012964(NotePool* pool);
void func_80012AC4(NotePool* pool, s32);
void func_80012C40(Note* note);
Note* func_8001301C(SequenceLayer* layer);
void func_800132E8(void);
void Audio_NoteDisable(Note* note);
void Audio_ProcessNotes(void);
void Audio_SeqLayerNoteDecay(SequenceLayer* layer);
void Audio_InitSyntheticWave(Note* note, SequenceLayer* layer);
void Audio_InitNoteLists(NotePool* pool);
void Audio_InitNoteFreeList(void);
void Audio_NotePoolClear(NotePool* pool);
void Audio_NotePoolFill(NotePool* pool, s32);
void Audio_AudioListRemove(Note* note);
Note* Audio_AllocNote(SequenceLayer* layer);
void Audio_NoteInitAll(void);
// audio_seqplayer
void func_8001415C(SequenceChannel* channel);
void func_800144E4(SequencePlayer* seqPlayer);
void func_800145BC(AudioListItem* list, AudioListItem* item);
void* func_800145FC(AudioListItem* list);
void func_8001678C(s32 arg0);
void func_80016804(s32 arg0);
void func_800168BC(void);
void AudioSeq_SequenceChannelDisable(SequenceChannel* channel);
void AudioSeq_SequencePlayerDisable(SequencePlayer* seqPlayer);
void AudioSeq_AudioListPushBack(AudioListItem* list, AudioListItem* item);
void* AudioSeq_AudioListPopBack(AudioListItem* list);
void AudioSeq_ProcessSequences(s32 arg0);
void AudioSeq_ResetSequencePlayer(s32 arg0);
void AudioSeq_InitSequencePlayers(void);
// audio_thread
void AudioThread_ScheduleProcessCmds(void);

View File

@ -233,15 +233,15 @@ func_800098DC = 0x800098DC;
func_80009984 = 0x80009984;
func_80009A2C = 0x80009A2C;
func_80009AAC = 0x80009AAC;
func_80009B64 = 0x80009B64;
AudioSynth_Update = 0x80009B64;
func_80009D78 = 0x80009D78;
func_8000A128 = 0x8000A128;
func_8000A25C = 0x8000A25C;
func_8000A700 = 0x8000A700;
func_8000B3F0 = 0x8000B3F0;
AudioSynth_LoadWaveSamples = 0x8000B3F0;
func_8000B480 = 0x8000B480;
func_8000B51C = 0x8000B51C;
func_8000B98C = 0x8000B98C;
AudioSynth_ApplyHaasEffect = 0x8000B98C;
@ -332,72 +332,72 @@ AudioLoad_GetSamplesForFont = 0x80011758;
func_80011890 = 0x80011890;
func_80011C58 = 0x80011C58;
func_80011D10 = 0x80011D10;
Audio_InitNoteSub = 0x80011890;
Audio_NoteSetResamplingRate = 0x80011C58;
Audio_GetInstrumentTunedSample = 0x80011D10;
Audio_GetInstrument = 0x80011D4C;
Audio_GetDrum = 0x80011DFC;
func_80011EB8 = 0x80011EB8;
func_80011F4C = 0x80011F4C;
func_80011FA8 = 0x80011FA8;
func_80012438 = 0x80012438;
func_8001266C = 0x8001266C;
func_8001268C = 0x8001268C;
func_800126AC = 0x800126AC;
func_800127B0 = 0x800127B0;
func_80012854 = 0x80012854;
func_80012864 = 0x80012864;
func_800128B4 = 0x800128B4;
func_80012964 = 0x80012964;
func_80012AC4 = 0x80012AC4;
func_80012C00 = 0x80012C00;
func_80012C40 = 0x80012C40;
func_80012C6C = 0x80012C6C;
func_80012CEC = 0x80012CEC;
Audio_NoteInit = 0x80011EB8;
Audio_NoteDisable = 0x80011F4C;
Audio_ProcessNotes = 0x80011FA8;
Audio_SeqLayerDecayRelease = 0x80012438;
Audio_SeqLayerNoteDecay = 0x8001266C;
Audio_SeqLayerNoteRelease = 0x8001268C;
Audio_BuildSyntheticWave = 0x800126AC;
Audio_InitSyntheticWave = 0x800127B0;
Audio_InitNoteList = 0x80012854;
Audio_InitNoteLists = 0x80012864;
Audio_InitNoteFreeList = 0x800128B4;
Audio_NotePoolClear = 0x80012964;
Audio_NotePoolFill = 0x80012AC4;
Audio_AudioListPushFront = 0x80012C00;
Audio_AudioListRemove = 0x80012C40;
Audio_FindNodeWithPrioLessThan = 0x80012C6C;
Audio_NoteInitForLayer = 0x80012CEC;
func_80012E28 = 0x80012E28;
func_80012E5C = 0x80012E5C;
func_80012E88 = 0x80012E88;
func_80012ED4 = 0x80012ED4;
func_80012F24 = 0x80012F24;
func_8001301C = 0x8001301C;
func_800132E8 = 0x800132E8;
Audio_NoteReleaseAndTakeOwnership = 0x80012E5C;
Audio_AllocNoteFromDisabled = 0x80012E88;
Audio_AllocNoteFromDecaying = 0x80012ED4;
Audio_AllocNoteFromActive = 0x80012F24;
Audio_AllocNote = 0x8001301C;
Audio_NoteInitAll = 0x800132E8;
func_80013400 = 0x80013400;
func_800135A8 = 0x800135A8;
func_80013708 = 0x80013708;
Audio_SequencePlayerProcessSound = 0x800135A8;
Audio_GetPortamentoFreqScale = 0x80013708;
func_800137DC = 0x800137DC;
func_80013820 = 0x80013820;
func_80013A18 = 0x80013A18;
func_80013A84 = 0x80013A84;
func_80013B6C = 0x80013B6C;
func_80013B90 = 0x80013B90;
Audio_GetVibratoFreqScale = 0x80013820;
Audio_NoteVibratoUpdate = 0x80013A18;
Audio_NoteVibratoInit = 0x80013A84;
Audio_AdsrInit = 0x80013B6C;
Audio_AdsrUpdate = 0x80013B90;
func_80013EA0 = 0x80013EA0;
func_80013FC4 = 0x80013FC4;
func_800140D0 = 0x800140D0;
func_8001410C = 0x8001410C;
func_8001415C = 0x8001415C;
func_800141C8 = 0x800141C8;
func_80014244 = 0x80014244;
func_80014370 = 0x80014370;
func_80014440 = 0x80014440;
func_800144E4 = 0x800144E4;
func_800145BC = 0x800145BC;
func_800145FC = 0x800145FC;
func_8001463C = 0x8001463C;
func_800146C0 = 0x800146C0;
func_800146D4 = 0x800146D4;
func_80014704 = 0x80014704;
func_80014748 = 0x80014748;
func_800152C0 = 0x800152C0;
func_80015330 = 0x80015330;
func_800153C4 = 0x800153C4;
func_800153E8 = 0x800153E8;
func_80015FD4 = 0x80015FD4;
func_8001678C = 0x8001678C;
func_80016804 = 0x80016804;
func_800168BC = 0x800168BC;
AudioSeq_InitSequenceChannel = 0x80013EA0;
AudioSeq_SeqChannelSetLayer = 0x80013FC4;
AudioSeq_SeqLayerDisable = 0x800140D0;
AudioSeq_SeqLayerFree = 0x8001410C;
AudioSeq_SequenceChannelDisable = 0x8001415C;
AudioSeq_RequestFreeSeqChannel = 0x800141C8;
AudioSeq_SequencePlayerSetupChannels = 0x80014244;
AudioSeq_SequencePlayerDisableChannels = 0x80014370;
AudioSeq_SequenceChannelEnable = 0x80014440;
AudioSeq_SequencePlayerDisable = 0x800144E4;
AudioSeq_AudioListPushBack = 0x800145BC;
AudioSeq_AudioListPopBack = 0x800145FC;
AudioSeq_InitLayerFreelist = 0x8001463C;
AudioSeq_ScriptReadU8 = 0x800146C0;
AudioSeq_ScriptReadS16 = 0x800146D4;
AudioSeq_ScriptReadCompressedU16 = 0x80014704;
AudioSeq_SeqLayerProcessScript = 0x80014748;
AudioSeq_GetInstrument = 0x800152C0;
AudioSeq_SetInstrument = 0x80015330;
AudioSeq_SequenceChannelSetVolume = 0x800153C4;
AudioSeq_SequenceChannelProcessScript = 0x800153E8;
AudioSeq_SequencePlayerProcessSequence = 0x80015FD4;
AudioSeq_ProcessSequences = 0x8001678C;
AudioSeq_ResetSequencePlayer = 0x80016804;
AudioSeq_InitSequencePlayers = 0x800168BC;

View File

@ -42,7 +42,7 @@ void func_80013400(SequenceChannel* channel, s32 updateVolume) {
channel->changes.asByte = 0;
}
void func_800135A8(SequencePlayer* seqplayer) {
void Audio_SequencePlayerProcessSound(SequencePlayer* seqplayer) {
s32 i;
if (seqplayer->fadeTimer != 0) {
@ -56,14 +56,14 @@ void func_800135A8(SequencePlayer* seqplayer) {
}
seqplayer->fadeTimer--;
if ((seqplayer->fadeTimer == 0) && (seqplayer->state == 2)) {
func_800144E4(seqplayer);
AudioSeq_SequencePlayerDisable(seqplayer);
return;
}
}
if (seqplayer->recalculateVolume) {
seqplayer->appliedFadeVolume = seqplayer->fadeVolume * seqplayer->fadeVolumeMod;
}
for (i = 0; i < 16; i++) {
for (i = 0; i < SEQ_NUM_CHANNELS; i++) {
if ((IS_SEQUENCE_CHANNEL_VALID(seqplayer->channels[i]) == 1) && (seqplayer->channels[i]->enabled == 1)) {
func_80013400(seqplayer->channels[i], seqplayer->recalculateVolume);
}
@ -71,7 +71,7 @@ void func_800135A8(SequencePlayer* seqplayer) {
seqplayer->recalculateVolume = false;
}
f32 func_80013708(Portamento* portamento) {
f32 Audio_GetPortamentoFreqScale(Portamento* portamento) {
u32 temp;
f32 temp2;
@ -92,7 +92,7 @@ s16 func_800137DC(VibratoState* vibrato) {
return vibrato->curve[index] >> 8;
}
f32 func_80013820(VibratoState* vibrato) {
f32 Audio_GetVibratoFreqScale(VibratoState* vibrato) {
s32 ret;
f32 temp;
f32 temp2;
@ -136,16 +136,16 @@ f32 func_80013820(VibratoState* vibrato) {
return temp2;
}
void func_80013A18(Note* note) {
void Audio_NoteVibratoUpdate(Note* note) {
if (note->playbackState.portamento.mode != 0) {
note->playbackState.portamentoFreqMod = func_80013708(&note->playbackState.portamento);
note->playbackState.portamentoFreqMod = Audio_GetPortamentoFreqScale(&note->playbackState.portamento);
}
if ((note->playbackState.vibratoState.active != 0) && (note->playbackState.parentLayer != NO_LAYER)) {
note->playbackState.vibratoFreqMod = func_80013820(&note->playbackState.vibratoState);
note->playbackState.vibratoFreqMod = Audio_GetVibratoFreqScale(&note->playbackState.vibratoState);
}
}
void func_80013A84(Note* note) {
void Audio_NoteVibratoInit(Note* note) {
NotePlaybackState* noteState = &note->playbackState;
VibratoState* vibrato = &noteState->vibratoState;
@ -173,7 +173,7 @@ void func_80013A84(Note* note) {
noteState->portamento = noteState->parentLayer->portamento;
}
void func_80013B6C(AdsrState* adsr, EnvelopePoint* envelope, s16* arg2) {
void Audio_AdsrInit(AdsrState* adsr, EnvelopePoint* envelope, s16* arg2) {
adsr->action.asByte = 0;
adsr->state = 0;
adsr->delay = 0;
@ -182,7 +182,7 @@ void func_80013B6C(AdsrState* adsr, EnvelopePoint* envelope, s16* arg2) {
adsr->current = 0.0f;
}
f32 func_80013B90(AdsrState* adsr) {
f32 Audio_AdsrUpdate(AdsrState* adsr) {
u8 action = adsr->action.asByte;
u8 state = adsr->state;

View File

@ -99,9 +99,9 @@ void AudioHeap_DiscardFont(s32 fontId) {
note->playbackState.parentLayer->enabled = false;
note->playbackState.parentLayer->finished = true;
}
func_80011F4C(note);
func_80012C40(note);
func_800145BC(&gNoteFreeLists.disabled, &note->listItem);
Audio_NoteDisable(note);
Audio_AudioListRemove(note);
AudioSeq_AudioListPushBack(&gNoteFreeLists.disabled, &note->listItem);
}
}
}
@ -111,7 +111,7 @@ void AudioHeap_DiscardSequence(s32 seqId) {
for (i = 0; i < ARRAY_COUNT(gSeqPlayers); i++) {
if (gSeqPlayers[i].enabled && gSeqPlayers[i].seqId == seqId) {
func_800144E4(&gSeqPlayers[i]);
AudioSeq_SequencePlayerDisable(&gSeqPlayers[i]);
}
}
}
@ -571,7 +571,7 @@ s32 AudioHeap_ResetStep(void) {
switch (gAudioResetStep) {
case 5:
for (i = 0; i < ARRAY_COUNT(gSeqPlayers); i++) {
func_800144E4(&gSeqPlayers[i]);
AudioSeq_SequencePlayerDisable(&gSeqPlayers[i]);
}
gResetFadeoutFramesLeft = 4 / sp24;
gAudioResetStep--;
@ -696,8 +696,8 @@ void AudioHeap_Init(void) {
AudioHeap_InitSampleCaches(spec->persistentSampleCacheSize, spec->temporarySampleCacheSize);
AudioHeap_ResetLoadStatus();
gNotes = AudioHeap_AllocZeroed(&gMiscPool, gNumNotes * sizeof(Note));
func_800132E8();
func_800128B4();
Audio_NoteInitAll();
Audio_InitNoteFreeList();
gNoteSubsEu = AudioHeap_AllocZeroed(&gMiscPool, gAudioBufferParams.ticksPerUpdate * gNumNotes * sizeof(NoteSubEu));
for (i = 0; i != 2; i++) {
gAbiCmdBuffs[i] = AudioHeap_AllocZeroed(&gMiscPool, gMaxAudioCmds * 8);

View File

@ -383,7 +383,7 @@ void AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) {
seqId = AudioLoad_GetLoadTableIndex(SEQUENCE_TABLE, seqId);
func_800144E4(&gSeqPlayers[playerIdx]);
AudioSeq_SequencePlayerDisable(&gSeqPlayers[playerIdx]);
index = *((u16*) gSeqFontTable + seqId);
numFonts = gSeqFontTable[index++];
@ -396,7 +396,7 @@ void AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) {
seqData = AudioLoad_SyncLoadSeq(seqId);
func_80016804(playerIdx);
AudioSeq_ResetSequencePlayer(playerIdx);
gSeqPlayers[playerIdx].seqId = seqId;
gSeqPlayers[playerIdx].defaultFont = fontId;
@ -978,7 +978,7 @@ void AudioLoad_Init(void) {
}
AudioHeap_InitPool(&gPermanentPool.pool, ramAddr, gPermanentPoolSize);
func_800168BC();
AudioSeq_InitSequencePlayers();
}
static const char devstr38[] = "Entry--- %d %d\n";

View File

@ -33,13 +33,13 @@ static const char devstr25[] = "Intterupt UseStop %d (Kill %d)\n";
static const char devstr26[] = "Intterupt RelWait %d (Kill %d)\n";
static const char devstr27[] = "Drop Voice (Prio %x)\n";
void func_80011C58(Note* note, f32);
void func_8001268C(SequenceLayer* layer);
void func_80012C00(AudioListItem* item1, AudioListItem* item2);
void func_80012C40(Note* note);
void func_80012CEC(Note* note, SequenceLayer* layer);
void Audio_NoteSetResamplingRate(Note* note, f32);
void Audio_SeqLayerNoteRelease(SequenceLayer* layer);
void Audio_AudioListPushFront(AudioListItem* list, AudioListItem* item);
void Audio_AudioListRemove(Note* note);
void Audio_NoteInitForLayer(Note* note, SequenceLayer* layer);
void func_80011890(Note* note, NoteAttributes* noteAttr) {
void Audio_InitNoteSub(Note* note, NoteAttributes* noteAttr) {
NoteSubEu* noteSub;
f32 panVolumeLeft;
f32 pamVolumeRight;
@ -52,7 +52,7 @@ void func_80011890(Note* note, NoteAttributes* noteAttr) {
u8 reverb;
Stereo stereo;
func_80011C58(note, noteAttr->freqMod);
Audio_NoteSetResamplingRate(note, noteAttr->freqMod);
noteSub = &note->noteSubEu;
velocity = noteAttr->velocity;
pan = noteAttr->pan;
@ -130,34 +130,30 @@ void func_80011890(Note* note, NoteAttributes* noteAttr) {
}
}
void func_80011C58(Note* note, f32 arg1) {
void Audio_NoteSetResamplingRate(Note* note, f32 resamplingRateInput) {
NoteSubEu* noteSub = &note->noteSubEu;
f32 var_fv0;
f32 resamplingRate;
if (arg1 < 2.0f) {
noteSub->bitField1.hasTwoParts = 0;
if (arg1 > 1.99998f) {
var_fv0 = 1.99998f;
} else {
var_fv0 = arg1;
}
if (resamplingRateInput < 2.0f) {
noteSub->bitField1.hasTwoParts = false;
resamplingRate = CLAMP_MAX(resamplingRateInput, 1.99998f);
} else {
noteSub->bitField1.hasTwoParts = 1;
if (arg1 > 3.99996f) {
var_fv0 = 1.99998f;
noteSub->bitField1.hasTwoParts = true;
if (resamplingRateInput > 3.99996f) {
resamplingRate = 1.99998f;
} else {
var_fv0 = arg1 * 0.5f;
resamplingRate = resamplingRateInput * 0.5f;
}
}
note->noteSubEu.resampleRate = (s32) (var_fv0 * 32768.0f);
note->noteSubEu.resampleRate = (s32) (resamplingRate * 32768.0f);
}
TunedSample* func_80011D10(Instrument* instrument, s32 arg1) {
TunedSample* Audio_GetInstrumentTunedSample(Instrument* instrument, s32 semitone) {
TunedSample* sample;
if (arg1 < instrument->normalRangeLo) {
if (semitone < instrument->normalRangeLo) {
sample = &instrument->lowPitchTunedSample;
} else if (arg1 <= instrument->normalRangeHi) {
} else if (semitone <= instrument->normalRangeHi) {
sample = &instrument->normalPitchTunedSample;
} else {
sample = &instrument->highPitchTunedSample;
@ -205,33 +201,33 @@ Drum* Audio_GetDrum(s32 fontId, s32 drumId) {
return drum;
}
void func_80011EB8(Note* note) {
void Audio_NoteInit(Note* note) {
if (note->playbackState.parentLayer->adsr.decayIndex == 0) {
func_80013B6C(&note->playbackState.adsr, note->playbackState.parentLayer->channel->adsr.envelope,
&note->playbackState.adsrVolModUnused);
Audio_AdsrInit(&note->playbackState.adsr, note->playbackState.parentLayer->channel->adsr.envelope,
&note->playbackState.adsrVolModUnused);
} else {
func_80013B6C(&note->playbackState.adsr, note->playbackState.parentLayer->adsr.envelope,
&note->playbackState.adsrVolModUnused);
Audio_AdsrInit(&note->playbackState.adsr, note->playbackState.parentLayer->adsr.envelope,
&note->playbackState.adsrVolModUnused);
}
note->playbackState.adsr.state = 1;
note->playbackState.adsr.state = ADSR_STATE_INITIAL;
note->noteSubEu = gDefaultNoteSub;
}
void func_80011F4C(Note* note) {
if (note->noteSubEu.bitField0.needsInit == 1) {
note->noteSubEu.bitField0.needsInit = 0;
void Audio_NoteDisable(Note* note) {
if (note->noteSubEu.bitField0.needsInit == true) {
note->noteSubEu.bitField0.needsInit = false;
}
note->playbackState.priority = 0;
note->noteSubEu.bitField0.enabled = false;
note->playbackState.unk_04 = 0;
note->noteSubEu.bitField0.enabled = 0;
note->playbackState.parentLayer = NO_LAYER;
note->playbackState.prevParentLayer = NO_LAYER;
note->noteSubEu.bitField0.finished = 0;
note->playbackState.adsr.state = 0;
note->playbackState.adsr.state = ADSR_STATE_DISABLED;
note->playbackState.adsr.current = 0.0f;
}
void func_80011FA8(void) {
void Audio_ProcessNotes(void) {
s32 pad2;
s32 pad;
Note* note;
@ -241,7 +237,7 @@ void func_80011FA8(void) {
s32 i;
NoteAttributes sp70;
u8 bookOffset;
f32 temp_fs0;
f32 scale;
for (i = 0; i < gNumNotes; i++) {
note = &gNotes[i];
@ -257,31 +253,31 @@ void func_80011FA8(void) {
playbackState->adsr.fadeOutVel = gAudioBufferParams.ticksPerUpdateInv;
playbackState->priority = 1;
playbackState->unk_04 = 2;
goto block_21;
goto out;
} else {
if ((playbackState->parentLayer->enabled) || (playbackState->unk_04 != 0) ||
(playbackState->priority <= 0)) {
if (playbackState->parentLayer->channel->seqPlayer == NULL) {
func_8001415C(playbackState->parentLayer->channel);
AudioSeq_SequenceChannelDisable(playbackState->parentLayer->channel);
playbackState->priority = 1;
playbackState->unk_04 = 1;
continue;
}
if (!(playbackState->parentLayer->channel->seqPlayer->muted &&
(playbackState->parentLayer->channel->muteBehavior & 0x40))) {
goto block_21;
(playbackState->parentLayer->channel->muteBehavior & MUTE_BEHAVIOR_STOP_NOTES))) {
goto out;
}
}
func_8001268C(playbackState->parentLayer);
func_80012C40(note);
func_80012C00(&note->listItem.pool->decaying, &note->listItem);
Audio_SeqLayerNoteRelease(playbackState->parentLayer);
Audio_AudioListRemove(note);
Audio_AudioListPushFront(&note->listItem.pool->decaying, &note->listItem);
playbackState->priority = 1;
playbackState->unk_04 = 2;
}
} else if ((playbackState->unk_04 == 0) && (playbackState->priority > 0)) {
continue;
}
block_21:
out:
if (playbackState->priority != 0) {
if (1) {}
@ -289,36 +285,36 @@ void func_80011FA8(void) {
if ((playbackState->unk_04 > 0) || noteSub->bitField0.finished) {
if ((playbackState->adsr.state == 0) || noteSub->bitField0.finished) {
if (playbackState->wantedParentLayer != NO_LAYER) {
func_80011F4C(note);
Audio_NoteDisable(note);
if (playbackState->wantedParentLayer->channel != NULL) {
func_80012CEC(note, playbackState->wantedParentLayer);
func_80013A84(note);
func_80012C40(note);
func_800145BC(&note->listItem.pool->active, &note->listItem);
Audio_NoteInitForLayer(note, playbackState->wantedParentLayer);
Audio_NoteVibratoInit(note);
Audio_AudioListRemove(note);
AudioSeq_AudioListPushBack(&note->listItem.pool->active, &note->listItem);
playbackState->wantedParentLayer = NO_LAYER;
} else {
func_80011F4C(note);
func_80012C40(note);
func_800145BC(&note->listItem.pool->disabled, &note->listItem);
Audio_NoteDisable(note);
Audio_AudioListRemove(note);
AudioSeq_AudioListPushBack(&note->listItem.pool->disabled, &note->listItem);
playbackState->wantedParentLayer = NO_LAYER;
goto next;
}
} else {
func_80011F4C(note);
func_80012C40(note);
func_800145BC(&note->listItem.pool->disabled, &note->listItem);
Audio_NoteDisable(note);
Audio_AudioListRemove(note);
AudioSeq_AudioListPushBack(&note->listItem.pool->disabled, &note->listItem);
goto next;
}
}
} else if (playbackState->adsr.state == 0) {
func_80011F4C(note);
func_80012C40(note);
func_800145BC(&note->listItem.pool->disabled, &note->listItem);
Audio_NoteDisable(note);
Audio_AudioListRemove(note);
AudioSeq_AudioListPushBack(&note->listItem.pool->disabled, &note->listItem);
goto next;
}
temp_fs0 = func_80013B90(&playbackState->adsr);
func_80013A18(note);
scale = Audio_AdsrUpdate(&playbackState->adsr);
Audio_NoteVibratoUpdate(note);
attr = &playbackState->attributes;
if ((playbackState->unk_04 == 1) || (playbackState->unk_04 == 2)) {
sp70.freqMod = attr->freqMod;
@ -345,15 +341,15 @@ void func_80011FA8(void) {
}
sp70.freqMod *= playbackState->vibratoFreqMod * playbackState->portamentoFreqMod;
sp70.freqMod *= gAudioBufferParams.resampleRate;
sp70.velocity *= temp_fs0;
func_80011890(note, &sp70);
sp70.velocity *= scale;
Audio_InitNoteSub(note, &sp70);
noteSub->bitField1.bookOffset = bookOffset;
next:;
}
}
}
void func_80012438(SequenceLayer* layer, s32 arg1) {
void Audio_SeqLayerDecayRelease(SequenceLayer* layer, s32 arg1) {
Note* note;
NoteAttributes* noteAttr;
@ -413,21 +409,21 @@ void func_80012438(SequenceLayer* layer, s32 arg1) {
}
}
if (arg1 == 6) {
func_80012C40(note);
func_80012C00(&note->listItem.pool->decaying, &note->listItem);
Audio_AudioListRemove(note);
Audio_AudioListPushFront(&note->listItem.pool->decaying, &note->listItem);
}
}
}
void func_8001266C(SequenceLayer* layer) {
func_80012438(layer, 6);
void Audio_SeqLayerNoteDecay(SequenceLayer* layer) {
Audio_SeqLayerDecayRelease(layer, ADSR_STATE_DECAY);
}
void func_8001268C(SequenceLayer* layer) {
func_80012438(layer, 7);
void Audio_SeqLayerNoteRelease(SequenceLayer* layer) {
Audio_SeqLayerDecayRelease(layer, ADSR_STATE_RELEASE);
}
s32 func_800126AC(Note* note, SequenceLayer* layer, s32 waveId) {
s32 Audio_BuildSyntheticWave(Note* note, SequenceLayer* layer, s32 waveId) {
f32 freqMod;
u8 harmonicIndex = 0;
@ -458,7 +454,7 @@ s32 func_800126AC(Note* note, SequenceLayer* layer, s32 waveId) {
return harmonicIndex;
}
void func_800127B0(Note* note, SequenceLayer* layer) {
void Audio_InitSyntheticWave(Note* note, SequenceLayer* layer) {
s32 harmonicIndex;
s32 waveId;
@ -468,39 +464,39 @@ void func_800127B0(Note* note, SequenceLayer* layer) {
}
harmonicIndex = note->playbackState.harmonicIndex;
note->synthesisState.samplePosInt =
(note->synthesisState.samplePosInt * sSamplesPerWavePeriod[func_800126AC(note, layer, waveId)]) /
(note->synthesisState.samplePosInt * sSamplesPerWavePeriod[Audio_BuildSyntheticWave(note, layer, waveId)]) /
sSamplesPerWavePeriod[harmonicIndex];
}
void func_80012854(AudioListItem* item) {
void Audio_InitNoteList(AudioListItem* item) {
item->prev = item;
item->next = item;
item->u.value = NULL;
}
void func_80012864(NotePool* pool) {
func_80012854(&pool->disabled);
func_80012854(&pool->decaying);
func_80012854(&pool->releasing);
func_80012854(&pool->active);
void Audio_InitNoteLists(NotePool* pool) {
Audio_InitNoteList(&pool->disabled);
Audio_InitNoteList(&pool->decaying);
Audio_InitNoteList(&pool->releasing);
Audio_InitNoteList(&pool->active);
pool->disabled.pool = pool;
pool->decaying.pool = pool;
pool->releasing.pool = pool;
pool->active.pool = pool;
}
void func_800128B4(void) {
void Audio_InitNoteFreeList(void) {
s32 i;
func_80012864(&gNoteFreeLists);
Audio_InitNoteLists(&gNoteFreeLists);
for (i = 0; i < gNumNotes; i++) {
gNotes[i].listItem.u.value = &gNotes[i];
gNotes[i].listItem.prev = NULL;
func_800145BC(&gNoteFreeLists.disabled, &gNotes[i].listItem);
AudioSeq_AudioListPushBack(&gNoteFreeLists.disabled, &gNotes[i].listItem);
}
}
void func_80012964(NotePool* pool) {
void Audio_NotePoolClear(NotePool* pool) {
s32 poolType;
AudioListItem* poolItem;
AudioListItem* nextPoolItem;
@ -531,23 +527,22 @@ void func_80012964(NotePool* pool) {
if ((nextPoolItem == poolItem) || (nextPoolItem == NULL)) {
break;
}
func_80012C40((Note*) nextPoolItem);
func_800145BC(freeList, nextPoolItem);
Audio_AudioListRemove((Note*) nextPoolItem);
AudioSeq_AudioListPushBack(freeList, nextPoolItem);
}
}
}
void func_80012AC4(NotePool* pool, s32 arg1) {
s32 var_s0;
void Audio_NotePoolFill(NotePool* pool, s32 count) {
s32 j;
s32 poolType;
AudioListItem* note;
AudioListItem* freeList;
AudioListItem* poolList;
func_80012964(pool);
poolType = 0;
var_s0 = 0;
while (var_s0 < arg1) {
Audio_NotePoolClear(pool);
for (poolType = 0, j = 0; j < count; poolType++) {
if (poolType == 4) {
return;
}
@ -569,30 +564,31 @@ void func_80012AC4(NotePool* pool, s32 arg1) {
poolList = &pool->active;
break;
}
while (var_s0 < arg1) {
note = func_800145FC(freeList);
while (j < count) {
note = AudioSeq_AudioListPopBack(freeList);
if (note == NULL) {
break;
}
func_800145BC(poolList, note);
var_s0++;
AudioSeq_AudioListPushBack(poolList, note);
j++;
}
poolType++;
}
}
void func_80012C00(AudioListItem* item1, AudioListItem* item2) {
if (item2->prev == NULL) {
item2->prev = item1;
item2->next = item1->next;
item1->next->prev = item2;
item1->next = item2;
item1->u.count++;
item2->pool = item1->pool;
void Audio_AudioListPushFront(AudioListItem* list, AudioListItem* item) {
// add 'item' to the front of the list given by 'list', if it's not in any list
if (item->prev == NULL) {
item->prev = list;
item->next = list->next;
list->next->prev = item;
list->next = item;
list->u.count++;
item->pool = list->pool;
}
}
void func_80012C40(Note* note) {
void Audio_AudioListRemove(Note* note) {
// remove 'item' from the list it's in, if any
if (note->listItem.prev != NULL) {
note->listItem.prev->next = note->listItem.next;
note->listItem.next->prev = note->listItem.prev;
@ -600,7 +596,7 @@ void func_80012C40(Note* note) {
}
}
Note* func_80012C6C(AudioListItem* item, s32 priority) {
Note* Audio_FindNodeWithPrioLessThan(AudioListItem* item, s32 priority) {
AudioListItem* priorityItem;
AudioListItem* nextItem = item->next;
@ -625,7 +621,7 @@ Note* func_80012C6C(AudioListItem* item, s32 priority) {
return (Note*) priorityItem->u.value;
}
void func_80012CEC(Note* note, SequenceLayer* layer) {
void Audio_NoteInitForLayer(Note* note, SequenceLayer* layer) {
s32 pad[4];
s32 var_a2;
NoteSubEu* noteSub;
@ -639,7 +635,7 @@ void func_80012CEC(Note* note, SequenceLayer* layer) {
layer->channel->noteUnused = note;
layer->channel->layerUnused = layer;
layer->noteVelocity = 0.0f;
func_80011EB8(note);
Audio_NoteInit(note);
var_a2 = layer->instOrWave;
noteSub = &note->noteSubEu;
if (var_a2 == 0xFF) {
@ -652,7 +648,7 @@ void func_80012CEC(Note* note, SequenceLayer* layer) {
noteSub->bitField1.isSyntheticWave = false;
}
if (noteSub->bitField1.isSyntheticWave) {
func_800126AC(note, layer, var_a2);
Audio_BuildSyntheticWave(note, layer, var_a2);
}
note->playbackState.fontId = layer->channel->fontId;
noteSub->bitField0.stereoHeadsetEffects = layer->channel->stereoHeadsetEffects;
@ -660,122 +656,126 @@ void func_80012CEC(Note* note, SequenceLayer* layer) {
}
void func_80012E28(Note* note, SequenceLayer* layer) {
func_8001268C(note->playbackState.parentLayer);
Audio_SeqLayerNoteRelease(note->playbackState.parentLayer);
note->playbackState.wantedParentLayer = layer;
}
void func_80012E5C(Note* note, SequenceLayer* layer) {
void Audio_NoteReleaseAndTakeOwnership(Note* note, SequenceLayer* layer) {
note->playbackState.wantedParentLayer = layer;
note->playbackState.priority = layer->channel->notePriority;
note->playbackState.adsr.fadeOutVel = gAudioBufferParams.ticksPerUpdateInv;
note->playbackState.adsr.action.asByte |= 0x10;
}
Note* func_80012E88(NotePool* pool, SequenceLayer* layer) {
Note* note = func_800145FC(&pool->disabled);
Note* Audio_AllocNoteFromDisabled(NotePool* pool, SequenceLayer* layer) {
Note* note = AudioSeq_AudioListPopBack(&pool->disabled);
if (note != NULL) {
func_80012CEC(note, layer);
func_80012C00(&pool->active, &note->listItem);
Audio_NoteInitForLayer(note, layer);
Audio_AudioListPushFront(&pool->active, &note->listItem);
}
return note;
}
Note* func_80012ED4(NotePool* pool, SequenceLayer* layer) {
Note* note = func_800145FC(&pool->decaying);
Note* Audio_AllocNoteFromDecaying(NotePool* pool, SequenceLayer* layer) {
Note* note = AudioSeq_AudioListPopBack(&pool->decaying);
if (note != NULL) {
func_80012E5C(note, layer);
func_800145BC(&pool->releasing, &note->listItem);
Audio_NoteReleaseAndTakeOwnership(note, layer);
AudioSeq_AudioListPushBack(&pool->releasing, &note->listItem);
}
return note;
}
Note* func_80012F24(NotePool* pool, SequenceLayer* layer) {
Note* sp34;
Note* sp30;
s32 sp2C;
s32 sp28;
Note* Audio_AllocNoteFromActive(NotePool* pool, SequenceLayer* layer) {
Note* rNote;
Note* aNote;
s32 rPriority;
s32 aPriority;
sp2C = sp28 = 0x10;
sp34 = func_80012C6C(&pool->releasing, layer->channel->notePriority);
if (sp34 != NULL) {
sp2C = sp34->playbackState.priority;
rPriority = aPriority = 0x10;
rNote = Audio_FindNodeWithPrioLessThan(&pool->releasing, layer->channel->notePriority);
if (rNote != NULL) {
rPriority = rNote->playbackState.priority;
}
sp30 = func_80012C6C(&pool->active, layer->channel->notePriority);
if (sp30 != NULL) {
sp28 = sp30->playbackState.priority;
aNote = Audio_FindNodeWithPrioLessThan(&pool->active, layer->channel->notePriority);
if (aNote != NULL) {
aPriority = aNote->playbackState.priority;
}
if ((sp34 == NULL) && (sp30 == NULL)) {
if (rNote == NULL && aNote == NULL) {
return NULL;
}
if (sp28 < sp2C) {
func_80012C40(sp30);
func_80012E28(sp30, layer);
func_800145BC(&pool->releasing, &sp30->listItem);
sp30->playbackState.priority = layer->channel->notePriority;
return sp30;
} else {
sp34->playbackState.wantedParentLayer = layer;
sp34->playbackState.priority = layer->channel->notePriority;
return sp34;
if (aPriority < rPriority) {
Audio_AudioListRemove(aNote);
func_80012E28(aNote, layer);
AudioSeq_AudioListPushBack(&pool->releasing, &aNote->listItem);
aNote->playbackState.priority = layer->channel->notePriority;
return aNote;
}
rNote->playbackState.wantedParentLayer = layer;
rNote->playbackState.priority = layer->channel->notePriority;
return rNote;
}
Note* func_8001301C(SequenceLayer* layer) {
Note* sp24;
Note* Audio_AllocNote(SequenceLayer* layer) {
Note* note;
if (layer->channel->noteAllocPolicy & 1) {
sp24 = layer->note;
if ((sp24 != NULL) && (layer == sp24->playbackState.prevParentLayer) &&
(sp24->playbackState.wantedParentLayer == NO_LAYER)) {
note = layer->note;
if ((note != NULL) && (layer == note->playbackState.prevParentLayer) &&
(note->playbackState.wantedParentLayer == NO_LAYER)) {
func_80012E5C(sp24, layer);
func_80012C40(sp24);
func_800145BC(&sp24->listItem.pool->releasing, &sp24->listItem);
return sp24;
Audio_NoteReleaseAndTakeOwnership(note, layer);
Audio_AudioListRemove(note);
AudioSeq_AudioListPushBack(&note->listItem.pool->releasing, &note->listItem);
return note;
}
}
if (layer->channel->noteAllocPolicy & 2) {
if (((sp24 = func_80012E88(&layer->channel->notePool, layer)) != NULL) ||
((sp24 = func_80012ED4(&layer->channel->notePool, layer)) != NULL) ||
((sp24 = func_80012F24(&layer->channel->notePool, layer)) != NULL)) {
return sp24;
if (((note = Audio_AllocNoteFromDisabled(&layer->channel->notePool, layer)) != NULL) ||
((note = Audio_AllocNoteFromDecaying(&layer->channel->notePool, layer)) != NULL) ||
((note = Audio_AllocNoteFromActive(&layer->channel->notePool, layer)) != NULL)) {
return note;
}
} else if (layer->channel->noteAllocPolicy & 4) {
if (((sp24 = func_80012E88(&layer->channel->notePool, layer)) != NULL) ||
((sp24 = func_80012E88(&layer->channel->seqPlayer->notePool, layer)) != NULL) ||
((sp24 = func_80012ED4(&layer->channel->notePool, layer)) != NULL) ||
((sp24 = func_80012ED4(&layer->channel->seqPlayer->notePool, layer)) != NULL) ||
((sp24 = func_80012F24(&layer->channel->notePool, layer)) != NULL) ||
((sp24 = func_80012F24(&layer->channel->seqPlayer->notePool, layer)) != NULL)) {
return sp24;
if (((note = Audio_AllocNoteFromDisabled(&layer->channel->notePool, layer)) != NULL) ||
((note = Audio_AllocNoteFromDisabled(&layer->channel->seqPlayer->notePool, layer)) != NULL) ||
((note = Audio_AllocNoteFromDecaying(&layer->channel->notePool, layer)) != NULL) ||
((note = Audio_AllocNoteFromDecaying(&layer->channel->seqPlayer->notePool, layer)) != NULL) ||
((note = Audio_AllocNoteFromActive(&layer->channel->notePool, layer)) != NULL) ||
((note = Audio_AllocNoteFromActive(&layer->channel->seqPlayer->notePool, layer)) != NULL)) {
return note;
}
} else if (layer->channel->noteAllocPolicy & 8) {
if (((sp24 = func_80012E88(&gNoteFreeLists, layer)) != NULL) ||
((sp24 = func_80012ED4(&gNoteFreeLists, layer)) != NULL) ||
((sp24 = func_80012F24(&gNoteFreeLists, layer)) != NULL)) {
return sp24;
if (((note = Audio_AllocNoteFromDisabled(&gNoteFreeLists, layer)) != NULL) ||
((note = Audio_AllocNoteFromDecaying(&gNoteFreeLists, layer)) != NULL) ||
((note = Audio_AllocNoteFromActive(&gNoteFreeLists, layer)) != NULL)) {
return note;
}
} else {
if (((sp24 = func_80012E88(&layer->channel->notePool, layer)) != NULL) ||
((sp24 = func_80012E88(&layer->channel->seqPlayer->notePool, layer)) != NULL) ||
((sp24 = func_80012E88(&gNoteFreeLists, layer)) != NULL) ||
((sp24 = func_80012ED4(&layer->channel->notePool, layer)) != NULL) ||
((sp24 = func_80012ED4(&layer->channel->seqPlayer->notePool, layer)) != NULL) ||
((sp24 = func_80012ED4(&gNoteFreeLists, layer)) != NULL) ||
((sp24 = func_80012F24(&layer->channel->notePool, layer)) != NULL) ||
((sp24 = func_80012F24(&layer->channel->seqPlayer->notePool, layer)) != NULL) ||
((sp24 = func_80012F24(&gNoteFreeLists, layer)) != NULL)) {
return sp24;
if (((note = Audio_AllocNoteFromDisabled(&layer->channel->notePool, layer)) != NULL) ||
((note = Audio_AllocNoteFromDisabled(&layer->channel->seqPlayer->notePool, layer)) != NULL) ||
((note = Audio_AllocNoteFromDisabled(&gNoteFreeLists, layer)) != NULL) ||
((note = Audio_AllocNoteFromDecaying(&layer->channel->notePool, layer)) != NULL) ||
((note = Audio_AllocNoteFromDecaying(&layer->channel->seqPlayer->notePool, layer)) != NULL) ||
((note = Audio_AllocNoteFromDecaying(&gNoteFreeLists, layer)) != NULL) ||
((note = Audio_AllocNoteFromActive(&layer->channel->notePool, layer)) != NULL) ||
((note = Audio_AllocNoteFromActive(&layer->channel->seqPlayer->notePool, layer)) != NULL) ||
((note = Audio_AllocNoteFromActive(&gNoteFreeLists, layer)) != NULL)) {
return note;
}
}
layer->unk_3 = 0;
return NULL;
}
void func_800132E8(void) {
void Audio_NoteInitAll(void) {
s32 i;
Note* note;

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,19 @@
#include "sys.h"
#include "sf64audio_provisional.h"
#define DMEM_LEFT_CH 0x990
#define DMEM_RIGHT_CH 0xB10
#define DMEM_HAAS_TEMP 0x650
#define DMEM_TEMP 0x450
#define DMEM_UNCOMPRESSED_NOTE 0x5F0
#define SAMPLE_SIZE sizeof(s16)
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;
s32 D_80145D40; // unused
// all of these are part of the DFT-related function
@ -36,12 +49,12 @@ Acmd* func_800098DC(Acmd* aList, u16 dmem, u16 startPos, s32 size, s32 reverbInd
Acmd* func_80009984(Acmd* aList, u16 dmem, u16 startPos, s32 size, s32 reverbIndex);
Acmd* func_80009D78(Acmd* aList, s32 aiBufLen, s16 reverbIndex, s16 updateIndex);
Acmd* func_8000A128(Acmd* aList, s16 reverbIndex, s16 updateIndex);
Acmd* func_8000B3F0(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisState* synthState, s32 numSamplesToLoad);
Acmd* AudioSynth_LoadWaveSamples(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisState* synthState, s32 numSamplesToLoad);
Acmd* func_8000B480(Acmd* aList, NoteSynthesisState* synthState, s32 size, u16 pitch, u16 inpDmem, u32 resampleFlags);
Acmd* func_8000B51C(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisState* synthState, s32 aiBufLen, u16 dmemSrc,
s32 delaySide, s32 flags);
Acmd* func_8000B98C(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisState* synthState, s32 size, s32 flags,
s32 delaySide);
Acmd* AudioSynth_ApplyHaasEffect(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisState* synthState, s32 size, s32 flags,
s32 delaySide);
void func_800080C0(s32 sampleCount, s32 itemIndex, s32 reverbIndex) {
ReverbRingBufferItem* ringItem;
@ -631,7 +644,7 @@ void func_80009AAC(s32 updateIndex) {
}
}
Acmd* func_80009B64(Acmd* aList, s32* cmdCount, s16* aiBufStart, s32 aiBufLen) {
Acmd* AudioSynth_Update(Acmd* aList, s32* cmdCount, s16* aiBufStart, s32 aiBufLen) {
Acmd* aCmdPtr;
s32* aiBufPtr;
s32 chunkLen;
@ -640,7 +653,7 @@ Acmd* func_80009B64(Acmd* aList, s32* cmdCount, s16* aiBufStart, s32 aiBufLen) {
aCmdPtr = aList;
for (i = gAudioBufferParams.ticksPerUpdate; i > 0; i--) {
func_8001678C(i - 1);
AudioSeq_ProcessSequences(i - 1);
func_80009AAC(gAudioBufferParams.ticksPerUpdate - i);
}
@ -883,9 +896,10 @@ Acmd* func_8000A700(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisState* synth
currentBook = NULL;
note = &gNotes[noteIndex];
flags = 0;
if (noteSub->bitField0.needsInit == 1) {
flags = 1;
flags = A_CONTINUE;
if (noteSub->bitField0.needsInit == true) {
flags = A_INIT;
synthState->restart = 0;
synthState->samplePosInt = 0;
synthState->samplePosFrac = 0;
@ -894,13 +908,15 @@ Acmd* func_8000A700(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisState* synth
synthState->prevHaasEffectLeftDelaySize = 0;
synthState->prevHaasEffectRightDelaySize = 0;
synthState->numParts = 0;
note->noteSubEu.bitField0.finished = 0;
note->noteSubEu.bitField0.finished = false;
}
resampleRateFixedPoint = noteSub->resampleRate;
nParts = noteSub->bitField1.hasTwoParts + 1;
sampleslenFixedPoint = (resampleRateFixedPoint * aiBufLen * 2) + synthState->samplePosFrac;
nSamplesToLoad = (sampleslenFixedPoint) >> 0x10;
synthState->samplePosFrac = sampleslenFixedPoint & 0xFFFF;
if ((synthState->numParts == 1) && (nParts == 2)) {
nSamplesToLoad += 2;
sp56 = 2;
@ -910,9 +926,11 @@ Acmd* func_8000A700(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisState* synth
} else {
sp56 = 0;
}
synthState->numParts = nParts;
if (noteSub->bitField1.isSyntheticWave) {
aList = func_8000B3F0(aList, noteSub, synthState, nSamplesToLoad);
aList = AudioSynth_LoadWaveSamples(aList, noteSub, synthState, nSamplesToLoad);
noteSamplesDmemAddrBeforeResampling = (synthState->samplePosInt * 2) + 0x5F0;
synthState->samplePosInt += nSamplesToLoad;
} else {
@ -922,17 +940,25 @@ Acmd* func_8000A700(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisState* synth
sampleAddr = bookSample->sampleAddr;
resampledTempLen = 0;
// If the frequency requested is more than double that of the raw sample,
// then the sample processing is split into two parts.
for (curPart = 0; curPart < nParts; curPart++) {
nAdpcmSamplesProcessed = 0;
s5 = 0;
// Adjust the number of samples to load only if there are two parts and an odd number of samples
if (nParts == 1) {
samplesLenAdjusted = nSamplesToLoad;
} else if (nSamplesToLoad & 1) {
// round down for the first part
// round up for the second part
samplesLenAdjusted = (nSamplesToLoad & ~1) + (curPart * 2);
} else {
samplesLenAdjusted = nSamplesToLoad;
}
if ((bookSample->codec == 0) && (currentBook != bookSample->book->book)) {
// Load the ADPCM codeBook
if ((bookSample->codec == CODEC_ADPCM) && (currentBook != bookSample->book->book)) {
switch (noteSub->bitField1.bookOffset) {
case 1:
currentBook = &gD_800DD200[1];
@ -946,9 +972,11 @@ Acmd* func_8000A700(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisState* synth
break;
}
nEntries = 16 * bookSample->book->order * bookSample->book->numPredictors;
nEntries = SAMPLES_PER_FRAME * bookSample->book->order * bookSample->book->numPredictors;
aLoadADPCM(aList++, nEntries, OS_K0_TO_PHYSICAL(currentBook));
}
// Continue processing samples until the number of samples needed to load is reached
while (nAdpcmSamplesProcessed != samplesLenAdjusted) {
restart = 0;
noteFinished = 0;
@ -958,51 +986,64 @@ Acmd* func_8000A700(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisState* synth
nFirstFrameSamplesToIgnore = synthState->samplePosInt & 0xF;
if ((nFirstFrameSamplesToIgnore == 0) && !synthState->restart) {
nFirstFrameSamplesToIgnore = 0x10;
nFirstFrameSamplesToIgnore = SAMPLES_PER_FRAME;
}
nSamplesInFirstFrame = SAMPLES_PER_FRAME - nFirstFrameSamplesToIgnore;
nSamplesInFirstFrame = 0x10 - nFirstFrameSamplesToIgnore;
// Determine the number of samples to decode based on whether the end will be reached or not.
if (nSamplesToProcess < samplesRemaining) {
nFramesToDecode = (nSamplesToProcess - nSamplesInFirstFrame + 0xF) / 16;
nSamplesToDecode = nFramesToDecode * 0x10;
// The end will not be reached.
nFramesToDecode =
(s32) (nSamplesToProcess - nSamplesInFirstFrame + SAMPLES_PER_FRAME - 1) / SAMPLES_PER_FRAME;
nSamplesToDecode = nFramesToDecode * SAMPLES_PER_FRAME;
// if(1) {}
nTrailingSamplesToIgnore = (nSamplesInFirstFrame + nSamplesToDecode) - nSamplesToProcess;
} else {
// The end will be reached.
nSamplesToDecode = samplesRemaining - nSamplesInFirstFrame;
nTrailingSamplesToIgnore = 0;
if (nSamplesToDecode <= 0) {
nSamplesToDecode = 0;
nSamplesInFirstFrame = samplesRemaining;
}
nFramesToDecode = (nSamplesToDecode + 0xF) / 16;
nFramesToDecode = (nSamplesToDecode + SAMPLES_PER_FRAME - 1) / SAMPLES_PER_FRAME;
if (loopInfo->count != 0) {
restart = 1;
} else {
noteFinished = 1;
}
}
// Set parameters based on compression type
switch (bookSample->codec) {
case 0:
case CODEC_ADPCM:
// 16 2-byte samples (32 bytes) compressed into 4-bit samples (8 bytes) + 1 header byte
frameSize = 9;
skipInitialSamples = 0x10;
skipInitialSamples = SAMPLES_PER_FRAME;
sampleDmaStart = 0;
break;
case 1:
frameSize = 0x10;
skipInitialSamples = 0x10;
case CODEC_S8:
// 16 2-byte samples (32 bytes) compressed into 8-bit samples (16 bytes)
frameSize = 16;
skipInitialSamples = SAMPLES_PER_FRAME;
sampleDmaStart = 0;
break;
case 2:
case CODEC_S16_INMEMORY:
temp =
func_800097A8(bookSample, samplesLenAdjusted, flags, &synthState->synthesisBuffers->unk_40);
aLoadBuffer(aList++, OS_K0_TO_PHYSICAL(temp), 0x5F0, (samplesLenAdjusted + 0x10) * 2);
aLoadBuffer(aList++, OS_K0_TO_PHYSICAL(temp), DMEM_UNCOMPRESSED_NOTE,
(samplesLenAdjusted + 0x10) * 2);
s5 = samplesLenAdjusted;
nAdpcmSamplesProcessed = samplesLenAdjusted;
skipBytes = 0;
goto skip;
}
aligned = ALIGN16(nFramesToDecode * frameSize + 0x10);
addr = 0x990 - aligned;
if (nFramesToDecode != 0) {
frameIndex = (synthState->samplePosInt + skipInitialSamples - nFirstFrameSamplesToIgnore) / 16;
sampleDataOffset = frameIndex * frameSize;
@ -1019,20 +1060,21 @@ Acmd* func_8000A700(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisState* synth
nSamplesToDecode = 0;
sampleDataStartPad = 0;
}
if (synthState->restart) {
aSetLoop(aList++, OS_K0_TO_PHYSICAL(bookSample->loop->predictorState));
flags = 2;
synthState->restart = 0;
}
nSamplesInThisIteration = nSamplesToDecode + nSamplesInFirstFrame - nTrailingSamplesToIgnore;
nSamplesInThisIteration = nSamplesToDecode + nSamplesInFirstFrame - nTrailingSamplesToIgnore;
if (nAdpcmSamplesProcessed == 0) {
switch (bookSample->codec) {
case 0:
case CODEC_ADPCM:
aSetBuffer(aList++, 0, addr + sampleDataStartPad, 0x5F0, nSamplesToDecode * 2);
aADPCMdec(aList++, flags, OS_K0_TO_PHYSICAL(synthState->synthesisBuffers));
break;
case 1:
case CODEC_S8:
aSetBuffer(aList++, 0, addr + sampleDataStartPad, 0x5F0, nSamplesToDecode * 2);
aS8Dec(aList++, flags, OS_K0_TO_PHYSICAL(synthState->synthesisBuffers));
break;
@ -1055,9 +1097,11 @@ Acmd* func_8000A700(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisState* synth
aDMEMMove(aList++, (align2 + (nFirstFrameSamplesToIgnore * 2) + 0x5F0), s5 + 0x5F0,
nSamplesInThisIteration * 2);
}
nAdpcmSamplesProcessed += nSamplesInThisIteration;
switch (flags) {
case 1:
case A_INIT:
skipBytes = 0x20;
s5 = (nSamplesToDecode + 0x10) * 2;
break;
@ -1075,7 +1119,7 @@ Acmd* func_8000A700(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisState* synth
break;
}
skip:
flags = 0;
flags = A_CONTINUE;
// goto dummy_label_147574; dummy_label_147574: ;
if (noteFinished) {
aClearBuffer(aList++, s5 + 0x5F0, (samplesLenAdjusted - nAdpcmSamplesProcessed) * 2);
@ -1091,6 +1135,7 @@ Acmd* func_8000A700(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisState* synth
synthState->samplePosInt += nSamplesToProcess;
}
}
switch (nParts) {
case 1:
noteSamplesDmemAddrBeforeResampling = skipBytes + 0x5F0;
@ -1125,12 +1170,15 @@ Acmd* func_8000A700(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisState* synth
flags = 1;
noteSub->bitField0.needsInit = 0;
}
flags = sp56 | flags;
aList = func_8000B480(aList, synthState, aiBufLen * 2, resampleRateFixedPoint, noteSamplesDmemAddrBeforeResampling,
flags);
if (flags & 1) {
flags = 1;
}
if (noteSub->bitField1.bookOffset == 3) {
aUnkCmd19(aList++, 0, aiBufLen * 2, 0x450, 0x450);
}
@ -1142,12 +1190,13 @@ Acmd* func_8000A700(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisState* synth
}
aHiLoGain(aList++, temp2, (aiBufLen + 0x10) * 2, 0x450, 0);
}
if ((noteSub->leftDelaySize != 0) || (synthState->prevHaasEffectLeftDelaySize != 0)) {
delaySide = 1;
delaySide = HAAS_EFFECT_DELAY_LEFT;
} else if ((noteSub->rightDelaySize != 0) || (synthState->prevHaasEffectRightDelaySize != 0)) {
delaySide = 2;
delaySide = HAAS_EFFECT_DELAY_RIGHT;
} else {
delaySide = 0;
delaySide = HAAS_EFFECT_DELAY_NONE;
}
aList = func_8000B51C(aList, noteSub, synthState, aiBufLen, 0x450, delaySide, flags);
@ -1156,7 +1205,7 @@ Acmd* func_8000A700(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisState* synth
if (!(flags & 1)) {
flags = 0;
}
aList = func_8000B98C(aList, noteSub, synthState, aiBufLen * 2, flags, delaySide);
aList = AudioSynth_ApplyHaasEffect(aList, noteSub, synthState, aiBufLen * 2, flags, delaySide);
}
return aList;
@ -1165,15 +1214,27 @@ Acmd* func_8000A700(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisState* synth
#pragma GLOBAL_ASM("asm/us/rev1/nonmatchings/audio/audio_synthesis/func_8000A700.s")
#endif
Acmd* func_8000B3F0(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisState* synthState, s32 numSamplesToLoad) {
s32 temp_v1;
Acmd* AudioSynth_LoadWaveSamples(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisState* synthState,
s32 numSamplesToLoad) {
s32 numSamplesAvail;
s32 numDuplicates;
aLoadBuffer(aList++, OS_K0_TO_PHYSICAL(noteSub->waveSampleAddr), 0x5F0, 0x80);
synthState->samplePosInt &= 0x3F;
temp_v1 = 0x40 - synthState->samplePosInt;
if (temp_v1 < numSamplesToLoad) {
if ((((numSamplesToLoad - temp_v1) + 0x3F) / 64) != 0) {
aDuplicate(aList++, ((numSamplesToLoad - temp_v1) + 0x3F) / 64, 0x5F0, 0x670);
aLoadBuffer(aList++, OS_K0_TO_PHYSICAL(noteSub->waveSampleAddr), DMEM_UNCOMPRESSED_NOTE,
WAVE_SAMPLE_COUNT * SAMPLE_SIZE);
// Offset in the WAVE_SAMPLE_COUNT samples of gWaveSamples to start processing the wave for continuity
synthState->samplePosInt = (u32) synthState->samplePosInt % WAVE_SAMPLE_COUNT;
// Number of samples in the initial WAVE_SAMPLE_COUNT samples available to be used to process
numSamplesAvail = WAVE_SAMPLE_COUNT - synthState->samplePosInt;
if (numSamplesToLoad > numSamplesAvail) {
// Duplicate (copy) the WAVE_SAMPLE_COUNT samples as many times as needed to reach numSamplesToLoad.
// (numSamplesToLoad - numSamplesAvail) is the number of samples missing.
// Divide by WAVE_SAMPLE_COUNT, rounding up, to get the amount of duplicates
numDuplicates = ((numSamplesToLoad - numSamplesAvail + WAVE_SAMPLE_COUNT - 1) / WAVE_SAMPLE_COUNT);
if (numDuplicates != 0) {
aDuplicate(aList++, numDuplicates, DMEM_UNCOMPRESSED_NOTE,
DMEM_UNCOMPRESSED_NOTE + (WAVE_SAMPLE_COUNT * SAMPLE_SIZE));
}
}
return aList;
@ -1263,60 +1324,67 @@ Acmd* func_8000B51C(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisState* synthSt
return aList;
}
Acmd* func_8000B98C(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisState* synthState, s32 size, s32 flags,
s32 delaySide) {
u16 var_t0;
u8 var_a1;
u8 var_v1;
u16 temp;
/**
* The Haas Effect gives directionality to sound by applying 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* aList, NoteSubEu* noteSub, NoteSynthesisState* synthState, s32 size, s32 flags,
s32 delaySide) {
u16 dmemDest;
u8 haasEffectDelaySize;
u8 prevHaasEffectDelaySize;
u16 pitch;
switch (delaySide) {
case 1:
var_t0 = 0x990;
var_a1 = noteSub->leftDelaySize;
case HAAS_EFFECT_DELAY_LEFT:
dmemDest = DMEM_LEFT_CH;
haasEffectDelaySize = noteSub->leftDelaySize;
prevHaasEffectDelaySize = synthState->prevHaasEffectLeftDelaySize;
synthState->prevHaasEffectRightDelaySize = 0;
var_v1 = synthState->prevHaasEffectLeftDelaySize;
synthState->prevHaasEffectLeftDelaySize = var_a1;
synthState->prevHaasEffectLeftDelaySize = haasEffectDelaySize;
break;
case 2:
var_t0 = 0xB10;
var_a1 = noteSub->rightDelaySize;
case HAAS_EFFECT_DELAY_RIGHT:
dmemDest = DMEM_RIGHT_CH;
haasEffectDelaySize = noteSub->rightDelaySize;
prevHaasEffectDelaySize = synthState->prevHaasEffectRightDelaySize;
synthState->prevHaasEffectRightDelaySize = haasEffectDelaySize;
synthState->prevHaasEffectLeftDelaySize = 0;
var_v1 = synthState->prevHaasEffectRightDelaySize;
synthState->prevHaasEffectRightDelaySize = var_a1;
break;
default:
default: // HAAS_EFFECT_DELAY_NONE
return aList;
}
if (flags != 1) {
if (var_a1 != var_v1) {
temp = (((size << 0xF) / 2) - 1) / ((size + var_a1 - var_v1 - 2) / 2);
aSetBuffer(aList++, 0, 0x650, 0x450, size + var_a1 - var_v1);
aResampleZoh(aList++, temp, 0);
if (flags != A_INIT) {
if (haasEffectDelaySize != prevHaasEffectDelaySize) {
pitch = (((size << 0xF) / 2) - 1) / ((size + haasEffectDelaySize - prevHaasEffectDelaySize - 2) / 2);
aSetBuffer(aList++, 0, DMEM_HAAS_TEMP, DMEM_TEMP, size + haasEffectDelaySize - prevHaasEffectDelaySize);
aResampleZoh(aList++, pitch, 0);
} else {
aDMEMMove(aList++, 0x650, 0x450, size);
aDMEMMove(aList++, DMEM_HAAS_TEMP, DMEM_TEMP, size);
}
if (var_v1 != 0) {
if (prevHaasEffectDelaySize != 0) {
aLoadBuffer(aList++, OS_K0_TO_PHYSICAL(synthState->synthesisBuffers->panSamplesBuffer), 0x650,
ALIGN16(var_v1));
aDMEMMove(aList++, 0x450, var_v1 + 0x650, size + var_a1 - var_v1);
ALIGN16(prevHaasEffectDelaySize));
aDMEMMove(aList++, DMEM_TEMP, prevHaasEffectDelaySize + DMEM_HAAS_TEMP,
size + haasEffectDelaySize - prevHaasEffectDelaySize);
} else {
aDMEMMove(aList++, 0x450, 0x650, size + var_a1);
aDMEMMove(aList++, DMEM_TEMP, DMEM_HAAS_TEMP, size + haasEffectDelaySize);
}
} else {
aDMEMMove(aList++, 0x650, 0x450, size);
aClearBuffer(aList++, 0x650, var_a1);
aDMEMMove(aList++, 0x450, var_a1 + 0x650, size);
}
if (var_a1) {
aSaveBuffer(aList++, size + 0x650, OS_K0_TO_PHYSICAL(synthState->synthesisBuffers->panSamplesBuffer),
ALIGN16(var_a1));
aDMEMMove(aList++, DMEM_HAAS_TEMP, DMEM_TEMP, size);
aClearBuffer(aList++, DMEM_HAAS_TEMP, haasEffectDelaySize);
aDMEMMove(aList++, DMEM_TEMP, haasEffectDelaySize + DMEM_HAAS_TEMP, size);
}
aAddMixer(aList++, ALIGN64(size), 0x650, var_t0, 0x7FFF);
if (haasEffectDelaySize) {
aSaveBuffer(aList++, size + DMEM_HAAS_TEMP, OS_K0_TO_PHYSICAL(synthState->synthesisBuffers->panSamplesBuffer),
ALIGN16(haasEffectDelaySize));
}
aAddMixer(aList++, ALIGN64(size), DMEM_HAAS_TEMP, dmemDest, 0x7FFF);
return aList;
}

View File

@ -114,7 +114,7 @@ SPTask* AudioThread_CreateTask(void) {
while (MQ_GET_MESG(gThreadCmdProcQueue, &msg)) {
AudioThread_ProcessCmds(msg);
}
gCurAbiCmdBuffer = func_80009B64(gCurAbiCmdBuffer, &abiCmdCount, aiBuffer, gAiBuffLengths[aiBuffIndex]);
gCurAbiCmdBuffer = AudioSynth_Update(gCurAbiCmdBuffer, &abiCmdCount, aiBuffer, gAiBuffLengths[aiBuffIndex]);
gAudioRandom = osGetCount() * (gAudioRandom + gAudioTaskCountQ);
gAudioRandom = gAiBuffers[aiBuffIndex][gAudioTaskCountQ & 0xFF] + gAudioRandom;
@ -174,7 +174,7 @@ void AudioThread_ProcessGlobalCmd(AudioCmd* cmd) {
case AUDIOCMD_OP_GLOBAL_DISABLE_SEQPLAYER:
if (gSeqPlayers[cmd->arg0].enabled) {
if (cmd->asInt == 0) {
func_800144E4(&gSeqPlayers[cmd->arg0]);
AudioSeq_SequencePlayerDisable(&gSeqPlayers[cmd->arg0]);
} else {
AudioThread_SetFadeOutTimer(cmd->arg0, cmd->asInt);
}