Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
core.h File Reference

Go to the source code of this file.

Functions

void create_audio_system (void)
 
void nuAuMgr (void *arg)
 
s32 nuAuDmaCallBack (s32 addr, s32 len, void *state, u8 useDma)
 DMA callback for audio sample streaming; manages a DMA buffer cache.
 
void au_release_voice (u8 index)
 
void au_engine_init (s32 outputRate)
 
void au_update_clients_for_video_frame (void)
 this is called once per video frame update (50 or 60 times per second)
 
void au_update_clients_for_audio_frame (void)
 this is called per audio frame generated by alAudioFrame (every 184 audio samples) there will be multiuple of these per video frame
 
void au_syn_begin_audio_frame (AuGlobals *globals)
 
void au_reset_nonfree_voice (AuVoice *arg0, u8 arg1)
 
void au_reset_voice (AuVoice *voice, u8 voiceIdx)
 
f32 au_compute_pitch_ratio (s32 tuning)
 Converts a linear pitch value (in cents) into a frequency ratio suitable for adjusting playback speed.
 
void au_fade_init (Fade *fade, s32 time, s32 startValue, s32 endValue)
 
void au_fade_clear (Fade *fade)
 
void au_fade_update (Fade *fade)
 
void au_fade_set_volume (u8 arg0, u16 arg1, s32 arg2)
 
void au_fade_flush (Fade *fade)
 
void au_fade_set_envelope (Fade *fade, s16 value)
 
void au_fade_calc_envelope (Fade *fade, u32 arg1, s32 target)
 
void au_fade_update_envelope (Fade *fade)
 
Instrumentau_get_instrument (AuGlobals *globals, BankSetIndex bank, s32 patch, EnvelopeData *arg3)
 Note that bank is supplied as BankSetIndex and not BankSet, which means it will be used to perform a raw access into AuGlobals::bankSets.
 
void au_get_bgm_player_and_file (u32 playerIndex, BGMHeader **outCurrentTrackData, BGMPlayer **outPlayer)
 
void au_get_bgm_player (u32 playerIndex, BGMPlayer **outPlayer)
 
AuResult au_load_song_files (u32 arg0, BGMHeader *arg1, BGMPlayer *arg2)
 
AuResult au_reload_song_files (s32 songID, BGMHeader *arg1)
 
BGMPlayerau_get_snapshot_by_index (s32 index)
 
AuResult au_ambient_load (u32 arg0)
 
BGMPlayerau_get_client_by_priority (u8 arg0)
 
void au_load_INIT (AuGlobals *arg0, s32 romAddr, ALHeap *heap)
 
AuResult au_fetch_SBN_file (u32 fileIdx, AuFileFormat format, SBNFileEntry *arg2)
 
void au_load_PER (AuGlobals *globals, s32 romAddr)
 
void au_load_PRG (AuGlobals *arg0, s32 romAddr)
 
InstrumentBankau_get_BK_instruments (BankSet bankSet, u32 bankIndex)
 
BKFileBufferau_load_BK_to_bank (s32 bkFileOffset, BKFileBuffer *bkFile, s32 bankIndex, BankSet bankSet)
 Loads an instrument bank file from ROM, allocates memory if needed, and sets up instrument pointers.
 
void au_swizzle_BK_instruments (s32 bkFileOffset, BKFileBuffer *bkFile, InstrumentBank instruments, u32 instrumentCount, u8 arg4)
 Fixes up (swizzles) instrument pointers in a loaded bank, converting file-relative offsets to valid RAM pointers.
 
BKFileBufferau_load_static_BK_to_bank (s32 *bkFileOffset, void *vaddr, s32 bankIndex, BankSet bankSet)
 UNUSED Loads an instrument bank file from ROM to a given buffer (allocates if needed), and sets up instrument pointers.
 
s32 au_load_aux_bank (s32 bkFileOffset, s32 bankIndex)
 
void au_clear_instrument_group (s32 bankIndex, BankSet bankSet)
 unused. resets all instruments in (bankIndex, bankSet) to default
 
void au_set_bus_volume_level (s32 arg0, u32 idx)
 
s32 au_set_reverb_type (s32 arg0, s32 arg1)
 
void au_sync_channel_delay_enabled (u32 arg0)
 
void au_read_rom (s32 romAddr, void *buffer, u32 size)
 
void au_memset (void *dst, s32 size, u8 value)
 
void au_copy_bytes (s8 *src, s8 *dest, s32 size)
 
void au_copy_words (void *src, void *dst, s32 size)
 
void au_driver_init (AuSynDriver *driver, ALConfig *config)
 
void au_driver_release (void)
 
void au_use_global_volume (void)
 
void au_set_global_volume (s16 arg0)
 
s16 au_get_global_volume (void)
 
void au_set_stereo_enabled (b8 enabled)
 
void au_bus_set_volume (u8 busID, u16 value)
 
u16 au_bus_get_volume (u8 busID)
 
void au_bus_set_effect (u8 busID, u8 effectID)
 
void au_bus_set_fx_params (u8 busID, s16 arg1, s16 arg2, s32 arg3)
 
void au_pvoice_set_bus (u8 voiceIdx, s8 busID)
 
void au_syn_stop_voice (u8 voiceIdx)
 
void au_syn_start_voice (u8 index)
 
void au_syn_start_voice_params (u8 index, u8 reverbType, Instrument *table, f32 pitch, s16 vol, u8 pan, u8 fxMix, s32 delta)
 
void au_syn_set_wavetable (u8 voiceIdx, Instrument *table)
 
void au_syn_set_pitch (u8 voiceIdx, f32 pitchRatio)
 
void au_syn_set_mixer_params (u8 voiceIdx, s16 volume, s32 arg2, u8 arg3, u8 arg4)
 
void au_syn_set_pan_fxmix (u8 voiceIdx, u8 arg1, u8 arg2)
 
void au_syn_set_volume_delta (u8 voiceIdx, s16 arg1, s32 arg2)
 
void au_syn_set_pan (u8 voiceIdx, u8 pan)
 
void au_syn_set_fxmix (u8 voiceIdx, u8 dryAmt)
 
s32 au_syn_get_playing (u8 voiceIdx)
 
s32 au_syn_get_bus (u8 voiceIdx)
 
f32 au_syn_get_pitch (u8 voiceIdx)
 
u8 au_syn_get_pan (u8 voiceIdx)
 
s16 au_syn_get_dryamt (u8 voiceIdx)
 
s16 au_syn_get_wetamt (u8 voiceIdx)
 
s32 au_syn_get_volume_left (u8 voiceIdx)
 
s32 au_syn_get_volume_right (u8 voiceIdx)
 
void au_set_delay_time (s32 arg0)
 
void au_delay_left_channel (u8 arg0)
 
void au_delay_right_channel (u8 arg0)
 
void au_disable_channel_delay (void)
 
void au_init_delay_channel (s16 arg0)
 
voidalHeapAlloc (ALHeap *heap, s32 count, s32 size)
 
void au_flush_finished_voices (AuGlobals *globals)
 (UNUSED) Immediately flush all voices which have finished playing.
 
void au_init_voices (AuGlobals *globals)
 Initializes all voices in the audio system.
 
void au_update_voices (AuGlobals *globals)
 Main envelope system update, called once per frame.
 
void au_voice_after_volume_change (AuVoice *voice)
 Applies volume update after a client-side volume change.
 
s32 au_voice_get_delta (s32 usecs)
 Converts envelope step duration from microseconds to num samples delta.
 
void au_voice_start (AuVoice *voice, EnvelopeData *envData)
 Starts a new voice with the given envelope data.
 
u8 au_voice_step (AuVoice *voice)
 Parses and executes envelope commands until a time interval is found.
 
void au_voice_set_vol_changed (AuVoice *voice)
 (UNUSED) Force recalculation of voice envelope volume during next update.
 
Acmdau_pull_voice (AuPVoice *pvoice, Acmd *cmdBufPos)
 
void au_fx_create (AuFX *fx, u8 mode, ALHeap *heap)
 
void au_filter_create (AuFilter *filter, ALHeap *heap)
 
void au_filter_init (AuFilter *filter, s16 arg1, s16 arg2, s16 fc)
 
void au_fx_load_preset (AuFX *fx, u8 effectType)
 
Acmdau_pull_fx (AuFX *fx, Acmd *cmdBusPos, s16, s16)
 Applies a chain of delay-line based effects to audio and mixes into output.
 
s32 au_fx_param_hdl (AuFX *fx, s16 index, s16 paramID, s32 value)
 

Function Documentation

◆ create_audio_system()

void create_audio_system ( void )

Definition at line 37 of file system.c.

37 {
38 u32 i;
39 u32 outputRate, frameSize;
41
43 nuAuPreNMI = 0;
45 config.num_pvoice = 24;
46 config.num_bus = 4;
48 frameSize = (nusched.retraceCount * outputRate + (VIDEO_FRAMES_PER_SECOND - 1)) / VIDEO_FRAMES_PER_SECOND;
49 config.outputRate = outputRate;
50 config.unused_0C = 0;
51 config.heap = &nuAuHeap;
52 config.dmaNew = nuAuDmaNew;
55
56 for (i = 0; i < ARRAY_COUNT(AlCmdListBuffers); i++) {
58 }
59
60 for (i = 0; i < ARRAY_COUNT(nuAuTasks); i++) {
61 nuAuTasks[i].next = NULL;
62 nuAuTasks[i].msg = 0;
63 nuAuTasks[i].list.t.type = M_AUDTASK;
64#if VERSION_IQUE
65 nuAuTasks[i].list.t.ucode_boot = (u64*) rspbootTextStart;
66 nuAuTasks[i].list.t.ucode_boot_size = (u32) rspbootTextEnd - (u32) rspbootTextStart;
67#else
68 nuAuTasks[i].list.t.ucode_boot = (u64*) rspbootUcodeBuffer;
69 nuAuTasks[i].list.t.ucode_boot_size = 0x100;
70#endif
71 nuAuTasks[i].list.t.ucode = n_aspMain_text_bin;
72 nuAuTasks[i].list.t.ucode_data = n_aspMain_data_bin;
73 nuAuTasks[i].list.t.ucode_data_size = SP_UCODE_DATA_SIZE;
74 nuAuTasks[i].list.t.dram_stack = NULL;
75 nuAuTasks[i].list.t.dram_stack_size = 0;
76 nuAuTasks[i].list.t.output_buff = NULL;
77 nuAuTasks[i].list.t.output_buff_size = 0;
78 nuAuTasks[i].list.t.yield_data_ptr = NULL;
79 nuAuTasks[i].list.t.yield_data_size = 0;
80 }
81
82 for (i = 0; i < ARRAY_COUNT(D_800A3628); i++) {
83 D_800A3628[i] = alHeapAlloc(config.heap, 1, AlFrameSize * 4);
84 }
85
86 nuAuDmaBufList[0].node.next = nuAuDmaBufList[0].node.prev = NULL;
87 for (i = 0; i < ARRAY_COUNT(nuAuDmaBufList) - 1; i++) {
89 nuAuDmaBufList[i].ptr = alHeapAlloc(config.heap, 1, 0x500);
90 }
91 nuAuDmaBufList[i].ptr = alHeapAlloc(config.heap, 1, 0x500);
92
96 au_engine_init(config.outputRate);
99}
BSS s32 PopupMenu_SelectedIndex
#define AUDIO_HEAP_SIZE
Definition audio.h:52
#define AUDIO_SAMPLES
Definition audio.h:16
#define VIDEO_FRAMES_PER_SECOND
Definition audio.h:51
#define HARDWARE_OUTPUT_RATE
Definition audio.h:23
#define AUDIO_MAX_SAMPLES
Definition audio.h:53
#define AUDIO_COMMAND_LIST_BUFFER_SIZE
Definition audio.h:54
void au_driver_init(AuSynDriver *driver, ALConfig *config)
Definition syn_driver.c:25
void au_engine_init(s32 outputRate)
Definition engine.c:36
void * alHeapAlloc(ALHeap *heap, s32 count, s32 size)
Definition syn_driver.c:765
@ THREAD_ID_AUDIO
Definition enums.h:5984
#define ARRAY_COUNT(arr)
Definition macros.h:40
void alHeapInit(ALHeap *hp, u8 *base, s32 len)
Definition syn_driver.c:747
BSS OSThread nuAuMgrThread
Definition system.c:13
u8 AuHeapBase[AUDIO_HEAP_SIZE]
u8 nuAuPreNMI
Definition system.c:5
u64 n_aspMain_data_bin[]
AuSynDriver auSynDriver
Definition system.c:27
BSS NUDMABuffer nuAuDmaBufList[50]
Definition system.c:24
ALHeap nuAuHeap
Definition system.c:26
void alLink(ALLink *element, ALLink *after)
Links a new element into a doubly-linked list.
Definition system.c:345
BSS NUScTask nuAuTasks[3]
Definition system.c:16
BSS s32 AlFrameSize
Definition system.c:18
void nuAuPreNMIProc(NUScMsg mesg_type, u32 frameCounter)
Handles global audio fade-out during system resets (NMI).
Definition system.c:317
BSS OSMesg nuAuDmaMesgBuf[50]
Definition system.c:21
BSS u8 * D_800A3628[3]
Definition system.c:17
void nuAuMgr(void *arg)
Definition system.c:108
BSS u64 AuStack[NU_AU_STACK_SIZE/sizeof(u64)]
Definition system.c:14
u64 n_aspMain_text_bin[]
BSS s32 AlMinFrameSize
Definition system.c:19
u8 nuAuTaskStop
Definition system.c:9
ALDMAproc nuAuDmaNew(NUDMAState **state)
Initializes the audio DMA state and returns the DMA callback.
Definition system.c:265
NUAuPreNMIFunc nuAuPreNMIFunc
Definition system.c:6
BSS Acmd * AlCmdListBuffers[3]
Definition system.c:15
BSS OSMesgQueue nuAuDmaMesgQ
Definition system.c:20

Referenced by create_audio_system_obfuscated().

◆ nuAuMgr()

void nuAuMgr ( void * arg)

Definition at line 108 of file system.c.

108 {
121 u8* bufferPtr;
122 s32 samples;
123 s32 cond;
124
128
129 cmdList_len = 0;
130 cmdListIndex = 0;
131 bufferIndex = 0;
132 samples = 0;
135 while (TRUE) {
137 switch (*mesg_type) {
139 if (cmdList_len != 0 && nuAuTaskStop == NU_AU_TASK_RUN) {
141 nuAuTasks[cmdListIndex].list.t.data_ptr = (u64*)cmdListBuf;
142 nuAuTasks[cmdListIndex].list.t.data_size = (cmdListAfter_ptr - cmdListBuf) * sizeof(Acmd);
148 if (++bufferIndex == 3) {
149 bufferIndex = 0;
150 }
151 if (++cmdListIndex == 3) {
152 cmdListIndex = 0;
153 }
154 }
155 profiler_audio_started(); // XXX: is this the right place?
157 cond = FALSE;
159 continue;
160 }
161 sampleSize = osAiGetLength() >> 2;
162 if (cmdList_len != 0 && nuAuTaskStop == NU_AU_TASK_RUN) {
166 }
169 cond = FALSE;
170 } else {
172 cond = TRUE;
173 }
175 if (nuAuPreNMIFunc != 0 && nuAuPreNMI != 0) {
177 nuAuPreNMI++;
178 }
179
180 break;
181 case NU_SC_PRENMI_MSG:
182 if (nuAuPreNMIFunc) {
184 }
185 nuAuPreNMI++;
186 break;
187 }
188 }
189
191}
@ PROFILER_RSP_AUDIO
Definition profiling.h:99
#define profiler_rsp_started(which)
Definition profiling.h:160
#define profiler_rsp_completed(which)
Definition profiling.h:161
#define profiler_audio_completed()
Definition profiling.h:164
#define profiler_audio_started()
Definition profiling.h:163
Acmd * alAudioFrame(Acmd *cmdList, s32 *cmdLen, s16 *outBuf, s32 outLen)
Definition syn_driver.c:119
void nuAuCleanDMABuffers(void)
Recycles DMA buffers which are no longer in use (based on frame count).
Definition system.c:278

Referenced by create_audio_system().

◆ nuAuDmaCallBack()

s32 nuAuDmaCallBack ( s32 addr,
s32 len,
void * state,
u8 useDma )

DMA callback for audio sample streaming; manages a DMA buffer cache.

Definition at line 194 of file system.c.

194 {
197 OSIoMesg* mesg;
198 s32 delta;
202
203 if (!useDma) {
204 return osVirtualToPhysical((void*)addr);
205 }
206
208 dmaPtr = nuAuDmaState.firstUsed;
209 addrEnd = addr + len;
210
211 while (dmaPtr != NULL) {
212 startAddr = dmaPtr->startAddr;
213 buffEnd = dmaPtr->startAddr + 0x500;
214 if (addr >= startAddr && buffEnd >= addrEnd) {
215 dmaPtr->frameCnt = nuAuFrameCounter;
216 freeBuffer = (NUDMABuffer*)(dmaPtr->ptr + addr - dmaPtr->startAddr);
218 } else if (addr < startAddr) {
219 break;
220 }
222 dmaPtr = (NUDMABuffer*)dmaPtr->node.next;
223 }
224
225 dmaPtr = nuAuDmaState.firstFree;
226 if (dmaPtr == NULL) {
227 return osVirtualToPhysical(nuAuDmaState.firstUsed);
228 }
229
230 nuAuDmaState.firstFree = (NUDMABuffer*)dmaPtr->node.next;
231 alUnlink(&dmaPtr->node);
232
233 if (lastDmaPtr != NULL) {
234 alLink(&dmaPtr->node, &lastDmaPtr->node);
235 } else if (nuAuDmaState.firstUsed != NULL){
236 lastDmaPtr = nuAuDmaState.firstUsed;
237 nuAuDmaState.firstUsed = dmaPtr;
238 dmaPtr->node.next = &lastDmaPtr->node;
239 dmaPtr->node.prev = NULL;
240 lastDmaPtr->node.prev = &dmaPtr->node;
241 } else {
242 nuAuDmaState.firstUsed = dmaPtr;
243 dmaPtr->node.next = NULL;
244 dmaPtr->node.prev = NULL;
245 }
246
248 delta = addr & 1;
249 addr -= delta;
250 dmaPtr->startAddr = addr;
251 dmaPtr->frameCnt = nuAuFrameCounter;
252
253 mesg = &nuAuDmaIOMesgBuf[nuAuDmaNext++];
254 mesg->hdr.pri = OS_MESG_PRI_NORMAL;
255 mesg->hdr.retQueue = &nuAuDmaMesgQ;
256 mesg->dramAddr = freeBuffer;
257 mesg->devAddr = addr;
258 mesg->size = 0x500;
260 return osVirtualToPhysical(freeBuffer) + delta;
261}
u32 nuAuFrameCounter
Definition system.c:8
BSS NUDMAState nuAuDmaState
Definition system.c:23
void alUnlink(ALLink *element)
Unlinks a list element from a doubly-linked list.
Definition system.c:356
s32 nuAuDmaNext
Definition system.c:7
BSS OSIoMesg nuAuDmaIOMesgBuf[50]
Definition system.c:22

Referenced by nuAuDmaNew().

◆ au_release_voice()

void au_release_voice ( u8 index)

Definition at line 29 of file engine.c.

29 {
31
32 voice->cmdPtr = NULL;
33 voice->priority = AU_PRIORITY_FREE;
34}
AuVoice voices[24]
Definition audio.h:1075
@ AU_PRIORITY_FREE
Definition audio.h:133
u8 * cmdPtr
Definition audio.h:846
AuGlobals * gSoundGlobals
Definition engine.c:10

Referenced by au_pull_voice().

◆ au_engine_init()

void au_engine_init ( s32 outputRate)

Definition at line 36 of file engine.c.

36 {
37 AuGlobals* globals;
41 u8 effects[4];
42 u32 i;
43
46
54
55 globals = gSoundGlobals;
56 dummyTrackData = alHeapAlloc(alHeap, 1, 0x8000);
57 globals->dataBGM[0] = (BGMHeader*) &dummyTrackData[0];
58 globals->dataBGM[1] = (BGMHeader*) &dummyTrackData[0x1400];
59 globals->dataMSEQ[0] = (MSEQHeader*) &dummyTrackData[0x1C00];
60 globals->dataMSEQ[1] = (MSEQHeader*) &dummyTrackData[0x1400];
61
62 for (i = 0; i < ARRAY_COUNT(globals->snapshots); i++) {
63 globals->snapshots[i].bgmPlayer = alHeapAlloc(alHeap, 1, sizeof(BGMPlayer));
64 }
65
66 globals->dataSEF = alHeapAlloc(alHeap, 1, 0x5200);
67 globals->defaultInstrument = alHeapAlloc(alHeap, 1, sizeof(Instrument));
68 globals->dataPER = alHeapAlloc(alHeap, 1, 6 * sizeof(PEREntry));
71 globals->outputRate = outputRate;
72 au_reset_instrument(globals->defaultInstrument);
73 au_reset_drum_entry(&globals->defaultDrumEntry);
74 au_reset_instrument_entry(&globals->defaultPRGEntry);
76
77 globals->audioThreadCallbacks[0] = NULL;
78 globals->audioThreadCallbacks[1] = NULL;
79
80 for (i = 0; i < ARRAY_COUNT(globals->snapshots); i++) {
81 globals->snapshots[i].assigned = 0;
82 globals->snapshots[i].priority = 0;
83 }
84
85 for (i = 0; i < ARRAY_COUNT(globals->effectChanges); i++) {
86 globals->effectChanges[i].type = AU_FX_NONE;
87 globals->effectChanges[i].changed = FALSE;
88 }
89
90 for (i = 0; i < ARRAY_COUNT(globals->voices); i++) {
94 voice = &globals->voices[i];
96 voice->pitchRatio = 0;
97 voice->volume = -1;
98 voice->pan = 0xFF;
99 voice->reverb = 0xFF;
100 voice->busID = 0;
101 voice->donePending = FALSE;
102 voice->syncFlags = 0;
103 voice->clientPriority = AU_PRIORITY_FREE;
104 voice->priority = AU_PRIORITY_FREE;
105 }
106
108
109 for (i = 0; i < ARRAY_COUNT(globals->auxBanks); i++) {
110 globals->auxBanks[i] = alHeapAlloc(alHeap, 1, sizeof(BKFileBuffer));
111 }
112
116 effects[2] = -1;
117 effects[3] = -1;
119
121 effects[0] = FX_BUS_BGMB;
122 effects[1] = -1;
123 effects[2] = -1;
124 effects[3] = -1;
126
129 au_init_voices(globals);
130 au_load_BK_headers(globals, alHeap);
132 au_read_rom(fileEntry.offset, globals->dataSEF, fileEntry.data & 0xFFFFFF);
133 }
136 au_load_PER(globals, fileEntry.offset);
137 }
139 au_load_PRG(globals, fileEntry.offset);
140 }
141
142 globals->bankSets[BANK_SET_IDX_0] = globals->auxBankSet;
143 globals->bankSets[BANK_SET_IDX_1] = globals->bankSet2;
144 globals->bankSets[BANK_SET_IDX_2] = globals->defaultBankSet;
145 globals->bankSets[BANK_SET_IDX_3] = globals->musicBankSet;
146 globals->bankSets[BANK_SET_IDX_4] = globals->bankSet4;
147 globals->bankSets[BANK_SET_IDX_5] = globals->bankSet5;
148 globals->bankSets[BANK_SET_IDX_6] = globals->bankSet6;
149 globals->bankSets[BANK_SET_IDX_7] = globals->auxBankSet;
150
152 globals->channelDelayTime = 0;
153 globals->channelDelayBusID = 0;
154 globals->channelDelayPending = FALSE;
155
158}
f32 outputRate
Definition audio.h:1027
u8 channelDelayPending
Definition audio.h:1041
InstrumentBank defaultBankSet[1]
Definition audio.h:1063
InstrumentBank bankSet5[16]
Definition audio.h:1068
SoundManager * soundManager
Definition audio.h:1140
@ AU_FX_NONE
Definition audio.h:155
InstrumentBank bankSet2[16]
Definition audio.h:1066
#define MUS_QUEUE_SIZE
Definition audio.h:107
Instrument * defaultInstrument
Definition audio.h:1028
BKFileBuffer * auxBanks[3]
Definition audio.h:1073
MusicEventTrigger * musicEventQueue
Definition audio.h:1058
struct MSEQHeader * dataMSEQ[2]
Definition audio.h:1048
@ AU_DELAY_CHANNEL_NONE
Definition audio.h:241
AuCallback audioThreadCallbacks[2]
Definition audio.h:1062
InstrumentBank auxBankSet[4]
Definition audio.h:1065
u8 channelDelayBusID
Definition audio.h:1042
@ BANK_SET_IDX_5
Definition audio.h:391
@ BANK_SET_IDX_6
Definition audio.h:392
@ BANK_SET_IDX_7
Definition audio.h:393
@ BANK_SET_IDX_0
Definition audio.h:386
@ BANK_SET_IDX_3
Definition audio.h:389
@ BANK_SET_IDX_1
Definition audio.h:387
@ BANK_SET_IDX_2
Definition audio.h:388
@ BANK_SET_IDX_4
Definition audio.h:390
BGMInstrumentInfo * dataPRG
Definition audio.h:1046
InstrumentBank bankSet6[4]
Definition audio.h:1069
InstrumentBank bankSet4[16]
Definition audio.h:1067
BGMPlayerSnapshot snapshots[1]
Definition audio.h:1049
ALHeap * heap
Definition audio.h:641
@ FX_BUS_BGMA_MAIN
Definition audio.h:234
@ FX_BUS_BGMA_AUX
Definition audio.h:237
@ FX_BUS_SOUND
Definition audio.h:235
@ FX_BUS_BGMB
Definition audio.h:236
AuSynDriver * gSynDriverPtr
Definition syn_driver.c:15
#define PRG_MAX_COUNT
Definition audio.h:119
u8 channelDelaySide
Definition audio.h:1044
Instrument * instrument
Definition audio.h:837
struct BGMHeader * dataBGM[2]
Definition audio.h:1047
PEREntry * dataPER
Definition audio.h:1045
BGMInstrumentInfo defaultPRGEntry
Definition audio.h:1030
struct BGMPlayer * bgmPlayer
Definition audio.h:1020
InstrumentBank * bankSets[8]
Definition audio.h:1070
@ AU_PRIORITY_BGM_PLAYER_MAIN
Definition audio.h:134
@ AU_PRIORITY_MSEQ_MANAGER
Definition audio.h:137
@ AU_PRIORITY_SFX_MANAGER
Definition audio.h:136
@ AU_PRIORITY_BGM_PLAYER_AUX
Definition audio.h:135
AuEffectChange effectChanges[4]
copied from INIT to the audio heap, seems to exist only to find SEF, PER, and PRG
Definition audio.h:1040
AuGlobals * globals
Definition audio.h:1367
SEFHeader * dataSEF
Definition audio.h:1061
u16 * extraFileList
Definition audio.h:1039
InstrumentBank musicBankSet[16]
Definition audio.h:1064
u8 channelDelayTime
Definition audio.h:1043
BGMDrumInfo defaultDrumEntry
Definition audio.h:1029
Represents a dummy BK file large enough to hold everything except the wave data.
Definition audio.h:1008
void au_bgm_player_init(BGMPlayer *player, s32 priority, s32 busID, AuGlobals *globals)
Definition bgm_player.c:523
void au_bgm_set_effect_indices(BGMPlayer *player, u8 *list)
Definition bgm_player.c:601
u32 MusicEventTrigger
void au_pvoice_set_bus(u8 voiceIdx, s8 busID)
Definition syn_driver.c:316
void au_init_voices(AuGlobals *globals)
Initializes all voices in the audio system.
Definition voice.c:19
void au_syn_set_wavetable(u8 voiceIdx, Instrument *table)
Definition syn_driver.c:420
void au_init_delay_channel(s16 arg0)
Definition syn_driver.c:732
BGMPlayer * gBGMPlayerB
Definition engine.c:7
void au_load_PRG(AuGlobals *globals, s32 romAddr)
Definition engine.c:837
SoundManager * gSoundManager
Definition engine.c:9
void au_load_INIT(AuGlobals *globals, s32 romAddr, ALHeap *heap)
Definition engine.c:745
#define SBN_ROM_OFFSET
Definition engine.c:26
void au_read_rom(s32 romAddr, void *buffer, u32 size)
Definition engine.c:1209
AuResult au_fetch_SBN_file(u32 fileIdx, AuFileFormat format, SBNFileEntry *outEntry)
Definition engine.c:796
BGMPlayer * gBGMPlayerA
Definition engine.c:6
BGMPlayer * gBGMPlayerC
Definition engine.c:8
void au_load_PER(AuGlobals *globals, s32 romAddr)
Definition engine.c:818
AmbienceManager * gAuAmbienceManager
Definition engine.c:11
@ AU_FMT_PRG
Definition enums.h:1783
@ AU_FMT_PER
Definition enums.h:1782
@ AU_FMT_SEF
Definition enums.h:1780
@ AU_RESULT_OK
Definition enums.h:1759
void au_load_BK_headers(AuGlobals *globals, ALHeap *heap)
Definition load_banks.c:4
void au_mseq_manager_init(AmbienceManager *manager, s8 priority, s8 busID, AuGlobals *globals)
Definition mseq_player.c:44
void au_sfx_load_groups_from_SEF(SoundManager *sndMgr)
Definition sfx_player.c:551
void au_sfx_init(SoundManager *manager, u8 arg1, u8 arg2, AuGlobals *arg3, u8 arg4)
Definition sfx_player.c:466
void snd_notify_engine_ready(ALHeap *heap)
void snd_song_clear_music_events(void)

Referenced by create_audio_system().

◆ au_update_clients_for_video_frame()

void au_update_clients_for_video_frame ( void )

this is called once per video frame update (50 or 60 times per second)

Definition at line 286 of file engine.c.

286 {
287 AuGlobals* globals = gSoundGlobals;
288 BGMPlayer* player = gBGMPlayerA;
290
291 if (globals->flushMusicEventQueue) {
293 }
294
298 }
299
301
302 player = gBGMPlayerB;
304
306}
s32 flushMusicEventQueue
Definition audio.h:1060
void au_bgm_begin_video_frame(BGMPlayer *player)
Definition bgm_player.c:23
AuCallback BeginSoundUpdateCallback
Definition engine.c:5
void au_sfx_begin_video_frame(SoundManager *manager)
Definition sfx_player.c:618

Referenced by alAudioFrame().

◆ au_update_clients_for_audio_frame()

void au_update_clients_for_audio_frame ( void )

this is called per audio frame generated by alAudioFrame (every 184 audio samples) there will be multiuple of these per video frame

this is called per audio frame generated by alAudioFrame (every 184 audio samples) there will be multiuple of these per video frame

Updates MSEQ, SFX, and BGM players for the current audio frame.

Definition at line 210 of file engine.c.

210 {
211 AuGlobals* globals = gSoundGlobals;
214 BGMPlayer* bgmPlayer;
215
217
218 // Update ambience manager every other frame
219 ambManager->nextUpdateCounter -= ambManager->nextUpdateStep;
220 if (ambManager->nextUpdateCounter <= 0) {
221 ambManager->nextUpdateCounter += ambManager->nextUpdateInterval;
223 }
224
225 // Update volume fade for SFX bus
226 if (sfxManager->fadeInfo.baseTicks != 0) {
227 au_fade_update(&sfxManager->fadeInfo);
228 au_fade_set_volume(sfxManager->busID, sfxManager->fadeInfo.baseVolume >> 16, sfxManager->busVolume);
229 }
230
231 // Periodic SFX manager update
232 sfxManager->nextUpdateCounter -= sfxManager->nextUpdateStep;
233 if (sfxManager->nextUpdateCounter <= 0) {
234 sfxManager->nextUpdateCounter += sfxManager->nextUpdateInterval;
236 }
237
238 // Update gBGMPlayerB
240 bgmPlayer = gBGMPlayerB;
241 if (bgmPlayer->fadeInfo.baseTicks != 0) {
242 au_bgm_update_fade(bgmPlayer);
243 }
244 if (bgmPlayer->songName != 0) {
245 bgmPlayer->songPlayingCounter++;
246 }
247
248 bgmPlayer->nextUpdateCounter -= bgmPlayer->nextUpdateStep;
249 if (bgmPlayer->nextUpdateCounter <= 0) {
250 bgmPlayer->nextUpdateCounter += bgmPlayer->tickUpdateInterval;
252 }
253 }
254
255 // Update gBGMPlayerA
257 if (globals->resumeRequested) {
259 }
260 bgmPlayer = gBGMPlayerA;
261 if (bgmPlayer->fadeInfo.envelopeTicks != 0) {
263 if (bgmPlayer->fadeInfo.baseTicks == 0) {
264 au_bgm_update_bus_volumes(bgmPlayer);
265 } else {
266 au_bgm_update_fade(bgmPlayer);
267 }
268 } else if (bgmPlayer->fadeInfo.baseTicks != 0) {
269 au_bgm_update_fade(bgmPlayer);
270 }
271 if (bgmPlayer->songName != 0) {
272 bgmPlayer->songPlayingCounter++;
273 }
274
275 bgmPlayer->nextUpdateCounter -= bgmPlayer->nextUpdateStep;
276 if (bgmPlayer->nextUpdateCounter <= 0) {
277 bgmPlayer->nextUpdateCounter += bgmPlayer->tickUpdateInterval;
279 }
280 }
281
282 // With all clients updated, now update all voices
283 au_update_voices(globals);
284}
s32 songPlayingCounter
video frames (60 fps)
Definition audio.h:1145
s16 baseTicks
Definition audio.h:508
s32 songName
Definition audio.h:1146
s32 nextUpdateCounter
update counter threshold for a single tick
Definition audio.h:1143
s32 nextUpdateStep
Definition audio.h:1141
s32 PreventBGMPlayerUpdate
While TRUE, the audio thread skips BGM player updates.
s16 envelopeTicks
Definition audio.h:513
s32 tickUpdateInterval
update counter amount to add per audio frame
Definition audio.h:1142
Fade fadeInfo
Definition audio.h:1150
b32 resumeRequested
Definition audio.h:1053
s16 prevUpdateResult
Definition audio.h:1157
s32 au_bgm_player_audio_frame_update(BGMPlayer *player)
Definition bgm_player.c:661
void au_bgm_update_bus_volumes(BGMPlayer *player)
Definition bgm_player.c:644
void au_bgm_restore_copied_player(AuGlobals *globals)
Definition bgm_player.c:473
void au_bgm_update_fade(BGMPlayer *player)
Definition bgm_player.c:622
void au_update_voices(AuGlobals *globals)
Main envelope system update, called once per frame.
Definition voice.c:37
void au_fade_update(Fade *fade)
Definition engine.c:438
void au_fade_set_volume(u8 busID, u16 volume, s32 busVolume)
Definition engine.c:453
void au_syn_begin_audio_frame(AuGlobals *globals)
Definition engine.c:308
void au_fade_update_envelope(Fade *fade)
Definition engine.c:489
void au_mseq_manager_audio_frame_update(AmbienceManager *manager)
s16 au_sfx_manager_audio_frame_update(SoundManager *manager)

Referenced by alAudioFrame().

◆ au_syn_begin_audio_frame()

void au_syn_begin_audio_frame ( AuGlobals * globals)

Definition at line 308 of file engine.c.

308 {
309 u32 i;
310
314 }
315
316 if (globals->channelDelayPending && (globals->channelDelayState == AU_DELAY_STATE_ON)) {
317 switch (globals->channelDelaySide) {
321 globals->channelDelayPending = FALSE;
322 break;
326 globals->channelDelayPending = FALSE;
327 break;
328 default:
330 globals->channelDelayPending = FALSE;
331 break;
332 }
333 }
334
335 // handle effect bus changes
336 if (globals->effectChanges[FX_BUS_BGMA_MAIN].changed) {
339 }
340 if (globals->effectChanges[FX_BUS_SOUND].changed) {
343
344 } if (globals->effectChanges[FX_BUS_BGMB].changed) {
347 }
348 if (globals->effectChanges[FX_BUS_BGMA_AUX].changed) {
351 }
352
353 for (i = 0; i < ARRAY_COUNT(globals->voices); i++) {
354 AuVoice* voice = &globals->voices[i];
356
357 if (voice->donePending) {
359 voice->donePending = FALSE;
360 voice->cmdPtr = NULL;
361 voice->priority = AU_PRIORITY_FREE;
362 }
363
365 au_voice_start(voice, &voice->envelope);
366 au_syn_start_voice_params(i, voice->busID, voice->instrument, voice->pitchRatio, voice->volume, voice->pan, voice->reverb, voice->delta);
367 // priority may be AU_PRIORITY_FREE if this voice was stolen and reset
368 voice->priority = voice->clientPriority;
369 } else {
371 au_syn_set_pitch(i, voice->pitchRatio);
372 }
373
375 au_syn_set_mixer_params(i, voice->volume, voice->delta, voice->pan, voice->reverb);
377 au_syn_set_pan_fxmix(i, voice->pan, voice->reverb);
378 }
379 }
380 voice->syncFlags = 0;
381 }
382}
@ AU_DELAY_CHANNEL_LEFT
Definition audio.h:242
@ AU_DELAY_CHANNEL_RIGHT
Definition audio.h:243
@ AU_VOICE_SYNC_FLAG_PARAMS
Definition audio.h:149
@ AU_VOICE_SYNC_FLAG_PAN_FXMIX
Definition audio.h:151
@ AU_VOICE_SYNC_FLAG_PITCH
Definition audio.h:150
@ AU_VOICE_SYNC_FLAG_ALL
Definition audio.h:148
u8 syncFlags
Definition audio.h:863
u8 channelDelayState
Definition audio.h:1071
@ AU_DELAY_STATE_OFF
channel delay is enabled (though not necessarily applied)
Definition audio.h:248
@ AU_DELAY_STATE_ON
Definition audio.h:247
@ AU_DELAY_STATE_REQUEST_OFF
channel delay is disabled
Definition audio.h:249
void au_disable_channel_delay(void)
Definition syn_driver.c:726
void au_syn_stop_voice(u8 voiceIdx)
Definition syn_driver.c:323
void au_delay_left_channel(u8 arg0)
Definition syn_driver.c:696
void au_delay_right_channel(u8 arg0)
Definition syn_driver.c:711
void au_syn_start_voice_params(u8 index, u8 reverbType, Instrument *table, f32 pitch, s16 vol, u8 pan, u8 fxMix, s32 delta)
Definition syn_driver.c:357
void au_syn_set_pan_fxmix(u8 voiceIdx, u8 arg1, u8 arg2)
Definition syn_driver.c:497
void au_voice_start(AuVoice *voice, EnvelopeData *envData)
Starts a new voice with the given envelope data.
Definition voice.c:187
void au_bus_set_effect(u8 busID, u8 effectID)
Definition syn_driver.c:301
void au_set_delay_time(s32 arg0)
Definition syn_driver.c:684
void au_syn_set_pitch(u8 voiceIdx, f32 pitchRatio)
Definition syn_driver.c:458
void au_syn_set_mixer_params(u8 voiceIdx, s16 volume, s32 arg2, u8 arg3, u8 arg4)
Definition syn_driver.c:464

Referenced by au_update_clients_for_audio_frame().

◆ au_reset_nonfree_voice()

void au_reset_nonfree_voice ( AuVoice * arg0,
u8 arg1 )

Definition at line 384 of file engine.c.

384 {
385 if (voice->priority != AU_PRIORITY_FREE) {
386 voice->cmdPtr = NULL;
387 voice->donePending = TRUE;
388 voice->syncFlags = 0;
390 }
391}
void au_syn_set_volume_delta(u8 voiceIdx, s16 arg1, s32 arg2)
Definition syn_driver.c:527

◆ au_reset_voice()

void au_reset_voice ( AuVoice * voice,
u8 voiceIdx )

◆ au_compute_pitch_ratio()

f32 au_compute_pitch_ratio ( s32 tuning)

Converts a linear pitch value (in cents) into a frequency ratio suitable for adjusting playback speed.

This function computes the playback rate corresponding to a pitch shift (up or down) in cents. Positive values increase pitch (higher frequency), and negative values decrease it. Recall 100 cents = 1 semitone, and therefore 1200 cents = 1 octave.

Parameters
tuningThe pitch offset in cents, from +4095 (~ 40.95 semitones up) to -16383 (~ 163.83 semitones down)
Returns
Floating point output rate multiplier. Multiply this with the base sample rate to apply the pitch.

Definition at line 406 of file engine.c.

406 {
407 if (tuning >= 0) {
410 } else {
411 tuning = -tuning;
414 }
415}
#define TUNE_SCALING_ARR_AMPLIFY_COARSE
Definition engine.c:402
#define TUNE_SCALING_ARR_ATTENUATE_COARSE
Definition engine.c:404
#define TUNE_SCALING_ARR_ATTENUATE_FINE
Definition engine.c:403
f32 AlTuneScaling[]
Definition sfx_player.c:378
#define TUNE_SCALING_ARR_AMPLIFY_FINE
Definition engine.c:401

Referenced by au_bgm_player_update_playing(), au_mseq_player_update(), and au_mseq_restore_voices().

◆ au_fade_init()

void au_fade_init ( Fade * fade,
s32 time,
s32 startValue,
s32 endValue )

Definition at line 417 of file engine.c.

417 {
418 fade->baseVolume = startValue << 16;
419 fade->baseTarget = endValue;
420
421 if (time != 0) {
422 fade->baseTicks = (time * 1000) / AU_FRAME_USEC;
423 fade->baseStep = ((endValue << 16) - fade->baseVolume) / fade->baseTicks;
424 } else {
425 fade->baseTicks = 1;
426 fade->baseStep = 0;
427 }
428
429 fade->onCompleteCallback = NULL;
430}
#define AU_FRAME_USEC
Definition audio.h:27

Referenced by au_bgm_process_init_song(), au_bgm_restore_copied_player(), and au_sfx_init().

◆ au_fade_clear()

void au_fade_clear ( Fade * fade)

Definition at line 432 of file engine.c.

432 {
433 fade->baseTicks = 0;
434 fade->baseStep = 0;
435 fade->onCompleteCallback = NULL;
436}

◆ au_fade_update()

void au_fade_update ( Fade * fade)

Definition at line 438 of file engine.c.

438 {
439 fade->baseTicks--;
440
441 if ((fade->baseTicks << 16) != 0) {
442 fade->baseVolume += fade->baseStep;
443 } else {
444 fade->baseVolume = fade->baseTarget << 16;
445 if (fade->onCompleteCallback != NULL) {
446 fade->onCompleteCallback();
447 fade->baseStep = 0;
448 fade->onCompleteCallback = NULL;
449 }
450 }
451}

Referenced by au_update_clients_for_audio_frame().

◆ au_fade_set_volume()

void au_fade_set_volume ( u8 arg0,
u16 arg1,
s32 arg2 )

Definition at line 453 of file engine.c.

453 {
454 au_bus_set_volume(busID, (u32)(volume * busVolume) / AU_MAX_BUS_VOLUME);
455}
#define AU_MAX_BUS_VOLUME
Definition audio.h:40
void au_bus_set_volume(u8 busID, u16 value)
Definition syn_driver.c:289

Referenced by au_bgm_update_bus_volumes(), au_sfx_init(), and au_update_clients_for_audio_frame().

◆ au_fade_flush()

void au_fade_flush ( Fade * fade)

Definition at line 457 of file engine.c.

457 {
458 if (fade->baseTicks == 0) {
459 fade->baseTicks = 1;
460 fade->baseStep = 0;
461 fade->baseTarget = ((u32)fade->baseVolume >> 16);
462 }
463}

Referenced by au_set_bus_volume_level().

◆ au_fade_set_envelope()

void au_fade_set_envelope ( Fade * fade,
s16 value )

Definition at line 465 of file engine.c.

465 {
466 fade->envelopeVolume = value << 16;
467 fade->envelopeTarget = value;
468 fade->envelopeTicks = 0;
469 fade->envelopeStep = 0;
470}

Referenced by au_bgm_player_init().

◆ au_fade_calc_envelope()

void au_fade_calc_envelope ( Fade * fade,
u32 arg1,
s32 target )

Definition at line 472 of file engine.c.

472 {
473 s16 ticks;
474 s32 delta;
475
476 if (duration >= 250 && duration <= 100000) {
477 ticks = (s32)(duration * 1000) / AU_FRAME_USEC;
478 delta = (target << 16) - fade->envelopeVolume;
479
480 fade->envelopeTarget = target;
481 fade->envelopeTicks = ticks;
482 fade->envelopeStep = delta / ticks;
483 } else {
484 fade->envelopeTicks = 0;
485 fade->envelopeStep = 0;
486 }
487}

Referenced by au_bgm_adjust_volume().

◆ au_fade_update_envelope()

void au_fade_update_envelope ( Fade * fade)

Definition at line 489 of file engine.c.

489 {
490 fade->envelopeTicks--;
491
492 if (fade->envelopeTicks != 0) {
493 fade->envelopeVolume += fade->envelopeStep;
494 } else {
495 fade->envelopeStep = 0;
496 fade->envelopeVolume = fade->envelopeTarget << 16;
497 }
498}

Referenced by au_update_clients_for_audio_frame().

◆ au_get_instrument()

Instrument * au_get_instrument ( AuGlobals * globals,
BankSetIndex bank,
s32 patch,
EnvelopeData * envData )

Note that bank is supplied as BankSetIndex and not BankSet, which means it will be used to perform a raw access into AuGlobals::bankSets.

This does not affect values above 3, but 1 and 2 differ.

Definition at line 502 of file engine.c.

502 {
503 // note that patch here can be up to 255, selecting from a maximum of 16 instruments and 16 banks per group
504 Instrument* instrument = (*globals->bankSets[(bank & 0x70) >> 4])[patch];
505 EnvelopePreset* envelope = instrument->envelopes;
506 u32 envelopeIdx = bank & 3;
507
508 if (envelopeIdx < envelope->count) {
509 envData->cmdListPress = AU_FILE_RELATIVE(envelope, envelope->offsets[envelopeIdx].offsetPress);
510 envData->cmdListRelease = AU_FILE_RELATIVE(envelope, envelope->offsets[envelopeIdx].offsetRelease);
511 } else {
512 envData->cmdListPress = EnvelopePressDefault;
513 envData->cmdListRelease = &EnvelopePressDefault[4]; //EnvelopeReleaseDefault;
514 }
515 return instrument;
516}
EnvelopeOffset offsets[1]
Definition audio.h:670
u16 offsetPress
Definition audio.h:663
#define AU_FILE_RELATIVE(base, offset)
Definition audio.h:43
EnvelopePreset * envelopes
Definition audio.h:696
u16 offsetRelease
Definition audio.h:664
u8 EnvelopePressDefault[]
Definition sfx_player.c:317

Referenced by au_bgm_player_update_playing(), au_BGMCmd_E8_TrackOverridePatch(), au_BGMCmd_F5_UseInstrument(), and au_mseq_player_update().

◆ au_get_bgm_player_and_file()

void au_get_bgm_player_and_file ( u32 playerIndex,
BGMHeader ** outCurrentTrackData,
BGMPlayer ** outPlayer )

Definition at line 518 of file engine.c.

518 {
519 AuGlobals* globals = gSoundGlobals;
520
521 switch (playerIndex) {
522 case 0:
523 *outFile = globals->dataBGM[0];
525 break;
526 case 1:
527 *outFile = globals->dataBGM[1];
529 break;
530 case 2:
531 *outFile = globals->dataBGM[0];
533 break;
534 default:
535 *outFile = NULL;
536 *outPlayer = NULL;
537 break;
538 }
539}

Referenced by snd_song_load().

◆ au_get_bgm_player()

void au_get_bgm_player ( u32 playerIndex,
BGMPlayer ** outPlayer )

Definition at line 541 of file engine.c.

541 {
542 switch (playerIndex) {
543 case 0:
545 break;
546 case 1:
548 break;
549 case 2:
551 break;
552 default:
553 *outPlayer = NULL;
554 break;
555 }
556}

◆ au_load_song_files()

AuResult au_load_song_files ( u32 arg0,
BGMHeader * arg1,
BGMPlayer * arg2 )

Definition at line 558 of file engine.c.

558 {
559 AuResult status;
563 AuGlobals* globals = gSoundGlobals;
565 s32 i;
566 u16 bkFileIndex;
567 s32 bgmFileIndex;
568 u32 data;
569 u32 offset;
572 s32 cond;
573
574 // needed to match
575 cond = songID < globals->songListLength;
576 playerCopy = player;
577 fileCopy = bgmFile;
578
579 if (cond) {
580 songInfo = &globals->songList[songID];
581 status = au_fetch_SBN_file(songInfo->bgmFileIndex, AU_FMT_BGM, &fileEntry);
582 if (status != AU_RESULT_OK) {
583 return status;
584 }
585
587 return AU_ERROR_201;
588 }
589
590 au_read_rom(fileEntry.offset, fileCopy, fileEntry.data & 0xFFFFFF);
591
592 for (i = 0; i < ARRAY_COUNT(songInfo->bkFileIndex); i++) {
593 bkFileIndex = songInfo->bkFileIndex[i];
594 if (bkFileIndex != 0) {
595 bkFileEntry = &globals->sbnFileList[bkFileIndex];
596
597 offset = (bkFileEntry->offset & 0xFFFFFF) + globals->baseRomOffset;
598 fileEntry2.offset = offset;
599
600 data = bkFileEntry->data;
601 fileEntry2.data = data;
602
603 if ((data >> 0x18) == AU_FMT_BK) {
604 au_load_aux_bank(offset, i);
605 }
606 }
607 }
608 bgmFileIndex = songInfo->bgmFileIndex;
609 playerCopy->songID = songID;
610 playerCopy->bgmFile = bgmFile;
611 playerCopy->bgmFileIndex = bgmFileIndex;
612 return fileCopy->name;
613 } else {
614 return AU_ERROR_151;
615 }
616}
s32 baseRomOffset
Definition audio.h:1031
InitSongEntry * songList
Definition audio.h:1035
SBNFileEntry * sbnFileList
Definition audio.h:1032
s32 songListLength
copied from INIT to the audio heap
Definition audio.h:1036
b32 au_bgm_player_is_active(BGMPlayer *player)
Definition bgm_player.c:279
s32 au_load_aux_bank(s32 bkFileOffset, s32 bankIndex)
Definition engine.c:1150
@ AU_FMT_BGM
Definition enums.h:1779
@ AU_FMT_BK
Definition enums.h:1781
AuResult
Definition enums.h:1758
@ AU_ERROR_151
Definition enums.h:1774
@ AU_ERROR_201
Definition enums.h:1775

Referenced by snd_song_load().

◆ au_reload_song_files()

AuResult au_reload_song_files ( s32 songID,
BGMHeader * arg1 )

Definition at line 618 of file engine.c.

618 {
619 AuResult status;
623 AuGlobals* globals;
625 s32 i;
626 u16 bkFileIndex;
627
628 globals = gSoundGlobals;
629 songInfo = &globals->songList[songID];
630 status = au_fetch_SBN_file(songInfo->bgmFileIndex, AU_FMT_BGM, &sbnEntry);
631 if (status == AU_RESULT_OK) {
632 // load BGM file
633 au_read_rom(sbnEntry.offset, bgmFile, sbnEntry.data & 0xFFFFFF);
634
635 // load any auxiliary banks required by this BGM
636 for (i = 0; i < ARRAY_COUNT(songInfo->bkFileIndex); i++) {
637 bkFileIndex = songInfo->bkFileIndex[i];
638 if (bkFileIndex != 0) {
639 bkFileEntry = &globals->sbnFileList[bkFileIndex];
640
641 fileEntry.offset = (bkFileEntry->offset & 0xFFFFFF) + globals->baseRomOffset;
642 fileEntry.data = bkFileEntry->data;
643
644 if ((fileEntry.data >> 0x18) == AU_FMT_BK) {
645 au_load_aux_bank(fileEntry.offset, i);
646 } else {
648 }
649 }
650 }
651 }
652
653 return status;
654}
s32 offset
Definition audio.h:916
@ AU_ERROR_SBN_FORMAT_MISMATCH
Definition enums.h:1773

Referenced by au_bgm_process_resume().

◆ au_get_snapshot_by_index()

BGMPlayer * au_get_snapshot_by_index ( s32 index)

Definition at line 656 of file engine.c.

656 {
657 if (index == BGM_SNAPSHOT_0) {
659 }
660 return NULL;
661}
@ BGM_SNAPSHOT_0
Definition audio.h:192

Referenced by au_bgm_process_resume(), and au_bgm_process_suspend().

◆ au_ambient_load()

AuResult au_ambient_load ( u32 arg0)

Definition at line 665 of file engine.c.

665 {
668 AuGlobals* globals;
669 MSEQHeader* mseqFile;
670 u32 i;
671
672 globals = gSoundGlobals;
675 if (manager->players[0].mseqName == 0) {
677 au_read_rom(fileEntry.offset, globals->dataMSEQ[0], fileEntry.data & 0xFFFFFF);
678 manager->mseqFiles[0] = globals->dataMSEQ[0];
679 for (i = 1; i < ARRAY_COUNT(manager->mseqFiles); i++) {
680 manager->mseqFiles[i] = NULL;
681 }
682 manager->numActivePlayers = 1;
683 }
684 }
685 } else if (ambSoundID == AMBIENT_RADIO
686 && manager->players[0].mseqName == 0
687 && manager->players[1].mseqName == 0
688 && manager->players[2].mseqName == 0
689 ) {
690 manager->numActivePlayers = 0;
691 for (i = 0; i < ARRAY_COUNT(manager->mseqFiles); i++) {
692 manager->mseqFiles[i] = NULL;
693 }
694
695 mseqFile = globals->dataMSEQ[1];
697 au_read_rom(fileEntry.offset, mseqFile, fileEntry.data & 0xFFFFFF);
698 manager->mseqFiles[0] = mseqFile;
699
700 mseqFile = AU_FILE_RELATIVE(mseqFile, (fileEntry.data + 0x40) & 0xFFFFFF);
702 au_read_rom(fileEntry.offset, mseqFile, fileEntry.data & 0xFFFFFF);
703 manager->mseqFiles[1] = mseqFile;
704
705 mseqFile = AU_FILE_RELATIVE(mseqFile, (fileEntry.data + 0x40) & 0xFFFFFF);
707 au_read_rom(fileEntry.offset, mseqFile, fileEntry.data & 0xFFFFFF);
708 manager->mseqFiles[2] = mseqFile;
709
710 mseqFile = AU_FILE_RELATIVE(mseqFile, (fileEntry.data + 0x40) & 0xFFFFFF);
712 au_read_rom(fileEntry.offset, mseqFile, fileEntry.data & 0xFFFFFF);
713 manager->mseqFiles[3] = mseqFile;
714
715 manager->numActivePlayers = 4;
717 // @bug perhaps meant to be 3?
718 // the index here corresponds to an entry in gSoundGlobals->banks
719 // 0-2 are used for the extra banks which may be loaded for BGM files
720 // there exists an unused 4th entry this could plausibly be intended for
721 au_load_aux_bank(fileEntry.offset, 2);
722 }
723 }
724 }
725 }
726 }
727 }
728
729 return AU_RESULT_OK;
730}
#define SBN_EXTRA_LOOKUP(i, fmt, e)
Definition engine.c:663
@ AMBIENT_RADIO
Definition enums.h:1921
@ AU_FMT_MSEQ
Definition enums.h:1784

Referenced by snd_load_ambient().

◆ au_get_client_by_priority()

BGMPlayer * au_get_client_by_priority ( u8 arg0)

Definition at line 732 of file engine.c.

732 {
733 switch (priority) {
735 return gBGMPlayerA;
737 return gBGMPlayerB;
739 return (BGMPlayer*)gSoundManager; // TODO: why return pointer to SoundManager?
740 default:
741 return NULL;
742 }
743}

Referenced by au_bgm_process_resume().

◆ au_load_INIT()

void au_load_INIT ( AuGlobals * arg0,
s32 romAddr,
ALHeap * heap )

Definition at line 745 of file engine.c.

745 {
750 s32 songListOffset, mseqListOffset;
751 s32* data;
752 s32 numEntries;
753 s32* romPtr = &globals->baseRomOffset;
754
756 numEntries = sbnHeader.numEntries;
757 fileListSize = numEntries * sizeof(SBNFileEntry);
758 globals->baseRomOffset = romAddr;
759 globals->fileListLength = sbnHeader.numEntries;
760 globals->sbnFileList = alHeapAlloc(heap, 1, fileListSize);
761 au_read_rom(globals->baseRomOffset + sbnHeader.fileListOffset, globals->sbnFileList, fileListSize);
762
763 entry = globals->sbnFileList;
764 while (sbnHeader.numEntries--) {
765 if ((entry->offset & 0xFFFFFF) == 0) {
766 break;
767 }
768
769 // 16-byte align size
770 size = entry->data;
771 entry->data = (entry->data + 0xF) & ~0xF;
772 entry++;
773 }
774
775 if (sbnHeader.INIToffset != 0) {
776 initBase = *romPtr + sbnHeader.INIToffset;
778
779 songListOffset = initBase + initHeader.songListOffset;
780 size = ALIGN16_(initHeader.songListSize);
781 globals->songList = alHeapAlloc(heap, 1, size);
782 au_read_rom(songListOffset, globals->songList, size);
783
784 mseqListOffset = initBase + initHeader.mseqListOffset;
785 size = ALIGN16_(initHeader.mseqListSize);
786 globals->extraFileList = alHeapAlloc(heap, 1, size);
787 au_read_rom(mseqListOffset, globals->extraFileList, size);
788
789 globals->bkFileListOffset = initBase + initHeader.bankListOffset;
790 globals->bkListLength = ALIGN16_(initHeader.bankListSize);
791
792 globals->songListLength = initHeader.songListSize / sizeof(InitSongEntry) - 1;
793 }
794}
#define ALIGN16_(val)
Definition audio.h:42

Referenced by au_engine_init().

◆ au_fetch_SBN_file()

AuResult au_fetch_SBN_file ( u32 fileIdx,
AuFileFormat format,
SBNFileEntry * arg2 )

Definition at line 796 of file engine.c.

796 {
798 s32 status = AU_RESULT_OK;
799
800 if (fileIdx < gSoundGlobals->fileListLength) {
802 s32 offset = (entry->offset & 0xFFFFFF) + gSoundGlobals->baseRomOffset;
803
804 fileEntry.offset = offset;
805 fileEntry.data = entry->data;
806 if ((fileEntry.data >> 0x18) == format) {
807 outEntry->offset = offset;
808 outEntry->data = fileEntry.data;
809 } else {
811 }
812 } else {
814 }
815 return status;
816}
@ AU_ERROR_SBN_INDEX_OUT_OF_RANGE
Definition enums.h:1772

Referenced by au_engine_init(), au_load_BK_headers(), au_load_song_files(), and au_reload_song_files().

◆ au_load_PER()

void au_load_PER ( AuGlobals * globals,
s32 romAddr )

Definition at line 818 of file engine.c.

818 {
819 PERHeader header;
820 u32 size;
822 s32 numItems;
823 void* end;
824
825 au_read_rom(romAddr, &header, sizeof(header));
826 size = header.mdata.size - sizeof(header);
827 au_read_rom(romAddr + sizeof(header), globals->dataPER, size);
828 numItems = size / sizeof(PEREntry);
829 numItemsLeft = 6 - numItems;
830 if (numItemsLeft > 0) {
831 end = &globals->dataPER[numItems];
832 au_copy_words(&globals->defaultDrumEntry, end, sizeof(BGMDrumInfo));
833 au_copy_words(end, end + sizeof(BGMDrumInfo), numItemsLeft * sizeof(PEREntry) - sizeof(BGMDrumInfo));
834 }
835}
AUFileMetadata mdata
Definition audio.h:976
void au_copy_words(void *src, void *dst, s32 size)
Definition engine.c:1273

Referenced by au_engine_init().

◆ au_load_PRG()

void au_load_PRG ( AuGlobals * arg0,
s32 romAddr )

Definition at line 837 of file engine.c.

837 {
838 PERHeader header;
839 u32 size;
841 s32 numItems;
843 void* end;
844
845 au_read_rom(romAddr, &header, sizeof(header));
846 dataRomAddr = romAddr + sizeof(header);
847 size = header.mdata.size - sizeof(header);
848 if (size > PRG_MAX_COUNT * sizeof(BGMInstrumentInfo)) {
849 size = PRG_MAX_COUNT * sizeof(BGMInstrumentInfo);
850 }
851 au_read_rom(dataRomAddr, globals->dataPRG, size);
852 numItems = size / sizeof(BGMInstrumentInfo);
853 numItemsLeft = PRG_MAX_COUNT - numItems;
854 if (numItemsLeft > 0) {
855 end = &globals->dataPRG[numItems];
856 au_copy_words(&globals->defaultPRGEntry, end, sizeof(BGMInstrumentInfo));
857 au_copy_words(end, end + sizeof(BGMInstrumentInfo), numItemsLeft * sizeof(BGMInstrumentInfo) - sizeof(BGMInstrumentInfo));
858 }
859}

Referenced by au_engine_init().

◆ au_get_BK_instruments()

InstrumentBank * au_get_BK_instruments ( BankSet bankSet,
u32 bankIndex )

Definition at line 895 of file engine.c.

895 {
897 AuGlobals* globals = gSoundGlobals;
898
899 // TODO fake match - this multiplying the bankIndex by 16 and then dividing it right after is dumb
900 bankIndex *= 16;
901
902 switch (bankSet) {
903 case BANK_SET_AUX:
904 ret = &globals->auxBankSet[bankIndex / 16];
905 break;
906 case BANK_SET_2:
907 ret = &globals->bankSet2[bankIndex / 16];
908 break;
909 case BANK_SET_4:
910 ret = &globals->bankSet4[bankIndex / 16];
911 break;
912 case BANK_SET_5:
913 ret = &globals->bankSet5[bankIndex / 16];
914 break;
915 case BANK_SET_6:
916 ret = &globals->bankSet6[bankIndex / 16];
917 break;
918 case BANK_SET_MUSIC:
919 ret = &globals->musicBankSet[bankIndex / 16];
920 break;
921 }
922
923 return ret;
924}
@ BANK_SET_2
Definition audio.h:376
@ BANK_SET_AUX
Definition audio.h:375
@ BANK_SET_MUSIC
Definition audio.h:377
@ BANK_SET_6
Definition audio.h:380
@ BANK_SET_5
Definition audio.h:379
@ BANK_SET_4
Definition audio.h:378
Instrument * InstrumentBank[16]
Definition audio.h:699

Referenced by au_clear_instrument_group(), au_load_BK_to_bank(), and au_load_static_BK_to_bank().

◆ au_load_BK_to_bank()

BKFileBuffer * au_load_BK_to_bank ( s32 bkFileOffset,
BKFileBuffer * bkFile,
s32 bankIndex,
BankSet bankSet )

Loads an instrument bank file from ROM, allocates memory if needed, and sets up instrument pointers.

Instruments in the bank will be configured to use DMA streaming for sample/codebook data. This is the standard loader for streamed instrument banks.

Definition at line 947 of file engine.c.

947 {
948 ALHeap* heap = gSynDriverPtr->heap;
950 BKHeader* header = &localHeader;
953 s32 instrumentCount;
956 s32 size;
957 u32 i;
958
959 au_read_rom(bkFileOffset, header, sizeof(*header));
962
963 while (keepReading) {
964 switch (readState) {
965 case BK_READ_DONE:
967 break;
969 if (header->signature != AL_HEADER_SIG_BK) {
971 } else if (header->size == 0) {
973 } else {
975 }
976 break;
978 if (header->format == AL_HEADER_SIG_CR) {
980 } else if (header->format == AL_HEADER_SIG_DR) {
982 } else if (header->format == AL_HEADER_SIG_SR) {
984 } else {
986 }
987 break;
988
990 size = ALIGN16_(header->instrumetsLength)
991 + ALIGN16_(header->loopStatesLength)
992 + ALIGN16_(header->predictorsLength)
993 + ALIGN16_(header->envelopesLength)
994 + sizeof(*header);
995 if (bkFile == NULL) {
996 bkFile = alHeapAlloc(heap, 1, size);
997 }
999
1000 group = au_get_BK_instruments(bankSet, bankIndex);
1001 inst = (*group);
1002 instrumentCount = 0;
1003
1004 for (i = 0; i < ARRAY_COUNT(header->instruments); inst++, i++) {
1005 u16 instOffset = header->instruments[i];
1006 if (instOffset != 0) {
1007 instrumentCount++;
1009 } else {
1010 *inst = NULL;
1011 }
1012 }
1013
1014 if (instrumentCount != 0) {
1016 } else {
1018 }
1019 break;
1020 case BK_READ_SWIZZLE_CR:
1023 break;
1024
1025 // inferred states
1026 case BK_READ_PROCESS_DR:
1027 case BK_READ_UNK_DR:
1028 case BK_READ_PROCESS_SR:
1029 case BK_READ_UNK_SR:
1030 default:
1032 break;
1033 }
1034 }
1035
1036 return bkFile;
1037}
u16 format
Definition audio.h:989
u16 loopStatesLength
Definition audio.h:995
u16 signature
Definition audio.h:985
u16 predictorsLength
Definition audio.h:997
u16 instrumetsLength
Definition audio.h:993
u16 envelopesLength
Definition audio.h:999
s32 size
Definition audio.h:987
u16 instruments[16]
Definition audio.h:992
#define AL_HEADER_SIG_BK
Definition engine.c:939
InstrumentBank * au_get_BK_instruments(BankSet bankSet, u32 bankIndex)
Definition engine.c:895
void au_swizzle_BK_instruments(s32 bkFileOffset, BKFileBuffer *file, InstrumentBank instruments, u32 instrumentCount, u8 useDma)
Fixes up (swizzles) instrument pointers in a loaded bank, converting file-relative offsets to valid R...
Definition engine.c:1042
#define AL_HEADER_SIG_DR
Definition engine.c:941
#define AL_HEADER_SIG_CR
Definition engine.c:940
@ BK_READ_SWIZZLE_CR
Definition engine.c:932
@ BK_READ_PROCESS_DR
Definition engine.c:933
@ BK_READ_FETCH_HEADER
Definition engine.c:928
@ BK_READ_UNK_DR
Definition engine.c:934
@ BK_READ_PROCESS_SR
Definition engine.c:935
@ BK_READ_FETCH_DATA
Definition engine.c:929
@ BK_READ_PROCESS_CR
Definition engine.c:931
@ BK_READ_DONE
Definition engine.c:927
@ BK_READ_UNK_SR
Definition engine.c:936
#define AL_HEADER_SIG_SR
Definition engine.c:942

Referenced by au_load_aux_bank(), and au_load_BK_headers().

◆ au_swizzle_BK_instruments()

void au_swizzle_BK_instruments ( s32 bkFileOffset,
BKFileBuffer * file,
InstrumentBank instruments,
u32 instrumentCount,
u8 useDma )

Fixes up (swizzles) instrument pointers in a loaded bank, converting file-relative offsets to valid RAM pointers.

Sets whether each instrument uses DMA streaming or not, and updates pitch ratios to match output rate. Replaces NULL instruments with a default instrument to ensure all loaded patches point to valid data.

Definition at line 1042 of file engine.c.

1042 {
1043 Instrument* defaultInstrument = gSoundGlobals->defaultInstrument;
1044 BKHeader* header = &file->header;
1045 f32 outputRate = gSoundGlobals->outputRate;
1046 s32 i;
1047
1048 if (!header->swizzled) {
1049 for (i = 0; i < instrumentCount; i++) {
1050 Instrument* instrument = instruments[i];
1051
1052 if (instrument != NULL) {
1053 if (instrument->wavData != 0) {
1054 instrument->wavData += bkFileOffset;
1055 }
1056 if (instrument->loopState != NULL) {
1057 instrument->loopState = AU_FILE_RELATIVE(file, instrument->loopState);
1058 }
1059 if (instrument->predictor != NULL) {
1060 instrument->predictor = AU_FILE_RELATIVE(file, instrument->predictor);
1061 }
1062 if (instrument->envelopes != NULL) {
1063 instrument->envelopes = AU_FILE_RELATIVE(file, instrument->envelopes);
1064 }
1065 instrument->useDma = useDma;
1066 instrument->pitchRatio = instrument->sampleRate / outputRate;
1067 } else {
1068 instruments[i] = defaultInstrument;
1069 }
1070 }
1071 header->swizzled = TRUE;
1072 }
1073}
ADPCM_STATE * loopState
Definition audio.h:677
s16 * predictor
Definition audio.h:681
b8 useDma
Definition audio.h:689
u8 swizzled
Definition audio.h:990
u8 * wavData
Definition audio.h:675

Referenced by au_load_BK_to_bank(), and au_load_static_BK_to_bank().

◆ au_load_static_BK_to_bank()

BKFileBuffer * au_load_static_BK_to_bank ( s32 * inAddr,
void * outAddr,
s32 bankIndex,
BankSet bankSet )

UNUSED Loads an instrument bank file from ROM to a given buffer (allocates if needed), and sets up instrument pointers.

Instruments are configured to always bypass DMA: sample and codebook data is assumed to be already present in RAM. Use this only for banks whose sample data is guaranteed to be preloaded, not for standard streaming.

Definition at line 1079 of file engine.c.

1079 {
1080 ALHeap* heap = gSynDriverPtr->heap;
1083 BKHeader* header = &localHeader;
1085 Instrument* instruments;
1086 Instrument** inst;
1087 s32 instrumentCount;
1089 u32 readState;
1090 u32 i;
1091 s32 useDma = FALSE;
1092
1094 keepReading = TRUE;
1095
1096 while (keepReading) {
1097 switch (readState) {
1098 case BK_READ_DONE:
1100 break;
1103 if (header->signature != AL_HEADER_SIG_BK) {
1105 } else if (header->size == 0) {
1107 } else if (header->format != AL_HEADER_SIG_CR) {
1109 } else {
1111 }
1112 break;
1113 case BK_READ_FETCH_DATA:
1114 if (bkFile == NULL) {
1115 bkFile = alHeapAlloc(heap, 1, header->size);
1116 }
1117 au_read_rom(*inAddr, bkFile, header->size);
1118
1119 instrumentCount = 0;
1120 group = au_get_BK_instruments(bankSet, bankIndex);
1121 inst = (*group);
1122 for (i = 0; i < ARRAY_COUNT(header->instruments); inst++, i++) {
1123 u16 instOffset = header->instruments[i];
1124 if (instOffset != 0) {
1125 instrumentCount++;
1127 } else {
1128 *inst = NULL;
1129 }
1130 }
1131
1132 if (instrumentCount != 0) {
1134 } else {
1136 }
1137 break;
1138 case BK_READ_SWIZZLE:
1141 break;
1142 default:
1144 break;
1145 }
1146 }
1147 return bkFile;
1148}
@ BK_READ_SWIZZLE
Definition engine.c:930

◆ au_load_aux_bank()

s32 au_load_aux_bank ( s32 bkFileOffset,
s32 bankIndex )

Definition at line 1150 of file engine.c.

1150 {
1152 return AU_RESULT_OK;
1153}
BKFileBuffer * au_load_BK_to_bank(s32 bkFileOffset, BKFileBuffer *bkFile, s32 bankIndex, BankSet bankSet)
Loads an instrument bank file from ROM, allocates memory if needed, and sets up instrument pointers.
Definition engine.c:947

Referenced by au_ambient_load(), au_load_BGM(), au_load_song_files(), and au_reload_song_files().

◆ au_clear_instrument_group()

void au_clear_instrument_group ( s32 bankIndex,
BankSet bankSet )

unused. resets all instruments in (bankIndex, bankSet) to default

Definition at line 1156 of file engine.c.

1156 {
1158 InstrumentBank* group = au_get_BK_instruments(bankSet, bankIndex);
1159 Instrument** ptr = *group;
1160 u32 i;
1161
1162 if (group != NULL) {
1163 for (i = 0; i < ARRAY_COUNT(*group); i++) {
1164 *ptr++ = instrument;
1165 }
1166 }
1167}

◆ au_set_bus_volume_level()

void au_set_bus_volume_level ( s32 arg0,
u32 idx )

Definition at line 1169 of file engine.c.

1169 {
1177 }
1181 }
1182 }
1183}
@ AUDIO_TYPE_BGM
Definition audio.h:398
@ AUDIO_TYPE_SFX
Definition audio.h:399
Fade fadeInfo
Definition audio.h:792
s32 busVolume
Definition audio.h:793
s32 busVolume
Definition audio.h:1151
u16 PerceptualVolumeLevels[9]
Volume steps use squared values so each level represents linear power increase, matching loudness per...
Definition sfx_player.c:299
void au_fade_flush(Fade *fade)
Definition engine.c:457

Referenced by snd_set_bgm_volume(), and snd_set_sfx_volume().

◆ au_set_reverb_type()

s32 au_set_reverb_type ( s32 arg0,
s32 arg1 )

Definition at line 1185 of file engine.c.

1185 {
1188 }
1189 return 0;
1190}
s32 au_sfx_set_reverb_type(SoundManager *manager, s32 arg1)
Definition sfx_player.c:719

Referenced by snd_set_sfx_reverb_type().

◆ au_sync_channel_delay_enabled()

void au_sync_channel_delay_enabled ( u32 arg0)

Definition at line 1192 of file engine.c.

1192 {
1193 if (bMonoSound % 2 == 1) {
1194 // mono sound
1197 }
1198 } else {
1199 // stereo sound
1203 }
1204 }
1205}

Referenced by snd_set_mono(), and snd_set_stereo().

◆ au_read_rom()

void au_read_rom ( s32 romAddr,
void * buffer,
u32 size )

Definition at line 1209 of file engine.c.

1209 {
1210 s32 nchunks = size / 0x2000;
1211 s32 offset = 0;
1212
1213 if (nchunks != 0) {
1214 while (nchunks--) {
1215 nuPiReadRom(romAddr + offset, buffer + offset, 0x2000);
1216 offset += 0x2000;
1217 }
1218 }
1219
1220 size %= 0x2000;
1221 if (size != 0) {
1222 nuPiReadRom(romAddr + offset, buffer + offset, size);
1223 }
1224}

Referenced by au_ambient_load(), au_engine_init(), au_load_BK_headers(), au_load_BK_to_bank(), au_load_INIT(), au_load_PER(), au_load_PRG(), au_load_song_files(), au_load_static_BK_to_bank(), and au_reload_song_files().

◆ au_memset()

void au_memset ( void * dst,
s32 size,
u8 value )

Definition at line 1226 of file engine.c.

1226 {
1227 s32 count;
1228 s32 intValue;
1229
1230 if (size == 0) {
1231 return;
1232 }
1233
1234 if (size < 1024) {
1235 while (size--) {
1236 *(u8*)dst++ = value;
1237 }
1238 } else {
1239 count = (u32)dst & 0x3;
1240 if (count != 0) {
1241 count = 4 - count;
1242 size -= count;
1243 while (count--) {
1244 *(u8*)dst++ = value;
1245 }
1246 }
1247
1248 count = size >> 2;
1249 intValue = (value << 8) + value;
1250 intValue = (intValue << 16) + intValue;
1251 while (count--) {
1252 *(u32*)dst = intValue;
1253 dst += 4;
1254 }
1255
1256 count = size & 3;
1257 if (count != 0) {
1258 while (count--) {
1259 *(u8*)dst++ = value;
1260 }
1261 }
1262 }
1263}

Referenced by au_mseq_manager_init(), and au_mseq_play_sequence().

◆ au_copy_bytes()

void au_copy_bytes ( s8 * src,
s8 * dest,
s32 size )

Definition at line 1265 of file engine.c.

1265 {
1266 if (size > 0) {
1267 while (size-- != 0) {
1268 *dest++ = *src++;
1269 }
1270 }
1271}

◆ au_copy_words()

void au_copy_words ( void * src,
void * dst,
s32 size )

Definition at line 1273 of file engine.c.

1273 {
1274 size /= 4;
1275
1276 if (size > 0) {
1277 if (!(((s32) src | (s32) dst) & 3)) {
1278 s32* srcIt = src;
1279 s32* dstIt = dst;
1280
1281 size--;
1282 do {
1283 *dstIt++ = *srcIt++;
1284 } while (size-- != 0);
1285 }
1286 }
1287}

Referenced by au_bgm_process_suspend(), au_bgm_restore_copied_player(), au_load_PER(), and au_load_PRG().

◆ au_driver_init()

void au_driver_init ( AuSynDriver * driver,
ALConfig * config )

Definition at line 25 of file syn_driver.c.

25 {
26 ALHeap* heap = config->heap;
27 s32 i;
28
30 return;
31 }
32
33 driver->num_pvoice = config->num_pvoice;
34 driver->num_bus = config->num_bus;
35 driver->curSamples = 0;
36 driver->unused_04 = 0;
37 driver->outputRate = config->outputRate;
38 driver->dmaNew = config->dmaNew;
39
45
46 gSynDriverPtr->pvoices = alHeapAlloc(heap, config->num_pvoice, sizeof(*gSynDriverPtr->pvoices));
47
48 // this is inlined alN_PVoiceNew
49 for (i = 0; i < config->num_pvoice; i++) {
51 voice->decoder.state = alHeapAlloc(heap, 1, sizeof(*voice->decoder.state));
52 voice->decoder.lstate = alHeapAlloc(heap, 1, sizeof(*voice->decoder.lstate));
53 voice->decoder.dmaFunc = gSynDriverPtr->dmaNew(&voice->decoder.dmaState);
54 voice->decoder.lastsam = 0;
55 voice->decoder.first = 1;
56 voice->decoder.memin = (s32)NULL;
57 voice->resampler.state = alHeapAlloc(heap, 1, sizeof(*voice->resampler.state));
58 voice->resampler.delta = 0;
59 voice->resampler.first = TRUE;
60 voice->resampler.ratio = 1.0f;
61 voice->envMixer.state = alHeapAlloc(heap, 1, sizeof(*voice->envMixer.state));
62 voice->envMixer.dirty = TRUE;
63 voice->envMixer.motion = AL_STOPPED;
64 voice->envMixer.volume = 1;
65 voice->envMixer.ltgt = 1;
66 voice->envMixer.rtgt = 1;
67 voice->envMixer.cvolL = 1;
68 voice->envMixer.cvolR = 1;
69 voice->envMixer.dryamt = 0;
70 voice->envMixer.wetamt = 0;
71 voice->envMixer.lratm = 1;
72 voice->envMixer.lratl = 0;
73 voice->envMixer.rratm = 1;
74 voice->envMixer.rratl = 0;
75 voice->envMixer.delta = 0;
76 voice->envMixer.segEnd = 0;
77 voice->envMixer.pan = 64;
78 voice->unused_74 = 0;
79 voice->next = NULL;
80 voice->busID = FX_BUS_BGMA_MAIN;
81 voice->index = i;
82 }
83
84 gSynDriverPtr->fxBus = alHeapAlloc(heap, config->num_bus, sizeof(*gSynDriverPtr->fxBus));
85
86 for (i = 0; i < config->num_bus; i++) {
87 AuFxBus* fxBus = &gSynDriverPtr->fxBus[i];
88 fxBus->head = NULL;
89 fxBus->tail = NULL;
90 fxBus->gain = 0x7FFF;
92 fxBus->fxL = alHeapAlloc(heap, 1, sizeof(*fxBus->fxL));
93 fxBus->fxR = alHeapAlloc(heap, 1, sizeof(*fxBus->fxR));
94 au_fx_create(fxBus->fxL, fxBus->curEffectType, heap);
95 au_fx_create(fxBus->fxR, fxBus->curEffectType, heap);
96 }
97
100 AuDelayedBusID = 0;
102 AuDelayCount = 4;
103
106 for (i = 0; i < 4 * AUDIO_SAMPLES; i++) {
108 }
109
110 gSynDriverPtr->heap = heap;
111}
u16 gain
Definition audio.h:561
s32 * dryAccumBuffer
Definition audio.h:644
ALDMANew2 dmaNew
Definition audio.h:640
u8 curEffectType
Definition audio.h:565
AuLoadFilter decoder
Definition audio.h:623
ADPCM_STATE * state
Definition audio.h:578
AuPVoice * pvoices
Definition audio.h:642
AuFxBus * fxBus
Definition audio.h:643
AuFX * fxR
Definition audio.h:564
struct AuPVoice * tail
Definition audio.h:568
struct AuPVoice * head
Definition audio.h:567
s32 * wetAccumBuffer
Definition audio.h:645
#define AU_MAX_VOLUME_16
Definition audio.h:62
AuFX * fxL
Definition audio.h:563
void au_fx_create(AuFX *fx, u8 mode, ALHeap *heap)
Definition reverb.c:138
BSS s16 AuDelayedChannel
Definition syn_driver.c:11
AuSynDriver * gActiveSynDriverPtr
Definition syn_driver.c:14
BSS s16 * AuDelayBufferAux
Definition syn_driver.c:8
BSS s16 * AuDelayBufferMain
Definition syn_driver.c:7
u8 AuUseGlobalVolume
Definition syn_driver.c:16
AuSynDriver * gSynDriverPtr
Definition syn_driver.c:15
u16 AuGlobalVolume
Definition syn_driver.c:17
void * alHeapAlloc(ALHeap *heap, s32 count, s32 size)
Definition syn_driver.c:765
BSS s32 AuDelayCount
Definition syn_driver.c:12
u8 AuSynStereoDirty
Definition syn_driver.c:18
BSS u8 AuDelayedBusID
Definition syn_driver.c:10

Referenced by create_audio_system().

◆ au_driver_release()

void au_driver_release ( void )

Definition at line 113 of file syn_driver.c.

113 {
114 if (gActiveSynDriverPtr != NULL) {
116 }
117}

◆ au_use_global_volume()

void au_use_global_volume ( void )

Definition at line 272 of file syn_driver.c.

272 {
274}

Referenced by nuAuPreNMIProc().

◆ au_set_global_volume()

void au_set_global_volume ( s16 arg0)

Definition at line 276 of file syn_driver.c.

276 {
277 AuGlobalVolume = volume;
278}

Referenced by nuAuPreNMIProc().

◆ au_get_global_volume()

s16 au_get_global_volume ( void )

Definition at line 280 of file syn_driver.c.

280 {
281 return AuGlobalVolume;
282}

Referenced by nuAuPreNMIProc().

◆ au_set_stereo_enabled()

void au_set_stereo_enabled ( b8 enabled)

Definition at line 284 of file syn_driver.c.

284 {
285 AuSynUseStereo = enabled;
287}
volatile u8 AuSynUseStereo
Definition system.c:10

Referenced by snd_set_mono(), and snd_set_stereo().

◆ au_bus_set_volume()

void au_bus_set_volume ( u8 busID,
u16 value )

Definition at line 289 of file syn_driver.c.

289 {
290 AuFxBus* fxBus = &gSynDriverPtr->fxBus[busID];
291
292 fxBus->gain = value & 0x7FFF;
293}

Referenced by au_fade_set_volume().

◆ au_bus_get_volume()

u16 au_bus_get_volume ( u8 busID)

Definition at line 295 of file syn_driver.c.

295 {
296 AuFxBus* fxBus = &gSynDriverPtr->fxBus[busID];
297
298 return fxBus->gain;
299}

◆ au_bus_set_effect()

void au_bus_set_effect ( u8 busID,
u8 effectID )

Definition at line 301 of file syn_driver.c.

301 {
302 AuFxBus* fxBus = &gSynDriverPtr->fxBus[busID];
303
304 fxBus->curEffectType = effectType;
305 au_fx_load_preset(fxBus->fxL, effectType);
306 au_fx_load_preset(fxBus->fxR, effectType);
307}
void au_fx_load_preset(AuFX *fx, u8 effectType)
Definition reverb.c:181

Referenced by au_syn_begin_audio_frame().

◆ au_bus_set_fx_params()

void au_bus_set_fx_params ( u8 busID,
s16 arg1,
s16 arg2,
s32 arg3 )

Definition at line 309 of file syn_driver.c.

309 {
310 AuFxBus* fxBus = &gSynDriverPtr->fxBus[busID];
311
312 au_fx_param_hdl(fxBus->fxL, delayIndex, paramID, value);
313 au_fx_param_hdl(fxBus->fxR, delayIndex, paramID, value);
314}
s32 au_fx_param_hdl(AuFX *fx, s16 index, s16 paramID, s32 value)
Definition reverb.c:416

◆ au_pvoice_set_bus()

void au_pvoice_set_bus ( u8 voiceIdx,
s8 busID )

Definition at line 316 of file syn_driver.c.

316 {
318
319 pvoice->busID = busID;
320}
u8 busID
Definition audio.h:628

Referenced by au_engine_init().

◆ au_syn_stop_voice()

void au_syn_stop_voice ( u8 voiceIdx)

Definition at line 323 of file syn_driver.c.

323 {
325 AuLoadFilter* decoder = &pvoice->decoder;
326
327 pvoice->envMixer.motion = AL_STOPPED;
328 pvoice->envMixer.dirty = TRUE;
329 pvoice->envMixer.volume = 1;
330 pvoice->resampler.delta = 0;
331 pvoice->resampler.first = 1;
332 decoder->lastsam = 0;
333 decoder->first = TRUE;
334 decoder->sample = 0;
335 if (decoder->instrument != NULL) {
336 decoder->memin = (s32)decoder->instrument->wavData;
337 if (decoder->instrument->type == AL_ADPCM_WAVE) {
338 if (decoder->instrument->loopEnd != 0){
339 decoder->loop.count = decoder->instrument->loopCount;
340 }
341 } else if (decoder->instrument->type == AL_RAW16_WAVE) {
342 if (decoder->instrument->loopEnd != 0){
343 decoder->loop.count = decoder->instrument->loopCount;
344 }
345 }
346 }
347}
s32 loopEnd
Definition audio.h:679
s32 loopCount
Definition audio.h:680
s32 lastsam
Definition audio.h:586
struct Instrument * instrument
Definition audio.h:581
ALRawLoop loop
Definition audio.h:580
s32 memin
Definition audio.h:588
u8 type
Definition audio.h:688
s32 first
Definition audio.h:587
s32 sample
Definition audio.h:585

Referenced by au_flush_finished_voices(), and au_syn_begin_audio_frame().

◆ au_syn_start_voice()

void au_syn_start_voice ( u8 index)

Definition at line 350 of file syn_driver.c.

350 {
352
353 pvoice->envMixer.motion = AL_PLAYING;
354}

◆ au_syn_start_voice_params()

void au_syn_start_voice_params ( u8 index,
u8 reverbType,
Instrument * table,
f32 pitch,
s16 vol,
u8 pan,
u8 fxMix,
s32 delta )

Definition at line 357 of file syn_driver.c.

357 {
359 AuLoadFilter* decoder = &pvoice->decoder;
360 AuEnvMixer* envMixer = &pvoice->envMixer;
361 AuResampler* resampler = &pvoice->resampler;
362
363 pvoice->busID = busID;
364 decoder->instrument = instrument;
365
366 pvoice->decoder.memin = (s32)decoder->instrument->wavData;
367 pvoice->decoder.sample = 0;
368
369 switch (decoder->instrument->type) {
370 case AL_ADPCM_WAVE:
371 decoder->instrument->wavDataLength = (decoder->instrument->wavDataLength / ADPCMFBYTES) * ADPCMFBYTES;
372 pvoice->decoder.bookSize = decoder->instrument->codebookSize;
373 if (decoder->instrument->loopEnd != 0) {
374 decoder->loop.start = decoder->instrument->loopStart;
375 decoder->loop.end = decoder->instrument->loopEnd;
376 decoder->loop.count = decoder->instrument->loopCount;
377 alCopy(decoder->instrument->loopState, decoder->lstate, sizeof(ADPCM_STATE));
378 } else {
379 decoder->loop.count = 0;
380 decoder->loop.end = 0;
381 decoder->loop.start = 0;
382 }
383 break;
384 case AL_RAW16_WAVE:
385 if (decoder->instrument->loopEnd != 0) {
386 decoder->loop.start = decoder->instrument->loopStart;
387 decoder->loop.end = decoder->instrument->loopEnd;
388 decoder->loop.count = decoder->instrument->loopCount;
389 } else {
390 decoder->loop.count = 0;
391 decoder->loop.end = 0;
392 decoder->loop.start = 0;
393 }
394 break;
395 }
396
397 envMixer->motion = AL_PLAYING;
398 envMixer->dirty = TRUE;
399 envMixer->delta = 0;
400 envMixer->segEnd = delta;
401 envMixer->pan = pan;
402 envMixer->volume = SQ(vol) >> 0xF;
403 envMixer->dryamt = AuEqPower[fxMix];
404 envMixer->wetamt = AuEqPower[AU_EQPOW_MAX_IDX - fxMix];
405 if (envMixer->segEnd != 0) {
406 envMixer->cvolL = 1;
407 envMixer->cvolR = 1;
408 } else {
409 if (!AuSynUseStereo) {
410 envMixer->cvolL = (envMixer->volume * AuEqPower[AU_EQPOW_MID_IDX]) >> 0xF;
411 envMixer->cvolR = (envMixer->volume * AuEqPower[AU_EQPOW_MID_IDX]) >> 0xF;
412 } else {
413 envMixer->cvolL = (envMixer->volume * AuEqPower[envMixer->pan]) >> 0xF;
414 envMixer->cvolR = (envMixer->volume * AuEqPower[AU_EQPOW_MAX_IDX - envMixer->pan]) >> 0xF;
415 }
416 }
417 resampler->ratio = pitchRatio;
418}
#define ADPCMFBYTES
Definition audio.h:57
#define SQ(x)
Definition macros.h:178
#define AU_EQPOW_MID_IDX
Definition syn_driver.c:22
#define AU_EQPOW_MAX_IDX
Definition syn_driver.c:23
void alCopy(void *src, void *dst, s32 size)
Definition syn_driver.c:777
s16 AuEqPower[128]
Definition pull_voice.c:10

Referenced by au_syn_begin_audio_frame().

◆ au_syn_set_wavetable()

void au_syn_set_wavetable ( u8 voiceIdx,
Instrument * table )

Definition at line 420 of file syn_driver.c.

420 {
422 AuLoadFilter* decoder = &pvoice->decoder;
423
424 pvoice->decoder.instrument = instrument;
425 pvoice->decoder.memin = (s32)decoder->instrument->wavData;
426 pvoice->decoder.sample = 0;
427
428 switch (decoder->instrument->type) {
429 case AL_ADPCM_WAVE:
430 decoder->instrument->wavDataLength = (decoder->instrument->wavDataLength / ADPCMFBYTES) * ADPCMFBYTES;
431 pvoice->decoder.bookSize = decoder->instrument->codebookSize;
432 if (decoder->instrument->loopEnd != 0) {
433 pvoice->decoder.loop.start = decoder->instrument->loopStart;
434 pvoice->decoder.loop.end = decoder->instrument->loopEnd;
435 pvoice->decoder.loop.count = decoder->instrument->loopCount;
436 alCopy(decoder->instrument->loopState, pvoice->decoder.lstate, sizeof(ADPCM_STATE));
437 } else {
438 pvoice->decoder.loop.count = 0;
439 pvoice->decoder.loop.end = 0;
440 pvoice->decoder.loop.start = 0;
441 }
442 break;
443 case AL_RAW16_WAVE:
444 if (decoder->instrument->loopEnd != 0) {
445 pvoice->decoder.loop.start = decoder->instrument->loopStart;
446 pvoice->decoder.loop.end = decoder->instrument->loopEnd;
447 pvoice->decoder.loop.count = decoder->instrument->loopCount;
448 } else {
449 pvoice->decoder.loop.count = 0;
450 pvoice->decoder.loop.end = 0;
451 pvoice->decoder.loop.start = 0;
452 }
453 break;
454 }
455}

Referenced by au_engine_init().

◆ au_syn_set_pitch()

void au_syn_set_pitch ( u8 voiceIdx,
f32 pitchRatio )

Definition at line 458 of file syn_driver.c.

458 {
460
461 pvoice->resampler.ratio = pitch;
462}
f32 ratio
Definition audio.h:594
AuResampler resampler
Definition audio.h:624

Referenced by au_syn_begin_audio_frame().

◆ au_syn_set_mixer_params()

void au_syn_set_mixer_params ( u8 voiceIdx,
s16 volume,
s32 arg2,
u8 arg3,
u8 arg4 )

Definition at line 464 of file syn_driver.c.

464 {
466 AuEnvMixer* envMixer = &pvoice->envMixer;
467
468 if (envMixer->delta >= envMixer->segEnd) {
469 envMixer->delta = envMixer->segEnd;
470 if (!AuSynUseStereo) {
471 envMixer->cvolL = (envMixer->volume * AuEqPower[AU_EQPOW_MID_IDX]) >> 0xF;
472 envMixer->cvolR = (envMixer->volume * AuEqPower[AU_EQPOW_MID_IDX]) >> 0xF;
473 } else {
474 envMixer->cvolL = (envMixer->volume * AuEqPower[envMixer->pan]) >> 0xF;
475 envMixer->cvolR = (envMixer->volume * AuEqPower[AU_EQPOW_MAX_IDX - envMixer->pan]) >> 0xF;
476 }
477 } else {
478 envMixer->cvolL = _getVol(envMixer->cvolL, envMixer->delta, envMixer->lratm, envMixer->lratl);
479 envMixer->cvolR = _getVol(envMixer->cvolR, envMixer->delta, envMixer->rratm, envMixer->rratl);
480 }
481 if (envMixer->cvolL == 0) {
482 envMixer->cvolL = 1;
483 }
484 if (envMixer->cvolR == 0) {
485 envMixer->cvolR = 1;
486 }
487
488 envMixer->delta = 0;
489 envMixer->segEnd = delta;
490 envMixer->pan = pan;
491 envMixer->volume = SQ(volume) >> 0xF;
492 envMixer->dryamt = AuEqPower[fxMix];
493 envMixer->wetamt = AuEqPower[AU_EQPOW_MAX_IDX - fxMix];
494 envMixer->dirty = TRUE;
495}
s16 dryamt
Definition audio.h:606
s16 wetamt
Definition audio.h:607
s32 segEnd
Definition audio.h:615
s16 cvolR
Definition audio.h:605
s16 lratm
Definition audio.h:609
s16 rratm
Definition audio.h:612
s16 volume
Definition audio.h:603
s16 pan
Definition audio.h:602
s32 delta
Definition audio.h:614
s16 cvolL
Definition audio.h:604
s16 rratl
Definition audio.h:611
s16 lratl
Definition audio.h:608
b32 dirty
Definition audio.h:616

Referenced by au_syn_begin_audio_frame().

◆ au_syn_set_pan_fxmix()

void au_syn_set_pan_fxmix ( u8 voiceIdx,
u8 arg1,
u8 arg2 )

Definition at line 497 of file syn_driver.c.

497 {
499 AuEnvMixer* envMixer = &pvoice->envMixer;
500
501 if (envMixer->delta >= envMixer->segEnd) {
502 envMixer->delta = envMixer->segEnd;
503 if (!AuSynUseStereo) {
504 envMixer->cvolL = (envMixer->volume * AuEqPower[AU_EQPOW_MID_IDX]) >> 0xF;
505 envMixer->cvolR = (envMixer->volume * AuEqPower[AU_EQPOW_MID_IDX]) >> 0xF;
506 } else {
507 envMixer->cvolL = (envMixer->volume * AuEqPower[envMixer->pan]) >> 0xF;
508 envMixer->cvolR = (envMixer->volume * AuEqPower[AU_EQPOW_MAX_IDX - envMixer->pan]) >> 0xF;
509 }
510 } else {
511 envMixer->cvolL = _getVol(envMixer->cvolL, envMixer->delta, envMixer->lratm, envMixer->lratl);
512 envMixer->cvolR = _getVol(envMixer->cvolR, envMixer->delta, envMixer->rratm, envMixer->rratl);
513 }
514 if (envMixer->cvolL == 0) {
515 envMixer->cvolL = 1;
516 }
517 if (envMixer->cvolR == 0) {
518 envMixer->cvolR = 1;
519 }
520
521 envMixer->pan = pan;
522 envMixer->dryamt = AuEqPower[fxMix];
523 envMixer->wetamt = AuEqPower[AU_EQPOW_MAX_IDX - fxMix];
524 envMixer->dirty = TRUE;
525}

Referenced by au_syn_begin_audio_frame().

◆ au_syn_set_volume_delta()

void au_syn_set_volume_delta ( u8 voiceIdx,
s16 arg1,
s32 arg2 )

Definition at line 527 of file syn_driver.c.

527 {
529 AuEnvMixer* envMixer = &pvoice->envMixer;
530
531 if (envMixer->delta >= envMixer->segEnd) {
532 envMixer->delta = envMixer->segEnd;
533 if (!AuSynUseStereo) {
534 envMixer->cvolL = (envMixer->volume * AuEqPower[AU_EQPOW_MID_IDX]) >> 0xF;
535 envMixer->cvolR = (envMixer->volume * AuEqPower[AU_EQPOW_MID_IDX]) >> 0xF;
536 } else {
537 envMixer->cvolL = (envMixer->volume * AuEqPower[envMixer->pan]) >> 0xF;
538 envMixer->cvolR = (envMixer->volume * AuEqPower[AU_EQPOW_MAX_IDX - envMixer->pan]) >> 0xF;
539 }
540 } else {
541 envMixer->cvolL = _getVol(envMixer->cvolL, envMixer->delta, envMixer->lratm, envMixer->lratl);
542 envMixer->cvolR = _getVol(envMixer->cvolR, envMixer->delta, envMixer->rratm, envMixer->rratl);
543 }
544 if (envMixer->cvolL == 0) {
545 envMixer->cvolL = 1;
546 }
547 if (envMixer->cvolR == 0) {
548 envMixer->cvolR = 1;
549 }
550
551 envMixer->volume = SQ(vol) >> 0xF;
552 envMixer->delta = 0;
553 envMixer->segEnd = delta;
554 envMixer->dirty = TRUE;
555}

Referenced by au_reset_nonfree_voice(), and au_reset_voice().

◆ au_syn_set_pan()

void au_syn_set_pan ( u8 voiceIdx,
u8 pan )

Definition at line 557 of file syn_driver.c.

557 {
559 AuEnvMixer* envMixer = &pvoice->envMixer;
560
561 if (envMixer->delta >= envMixer->segEnd) {
562 envMixer->delta = envMixer->segEnd;
563 if (!AuSynUseStereo) {
564 envMixer->cvolL = (envMixer->volume * AuEqPower[AU_EQPOW_MID_IDX]) >> 0xF;
565 envMixer->cvolR = (envMixer->volume * AuEqPower[AU_EQPOW_MID_IDX]) >> 0xF;
566 } else {
567 envMixer->cvolL = (envMixer->volume * AuEqPower[envMixer->pan]) >> 0xF;
568 envMixer->cvolR = (envMixer->volume * AuEqPower[AU_EQPOW_MAX_IDX - envMixer->pan]) >> 0xF;
569 }
570 } else {
571 envMixer->cvolL = _getVol(envMixer->cvolL, envMixer->delta, envMixer->lratm, envMixer->lratl);
572 envMixer->cvolR = _getVol(envMixer->cvolR, envMixer->delta, envMixer->rratm, envMixer->rratl);
573 }
574 if (envMixer->cvolL == 0) {
575 envMixer->cvolL = 1;
576 }
577 if (envMixer->cvolR == 0) {
578 envMixer->cvolR = 1;
579 }
580
581 envMixer->pan = pan;
582 envMixer->dirty = TRUE;
583}

Referenced by alAudioFrame().

◆ au_syn_set_fxmix()

void au_syn_set_fxmix ( u8 voiceIdx,
u8 dryAmt )

Definition at line 585 of file syn_driver.c.

585 {
587 AuEnvMixer* envMixer = &pvoice->envMixer;
588
589 if (envMixer->delta >= envMixer->segEnd) {
590 envMixer->delta = envMixer->segEnd;
591 if (!AuSynUseStereo) {
592 envMixer->cvolL = (envMixer->volume * AuEqPower[AU_EQPOW_MID_IDX]) >> 0xF;
593 envMixer->cvolR = (envMixer->volume * AuEqPower[AU_EQPOW_MID_IDX]) >> 0xF;
594 } else {
595 envMixer->cvolL = (envMixer->volume * AuEqPower[envMixer->pan]) >> 0xF;
596 envMixer->cvolR = (envMixer->volume * AuEqPower[AU_EQPOW_MAX_IDX - envMixer->pan]) >> 0xF;
597 }
598 } else {
599 envMixer->cvolL = _getVol(envMixer->cvolL, envMixer->delta, envMixer->lratm, envMixer->lratl);
600 envMixer->cvolR = _getVol(envMixer->cvolR, envMixer->delta, envMixer->rratm, envMixer->rratl);
601 }
602 if (envMixer->cvolL == 0) {
603 envMixer->cvolL = 1;
604 }
605 if (envMixer->cvolR == 0) {
606 envMixer->cvolR = 1;
607 }
608
609 envMixer->dryamt = AuEqPower[fxMix];
610 envMixer->wetamt = AuEqPower[AU_EQPOW_MAX_IDX - fxMix];
611 envMixer->dirty = TRUE;
612}

◆ au_syn_get_playing()

s32 au_syn_get_playing ( u8 voiceIdx)

Definition at line 614 of file syn_driver.c.

614 {
616
617 return pvoice->envMixer.motion;
618}
s32 motion
Definition audio.h:617
AuEnvMixer envMixer
Definition audio.h:625

◆ au_syn_get_bus()

s32 au_syn_get_bus ( u8 voiceIdx)

Definition at line 620 of file syn_driver.c.

620 {
622
623 return pvoice->busID;
624}

◆ au_syn_get_pitch()

f32 au_syn_get_pitch ( u8 voiceIdx)

Definition at line 626 of file syn_driver.c.

626 {
628
629 return pvoice->resampler.ratio;
630}

◆ au_syn_get_pan()

u8 au_syn_get_pan ( u8 voiceIdx)

Definition at line 632 of file syn_driver.c.

632 {
634
635 return pvoice->envMixer.pan;
636}

◆ au_syn_get_dryamt()

s16 au_syn_get_dryamt ( u8 voiceIdx)

Definition at line 638 of file syn_driver.c.

638 {
640
641 return pvoice->envMixer.dryamt;
642}

◆ au_syn_get_wetamt()

s16 au_syn_get_wetamt ( u8 voiceIdx)

Definition at line 644 of file syn_driver.c.

644 {
646
647 return pvoice->envMixer.wetamt;
648}

◆ au_syn_get_volume_left()

s32 au_syn_get_volume_left ( u8 voiceIdx)

Definition at line 650 of file syn_driver.c.

650 {
652 AuEnvMixer* envmixer = &pvoice->envMixer;
653 u32 retVal;
654
655 if (envmixer->delta >= envmixer->segEnd) {
656 if (!AuSynUseStereo) {
657 retVal = (envmixer->volume * AuEqPower[AU_EQPOW_MID_IDX] * 2) >> 0x10;
658 } else {
659 retVal = (envmixer->volume * AuEqPower[envmixer->pan] * 2) >> 0x10;
660 }
661 } else {
662 retVal = _getVol(envmixer->cvolL, envmixer->delta, envmixer->lratm, envmixer->lratl);
663 }
664 return retVal;
665}

◆ au_syn_get_volume_right()

s32 au_syn_get_volume_right ( u8 voiceIdx)

Definition at line 667 of file syn_driver.c.

667 {
669 AuEnvMixer* envmixer = &pvoice->envMixer;
670 u32 retVal;
671
672 if (envmixer->delta >= envmixer->segEnd) {
673 if (!AuSynUseStereo) {
674 retVal = (envmixer->volume * AuEqPower[AU_EQPOW_MID_IDX] * 2) >> 0x10;
675 } else {
676 retVal = (envmixer->volume * AuEqPower[AU_EQPOW_MAX_IDX - envmixer->pan] * 2) >> 0x10;
677 }
678 } else {
679 retVal = _getVol(envmixer->cvolL, envmixer->delta, envmixer->lratm, envmixer->lratl);
680 }
681 return retVal;
682}

◆ au_set_delay_time()

void au_set_delay_time ( s32 arg0)

Definition at line 684 of file syn_driver.c.

684 {
685 if (numFrames < 2) {
686 AuDelayCount = 0;
688 }
689
691 if (numFrames > 4) {
692 AuDelayCount = 4;
693 }
694}

Referenced by au_syn_begin_audio_frame().

◆ au_delay_left_channel()

void au_delay_left_channel ( u8 arg0)

Definition at line 696 of file syn_driver.c.

696 {
699 s32 i;
700
701 for (i = 0; i < 2 * AUDIO_SAMPLES; i++) {
702 *mainBuf++ = 0;
703 *auxBuf++ = 0;
704 }
705
706 AuDelayedBusID = busID;
708 AuDelayCounter = 0;
709}
BSS s32 AuDelayCounter
Definition syn_driver.c:9

Referenced by au_syn_begin_audio_frame().

◆ au_delay_right_channel()

void au_delay_right_channel ( u8 arg0)

Definition at line 711 of file syn_driver.c.

711 {
714 s32 i;
715
716 for (i = 0; i < 2 * AUDIO_SAMPLES; i++) {
717 *mainBuf++ = 0;
718 *auxBuf++ = 0;
719 }
720
721 AuDelayedBusID = busID;
723 AuDelayCounter = 0;
724}

Referenced by au_syn_begin_audio_frame().

◆ au_disable_channel_delay()

void au_disable_channel_delay ( void )

Definition at line 726 of file syn_driver.c.

Referenced by au_syn_begin_audio_frame().

◆ au_init_delay_channel()

void au_init_delay_channel ( s16 arg0)

Definition at line 732 of file syn_driver.c.

732 {
735 s32 i;
736
737 for (i = 0; i < 2 * AUDIO_SAMPLES; i++) {
738 *mainBuf++ = 0;
739 *auxBuf++ = 0;
740 }
741
742 AuDelayedBusID = 0;
744 AuDelayCounter = 0;
745}

Referenced by au_engine_init().

◆ alHeapAlloc()

void * alHeapAlloc ( ALHeap * heap,
s32 count,
s32 size )

Definition at line 765 of file syn_driver.c.

765 {
766 void* ret = NULL;
767 u8* newCur = &heap->cur[ALIGN16(count * size)];
768
769 if (&heap->base[heap->len] >= newCur) {
770 ret = heap->cur;
771 heap->cur = newCur;
772 }
773
774 return ret;
775}
#define ALIGN16(val)
Definition macros.h:20

Referenced by au_driver_init(), au_engine_init(), au_filter_create(), au_fx_create(), au_load_BK_to_bank(), au_load_INIT(), au_load_static_BK_to_bank(), and create_audio_system().

◆ au_flush_finished_voices()

void au_flush_finished_voices ( AuGlobals * globals)

(UNUSED) Immediately flush all voices which have finished playing.

These are normally released automatically during the start of each audio frame.

Definition at line 4 of file voice.c.

4 {
5 s32 i;
6
7 for (i = 0; i < ARRAY_COUNT(globals->voices); i++) {
8 AuVoice* voice = &globals->voices[i];
9
10 if (voice->donePending) {
12 voice->donePending = FALSE;
13 voice->cmdPtr = NULL;
14 voice->priority = AU_PRIORITY_FREE;
15 }
16 }
17}

◆ au_init_voices()

void au_init_voices ( AuGlobals * globals)

Initializes all voices in the audio system.

Sets default values and clears previous envelope state.

Definition at line 19 of file voice.c.

19 {
20 s32 i;
21
22 for (i = 0; i < ARRAY_COUNT(globals->voices); i++) {
23 AuVoice* voice = &globals->voices[i];
24
25 voice->cmdPtr = NULL;
26 voice->unused_20 = 0;
27 voice->envDuration = 0;
28 voice->envTimeLeft = 0;
29 voice->envIntervalIndex = 0;
30 voice->unused_3C = 0;
31 voice->envelopeFlags = 0;
32 voice->isRelativeRelease = FALSE;
33 voice->envRelativeStart = ENV_VOL_MAX;
34 }
35}
#define ENV_VOL_MAX
Definition audio.h:116

Referenced by au_engine_init().

◆ au_update_voices()

void au_update_voices ( AuGlobals * globals)

Main envelope system update, called once per frame.

Progresses envelope state for all active voices.

Definition at line 37 of file voice.c.

37 {
39 s16 current;
40 s8 temp;
41 s32 i;
42
43 for (i = 0; i < ARRAY_COUNT(globals->voices); i++) {
44 voice = &globals->voices[i];
45
46 // skip inactive voices
47 if (voice->cmdPtr == NULL) {
48 continue;
49 }
50
51 if (voice->envelopeFlags & AU_VOICE_ENV_FLAG_HANDLED_VOL_CHANGE) {
52 // client volume changed on previous frame
54 continue;
55 }
56
57 if (voice->envelopeFlags & AU_VOICE_ENV_FLAG_KEY_RELEASED) {
58 // client released the key
59 voice->envelopeFlags &= ~AU_VOICE_ENV_FLAG_KEY_RELEASED;
60 voice->envelopeFlags |= AU_VOICE_ENV_FLAG_RELEASING;
61 voice->cmdPtr = (u8*)voice->envelope.cmdListRelease;
62
63 // the key can be released before the press envelope is complete
64 if (voice->envTimeLeft > AU_FRAME_USEC) {
65 // get interpolated "current" value
66 voice->envInitial += (s32) (voice->envDelta * (f32) (voice->envDuration - voice->envTimeLeft));
67 } else {
68 voice->envInitial = voice->envTarget;
69 }
70
71 // read the first interval of the release envelope
72 voice->envIntervalIndex = *voice->cmdPtr++;
73 temp = *voice->cmdPtr;
74 if (*(s8*)voice->cmdPtr++ < 0) {
75 // in this case release volumes are relative to last press volume
76 temp &= 0x7F;
77 voice->isRelativeRelease = TRUE;
78 voice->envRelativeStart = voice->envInitial;
79 }
80 voice->envTarget = temp;
81 voice->envTimeLeft = AuEnvelopeIntervals[voice->envIntervalIndex];
82 voice->envDuration = voice->envTimeLeft;
83
84 if (voice->envelopeFlags & AU_VOICE_ENV_FLAG_VOL_CHANGED) {
85 voice->envelopeFlags &= ~AU_VOICE_ENV_FLAG_VOL_CHANGED;
86 if (voice->envTimeLeft > AU_FRAME_USEC) {
87 voice->envTimeLeft -= AU_FRAME_USEC;
89 current = voice->envInitial + (s32) (voice->envDelta * (voice->envDuration - voice->envTimeLeft));
90 } else {
91 current = voice->envTarget;
92 }
93 voice->delta = AUDIO_SAMPLES;
94 } else {
95 voice->delta = au_voice_get_delta(voice->envDuration);
96 current = voice->envTarget;
97 }
98 voice->volume = VOL_MULT_4(current, voice->clientVolume, voice->envRelativeStart, voice->envScale);
99 voice->syncFlags |= AU_VOICE_SYNC_FLAG_PARAMS;
100 } else {
101 if (voice->envTimeLeft == -1) {
102 // keep current volume, this is 'sustain' phase
103 if (voice->envelopeFlags & AU_VOICE_ENV_FLAG_VOL_CHANGED) {
104 voice->envelopeFlags &= ~AU_VOICE_ENV_FLAG_VOL_CHANGED;
105 voice->volume = VOL_MULT_4(voice->envInitial, voice->clientVolume, voice->envRelativeStart, voice->envScale);
106 voice->syncFlags |= AU_VOICE_SYNC_FLAG_PARAMS;
107 }
108 } else {
109 voice->envTimeLeft -= AU_FRAME_USEC;
110 if (voice->envTimeLeft <= 0) {
111 if (*voice->cmdPtr == ENV_CMD_END) {
112 if (voice->envelopeFlags & AU_VOICE_ENV_FLAG_RELEASING) {
113 // if we reached the end after key release, stop the voice completely
114 voice->envelopeFlags = 0;
115 voice->cmdPtr = NULL;
116 voice->donePending = TRUE;
117 } else {
118 // we reached the end of press cmdlist, keep the last volume until the key is released
119 voice->envTimeLeft = -1;
120 voice->envDuration = -1;
121 voice->envIntervalIndex = ENV_TIME_300MS; // doesn't seem to affect anything
122 voice->delta = AUDIO_SAMPLES;
123 voice->envDelta = 0.0f;
124 voice->envInitial = voice->envTarget;
125 }
126 } else {
127 // get next envelope point
128 voice->envIntervalIndex = au_voice_step(voice);
129 voice->envInitial = voice->envTarget;
130 voice->envTarget = (*voice->cmdPtr++) & 0x7F;
131 voice->envTimeLeft = AuEnvelopeIntervals[voice->envIntervalIndex];
132 voice->envDuration = voice->envTimeLeft;
133 if (voice->envDuration != 0) {
134 voice->envDelta = ((f32) voice->envTarget - (f32) voice->envInitial) / (f32) voice->envDuration;
135 } else {
136 voice->envDelta = 0.0f;
137 }
138 if (voice->envelopeFlags & AU_VOICE_ENV_FLAG_VOL_CHANGED) {
139 voice->envelopeFlags &= ~AU_VOICE_ENV_FLAG_VOL_CHANGED;
140 if (voice->envTimeLeft > AU_FRAME_USEC) {
141 voice->envTimeLeft -= AU_FRAME_USEC;
143 current = voice->envInitial + (s32) (voice->envDelta * (voice->envDuration - voice->envTimeLeft));
144 } else {
145 current = voice->envTarget;
146 }
147 voice->delta = AUDIO_SAMPLES;
148 } else {
149 voice->delta = au_voice_get_delta(voice->envDuration);
150 current = voice->envTarget;
151 }
152 voice->volume = VOL_MULT_4(current, voice->clientVolume, voice->envRelativeStart, voice->envScale);
153 voice->syncFlags |= AU_VOICE_SYNC_FLAG_PARAMS;
154 }
155 } else {
156 // we are between two envelope points, do nothing, just handle client volume change
157 if (voice->envelopeFlags & AU_VOICE_ENV_FLAG_VOL_CHANGED) {
158 voice->envelopeFlags &= ~AU_VOICE_ENV_FLAG_VOL_CHANGED;
159 if (voice->envTimeLeft > AU_FRAME_USEC) {
160 voice->envTimeLeft -= AU_FRAME_USEC;
162 current = voice->envInitial + (s32) (voice->envDelta * (voice->envDuration - voice->envTimeLeft));
163 } else {
164 current = voice->envTarget;
165 }
166 voice->delta = AUDIO_SAMPLES;
167 voice->volume = VOL_MULT_4(current, voice->clientVolume, voice->envRelativeStart, voice->envScale);
168 voice->syncFlags |= AU_VOICE_SYNC_FLAG_PARAMS;
169 }
170 }
171 }
172 }
173 }
174}
#define VOL_MULT_4(a, b, c, d)
Definition audio.h:128
@ ENV_CMD_END
Definition audio.h:257
s32 AuEnvelopeIntervals[]
Definition sfx_player.c:359
@ AU_VOICE_ENV_FLAG_KEY_RELEASED
Definition audio.h:143
@ AU_VOICE_ENV_FLAG_RELEASING
Definition audio.h:141
@ AU_VOICE_ENV_FLAG_VOL_CHANGED
Definition audio.h:144
@ AU_VOICE_ENV_FLAG_HANDLED_VOL_CHANGE
Definition audio.h:142
@ ENV_TIME_300MS
Definition audio.h:320
void au_voice_after_volume_change(AuVoice *voice)
Applies volume update after a client-side volume change.
Definition voice.c:176
s32 au_voice_get_delta(s32 usecs)
Converts envelope step duration from microseconds to num samples delta.
Definition voice.c:183
u8 au_voice_step(AuVoice *voice)
Parses and executes envelope commands until a time interval is found.
Definition voice.c:215

Referenced by au_update_clients_for_audio_frame().

◆ au_voice_after_volume_change()

void au_voice_after_volume_change ( AuVoice * voice)

Applies volume update after a client-side volume change.

This is deferred to avoid modifying envelope state mid-step.

Definition at line 176 of file voice.c.

176 {
177 voice->volume = VOL_MULT_4(voice->envTarget, voice->clientVolume, voice->envRelativeStart, voice->envScale);
178 voice->delta = au_voice_get_delta(voice->envTimeLeft);
180 voice->syncFlags |= AU_VOICE_SYNC_FLAG_PARAMS;
181}

Referenced by au_update_voices().

◆ au_voice_get_delta()

s32 au_voice_get_delta ( s32 usecs)

Converts envelope step duration from microseconds to num samples delta.

Uses AU_FRAME_USEC as the base time slice, returning the number of audio samples corresponding to the provided duration.

Parameters
msecsTime duration in microseconds.
Returns
Number of samples that should pass in this interval.

Definition at line 183 of file voice.c.

183 {
184 return (usecs / AU_FRAME_USEC) * AUDIO_SAMPLES;
185}

Referenced by au_update_voices(), au_voice_after_volume_change(), and au_voice_start().

◆ au_voice_start()

void au_voice_start ( AuVoice * voice,
EnvelopeData * envData )

Starts a new voice with the given envelope data.

Initializes envelope state and prepares the press phase for playback.

Parameters
voicePointer to the voice being started.
envDataEnvelope command lists (press and release) to use.

Definition at line 187 of file voice.c.

187 {
189
190 voice->envelope.cmdListPress = envData->cmdListPress;
191 voice->cmdPtr = voice->envelope.cmdListPress;
192 voice->envelope.cmdListRelease = envData->cmdListRelease;
193 voice->envScale = ENV_VOL_MAX;
194 voice->loopStart = NULL;
195
197 voice->envelopeFlags = 0;
198 voice->envInitial = 0;
199 voice->envTarget = *voice->cmdPtr++;
200 voice->envIntervalIndex = intervalIndex;
202 voice->envTimeLeft = voice->envDuration;
203
204 voice->volume = VOL_MULT_3(voice->envTarget, voice->clientVolume, voice->envScale);
205 voice->delta = au_voice_get_delta(voice->envDuration);
206 if (voice->envDuration != 0) {
207 voice->envDelta = ((f32) voice->envTarget - (f32) voice->envInitial) / voice->envDuration;
208 } else {
209 voice->envDelta = 0.0f;
210 }
211 voice->isRelativeRelease = FALSE;
212 voice->envRelativeStart = ENV_VOL_MAX;
213}
#define VOL_MULT_3(a, b, c)
Definition audio.h:125

Referenced by au_syn_begin_audio_frame().

◆ au_voice_step()

u8 au_voice_step ( AuVoice * voice)

Parses and executes envelope commands until a time interval is found.

Commands include setting multipliers, loop control, etc.

Definition at line 215 of file voice.c.

215 {
216 u32 op;
217 u8 arg;
218
219 while (TRUE) {
220 if ((s8)(op = *voice->cmdPtr++) >= 0) {
221 break;
222 }
223 switch ((u8)op) {
225 arg = *voice->cmdPtr++;
226 if (arg > ENV_VOL_MAX) {
228 }
229 voice->envScale = arg;
230 break;
232 voice->envScale += (s8) *voice->cmdPtr++;
233 if (voice->envScale > ENV_VOL_MAX) {
234 voice->envScale = ENV_VOL_MAX;
235 } else if (voice->envScale < 0) {
236 voice->envScale = 0;
237 }
238 break;
240 voice->loopCounter = *voice->cmdPtr++; // 0 = infinite loop
241 voice->loopStart = voice->cmdPtr;
242 break;
243 case ENV_CMD_END_LOOP:
244 voice->cmdPtr++;
245 if (voice->loopCounter == 0 || --voice->loopCounter != 0) {
246 voice->cmdPtr = voice->loopStart;
247 }
248 break;
249 default:
250 // unknown command, skip argument
251 voice->cmdPtr++;
252 break;
253 }
254 }
255 return op;
256}
@ ENV_CMD_ADD_SCALE
Definition audio.h:255
@ ENV_CMD_SET_SCALE
Definition audio.h:256
@ ENV_CMD_START_LOOP
Definition audio.h:254
@ ENV_CMD_END_LOOP
Definition audio.h:253

Referenced by au_update_voices(), and au_voice_start().

◆ au_voice_set_vol_changed()

void au_voice_set_vol_changed ( AuVoice * voice)

(UNUSED) Force recalculation of voice envelope volume during next update.

Definition at line 258 of file voice.c.

258 {
259 voice->envelopeFlags |= AU_VOICE_ENV_FLAG_VOL_CHANGED;
260}

◆ au_pull_voice()

Acmd * au_pull_voice ( AuPVoice * pvoice,
Acmd * cmdBufPos )

Definition at line 33 of file pull_voice.c.

33 {
34 Acmd* ptr = cmdBufPos;
35 AuLoadFilter* decoder;
36 AuResampler* resampler;
37 AuEnvMixer* envMixer;
38 s16 inp;
40 s16 outp;
43 s32 incr;
44
45 envMixer = &pvoice->envMixer;
46 resampler = &pvoice->resampler;
47 decoder = &pvoice->decoder;
48
49 // return if voice is not playing
50 if (envMixer->motion != AL_PLAYING) {
51 return ptr;
52 }
53
54 // buffer to store decoded (or raw) samples before mixing
56
57 if (resampler->ratio > MAX_RATIO) {
58 resampler->ratio = MAX_RATIO;
59 }
60
61 // convert pitch ratio to fixed-point resampling increment
62 resampler->ratio = (s32)(resampler->ratio * UNITY_PITCH);
63 resampler->ratio = resampler->ratio / UNITY_PITCH;
64
65 // determine how many output samples are needed for this frame
66 finCount = resampler->delta + resampler->ratio * (f32)AUDIO_SAMPLES;
68 resampler->delta = finCount - (f32) outCount;
69
70 if (outCount != 0) {
71 if (decoder->instrument->type == AL_ADPCM_WAVE) {
72 s32 nSam;
73 s32 nbytes;
75 s32 op;
76 s32 tsam;
77 s32 nLeft;
78 s32 bEnd;
79 s32 nOver;
84
85 // load ADPCM predictor
86 aLoadADPCM(ptr++, decoder->bookSize, K0_TO_PHYS(decoder->instrument->predictor));
87
88 // will loop be triggered during this frame? if so, only process up to loop end
89 looped = (decoder->loop.end < outCount + decoder->sample) && (decoder->loop.count != 0);
90
91 if (looped) {
92 nSam = decoder->loop.end - decoder->sample;
93 } else {
94 nSam = outCount;
95 }
96
97 if (decoder->lastsam != 0) {
98 nLeft = ADPCMFSIZE - decoder->lastsam;
99 } else {
100 nLeft = 0;
101 }
102
103 tsam = nSam - nLeft;
104 if (tsam < 0) {
105 tsam = 0;
106 }
107
108 nframes = (tsam + ADPCMFSIZE - 1) >> LFSAMPLES;
110
111 if (looped) {
112 ptr = _decodeChunk(ptr, decoder, tsam, nbytes, outp, inp, decoder->first);
113 if (decoder->lastsam != 0) {
114 outp += (decoder->lastsam << 1);
115 } else {
116 outp += (ADPCMFSIZE << 1);
117 }
118
119 decoder->lastsam = decoder->loop.start & 0xF;
120 decoder->memin = (s32)decoder->instrument->wavData + ADPCMFBYTES * ((s32)(decoder->loop.start >> LFSAMPLES) + 1);
121 decoder->sample = decoder->loop.start;
122
123 // continue decoding looped portion if needed
124 bEnd = outp;
125 while (outCount > nSam) {
126 outCount -= nSam;
127 op = (bEnd + ((nframes + 1) << (LFSAMPLES + 1)) + 16) & ~0x1F;
128 bEnd += nSam << 1;
129 if (decoder->loop.count != -1 && decoder->loop.count != 0) {
130 decoder->loop.count--;
131 }
132 nSam = MIN(outCount, decoder->loop.end - decoder->loop.start);
133 tsam = nSam - ADPCMFSIZE + decoder->lastsam;
134 if (tsam < 0) {
135 tsam = 0;
136 }
137 nframes = (tsam + ADPCMFSIZE - 1) >> LFSAMPLES;
139 ptr = _decodeChunk(ptr, decoder, tsam, nbytes, op, inp, decoder->first | A_LOOP);
140 aDMEMMove(ptr++, op + (decoder->lastsam << 1), bEnd, nSam << 1);
141 }
142 decoder->lastsam = (outCount + decoder->lastsam) & 0xF;
143 decoder->sample += outCount;
144 decoder->memin += ADPCMFBYTES * nframes;
145 } else {
147 overFlow = decoder->memin + nbytes - ((s32)decoder->instrument->wavData + decoder->instrument->wavDataLength);
148
149 if (overFlow <= 0) {
150 overFlow = 0;
151 } else {
152 envMixer->motion = AL_STOPPED;
153 }
155 if (nOver > nSam + nLeft) {
156 nOver = nSam + nLeft;
157 }
158 nbytes -= overFlow;
159 if (nOver - (nOver & 0xF) < outCount) {
160 decoded = TRUE;
161 ptr = _decodeChunk(ptr, decoder, nSam - nOver, nbytes, outp, inp, decoder->first);
162 if (decoder->lastsam != 0) {
163 outp += decoder->lastsam << 1;
164 } else {
165 outp += ADPCMFSIZE << 1;
166 }
167 decoder->lastsam = (outCount + decoder->lastsam) & 0xF;
168 decoder->sample += outCount;
169 decoder->memin += ADPCMFBYTES * nframes;
170 } else {
171 decoder->lastsam = 0;
172 decoder->memin += ADPCMFBYTES * nframes;
173 }
174
175 if (nOver != 0) {
176 decoder->lastsam = 0;
177 if (decoded) {
178 startZero = (nLeft + nSam - nOver) << 1;
179 } else {
180 startZero = 0;
181 }
182 aClearBuffer(ptr++, startZero + outp, nOver << 1);
183 }
184 }
185 } else {
186 s32 nSam;
187 s32 nbytes;
188 s32 op;
190 s32 dramLoc;
193 if (decoder->loop.end < outCount + decoder->sample && decoder->loop.count != 0) {
194 nSam = decoder->loop.end - decoder->sample;
195 nbytes = nSam << 1;
196 if (nSam > 0) {
197 dramLoc = decoder->dmaFunc(decoder->memin, nbytes, decoder->dmaState, decoder->instrument->useDma);
198 dramAlign = dramLoc & 7;
199 nbytes += dramAlign;
200 n_aLoadBuffer(ptr++, nbytes + 8 - (nbytes & 7), outp, dramLoc - dramAlign);
201 } else {
202 dramAlign = 0;
203 }
204 outp += dramAlign;
205 decoder->memin = (s32)decoder->instrument->wavData + (decoder->loop.start << 1);
206 decoder->sample = decoder->loop.start;
207 op = outp;
208 while (outCount > nSam){
209 op += nSam << 1;
210 outCount -= nSam;
211 if (decoder->loop.count != -1 && decoder->loop.count != 0) {
212 decoder->loop.count--;
213 }
214 nSam = MIN(outCount, decoder->loop.end - decoder->loop.start);
215 nbytes = nSam << 1;
216 dramLoc = decoder->dmaFunc(decoder->memin, nbytes, decoder->dmaState, decoder->instrument->useDma);
217 dramAlign = dramLoc & 7;
218 nbytes += dramAlign;
219 if ((op & 7) != 0) {
220 dmemAlign = 8 - (op & 7);
221 } else {
222 dmemAlign = 0;
223 }
224 n_aLoadBuffer(ptr++, nbytes + 8 - (nbytes & 7), op + dmemAlign, dramLoc - dramAlign);
225
226 if (dramAlign != 0 || dmemAlign != 0) {
227 aDMEMMove(ptr++, op + dramAlign + dmemAlign, op, nSam * 2);
228 }
229 }
230 decoder->sample += outCount;
231 decoder->memin += outCount << 1;
232 } else {
233 nbytes = outCount << 1;
234 overFlow = decoder->memin + nbytes - ((s32)decoder->instrument->wavData + decoder->instrument->wavDataLength);
235 if (overFlow <= 0) {
236 overFlow = 0;
237 } else {
238 envMixer->motion = AL_STOPPED;
239 }
240 if (nbytes < overFlow) {
242 }
243 if (overFlow < nbytes) {
244 if (outCount > 0) {
245 nbytes -= overFlow;
246 dramLoc = decoder->dmaFunc(decoder->memin, nbytes, decoder->dmaState, decoder->instrument->useDma);
247 dramAlign = dramLoc & 7;
248 nbytes += dramAlign;
249 n_aLoadBuffer(ptr++, nbytes + 8 - (nbytes & 7), outp, dramLoc - dramAlign);
250 } else {
251 dramAlign = 0;
252 }
253 outp += dramAlign;
254 decoder->sample += outCount;
255 decoder->memin += outCount << 1;
256 } else {
257 decoder->memin += outCount << 1;
258 }
259
260 if (overFlow != 0) {
261 startZero = (outCount << 1) - overFlow;
262 if (startZero < 0) {
263 startZero = 0;
264 }
266 }
267 }
268 }
269 }
270
271 // resample audio from source buffer to output buffer
272 incr = (s32)(resampler->ratio * UNITY_PITCH);
273 n_aResample(ptr++, osVirtualToPhysical(resampler->state), resampler->first, incr, outp, 0);
274 resampler->first = FALSE;
275
276 // set up envelope mixing
277 if (envMixer->dirty) {
278 envMixer->dirty = FALSE;
279 if (!AuSynUseStereo) {
280 envMixer->ltgt = (envMixer->volume * AuEqPower[AUEQPOWER_LENGTH / 2]) >> 15;
281 envMixer->rtgt = (envMixer->volume * AuEqPower[AUEQPOWER_LENGTH / 2]) >> 15;
282 } else {
283 envMixer->ltgt = (envMixer->volume * AuEqPower[envMixer->pan]) >> 15;
284 envMixer->rtgt = (envMixer->volume * AuEqPower[AUEQPOWER_LENGTH - envMixer->pan - 1]) >> 15;
285 }
286 envMixer->lratm = _getRate(envMixer->cvolL, envMixer->ltgt, envMixer->segEnd, &envMixer->lratl);
287 envMixer->rratm = _getRate(envMixer->cvolR, envMixer->rtgt, envMixer->segEnd, &envMixer->rratl);
288 n_aSetVolume(ptr++, A_RATE, envMixer->ltgt, envMixer->lratm, envMixer->lratl);
289 n_aSetVolume(ptr++, A_VOL | A_LEFT, envMixer->cvolL, envMixer->dryamt, envMixer->wetamt);
290 n_aSetVolume(ptr++, A_VOL | A_RIGHT, envMixer->rtgt, envMixer->rratm, envMixer->rratl);
291 n_aEnvMixer(ptr++, A_INIT, envMixer->cvolR, osVirtualToPhysical(envMixer->state));
292 } else {
293 n_aEnvMixer(ptr++, A_CONTINUE, 0, osVirtualToPhysical(envMixer->state));
294 }
295
296 // advance envelope segment
297 envMixer->delta += AUDIO_SAMPLES;
298 if (envMixer->segEnd < envMixer->delta) {
299 envMixer->delta = envMixer->segEnd;
300 }
301
302 // if stopped, reset state
303 if (envMixer->motion == AL_STOPPED) {
304 envMixer->dirty = TRUE;
305 envMixer->volume = 1;
306 resampler->delta = 0.0f;
307 resampler->first = TRUE;
308 decoder->lastsam = 0;
309 decoder->first = 1;
310 decoder->sample = 0;
311 decoder->memin = (s32) decoder->instrument->wavData;
312 decoder->loop.count = decoder->instrument->loopCount;
313 au_release_voice(pvoice->index);
314 }
315 return ptr;
316}
f32 delta
Definition audio.h:595
#define N_AL_DECODER_OUT
Definition audio.h:32
s16 rtgt
Definition audio.h:613
s32 bookSize
Definition audio.h:582
u32 wavDataLength
Definition audio.h:676
b32 first
Definition audio.h:596
ENVMIX_STATE * state
Definition audio.h:601
ALDMAproc2 dmaFunc
Definition audio.h:583
NUDMAState * dmaState
Definition audio.h:584
#define N_AL_DECODER_IN
Definition audio.h:29
RESAMPLE_STATE * state
Definition audio.h:593
s16 ltgt
Definition audio.h:610
void au_release_voice(u8 index)
Definition engine.c:29
#define LFSAMPLES
Definition pull_voice.c:4
#define AUEQPOWER_LENGTH
Definition pull_voice.c:5
s16 AuEqPower[128]
Definition pull_voice.c:10

Referenced by alAudioFrame().

◆ au_fx_create()

void au_fx_create ( AuFX * fx,
u8 effectType,
ALHeap * heap )
Parameters
effectTypefrom enum AuEffectType

Definition at line 138 of file reverb.c.

138 {
139 AuDelay* delay;
140 u16 i;
141
142 // allocate space for 4 AuDelay
143 fx->delays = alHeapAlloc(heap, AU_FX_MAX_TAPS, sizeof(AuDelay));
144 fx->base = alHeapAlloc(heap, AU_FX_LENGTH, sizeof(s16));
145
146 for (i = 0; i < AU_FX_MAX_TAPS; i++) {
147 delay = &fx->delays[i];
148 delay->resamplerTemplate = alHeapAlloc(heap, 1, sizeof(AuResampler));
149 delay->resamplerTemplate->state = alHeapAlloc(heap, 1, sizeof(RESAMPLE_STATE));
150 delay->lowpassTemplate = alHeapAlloc(heap, 1, sizeof(AuLowPass));
151 delay->lowpassTemplate->fstate = alHeapAlloc(heap, 1, sizeof(POLEF_STATE));
152 }
153
154 au_fx_load_preset(fx, effectType);
155}
#define AU_FX_LENGTH
Definition audio.h:19
struct AuResampler * resamplerTemplate
Definition audio.h:530
POLEF_STATE * fstate
Definition audio.h:546
struct AuLowPass * lowpassTemplate
Definition audio.h:528
#define AU_FX_MAX_TAPS
Definition audio.h:18
void au_fx_load_preset(AuFX *fx, u8 effectType)
Definition reverb.c:181

Referenced by au_driver_init().

◆ au_filter_create()

void au_filter_create ( AuFilter * filter,
ALHeap * heap )

Definition at line 158 of file reverb.c.

158 {
159 filter->base = alHeapAlloc(heap, AU_FILTER_LENGTH, sizeof(s16));
160 filter->lowpassTemplate = alHeapAlloc(heap, 1, sizeof(AuLowPass));
161 filter->lowpassTemplate->fstate = alHeapAlloc(heap, 1, sizeof(POLEF_STATE));
162 au_filter_init(filter, 0, 0, 0x5000);
163}
#define AU_FILTER_LENGTH
Definition audio.h:21
void au_filter_init(AuFilter *filter, s16 arg1, s16 arg2, s16 cutoff)
Definition reverb.c:166

◆ au_filter_init()

void au_filter_init ( AuFilter * filter,
s16 arg1,
s16 arg2,
s16 fc )

Definition at line 166 of file reverb.c.

166 {
167 filter->unused_06 = arg1;
168 filter->unused_08 = arg2;
169
170 if (cutoff != 0) {
171 filter->activeLowpass = filter->lowpassTemplate;
172 filter->activeLowpass->fc = cutoff;
173 _init_lpfilter(filter->activeLowpass);
174 return;
175 }
176
177 filter->activeLowpass = NULL;
178}

Referenced by au_filter_create().

◆ au_fx_load_preset()

void au_fx_load_preset ( AuFX * fx,
u8 effectType )

Definition at line 181 of file reverb.c.

181 {
182 s32* params;
183 s32* clr;
184 s32 i, j;
185 clr = (s32*)fx->base;
186
187 switch (effectType) {
188 case AU_FX_SMALLROOM:
189 params = SMALL_ROOM_PARAMS;
190 break;
191 case AU_FX_BIGROOM:
192 params = BIG_ROOM_PARAMS;
193 break;
194 case AU_FX_ECHO:
195 params = ECHO_PARAMS;
196 break;
197 case AU_FX_CHORUS:
198 params = CHORUS_PARAMS;
199 break;
200 case AU_FX_FLANGE:
201 params = FLANGE_PARAMS;
202 break;
203 case AU_FX_CUSTOM_0:
204 params = AU_FX_CUSTOM_PARAMS[0];
205 break;
206 case AU_FX_CUSTOM_1:
207 params = AU_FX_CUSTOM_PARAMS[1];
208 break;
209 case AU_FX_CUSTOM_2:
210 params = AU_FX_CUSTOM_PARAMS[2];
211 break;
212 case AU_FX_CUSTOM_3:
213 params = AU_FX_CUSTOM_PARAMS[3];
214 break;
216 params = BIG_ROOM_PARAMS;
217 break;
218 default:
219 params = NULL_PARAMS;
220 break;
221 }
222
223 j = 0;
224 fx->delayCount = params[j++];
225 fx->length = params[j++] * AUDIO_SAMPLES;
226 fx->input = fx->base;
227
228 for (i = 0; i < AU_FX_LENGTH/2; i++) {
229 *clr++ = 0;
230 }
231
232 for (i = 0; i < fx->delayCount; i++) {
233 AuDelay* delay = &fx->delays[i];
234 delay->input = params[j++] * AUDIO_SAMPLES;
235 delay->output = params[j++] * AUDIO_SAMPLES;
236 delay->fbcoef = (u16) params[j++];
237 delay->ffcoef = (u16) params[j++];
238 delay->gain = (u16) params[j++];
239
240 if (params[j]) {
241 delay->rsinc = (2.0 * (params[j++] / 1000.0f)) / gActiveSynDriverPtr->outputRate;
242 delay->rsgain = ((f32)params[j++] / CONVERT) * (delay->output - delay->input);
243 delay->rsval = 1.0f;
244 delay->rsdelta = 0.0f;
245 delay->activeResampler = delay->resamplerTemplate;
246 delay->resamplerTemplate->delta = 0.0;
247 delay->activeResampler->first = TRUE;
248 } else {
249 delay->activeResampler = NULL;
250 j++;
251 j++;
252 }
253
254 if (params[j]) {
255 delay->activeLowpass = delay->lowpassTemplate;
256 delay->activeLowpass->fc = params[j++];
257 _init_lpfilter(delay->activeLowpass);
258 } else {
259 delay->activeLowpass = NULL;
260 j++;
261 }
262 }
263}
f32 rsval
Definition audio.h:524
s32 rsdelta
Definition audio.h:525
@ AU_FX_CUSTOM_3
Definition audio.h:164
@ AU_FX_FLANGE
Definition audio.h:159
@ AU_FX_CUSTOM_2
Definition audio.h:163
@ AU_FX_CUSTOM_1
Definition audio.h:162
@ AU_FX_ECHO
Definition audio.h:160
@ AU_FX_CHORUS
Definition audio.h:158
@ AU_FX_SMALLROOM
Definition audio.h:156
@ AU_FX_OTHER_BIGROOM
Definition audio.h:165
@ AU_FX_BIGROOM
Definition audio.h:157
@ AU_FX_CUSTOM_0
Definition audio.h:161
AuSynDriver * gActiveSynDriverPtr
Definition syn_driver.c:14
s16 fc
Definition audio.h:542
s32 outputRate
Definition audio.h:637
u32 output
Definition audio.h:518
s16 fbcoef
Definition audio.h:520
s16 ffcoef
Definition audio.h:519
f32 rsgain
Definition audio.h:526
struct AuResampler * activeResampler
Definition audio.h:529
f32 rsinc
Definition audio.h:523
u32 input
Definition audio.h:517
s16 gain
Definition audio.h:521
struct AuLowPass * activeLowpass
Definition audio.h:527
#define CONVERT
Definition reverb.c:27
s32 ECHO_PARAMS[]
Definition reverb.c:73
s32 CHORUS_PARAMS[]
Definition reverb.c:81
s32 * AU_FX_CUSTOM_PARAMS[]
Definition reverb.c:106
s32 BIG_ROOM_PARAMS[]
Definition reverb.c:50
s32 FLANGE_PARAMS[]
Definition reverb.c:89
s32 NULL_PARAMS[]
Definition reverb.c:97
s32 SMALL_ROOM_PARAMS[]
Definition reverb.c:40

Referenced by au_bus_set_effect(), and au_fx_create().

◆ au_pull_fx()

Acmd * au_pull_fx ( AuFX * fx,
Acmd * ptr,
s16 wetDmem,
s16 tempDmem )

Applies a chain of delay-line based effects to audio and mixes into output.

For each delay tap in the FX chain:

  • Loads delay input/output from circular buffer.
  • Applies optional modulation and resampling.
  • Applies feedforward/feedback mixing.
  • Applies optional lowpass filtering.
  • Mixes result into wet output buffer.
Parameters
fxPointer to FX state (delay taps, buffers, etc.)
ptrPointer to the current audio command list position.
wetDmemDMEM offset to mix wet output into.
tempDmemBase DMEM offset for temporary working buffers.
Returns
Updated command list pointer.

Definition at line 281 of file reverb.c.

281 {
282 Acmd* cmdBufPos = ptr;
284
285 s16* inPtr;
286 s16* outPtr;
287
288 // DMEM temp buffer layout:
292
293 s16* prevOutPtr = 0;
295
296 // save wet input from voice mixing into circular delay buffer
298
299 // clear the wet output buffer for this frame
301
302 for (delayIdx = 0; delayIdx < fx->delayCount; delayIdx++) {
303 AuDelay* delay = &fx->delays[delayIdx];
305
306 // calculate read positions for input and output taps, wrapping the circular buffer if necessary
307 inPtr = &fx->input[-delay->input];
308 if (inPtr < fx->base) {
309 inPtr += fx->length;
310 }
311 outPtr = &fx->input[-delay->output];
312 if (outPtr < fx->base) {
313 outPtr += fx->length;
314 }
315
316 // if output is same as previous tap, reuse loaded data by swapping buffers
317 if (inPtr == prevOutPtr) {
319 } else {
320 // load from input tap into buffer
322 }
323
324 if (delay->activeResampler) {
325 // triangle wave modulation for chorus/flange
326 s32 ratio;
327 s32 length, count;
328 f32 delta, fratio, fincount;
330 s16 tmp;
331 s16* rsOutPtr;
332
333 // modulate delay time (triangle wave)
334 length = delay->output - delay->input;
335 delta = updateTriangleModulation(delay, AUDIO_SAMPLES);
336 delta /= length;
337 delta = (s32)(delta * fUnityPitch);
338 delta = delta / UNITY_PITCH;
339
340 fratio = 1.0 - delta;
341
342 // calculate fractional resampling count
344 count = (s32) fincount;
345 delay->activeResampler->delta = fincount - count;
346
347 // prepare delay line for resampling (wrap if needed)
348 rsOutPtr = &fx->input[-(delay->output - delay->rsdelta)];
349 ramAlign = ((s32) rsOutPtr & 7) >> 1;
351 if (rsOutPtr < fx->base) {
352 rsOutPtr += fx->length;
353 }
354
355 // load from delay line
356 cmdBufPos = _loadDelayLineBuffer(fx, rsOutPtr, resampleBuffer, count + ramAlign, cmdBufPos);
357
358 // process resampler
359 ratio = fratio * fUnityPitch;
360 tmp = outputTapBuffer >> 8;
362 delay->activeResampler->first, ratio, resampleBuffer + (ramAlign<<1), tmp);
363 delay->activeResampler->first = FALSE;
364 delay->rsdelta += count - AUDIO_SAMPLES;
365 } else {
366 // no resampling -- just load from output pointer
368 }
369
370 // feedforward: input -> output
371 if (delay->ffcoef) {
373
374 // save output if no additional processing needed
375 if (delay->activeResampler == NULL && delay->activeLowpass == NULL) {
377 }
378 }
379
380 // feedback: output -> input
381 if (delay->fbcoef) {
384 }
385
386 // Save processed output back into delay line (if not resampled)
387 if (delay->activeLowpass != NULL) {
388 // modified _n_filterBuffer
392 delay->activeLowpass->first = 0;
393 }
394
395 // save output (if not already saved earlier)
396 if (!delay->activeResampler) {
398 }
399
400 // mix input from this delay into wet output buffer
401 if (delay->gain) {
402 aMix(cmdBufPos++, 0, (u16)delay->gain, outputTapBuffer, outDmem);
403 }
404 prevOutPtr = &fx->input[delay->output];
405 }
406
407 // advance position in ring buffer
408 fx->input += AUDIO_SAMPLES;
409 if (fx->input >= &fx->base[fx->length]) {
410 fx->input = fx->base;
411 }
412
413 return cmdBufPos;
414}
s16 fccoef[16]
Definition audio.h:545
s32 first
Definition audio.h:547
s16 fgain
Definition audio.h:543
#define SWAP16(in, out)
Definition reverb.c:5

Referenced by alAudioFrame().

◆ au_fx_param_hdl()

s32 au_fx_param_hdl ( AuFX * fx,
s16 index,
s16 paramID,
s32 value )

Definition at line 416 of file reverb.c.

416 {
417 switch (paramID) {
418 case INPUT_PARAM:
419 fx->delays[index].input = value & 0xFFFFFFF8;
420 break;
421 case OUTPUT_PARAM:
422 fx->delays[index].output = value & 0xFFFFFFF8;
423 break;
424 case FFCOEF_PARAM:
425 fx->delays[index].ffcoef = value;
426 break;
427 case FBCOEF_PARAM:
428 fx->delays[index].fbcoef = value;
429 break;
430 case GAIN_PARAM:
431 fx->delays[index].gain = value;
432 break;
433 case CHORUSRATE_PARAM:
434 fx->delays[index].rsinc = (2.0 * (value / 1000.0f)) / gActiveSynDriverPtr->outputRate;
435 break;
437 fx->delays[index].rsgain = ((f32)value / CONVERT) * (fx->delays[index].output - fx->delays[index].input);
438 break;
439 case LPFILT_PARAM:
440 if (fx->delays[index].activeLowpass) {
441 fx->delays[index].activeLowpass->fc = value;
442 _init_lpfilter(fx->delays[index].activeLowpass);
443 }
444 break;
445 }
446 return 0;
447}
#define FBCOEF_PARAM
Definition reverb.c:33
#define INPUT_PARAM
Definition reverb.c:31
#define CHORUSRATE_PARAM
Definition reverb.c:36
#define OUTPUT_PARAM
Definition reverb.c:32
#define CHORUSDEPTH_PARAM
Definition reverb.c:37
#define GAIN_PARAM
Definition reverb.c:35
#define FFCOEF_PARAM
Definition reverb.c:34
#define LPFILT_PARAM
Definition reverb.c:38

Referenced by au_bus_set_fx_params().