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