mirror of https://github.com/sm64pc/sm64pc.git
properly merge refresh 10.1's audio code
this fixes crashes on EU, there is now audio output but it's still borked
This commit is contained in:
parent
99f69eff1c
commit
52e32ba763
|
@ -763,10 +763,6 @@ void func_eu_802e9bec(s32 player, s32 channel, s32 arg2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
// Stubbed N64-US/JP audio code
|
|
||||||
// continue;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
struct SPTask *create_next_audio_frame_task(void) {
|
struct SPTask *create_next_audio_frame_task(void) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -783,6 +779,7 @@ void create_next_audio_buffer(s16 *samples, u32 num_samples) {
|
||||||
gAudioRandom = ((gAudioRandom + gAudioFrameCount) * gAudioFrameCount);
|
gAudioRandom = ((gAudioRandom + gAudioFrameCount) * gAudioFrameCount);
|
||||||
decrease_sample_dma_ttls();
|
decrease_sample_dma_ttls();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void play_sound(s32 soundBits, f32 *pos) {
|
void play_sound(s32 soundBits, f32 *pos) {
|
||||||
sSoundRequests[sSoundRequestCount].soundBits = soundBits;
|
sSoundRequests[sSoundRequestCount].soundBits = soundBits;
|
||||||
|
|
|
@ -648,9 +648,8 @@ s32 audio_shut_down_and_reset_step(void) {
|
||||||
/**
|
/**
|
||||||
* Waits until a specified number of audio frames have been created
|
* Waits until a specified number of audio frames have been created
|
||||||
*/
|
*/
|
||||||
void wait_for_audio_frames(s32 frames) {
|
void wait_for_audio_frames(UNUSED s32 frames) {
|
||||||
gAudioFrameCount = 0;
|
gAudioFrameCount = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -894,13 +894,13 @@ void audio_init() {
|
||||||
UNUSED s8 pad[32];
|
UNUSED s8 pad[32];
|
||||||
u8 buf[0x10];
|
u8 buf[0x10];
|
||||||
#endif
|
#endif
|
||||||
s32 i, j, k;
|
s32 i, j, UNUSED k;
|
||||||
UNUSED s32 lim1; // lim1 unused in EU
|
UNUSED s32 lim1; // lim1 unused in EU
|
||||||
#ifdef VERSION_EU
|
#ifdef VERSION_EU
|
||||||
u8 buf[0x10];
|
u8 buf[0x10];
|
||||||
s32 UNUSED lim2, lim3;
|
s32 UNUSED lim2, lim3;
|
||||||
#else
|
#else
|
||||||
s32 lim2, lim3;
|
s32 lim2, UNUSED lim3;
|
||||||
#endif
|
#endif
|
||||||
u32 size;
|
u32 size;
|
||||||
UNUSED u64 *ptr64;
|
UNUSED u64 *ptr64;
|
||||||
|
@ -920,7 +920,6 @@ void audio_init() {
|
||||||
for (i = 0; i <= lim2 / 8 - 1; i++) {
|
for (i = 0; i <= lim2 / 8 - 1; i++) {
|
||||||
((u64 *) gAudioHeap)[i] = 0;
|
((u64 *) gAudioHeap)[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
for (i = 0; i < gAudioHeapSize / 8; i++) {
|
for (i = 0; i < gAudioHeapSize / 8; i++) {
|
||||||
((u64 *) gAudioHeap)[i] = 0;
|
((u64 *) gAudioHeap)[i] = 0;
|
||||||
|
|
|
@ -35,100 +35,28 @@ s32 audio_shut_down_and_reset_step(void);
|
||||||
void func_802ad7ec(u32);
|
void func_802ad7ec(u32);
|
||||||
|
|
||||||
struct SPTask *create_next_audio_frame_task(void) {
|
struct SPTask *create_next_audio_frame_task(void) {
|
||||||
u32 samplesRemainingInAI;
|
return NULL;
|
||||||
|
}
|
||||||
|
void create_next_audio_buffer(s16 *samples, u32 num_samples) {
|
||||||
s32 writtenCmds;
|
s32 writtenCmds;
|
||||||
s32 index;
|
OSMesg msg;
|
||||||
OSTask_t *task;
|
|
||||||
s32 flags;
|
|
||||||
s16 *currAiBuffer;
|
|
||||||
s32 oldDmaCount;
|
|
||||||
OSMesg sp30;
|
|
||||||
OSMesg sp2C;
|
|
||||||
|
|
||||||
gAudioFrameCount++;
|
gAudioFrameCount++;
|
||||||
if (gAudioFrameCount % gAudioBufferParameters.presetUnk4 != 0) {
|
|
||||||
stubbed_printf("DAC:Lost 1 Frame.\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
osSendMesg(OSMesgQueues[0], (OSMesg) gAudioFrameCount, 0);
|
|
||||||
|
|
||||||
gAudioTaskIndex ^= 1;
|
|
||||||
gCurrAiBufferIndex++;
|
|
||||||
gCurrAiBufferIndex %= NUMAIBUFFERS;
|
|
||||||
index = (gCurrAiBufferIndex - 2 + NUMAIBUFFERS) % NUMAIBUFFERS;
|
|
||||||
samplesRemainingInAI = osAiGetLength() / 4;
|
|
||||||
|
|
||||||
if (gAiBufferLengths[index] != 0) {
|
|
||||||
osAiSetNextBuffer(gAiBuffers[index], gAiBufferLengths[index] * 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
oldDmaCount = gCurrAudioFrameDmaCount;
|
|
||||||
if (oldDmaCount > AUDIO_FRAME_DMA_QUEUE_SIZE) {
|
|
||||||
stubbed_printf("DMA: Request queue over.( %d )\n", oldDmaCount);
|
|
||||||
}
|
|
||||||
gCurrAudioFrameDmaCount = 0;
|
|
||||||
|
|
||||||
decrease_sample_dma_ttls();
|
decrease_sample_dma_ttls();
|
||||||
if (osRecvMesg(OSMesgQueues[2], &sp30, 0) != -1) {
|
if (osRecvMesg(OSMesgQueues[2], &msg, 0) != -1) {
|
||||||
gAudioResetPresetIdToLoad = (u8) (s32) sp30;
|
gAudioResetPresetIdToLoad = (u8) (s32) msg;
|
||||||
gAudioResetStatus = 5;
|
gAudioResetStatus = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gAudioResetStatus != 0) {
|
if (gAudioResetStatus != 0) {
|
||||||
if (audio_shut_down_and_reset_step() == 0) {
|
audio_reset_session();
|
||||||
if (gAudioResetStatus == 0) {
|
gAudioResetStatus = 0;
|
||||||
osSendMesg(OSMesgQueues[3], (OSMesg) (s32) gAudioResetPresetIdToLoad, OS_MESG_NOBLOCK);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (osRecvMesg(OSMesgQueues[1], &msg, OS_MESG_NOBLOCK) != -1) {
|
||||||
gAudioTask = &gAudioTasks[gAudioTaskIndex];
|
func_802ad7ec((u32) msg);
|
||||||
gAudioCmd = gAudioCmdBuffers[gAudioTaskIndex];
|
|
||||||
index = gCurrAiBufferIndex;
|
|
||||||
currAiBuffer = gAiBuffers[index];
|
|
||||||
|
|
||||||
gAiBufferLengths[index] = ((gAudioBufferParameters.samplesPerFrameTarget - samplesRemainingInAI +
|
|
||||||
EXTRA_BUFFERED_AI_SAMPLES_TARGET) & ~0xf) + SAMPLES_TO_OVERPRODUCE;
|
|
||||||
if (gAiBufferLengths[index] < gAudioBufferParameters.minAiBufferLength) {
|
|
||||||
gAiBufferLengths[index] = gAudioBufferParameters.minAiBufferLength;
|
|
||||||
}
|
}
|
||||||
if (gAiBufferLengths[index] > gAudioBufferParameters.maxAiBufferLength) {
|
synthesis_execute(gAudioCmdBuffers[0], &writtenCmds, samples, num_samples);
|
||||||
gAiBufferLengths[index] = gAudioBufferParameters.maxAiBufferLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (osRecvMesg(OSMesgQueues[1], &sp2C, OS_MESG_NOBLOCK) != -1) {
|
|
||||||
func_802ad7ec((u32) sp2C);
|
|
||||||
}
|
|
||||||
|
|
||||||
flags = 0;
|
|
||||||
gAudioCmd = synthesis_execute(gAudioCmd, &writtenCmds, currAiBuffer, gAiBufferLengths[index]);
|
|
||||||
gAudioRandom = ((gAudioRandom + gAudioFrameCount) * gAudioFrameCount);
|
gAudioRandom = ((gAudioRandom + gAudioFrameCount) * gAudioFrameCount);
|
||||||
gAudioRandom = gAudioRandom + writtenCmds / 8;
|
gAudioRandom = gAudioRandom + writtenCmds / 8;
|
||||||
|
|
||||||
index = gAudioTaskIndex;
|
|
||||||
gAudioTask->msgqueue = NULL;
|
|
||||||
gAudioTask->msg = NULL;
|
|
||||||
|
|
||||||
task = &gAudioTask->task.t;
|
|
||||||
task->type = M_AUDTASK;
|
|
||||||
task->flags = flags;
|
|
||||||
task->ucode_boot = rspF3DBootStart;
|
|
||||||
task->ucode_boot_size = (u8 *) rspF3DBootEnd - (u8 *) rspF3DBootStart;
|
|
||||||
task->ucode = rspAspMainStart;
|
|
||||||
task->ucode_data = rspAspMainDataStart;
|
|
||||||
task->ucode_size = 0x800; // (this size is ignored)
|
|
||||||
task->ucode_data_size = (rspAspMainDataEnd - rspAspMainDataStart) * sizeof(u64);
|
|
||||||
task->dram_stack = NULL;
|
|
||||||
task->dram_stack_size = 0;
|
|
||||||
task->output_buff = NULL;
|
|
||||||
task->output_buff_size = NULL;
|
|
||||||
task->data_ptr = gAudioCmdBuffers[index];
|
|
||||||
task->data_size = writtenCmds * sizeof(u64);
|
|
||||||
task->yield_data_ptr = NULL;
|
|
||||||
task->yield_data_size = 0;
|
|
||||||
return gAudioTask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void eu_process_audio_cmd(struct EuAudioCmd *cmd) {
|
void eu_process_audio_cmd(struct EuAudioCmd *cmd) {
|
||||||
|
|
1259
src/pc/mixer.c
1259
src/pc/mixer.c
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,8 @@
|
||||||
#ifndef MIXER_H
|
#ifndef MIXER_H
|
||||||
#define MIXER_H
|
#define MIXER_H
|
||||||
|
|
||||||
#include <PR/ultratypes.h>
|
#include <stdint.h>
|
||||||
|
#include <ultra64.h>
|
||||||
|
|
||||||
#undef aSegment
|
#undef aSegment
|
||||||
#undef aClearBuffer
|
#undef aClearBuffer
|
||||||
|
@ -19,21 +20,34 @@
|
||||||
#undef aLoadADPCM
|
#undef aLoadADPCM
|
||||||
#undef aADPCMdec
|
#undef aADPCMdec
|
||||||
|
|
||||||
#define aSegment(pkt, s, b)
|
void aClearBufferImpl(uint16_t addr, int nbytes);
|
||||||
void aClearBuffer(uint64_t *cmd, uint16_t dmem, uint16_t count);
|
void aLoadBufferImpl(const void *source_addr);
|
||||||
void aSetBuffer(uint64_t *cmd, uint8_t flags, uint16_t dmemin, uint16_t dmemout, uint16_t count);
|
void aSaveBufferImpl(int16_t *dest_addr);
|
||||||
void aLoadBuffer(uint64_t *cmd, uint16_t *addr);
|
void aLoadADPCMImpl(int num_entries_times_16, const int16_t *book_source_addr);
|
||||||
void aSaveBuffer(uint64_t *cmd, uint16_t *addr);
|
void aSetBufferImpl(uint8_t flags, uint16_t in, uint16_t out, uint16_t nbytes);
|
||||||
void aDMEMMove(uint64_t *cmd, uint16_t dmemin, uint16_t dmemout, uint16_t count);
|
void aSetVolumeImpl(uint8_t flags, int16_t v, int16_t t, int16_t r);
|
||||||
void aMix(uint64_t *cmd, uint8_t flags, uint16_t gain, uint16_t dmemin, uint16_t dmemout);
|
void aInterleaveImpl(uint16_t left, uint16_t right);
|
||||||
void aEnvMixer(uint64_t *cmd, uint8_t flags, uint16_t *addr);
|
void aDMEMMoveImpl(uint16_t in_addr, uint16_t out_addr, int nbytes);
|
||||||
void aResample(uint64_t *cmd, uint8_t flags, uint16_t pitch, uint16_t *state_addr);
|
void aSetLoopImpl(ADPCM_STATE *adpcm_loop_state);
|
||||||
void aInterleave(uint64_t *cmd, uint16_t inL, uint16_t inR);
|
void aADPCMdecImpl(uint8_t flags, ADPCM_STATE state);
|
||||||
void aSetVolume(uint64_t *cmd, uint8_t flags, uint16_t vol, uint16_t voltgt, uint16_t volrate);
|
void aResampleImpl(uint8_t flags, uint16_t pitch, RESAMPLE_STATE state);
|
||||||
void aSetVolume32(uint64_t *cmd, uint8_t flags, uint16_t voltgt, uint32_t volrate);
|
void aEnvMixerImpl(uint8_t flags, ENVMIX_STATE state);
|
||||||
void aSetLoop(uint64_t *cmd, uint16_t *addr);
|
void aMixImpl(int16_t gain, uint16_t in_addr, uint16_t out_addr);
|
||||||
void aLoadADPCM(uint64_t *cmd, uint16_t count, uint16_t *addr);
|
|
||||||
void aADPCMdec(uint64_t *cmd, uint8_t flags, uint16_t *last_frame_addr);
|
|
||||||
|
|
||||||
|
#define aSegment(pkt, s, b) do { } while(0)
|
||||||
|
#define aClearBuffer(pkt, d, c) aClearBufferImpl(d, c)
|
||||||
|
#define aLoadBuffer(pkt, s) aLoadBufferImpl(s)
|
||||||
|
#define aSaveBuffer(pkt, s) aSaveBufferImpl(s)
|
||||||
|
#define aLoadADPCM(pkt, c, d) aLoadADPCMImpl(c, d)
|
||||||
|
#define aSetBuffer(pkt, f, i, o, c) aSetBufferImpl(f, i, o, c)
|
||||||
|
#define aSetVolume(pkt, f, v, t, r) aSetVolumeImpl(f, v, t, r)
|
||||||
|
#define aSetVolume32(pkt, f, v, tr) aSetVolume(pkt, f, v, (int16_t)((tr) >> 16), (int16_t)(tr))
|
||||||
|
#define aInterleave(pkt, l, r) aInterleaveImpl(l, r)
|
||||||
|
#define aDMEMMove(pkt, i, o, c) aDMEMMoveImpl(i, o, c)
|
||||||
|
#define aSetLoop(pkt, a) aSetLoopImpl(a)
|
||||||
|
#define aADPCMdec(pkt, f, s) aADPCMdecImpl(f, s)
|
||||||
|
#define aResample(pkt, f, p, s) aResampleImpl(f, p, s)
|
||||||
|
#define aEnvMixer(pkt, f, s) aEnvMixerImpl(f, s)
|
||||||
|
#define aMix(pkt, f, g, i, o) aMixImpl(g, i, o)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -72,7 +72,13 @@ void send_display_list(struct SPTask *spTask) {
|
||||||
gfx_run((Gfx *)spTask->task.t.data_ptr);
|
gfx_run((Gfx *)spTask->task.t.data_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define printf
|
#ifdef VERSION_EU
|
||||||
|
#define SAMPLES_HIGH 656
|
||||||
|
#define SAMPLES_LOW 640
|
||||||
|
#else
|
||||||
|
#define SAMPLES_HIGH 544
|
||||||
|
#define SAMPLES_LOW 528
|
||||||
|
#endif
|
||||||
|
|
||||||
void produce_one_frame(void) {
|
void produce_one_frame(void) {
|
||||||
gfx_start_frame();
|
gfx_start_frame();
|
||||||
|
@ -86,9 +92,9 @@ void produce_one_frame(void) {
|
||||||
thread6_rumble_loop(NULL);
|
thread6_rumble_loop(NULL);
|
||||||
|
|
||||||
int samples_left = audio_api->buffered();
|
int samples_left = audio_api->buffered();
|
||||||
u32 num_audio_samples = samples_left < audio_api->get_desired_buffered() ? 544 : 528;
|
u32 num_audio_samples = samples_left < audio_api->get_desired_buffered() ? SAMPLES_HIGH : SAMPLES_LOW;
|
||||||
//printf("Audio samples: %d %u\n", samples_left, num_audio_samples);
|
//printf("Audio samples: %d %u\n", samples_left, num_audio_samples);
|
||||||
s16 audio_buffer[544 * 2 * 2];
|
s16 audio_buffer[SAMPLES_HIGH * 2 * 2];
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
/*if (audio_cnt-- == 0) {
|
/*if (audio_cnt-- == 0) {
|
||||||
audio_cnt = 2;
|
audio_cnt = 2;
|
||||||
|
@ -98,7 +104,7 @@ void produce_one_frame(void) {
|
||||||
}
|
}
|
||||||
//printf("Audio samples before submitting: %d\n", audio_api->buffered());
|
//printf("Audio samples before submitting: %d\n", audio_api->buffered());
|
||||||
|
|
||||||
audio_api->play((u8*)audio_buffer, 2 * num_audio_samples * 4);
|
audio_api->play((u8 *)audio_buffer, 2 * num_audio_samples * 4);
|
||||||
|
|
||||||
gfx_end_frame();
|
gfx_end_frame();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,15 +22,42 @@ s32 osPiStartDma(UNUSED OSIoMesg *mb, UNUSED s32 priority, UNUSED s32 direction,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void osCreateMesgQueue(OSMesgQueue *mq, OSMesg *msgBuf, s32 count) {
|
||||||
|
mq->validCount = 0;
|
||||||
|
mq->first = 0;
|
||||||
|
mq->msgCount = count;
|
||||||
|
mq->msg = msgBuf;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void osSetEventMesg(UNUSED OSEvent e, UNUSED OSMesgQueue *mq, UNUSED OSMesg msg) {
|
void osSetEventMesg(UNUSED OSEvent e, UNUSED OSMesgQueue *mq, UNUSED OSMesg msg) {
|
||||||
}
|
}
|
||||||
s32 osJamMesg(UNUSED OSMesgQueue *mq, UNUSED OSMesg msg, UNUSED s32 flag) {
|
s32 osJamMesg(UNUSED OSMesgQueue *mq, UNUSED OSMesg msg, UNUSED s32 flag) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
s32 osSendMesg(UNUSED OSMesgQueue *mq, UNUSED OSMesg msg, UNUSED s32 flag) {
|
s32 osSendMesg(UNUSED OSMesgQueue *mq, UNUSED OSMesg msg, UNUSED s32 flag) {
|
||||||
|
#ifdef VERSION_EU
|
||||||
|
s32 index;
|
||||||
|
if (mq->validCount >= mq->msgCount) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
index = (mq->first + mq->validCount) % mq->msgCount;
|
||||||
|
mq->msg[index] = msg;
|
||||||
|
mq->validCount++;
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
s32 osRecvMesg(UNUSED OSMesgQueue *mq, UNUSED OSMesg *msg, UNUSED s32 flag) {
|
s32 osRecvMesg(UNUSED OSMesgQueue *mq, UNUSED OSMesg *msg, UNUSED s32 flag) {
|
||||||
|
#ifdef VERSION_EU
|
||||||
|
if (mq->validCount == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (msg != NULL) {
|
||||||
|
*msg = *(mq->first + mq->msg);
|
||||||
|
}
|
||||||
|
mq->first = (mq->first + 1) % mq->msgCount;
|
||||||
|
mq->validCount--;
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue