Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
system.c
Go to the documentation of this file.
1#include "audio.h"
2#include "audio/core.h"
3#include "dx/profiling.h"
4
11
25
28#if !VERSION_IQUE
30#endif
31
32extern u64 n_aspMain_text_bin[];
33extern u64 n_aspMain_data_bin[];
34
36
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}
100
107
108void nuAuMgr(void* arg) {
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}
192
194s32 nuAuDmaCallBack(s32 addr, s32 len, void *state, u8 useDma) {
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}
262
266 if (!nuAuDmaState.initialized) {
267 nuAuDmaState.firstFree = &nuAuDmaBufList[0];
268 nuAuDmaState.firstUsed = NULL;
269 nuAuDmaState.initialized = TRUE;
270 }
271
272 nuAuDmaNext = 0;
273 *state = &nuAuDmaState;
275}
276
279 NUDMAState* state = &nuAuDmaState;
280 NUDMABuffer* dmaPtr = state->firstUsed;
281
282 // A bit odd, this
283 do {
284 NUDMAState* state = &nuAuDmaState;
286 u32* frameCounter;
287
288 while (dmaPtr != NULL) {
289 nextPtr = (NUDMABuffer*)dmaPtr->node.next;
290
291 if (dmaPtr->frameCnt + 1 < nuAuFrameCounter) {
292 if (state->firstUsed == dmaPtr) {
293 state->firstUsed = nextPtr;
294 }
295
296 alUnlink(&dmaPtr->node);
297
298 if (state->firstFree != NULL) {
299 alLink(&dmaPtr->node, &state->firstFree->node);
300 } else {
301 state->firstFree = dmaPtr;
302 dmaPtr->node.next = NULL;
303 dmaPtr->node.prev = NULL;
304 }
305 }
306
307 dmaPtr = nextPtr;
308 }
309
310 nuAuDmaNext = 0;
311 frameCounter = &nuAuFrameCounter;
312 (*frameCounter)++;
313 } while (0);
314}
315
317void nuAuPreNMIProc(NUScMsg mesg_type, u32 frameCounter) {
318 s16 maxVol;
319 s32 vol;
320
321 switch (mesg_type) {
322 case NU_SC_PRENMI_MSG:
325 break;
328 vol = maxVol - (maxVol / 20) * frameCounter;
329
330 if (vol < 0) {
331 vol = 0;
332 }
333
334 vol = SQ(vol) >> 15;
336
337 if (vol == 0) {
339 }
340 break;
341 }
342}
343
346 element->next = after->next;
347 element->prev = after;
348
349 if (after->next != NULL) {
350 after->next->prev = element;
351 }
352 after->next = element;
353}
354
357 if (element->next != NULL) {
358 element->next->prev = element->prev;
359 }
360
361 if (element->prev != NULL) {
362 element->prev->next = element->next;
363 }
364}
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_set_global_volume(s16 arg0)
Definition syn_driver.c:276
void au_use_global_volume(void)
Definition syn_driver.c:272
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
s16 au_get_global_volume(void)
Definition syn_driver.c:280
@ THREAD_ID_AUDIO
Definition enums.h:5984
@ 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
#define BSS
Definition macros.h:7
#define ARRAY_COUNT(arr)
Definition macros.h:40
#define ALIGNED(x)
Definition macros.h:10
#define SQ(x)
Definition macros.h:178
Acmd * alAudioFrame(Acmd *cmdList, s32 *cmdLen, s16 *outBuf, s32 outLen)
Definition syn_driver.c:119
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
void nuAuPreNMIFuncSet(NUAuPreNMIFunc func)
Definition system.c:101
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
u32 nuAuFrameCounter
Definition system.c:8
BSS NUDMAState nuAuDmaState
Definition system.c:23
BSS NUScTask nuAuTasks[3]
Definition system.c:16
BSS s32 AlFrameSize
Definition system.c:18
s32 nuAuDmaCallBack(s32 addr, s32 len, void *state, u8 useDma)
DMA callback for audio sample streaming; manages a DMA buffer cache.
Definition system.c:194
void nuAuPreNMIProc(NUScMsg mesg_type, u32 frameCounter)
Handles global audio fade-out during system resets (NMI).
Definition system.c:317
void alUnlink(ALLink *element)
Unlinks a list element from a doubly-linked list.
Definition system.c:356
BSS u16 AuInitialGlobalVolume
Definition system.c:12
void create_audio_system(void)
Definition system.c:37
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
u8 volatile AuSynUseStereo
Definition system.c:10
void nuAuCleanDMABuffers(void)
Recycles DMA buffers which are no longer in use (based on frame count).
Definition system.c:278
s32 nuAuDmaNext
Definition system.c:7
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 OSIoMesg nuAuDmaIOMesgBuf[50]
Definition system.c:22
BSS OSMesgQueue nuAuDmaMesgQ
Definition system.c:20