Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/src/audio/port_eu.c
7857 views
1
#include <ultra64.h>
2
#include "internal.h"
3
#include "load.h"
4
#include "data.h"
5
#include "seqplayer.h"
6
#include "synthesis.h"
7
8
#ifdef VERSION_EU
9
10
#ifdef __sgi
11
#define stubbed_printf
12
#else
13
#define stubbed_printf(...)
14
#endif
15
16
#define SAMPLES_TO_OVERPRODUCE 0x10
17
#define EXTRA_BUFFERED_AI_SAMPLES_TARGET 0x40
18
19
#ifdef VERSION_JP
20
typedef u16 FadeT;
21
#else
22
typedef s32 FadeT;
23
#endif
24
25
extern volatile u8 gAudioResetStatus;
26
extern u8 gAudioResetPresetIdToLoad;
27
extern OSMesgQueue *OSMesgQueues[];
28
extern struct EuAudioCmd sAudioCmd[0x100];
29
30
void func_8031D690(s32 player, FadeT fadeInTime);
31
void seq_player_fade_to_zero_volume(s32 player, FadeT fadeOutTime);
32
void decrease_sample_dma_ttls(void);
33
s32 audio_shut_down_and_reset_step(void);
34
void func_802ad7ec(u32);
35
36
#ifdef TARGET_N64
37
struct SPTask *create_next_audio_frame_task(void) {
38
u32 samplesRemainingInAI;
39
s32 writtenCmds;
40
s32 index;
41
OSTask_t *task;
42
s32 flags;
43
s16 *currAiBuffer;
44
s32 oldDmaCount;
45
OSMesg sp30;
46
OSMesg sp2C;
47
48
gAudioFrameCount++;
49
if (gAudioFrameCount % gAudioBufferParameters.presetUnk4 != 0) {
50
stubbed_printf("DAC:Lost 1 Frame.\n");
51
return NULL;
52
}
53
54
osSendMesg(OSMesgQueues[0], (OSMesg) gAudioFrameCount, 0);
55
56
gAudioTaskIndex ^= 1;
57
gCurrAiBufferIndex++;
58
gCurrAiBufferIndex %= NUMAIBUFFERS;
59
index = (gCurrAiBufferIndex - 2 + NUMAIBUFFERS) % NUMAIBUFFERS;
60
samplesRemainingInAI = osAiGetLength() / 4;
61
62
if (gAiBufferLengths[index] != 0) {
63
osAiSetNextBuffer(gAiBuffers[index], gAiBufferLengths[index] * 4);
64
}
65
66
oldDmaCount = gCurrAudioFrameDmaCount;
67
if (oldDmaCount > AUDIO_FRAME_DMA_QUEUE_SIZE) {
68
stubbed_printf("DMA: Request queue over.( %d )\n", oldDmaCount);
69
}
70
gCurrAudioFrameDmaCount = 0;
71
72
decrease_sample_dma_ttls();
73
if (osRecvMesg(OSMesgQueues[2], &sp30, 0) != -1) {
74
gAudioResetPresetIdToLoad = (u8) (s32) sp30;
75
gAudioResetStatus = 5;
76
}
77
78
if (gAudioResetStatus != 0) {
79
if (audio_shut_down_and_reset_step() == 0) {
80
if (gAudioResetStatus == 0) {
81
osSendMesg(OSMesgQueues[3], (OSMesg) (s32) gAudioResetPresetIdToLoad, OS_MESG_NOBLOCK);
82
}
83
return NULL;
84
}
85
}
86
87
gAudioTask = &gAudioTasks[gAudioTaskIndex];
88
gAudioCmd = gAudioCmdBuffers[gAudioTaskIndex];
89
index = gCurrAiBufferIndex;
90
currAiBuffer = gAiBuffers[index];
91
92
gAiBufferLengths[index] = ((gAudioBufferParameters.samplesPerFrameTarget - samplesRemainingInAI +
93
EXTRA_BUFFERED_AI_SAMPLES_TARGET) & ~0xf) + SAMPLES_TO_OVERPRODUCE;
94
if (gAiBufferLengths[index] < gAudioBufferParameters.minAiBufferLength) {
95
gAiBufferLengths[index] = gAudioBufferParameters.minAiBufferLength;
96
}
97
if (gAiBufferLengths[index] > gAudioBufferParameters.maxAiBufferLength) {
98
gAiBufferLengths[index] = gAudioBufferParameters.maxAiBufferLength;
99
}
100
101
if (osRecvMesg(OSMesgQueues[1], &sp2C, OS_MESG_NOBLOCK) != -1) {
102
func_802ad7ec((u32) sp2C);
103
}
104
105
flags = 0;
106
gAudioCmd = synthesis_execute(gAudioCmd, &writtenCmds, currAiBuffer, gAiBufferLengths[index]);
107
gAudioRandom = ((gAudioRandom + gAudioFrameCount) * gAudioFrameCount);
108
gAudioRandom = gAudioRandom + writtenCmds / 8;
109
110
index = gAudioTaskIndex;
111
gAudioTask->msgqueue = NULL;
112
gAudioTask->msg = NULL;
113
114
task = &gAudioTask->task.t;
115
task->type = M_AUDTASK;
116
task->flags = flags;
117
task->ucode_boot = rspF3DBootStart;
118
task->ucode_boot_size = (u8 *) rspF3DBootEnd - (u8 *) rspF3DBootStart;
119
task->ucode = rspAspMainStart;
120
task->ucode_data = rspAspMainDataStart;
121
task->ucode_size = 0x800; // (this size is ignored)
122
task->ucode_data_size = (rspAspMainDataEnd - rspAspMainDataStart) * sizeof(u64);
123
task->dram_stack = NULL;
124
task->dram_stack_size = 0;
125
task->output_buff = NULL;
126
task->output_buff_size = NULL;
127
task->data_ptr = gAudioCmdBuffers[index];
128
task->data_size = writtenCmds * sizeof(u64);
129
task->yield_data_ptr = NULL;
130
task->yield_data_size = 0;
131
return gAudioTask;
132
}
133
#else
134
struct SPTask *create_next_audio_frame_task(void) {
135
return NULL;
136
}
137
void create_next_audio_buffer(s16 *samples, u32 num_samples) {
138
s32 writtenCmds;
139
OSMesg msg;
140
gAudioFrameCount++;
141
decrease_sample_dma_ttls();
142
if (osRecvMesg(OSMesgQueues[2], &msg, 0) != -1) {
143
gAudioResetPresetIdToLoad = (u8) (intptr_t) msg;
144
gAudioResetStatus = 5;
145
}
146
147
if (gAudioResetStatus != 0) {
148
audio_reset_session();
149
gAudioResetStatus = 0;
150
}
151
if (osRecvMesg(OSMesgQueues[1], &msg, OS_MESG_NOBLOCK) != -1) {
152
func_802ad7ec((u32) msg);
153
}
154
synthesis_execute(gAudioCmdBuffers[0], &writtenCmds, samples, num_samples);
155
gAudioRandom = ((gAudioRandom + gAudioFrameCount) * gAudioFrameCount);
156
gAudioRandom = gAudioRandom + writtenCmds / 8;
157
}
158
#endif
159
160
void eu_process_audio_cmd(struct EuAudioCmd *cmd) {
161
s32 i;
162
163
switch (cmd->u.s.op) {
164
case 0x81:
165
preload_sequence(cmd->u.s.arg2, 3);
166
break;
167
168
case 0x82:
169
case 0x88:
170
load_sequence(cmd->u.s.arg1, cmd->u.s.arg2, cmd->u.s.arg3);
171
func_8031D690(cmd->u.s.arg1, cmd->u2.as_s32);
172
break;
173
174
case 0x83:
175
if (gSequencePlayers[cmd->u.s.arg1].enabled != FALSE) {
176
if (cmd->u2.as_s32 == 0) {
177
sequence_player_disable(&gSequencePlayers[cmd->u.s.arg1]);
178
}
179
else {
180
seq_player_fade_to_zero_volume(cmd->u.s.arg1, cmd->u2.as_s32);
181
}
182
}
183
break;
184
185
case 0xf0:
186
gSoundMode = cmd->u2.as_s32;
187
break;
188
189
case 0xf1:
190
for (i = 0; i < 4; i++) {
191
gSequencePlayers[i].muted = TRUE;
192
gSequencePlayers[i].recalculateVolume = TRUE;
193
}
194
break;
195
196
case 0xf2:
197
for (i = 0; i < 4; i++) {
198
gSequencePlayers[i].muted = FALSE;
199
gSequencePlayers[i].recalculateVolume = TRUE;
200
}
201
break;
202
}
203
}
204
205
const char undefportcmd[] = "Undefined Port Command %d\n";
206
207
extern OSMesgQueue *OSMesgQueues[];
208
extern u8 D_EU_80302010;
209
extern u8 D_EU_80302014;
210
extern OSMesg OSMesg0;
211
extern OSMesg OSMesg1;
212
extern OSMesg OSMesg2;
213
extern OSMesg OSMesg3;
214
215
void seq_player_fade_to_zero_volume(s32 player, FadeT fadeOutTime) {
216
if (fadeOutTime == 0) {
217
fadeOutTime = 1;
218
}
219
gSequencePlayers[player].fadeVelocity = -(gSequencePlayers[player].fadeVolume / fadeOutTime);
220
gSequencePlayers[player].state = 2;
221
gSequencePlayers[player].fadeRemainingFrames = fadeOutTime;
222
223
}
224
225
void func_8031D690(s32 player, FadeT fadeInTime) {
226
if (fadeInTime != 0) {
227
gSequencePlayers[player].state = 1;
228
gSequencePlayers[player].fadeTimerUnkEu = fadeInTime;
229
gSequencePlayers[player].fadeRemainingFrames = fadeInTime;
230
gSequencePlayers[player].fadeVolume = 0.0f;
231
gSequencePlayers[player].fadeVelocity = 0.0f;
232
}
233
}
234
235
void port_eu_init_queues(void) {
236
D_EU_80302010 = 0;
237
D_EU_80302014 = 0;
238
osCreateMesgQueue(OSMesgQueues[0], &OSMesg0, 1);
239
osCreateMesgQueue(OSMesgQueues[1], &OSMesg1, 4);
240
osCreateMesgQueue(OSMesgQueues[2], &OSMesg2, 1);
241
osCreateMesgQueue(OSMesgQueues[3], &OSMesg3, 1);
242
}
243
244
void func_802ad6f0(s32 arg0, s32 *arg1) {
245
struct EuAudioCmd *cmd = &sAudioCmd[D_EU_80302010 & 0xff];
246
cmd->u.first = arg0;
247
cmd->u2.as_u32 = *arg1;
248
D_EU_80302010++;
249
}
250
251
void func_802ad728(u32 arg0, f32 arg1) {
252
func_802ad6f0(arg0, (s32*) &arg1);
253
}
254
255
void func_802ad74c(u32 arg0, u32 arg1) {
256
func_802ad6f0(arg0, (s32*) &arg1);
257
}
258
259
void func_802ad770(u32 arg0, s8 arg1) {
260
s32 sp1C = arg1 << 24;
261
func_802ad6f0(arg0, &sp1C);
262
}
263
264
void func_802ad7a0(void) {
265
osSendMesg(OSMesgQueues[1],
266
(OSMesg)(u32)((D_EU_80302014 & 0xff) << 8 | (D_EU_80302010 & 0xff)),
267
OS_MESG_NOBLOCK);
268
D_EU_80302014 = D_EU_80302010;
269
}
270
271
void func_802ad7ec(u32 arg0) {
272
struct EuAudioCmd *cmd;
273
struct SequencePlayer *seqPlayer;
274
struct SequenceChannel *chan;
275
u8 end = arg0 & 0xff;
276
u8 i = (arg0 >> 8) & 0xff;
277
278
for (;;) {
279
if (i == end) break;
280
cmd = &sAudioCmd[i++ & 0xff];
281
282
if (cmd->u.s.arg1 < SEQUENCE_PLAYERS) {
283
seqPlayer = &gSequencePlayers[cmd->u.s.arg1];
284
if ((cmd->u.s.op & 0x80) != 0) {
285
eu_process_audio_cmd(cmd);
286
}
287
else if ((cmd->u.s.op & 0x40) != 0) {
288
switch (cmd->u.s.op) {
289
case 0x41:
290
seqPlayer->fadeVolumeScale = cmd->u2.as_f32;
291
seqPlayer->recalculateVolume = TRUE;
292
break;
293
294
case 0x47:
295
seqPlayer->tempo = cmd->u2.as_s32 * TATUMS_PER_BEAT;
296
break;
297
298
case 0x48:
299
seqPlayer->transposition = cmd->u2.as_s8;
300
break;
301
302
case 0x46:
303
seqPlayer->seqVariationEu[cmd->u.s.arg3] = cmd->u2.as_s8;
304
break;
305
}
306
}
307
else if (seqPlayer->enabled != FALSE && cmd->u.s.arg2 < 0x10) {
308
chan = seqPlayer->channels[cmd->u.s.arg2];
309
if (IS_SEQUENCE_CHANNEL_VALID(chan))
310
{
311
switch (cmd->u.s.op) {
312
case 1:
313
chan->volumeScale = cmd->u2.as_f32;
314
chan->changes.as_bitfields.volume = TRUE;
315
break;
316
case 2:
317
chan->volume = cmd->u2.as_f32;
318
chan->changes.as_bitfields.volume = TRUE;
319
break;
320
case 3:
321
chan->newPan = cmd->u2.as_s8;
322
chan->changes.as_bitfields.pan = TRUE;
323
break;
324
case 4:
325
chan->freqScale = cmd->u2.as_f32;
326
chan->changes.as_bitfields.freqScale = TRUE;
327
break;
328
case 5:
329
chan->reverbVol = cmd->u2.as_s8;
330
break;
331
case 6:
332
if (cmd->u.s.arg3 < 8) {
333
chan->soundScriptIO[cmd->u.s.arg3] = cmd->u2.as_s8;
334
}
335
break;
336
case 8:
337
chan->stopSomething2 = cmd->u2.as_s8;
338
}
339
}
340
}
341
}
342
343
cmd->u.s.op = 0;
344
}
345
}
346
347
void port_eu_init(void) {
348
port_eu_init_queues();
349
}
350
351
#endif
352
353