Pushed the final changes that got audio working!

This commit is contained in:
MeltyPlayer
2022-11-06 20:22:00 -06:00
parent 7bd0cc9a2c
commit 3a4115e8f6
17 changed files with 274 additions and 371 deletions
+21 -9
View File
@@ -35,11 +35,6 @@
#define SAMPLES_TO_OVERPRODUCE 0x10
#define EXTRA_BUFFERED_AI_SAMPLES_TARGET 0x40
struct Sound {
s32 soundBits;
f32 *position;
}; // size = 0x8
struct ChannelVolumeScaleFade {
f32 velocity;
u8 target;
@@ -413,7 +408,7 @@ extern void func_802ad74c(u32 bits, u32 arg);
extern void func_802ad770(u32 bits, s8 arg);
static void update_background_music_after_sound(u8 bank, u8 soundIndex);
static void update_game_sound(void);
void update_game_sound(void);
static void fade_channel_volume_scale(u8 player, u8 channelId, u8 targetScale, u16 fadeTimer);
void process_level_music_dynamics(void);
static u8 begin_background_music_fade(u16 fadeDuration);
@@ -663,7 +658,11 @@ extern void func_sh_802F64C8(void);
* Called from threads: thread5_game_loop
*/
void maybe_tick_game_sound(void) {
DEBUG_PRINT("maybe_tick_game_sound()");
DEBUG_PRINT("- if game loop ticked is false...");
if (sGameLoopTicked != 0) {
DEBUG_PRINT("- updating game sound");
update_game_sound();
sGameLoopTicked = 0;
}
@@ -794,14 +793,17 @@ struct SPTask *create_next_audio_frame_task(void) {
return NULL;
}
void create_next_audio_buffer(s16 *samples, u32 num_samples) {
DEBUG_PRINT("create_next_audio_buffer()");
gAudioFrameCount++;
if (sGameLoopTicked != 0) {
update_game_sound();
sGameLoopTicked = 0;
}
s32 writtenCmds;
DEBUG_PRINT("- synthesis execute");
synthesis_execute(gAudioCmdBuffers[0], &writtenCmds, samples, num_samples);
gAudioRandom = ((gAudioRandom + gAudioFrameCount) * gAudioFrameCount);
DEBUG_PRINT("- decrease sample dma ttls");
decrease_sample_dma_ttls();
}
#endif
@@ -811,7 +813,7 @@ void create_next_audio_buffer(s16 *samples, u32 num_samples) {
* Called from threads: thread4_sound, thread5_game_loop (EU only)
*/
static void process_sound_request(u32 bits, f32 *pos) {
//DEBUG_PRINT("process_sound_request %d\n", bits);
DEBUG_PRINT("# process_sound_request %d\n", bits);
u8 bank;
u8 soundIndex;
u8 counter = 0;
@@ -874,7 +876,7 @@ static void process_sound_request(u32 bits, f32 *pos) {
// If free list has more than one element remaining
if (sSoundBanks[bank][sSoundBankFreeListFront[bank]].next != 0xff && soundIndex != 0) {
//DEBUG_PRINT("process_sound_request2: soundIndex %d\n", soundIndex);
DEBUG_PRINT("process_sound_request2: soundIndex %d\n", soundIndex);
// Allocate from free list
soundIndex = sSoundBankFreeListFront[bank];
@@ -1333,7 +1335,7 @@ void audio_signal_game_loop_tick(void) {
/**
* Called from threads: thread4_sound, thread5_game_loop (EU and SH only)
*/
static void update_game_sound(void) {
void update_game_sound(void) {
u8 soundStatus;
u8 i;
u8 soundId;
@@ -2628,6 +2630,7 @@ void play_toads_jingle(void) {
* Called from threads: thread5_game_loop
*/
void sound_reset(u8 presetId) {
DEBUG_PRINT("sound_reset()");
#ifndef VERSION_JP
if (presetId >= 8) {
presetId = 0;
@@ -2635,26 +2638,35 @@ void sound_reset(u8 presetId) {
}
#endif
sGameLoopTicked = 0;
DEBUG_PRINT("- disable all sequence players");
disable_all_sequence_players();
DEBUG_PRINT("- sound init");
sound_init();
#ifdef VERSION_SH
func_802ad74c(0xF2000000, 0);
#endif
#if defined(VERSION_JP) || defined(VERSION_US)
DEBUG_PRINT("- audio reset session");
audio_reset_session(&gAudioSessionPresets[presetId]);
#else
audio_reset_session_eu(presetId);
#endif
DEBUG_PRINT("- os write back dcache all");
osWritebackDCacheAll();
if (presetId != 7) {
DEBUG_PRINT("- preloading solve puzzle sequence");
preload_sequence(SEQ_EVENT_SOLVE_PUZZLE, PRELOAD_BANKS | PRELOAD_SEQUENCE);
DEBUG_PRINT("- preloading peach message");
preload_sequence(SEQ_EVENT_PEACH_MESSAGE, PRELOAD_BANKS | PRELOAD_SEQUENCE);
DEBUG_PRINT("- preloading star spawn");
preload_sequence(SEQ_EVENT_CUTSCENE_STAR_SPAWN, PRELOAD_BANKS | PRELOAD_SEQUENCE);
}
DEBUG_PRINT("- playing sfx sequence");
seq_player_play_sequence(SEQ_PLAYER_SFX, SEQ_SOUND_PLAYER, 0);
D_80332108 = (D_80332108 & 0xf0) + presetId;
gSoundMode = D_80332108 >> 4;
sHasStartedFadeOut = FALSE;
DEBUG_PRINT("- done resetting sound");
}
/**
+9 -1
View File
@@ -24,11 +24,20 @@ extern u32 gAudioRandom;
extern f32 gAudioVolume;
extern u8 gAudioReverb;
struct Sound {
s32 soundBits;
f32 *position;
}; // size = 0x8
extern struct Sound sSoundRequests[0x100];
extern u8 sSoundRequestCount;
extern u8 gAudioSPTaskYieldBuffer[]; // ucode yield data ptr; only used in JP
struct SPTask *create_next_audio_frame_task(void);
void create_next_audio_buffer(s16 *samples, u32 num_samples);
void audio_signal_game_loop_tick(void);
void update_game_sound(void);
void seq_player_fade_out(u8 player, u16 fadeDuration);
void fade_volume_scale(u8 player, u8 targetScale, u16 fadeDuration);
void seq_player_lower_volume(u8 player, u16 fadeDuration, u8 percentage);
@@ -41,7 +50,6 @@ void stop_sounds_from_source(f32 *pos);
void stop_sounds_in_continuous_banks(void);
void sound_banks_disable(u8 player, u16 bankMask);
void sound_banks_enable(u8 player, u16 bankMask);
void func_80320A4C(u8 bankIndex, u8 arg1);
void set_sound_moving_speed(u8 bank, u8 speed);
void play_dialog_sound(u8 dialogID);
void play_music(u8 player, u16 seqArgs, u16 fadeTimer);
+2 -21
View File
@@ -1,5 +1,6 @@
#include <ultra64.h>
#include "../../debug_print.h"
#include "heap.h"
#include "data.h"
#include "load.h"
@@ -252,26 +253,7 @@ void discard_sequence(s32 seqId) {
}
void *soundAlloc(struct SoundAllocPool *pool, u32 size) {
#if defined(VERSION_EU) || defined(VERSION_SH)
u8 *start;
u8 *pos;
u32 alignedSize = ALIGN16(size);
start = pool->cur;
if (start + alignedSize <= pool->start + pool->size) {
pool->cur += alignedSize;
for (pos = start; pos < pool->cur; pos++) {
*pos = 0;
}
} else {
eu_stubbed_printf_1("Heap OverFlow : Not Allocate %d!\n", size);
return NULL;
}
#ifdef VERSION_SH
pool->numAllocatedEntries++;
#endif
return start;
#else
DEBUG_PRINT("soundAlloc()");
u8 *start;
s32 last;
s32 i;
@@ -287,7 +269,6 @@ void *soundAlloc(struct SoundAllocPool *pool, u32 size) {
return NULL;
}
return start;
#endif
}
#ifdef VERSION_SH
+53 -62
View File
@@ -1,6 +1,7 @@
#ifndef VERSION_SH
#include <ultra64.h>
#include "../../debug_print.h"
#include "data.h"
#include "external.h"
#include "heap.h"
@@ -110,10 +111,17 @@ ALSeqFile *get_audio_file_header(s32 arg0);
* Performs an immediate DMA copy
*/
void audio_dma_copy_immediate(uintptr_t devAddr, void *vAddr, size_t nbytes) {
DEBUG_PRINT("audio_dma_copy_immediate()");
DEBUG_PRINT("- dev addr: %x", devAddr);
DEBUG_PRINT("- vAddr: %x", vAddr);
DEBUG_PRINT("- # bytes: %d", nbytes);
eu_stubbed_printf_3("Romcopy %x -> %x ,size %x\n", devAddr, vAddr, nbytes);
DEBUG_PRINT("- invalidate d cache");
osInvalDCache(vAddr, nbytes);
DEBUG_PRINT("- start dma");
osPiStartDma(&gAudioDmaIoMesg, OS_MESG_PRI_HIGH, OS_READ, devAddr, vAddr, nbytes,
&gAudioDmaMesgQueue);
DEBUG_PRINT("- recv message");
osRecvMesg(&gAudioDmaMesgQueue, NULL, OS_MESG_BLOCK);
eu_stubbed_printf_0("Romcopyend\n");
}
@@ -580,6 +588,8 @@ l2:
}
struct AudioBank *bank_load_immediate(s32 bankId, s32 arg1) {
DEBUG_PRINT("bank_load_immediate()");
UNUSED u32 pad1[4];
u32 buf[4];
u32 numInstruments, numDrums;
@@ -589,24 +599,35 @@ struct AudioBank *bank_load_immediate(s32 bankId, s32 arg1) {
// (This is broken if the length is 1 (mod 16), but that never happens --
// it's always divisible by 4.)
DEBUG_PRINT("- getting alloc");
alloc = gAlCtlHeader->seqArray[bankId].len + 0xf;
DEBUG_PRINT("- aligning");
alloc = ALIGN16(alloc);
alloc -= 0x10;
DEBUG_PRINT("- getting ctl data for bank %d", bankId);
ctlData = gAlCtlHeader->seqArray[bankId].offset;
DEBUG_PRINT("- alloc bank or seq");
ret = alloc_bank_or_seq(&gBankLoadedPool, 1, alloc, arg1, bankId);
if (ret == NULL) {
return NULL;
}
DEBUG_PRINT("- copying dma immediate 1");
DEBUG_PRINT("- ctlData: %x", ctlData);
audio_dma_copy_immediate((uintptr_t) ctlData, buf, 0x10);
DEBUG_PRINT("- getting nums");
numInstruments = buf[0];
numDrums = buf[1];
DEBUG_PRINT("- copying dma immediate 2");
audio_dma_copy_immediate((uintptr_t)(ctlData + 0x10), ret, alloc);
DEBUG_PRINT("- patching bank");
patch_audio_bank(ret, gAlTbl->seqArray[bankId].offset, numInstruments, numDrums);
DEBUG_PRINT("- setting ctl entries");
gCtlEntries[bankId].numInstruments = (u8) numInstruments;
gCtlEntries[bankId].numDrums = (u8) numDrums;
gCtlEntries[bankId].instruments = ret->instruments;
gCtlEntries[bankId].drums = ret->drums;
DEBUG_PRINT("- setting load status");
gBankLoadStatus[bankId] = SOUND_LOAD_STATUS_COMPLETE;
return ret;
}
@@ -763,26 +784,32 @@ u8 get_missing_bank(u32 seqId, s32 *nonNullCount, s32 *nullCount) {
}
struct AudioBank *load_banks_immediate(s32 seqId, u8 *outDefaultBank) {
DEBUG_PRINT("load_banks_immediate()");
void *ret;
u32 bankId;
u16 offset;
u8 i;
DEBUG_PRINT("- getting offset");
offset = ((u16 *) gAlBankSets)[seqId];
#ifdef VERSION_EU
for (i = gAlBankSets[offset++]; i != 0; i--) {
bankId = gAlBankSets[offset++];
#else
offset++;
DEBUG_PRINT("- looping through bank sets");
for (i = gAlBankSets[offset - 1]; i != 0; i--) {
offset++;
DEBUG_PRINT("- getting bank id");
bankId = gAlBankSets[offset - 1];
#endif
DEBUG_PRINT("- checking if bank load is complete");
if (IS_BANK_LOAD_COMPLETE(bankId) == TRUE) {
#ifdef VERSION_EU
ret = get_bank_or_seq(&gBankLoadedPool, 2, bankId);
#else
DEBUG_PRINT("- getting bank or seq");
ret = get_bank_or_seq(&gBankLoadedPool, 2, gAlBankSets[offset - 1]);
#endif
} else {
@@ -790,6 +817,7 @@ struct AudioBank *load_banks_immediate(s32 seqId, u8 *outDefaultBank) {
}
if (ret == NULL) {
DEBUG_PRINT("- bank load immediate");
ret = bank_load_immediate(bankId, 2);
}
}
@@ -798,6 +826,7 @@ struct AudioBank *load_banks_immediate(s32 seqId, u8 *outDefaultBank) {
}
void preload_sequence(u32 seqId, u8 preloadMask) {
DEBUG_PRINT("preload_sequence()");
void *sequenceData;
u8 temp;
@@ -807,17 +836,21 @@ void preload_sequence(u32 seqId, u8 preloadMask) {
gAudioLoadLock = AUDIO_LOCK_LOADING;
if (preloadMask & PRELOAD_BANKS) {
DEBUG_PRINT("- load banks immediate");
load_banks_immediate(seqId, &temp);
}
if (preloadMask & PRELOAD_SEQUENCE) {
// @bug should be IS_SEQ_LOAD_COMPLETE
DEBUG_PRINT("- checking if bank load immediate");
if (IS_BANK_LOAD_COMPLETE(seqId) == TRUE) {
eu_stubbed_printf_1("SEQ %d ALREADY CACHED\n", seqId);
DEBUG_PRINT("- getting bank or seq");
sequenceData = get_bank_or_seq(&gSeqLoadedPool, 2, seqId);
} else {
sequenceData = NULL;
}
DEBUG_PRINT("- checking dma immediate");
if (sequenceData == NULL && sequence_dma_immediate(seqId, 2) == NULL) {
gAudioLoadLock = AUDIO_LOCK_NOT_LOADING;
return;
@@ -905,22 +938,12 @@ void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) {
// (void) must be omitted from parameters to fix stack with -framepointer
void audio_init() {
#if defined(VERSION_EU)
UNUSED s8 pad[16];
#else
DEBUG_PRINT("audio_init()");
UNUSED s8 pad[32];
#endif
#if defined(VERSION_JP) || defined(VERSION_US)
u8 buf[0x10];
#endif
s32 i, j, UNUSED k;
UNUSED s32 lim1; // lim1 unused in EU
#if defined(VERSION_EU)
UNUSED u8 buf[0x10];
s32 UNUSED lim2, lim3;
#else
s32 lim2, UNUSED lim3;
#endif
UNUSED u32 size;
UNUSED u64 *ptr64;
void *data;
@@ -928,57 +951,19 @@ void audio_init() {
gAudioLoadLock = AUDIO_LOCK_UNINITIALIZED;
#if defined(VERSION_JP) || defined(VERSION_US)
DEBUG_PRINT("- setting values in unused");
lim1 = gUnusedCount80333EE8;
for (i = 0; i < lim1; i++) {
gUnused80226E58[i] = 0;
gUnused80226E98[i] = 0;
}
DEBUG_PRINT("- clearing audio heap");
lim2 = gAudioHeapSize;
for (i = 0; i <= lim2 / 8 - 1; i++) {
((u64 *) gAudioHeap)[i] = 0;
}
#ifdef TARGET_N64
// It seems boot.s doesn't clear the .bss area for audio, so do it here.
i = 0;
lim3 = ((uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker) / 8;
ptr64 = &gAudioGlobalsStartMarker - 1;
for (k = lim3; k >= 0; k--) {
i++;
ptr64[i] = 0;
}
#endif
#else
for (i = 0; i < gAudioHeapSize / 8; i++) {
((u64 *) gAudioHeap)[i] = 0;
}
#ifdef TARGET_N64
// It seems boot.s doesn't clear the .bss area for audio, so do it here.
lim3 = ((uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker) / 8;
ptr64 = &gAudioGlobalsStartMarker;
for (k = lim3; k >= 0; k--) {
*ptr64++ = 0;
}
#endif
D_EU_802298D0 = 20.03042f;
gRefreshRate = 50;
port_eu_init();
if (k) {
}
#endif
#ifdef TARGET_N64
eu_stubbed_printf_3("Clear Workarea %x -%x size %x \n",
(uintptr_t) &gAudioGlobalsStartMarker,
(uintptr_t) &gAudioGlobalsEndMarker,
(uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker
);
#endif
eu_stubbed_printf_1("AudioHeap is %x\n", gAudioHeapSize);
@@ -1009,13 +994,7 @@ void audio_init() {
}
}
#if defined(VERSION_EU)
gAudioResetPresetIdToLoad = 0;
gAudioResetStatus = 1;
audio_shut_down_and_reset_step();
#else
audio_reset_session(&gAudioSessionPresets[0]);
#endif
// Not sure about these prints
eu_stubbed_printf_1("Heap reset.Synth Change %x \n", 0);
@@ -1027,33 +1006,45 @@ void audio_init() {
data = gMusicData;
audio_dma_copy_immediate((uintptr_t) data, gSeqFileHeader, 0x10);
gSequenceCount = gSeqFileHeader->seqCount;
#if defined(VERSION_EU)
size = gSequenceCount * sizeof(ALSeqData) + 4;
size = ALIGN16(size);
#else
size = ALIGN16(gSequenceCount * sizeof(ALSeqData) + 4);
#endif
gSeqFileHeader = soundAlloc(&gAudioInitPool, size);
audio_dma_copy_immediate((uintptr_t) data, gSeqFileHeader, size);
alSeqFileNew(gSeqFileHeader, data);
// Load header for CTL (instrument metadata)
DEBUG_PRINT("- loading ctl header");
gAlCtlHeader = (ALSeqFile *) buf;
data = gSoundDataADSR;
DEBUG_PRINT("- copying dma immediate");
audio_dma_copy_immediate((uintptr_t) data, gAlCtlHeader, 0x10);
size = gAlCtlHeader->seqCount * sizeof(ALSeqData) + 4;
DEBUG_PRINT("- seq count: %d", gAlCtlHeader->seqCount);
DEBUG_PRINT("- size after read: %d", size);
size = ALIGN16(size);
DEBUG_PRINT("- size after align: %d", size);
gCtlEntries = soundAlloc(&gAudioInitPool, gAlCtlHeader->seqCount * sizeof(struct CtlEntry));
gAlCtlHeader = soundAlloc(&gAudioInitPool, size);
DEBUG_PRINT("@ copying data from sound data adsr to ctl header");
DEBUG_PRINT("- data: %x", data);
DEBUG_PRINT("- ctl header: %x", gAlCtlHeader);
DEBUG_PRINT("- size: %d", size);
audio_dma_copy_immediate((uintptr_t) data, gAlCtlHeader, size);
DEBUG_PRINT("- creating new seq file for ctl");
alSeqFileNew(gAlCtlHeader, data);
// Load header for TBL (raw sound data)
DEBUG_PRINT("- loading tbl");
gAlTbl = (ALSeqFile *) buf;
DEBUG_PRINT("- copying dma");
audio_dma_copy_immediate((uintptr_t) data, gAlTbl, 0x10);
DEBUG_PRINT("- tbl seq count: %d", gAlTbl->seqCount);
size = gAlTbl->seqCount * sizeof(ALSeqData) + 4;
DEBUG_PRINT("- size: %d", size);
size = ALIGN16(size);
DEBUG_PRINT("- size after align: %d", size);
gAlTbl = soundAlloc(&gAudioInitPool, size);
DEBUG_PRINT("- tbl alloc at %x", gAlTbl);
DEBUG_PRINT("- gSoundDataRaw at %x", gSoundDataRaw);
audio_dma_copy_immediate((uintptr_t) gSoundDataRaw, gAlTbl, size);
alSeqFileNew(gAlTbl, gSoundDataRaw);
+36 -16
View File
@@ -6,6 +6,7 @@
#include "heap.h"
#include "load.h"
#include "seqplayer.h"
#include "../../debug_print.h"
#define PORTAMENTO_IS_SPECIAL(x) ((x).mode & 0x80)
#define PORTAMENTO_MODE(x) ((x).mode & ~0x80)
@@ -398,12 +399,11 @@ void init_layer_freelist(void) {
}
u8 m64_read_u8(struct M64ScriptState *state) {
#if defined(VERSION_EU) || defined(VERSION_SH)
return *(state->pc++);
#else
DEBUG_PRINT("m64_read_u8()");
DEBUG_PRINT("- state at %x", state);
u8 *midiArg = state->pc++;
DEBUG_PRINT("- read u8 (%d) at (%x)", *midiArg, midiArg);
return *midiArg;
#endif
}
s16 m64_read_s16(struct M64ScriptState *state) {
@@ -1109,7 +1109,11 @@ s32 seq_channel_layer_process_script_part2(struct SequenceChannelLayer *layer) {
break;
case 0xc6: // layer_setinstr
DEBUG_PRINT(" - cmd 0xc6, setinstr");
cmd = m64_read_u8(state);
DEBUG_PRINT(" - read %d from state", cmd);
if (cmd >= 0x7f) {
if (cmd == 0x7f) {
layer->instOrWave = 0;
@@ -1401,6 +1405,9 @@ s32 seq_channel_layer_process_script_part3(struct SequenceChannelLayer *layer, s
#endif
u8 get_instrument(struct SequenceChannel *seqChannel, u8 instId, struct Instrument **instOut, struct AdsrSettings *adsr) {
DEBUG_PRINT("@ get_instrument()");
DEBUG_PRINT("- instrument id: %d", instId);
struct Instrument *inst;
#if defined(VERSION_EU) || defined(VERSION_SH)
inst = get_instrument_inner(seqChannel->bankId, instId);
@@ -1458,6 +1465,10 @@ u8 get_instrument(struct SequenceChannel *seqChannel, u8 instId, struct Instrume
}
void set_instrument(struct SequenceChannel *seqChannel, u8 instId) {
DEBUG_PRINT("@ set_instrument()");
DEBUG_PRINT("- bank id: %d", seqChannel->bankId);
DEBUG_PRINT("- instrument id: %d", instId);
if (instId >= 0x80) {
seqChannel->instOrWave = instId;
seqChannel->instrument = NULL;
@@ -1486,6 +1497,8 @@ void sequence_channel_set_volume(struct SequenceChannel *seqChannel, u8 volume)
}
void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
DEBUG_PRINT("sequence_channel_process_script()");
struct M64ScriptState *state;
struct SequencePlayer *seqPlayer;
u8 cmd;
@@ -1523,6 +1536,8 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
if (seqChannel->delay == 0) {
for (;;) {
cmd = m64_read_u8(state);
DEBUG_PRINT("- handling command: %x", cmd);
#if !defined(VERSION_EU) && !defined(VERSION_SH)
if (cmd == 0xff) // chan_end
{
@@ -1703,7 +1718,12 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
#endif
case 0xc1: // chan_setinstr ("set program"?)
set_instrument(seqChannel, m64_read_u8(state));
DEBUG_PRINT(" - cmd 0xc1, setinstr");
u8 instrId = m64_read_u8(state);
DEBUG_PRINT(" - read %d from state", instrId);
set_instrument(seqChannel, instrId);
break;
case 0xc3: // chan_largenotesoff
@@ -1832,25 +1852,21 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
break;
case 0xc6: // chan_setbank; switch bank within set
DEBUG_PRINT(" - case 0xc6 - switch bank");
DEBUG_PRINT(" - seq id %d", seqPlayer->seqId);
cmd = m64_read_u8(state);
DEBUG_PRINT(" - backwards bank id %d", cmd);
// Switch to the temp's (0-indexed) bank in this sequence's
// bank set. Note that in the binary format (not in the JSON!)
// the banks are listed backwards, so we counts from the back.
// (gAlBankSets[offset] is number of banks)
#if defined(VERSION_EU) || defined(VERSION_SH)
sp38 = ((u16 *) gAlBankSets)[seqPlayer->seqId];
loBits = *(sp38 + gAlBankSets);
cmd = gAlBankSets[(s32)sp38 + loBits - cmd];
#else
sp5A = ((u16 *) gAlBankSets)[seqPlayer->seqId];
loBits = *(sp5A + gAlBankSets);
cmd = gAlBankSets[sp5A + loBits - cmd];
#endif
#ifdef VERSION_SH
if (get_bank_or_seq(1, 2, cmd) != NULL)
#else
if (get_bank_or_seq(&gBankLoadedPool, 2, cmd) != NULL)
#endif
{
seqChannel->bankId = cmd;
} else {
@@ -2138,6 +2154,8 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
#else
case 0x80: // chan_ioreadval; read data from audio lib
#endif
DEBUG_PRINT("- cmd 0x80, read data from audio lib");
DEBUG_PRINT(" - reading index: %d", loBits);
value = seqChannel->soundScriptIO[loBits];
if (loBits < 4) {
seqChannel->soundScriptIO[loBits] = -1;
@@ -2229,7 +2247,9 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
}
void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) {
u8 cmd;
DEBUG_PRINT("sequence_player_process_sequence()");
u8 cmd;
#ifdef VERSION_SH
UNUSED u32 pad;
#endif
+66 -203
View File
@@ -1,6 +1,7 @@
#ifndef VERSION_SH
#include <ultra64.h>
#include "../../debug_print.h"
#include "synthesis.h"
#include "heap.h"
#include "data.h"
@@ -27,9 +28,13 @@
#define DMEM_ADDR_WET_RIGHT_CH 0x880
#define aSetLoadBufferPair(pkt, c, off) \
DEBUG_PRINT("- (in set load buffer pair, set buffer 1) "); \
aSetBuffer(pkt, 0, c + DMEM_ADDR_WET_LEFT_CH, 0, DEFAULT_LEN_1CH - c); \
DEBUG_PRINT("- (in set load buffer pair, load buffer 1) "); \
aLoadBuffer(pkt, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.ringBuffer.left + (off))); \
DEBUG_PRINT("- (in set load buffer pair, set buffer 2) "); \
aSetBuffer(pkt, 0, c + DMEM_ADDR_WET_RIGHT_CH, 0, DEFAULT_LEN_1CH - c); \
DEBUG_PRINT("- (in set load buffer pair, load buffer 2) "); \
aLoadBuffer(pkt, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.ringBuffer.right + (off)))
#define aSetSaveBufferPair(pkt, c, d, off) \
@@ -324,6 +329,7 @@ u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen) {
#else
// bufLen will be divisible by 16
u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen) {
DEBUG_PRINT("synthesis_execute()");
s32 chunkLen;
s32 i;
u32 *aiBufPtr = (u32 *) aiBuf;
@@ -506,6 +512,8 @@ u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateI
}
#else
u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex) {
DEBUG_PRINT("synthesis_do_one_audio_update()");
UNUSED s32 pad1[1];
s16 ra;
s16 t4;
@@ -514,35 +522,52 @@ u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateI
UNUSED s32 pad2[1];
s16 temp;
DEBUG_PRINT("- curFrame: %d", gSynthesisReverb.curFrame);
DEBUG_PRINT("- updateIndex: %d", updateIndex);
v1 = &gSynthesisReverb.items[gSynthesisReverb.curFrame][updateIndex];
DEBUG_PRINT("- v1: %x", v1);
if (gSynthesisReverb.useReverb == 0) {
DEBUG_PRINT("- w/o reverb");
aClearBuffer(cmd++, DMEM_ADDR_LEFT_CH, DEFAULT_LEN_2CH);
cmd = synthesis_process_notes(aiBuf, bufLen, cmd);
} else {
DEBUG_PRINT("- w/ reverb");
if (gReverbDownsampleRate == 1) {
DEBUG_PRINT("- w/ reverb downsample");
// Put the oldest samples in the ring buffer into the wet channels
DEBUG_PRINT("- set load buffer pair 1");
DEBUG_PRINT("- startPos: %d", v1->startPos);
aSetLoadBufferPair(cmd++, 0, v1->startPos);
if (v1->lengthB != 0) {
// Ring buffer wrapped
DEBUG_PRINT("- set load buffer pair 2");
aSetLoadBufferPair(cmd++, v1->lengthA, 0);
temp = 0;
}
// Use the reverb sound as initial sound for this audio update
DEBUG_PRINT("- dmem move");
aDMEMMove(cmd++, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_LEFT_CH, DEFAULT_LEN_2CH);
// (Hopefully) lower the volume of the wet channels. New reverb will later be mixed into
// these channels.
DEBUG_PRINT("- set buffer");
aSetBuffer(cmd++, 0, 0, 0, DEFAULT_LEN_2CH);
// 0x8000 here is -100%
DEBUG_PRINT("- mix");
aMix(cmd++, 0, /*gain*/ 0x8000 + gSynthesisReverb.reverbGain, /*in*/ DMEM_ADDR_WET_LEFT_CH,
/*out*/ DMEM_ADDR_WET_LEFT_CH);
} else {
DEBUG_PRINT("- w/o reverb downsample");
// Same as above but upsample the previously downsampled samples used for reverb first
temp = 0; //! jesus christ
t4 = (v1->startPos & 7) * 2;
ra = ALIGN(v1->lengthA + t4, 4);
DEBUG_PRINT("- set load buffer pair");
aSetLoadBufferPair(cmd++, 0, v1->startPos - t4 / 2);
if (v1->lengthB != 0) {
// Ring buffer wrapped
@@ -553,12 +578,19 @@ u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateI
//! useless assignment.
ra = ra + temp;
}
DEBUG_PRINT("- set buffer 1");
aSetBuffer(cmd++, 0, t4 + DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_LEFT_CH, bufLen << 1);
DEBUG_PRINT("- resample 1");
aResample(cmd++, gSynthesisReverb.resampleFlags, (u16) gSynthesisReverb.resampleRate, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.resampleStateLeft));
DEBUG_PRINT("- set buffer 2");
aSetBuffer(cmd++, 0, t4 + DMEM_ADDR_WET_RIGHT_CH, DMEM_ADDR_RIGHT_CH, bufLen << 1);
DEBUG_PRINT("- resample 2");
aResample(cmd++, gSynthesisReverb.resampleFlags, (u16) gSynthesisReverb.resampleRate, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.resampleStateRight));
DEBUG_PRINT("- set buffer 3");
aSetBuffer(cmd++, 0, 0, 0, DEFAULT_LEN_2CH);
DEBUG_PRINT("- mix");
aMix(cmd++, 0, /*gain*/ 0x8000 + gSynthesisReverb.reverbGain, /*in*/ DMEM_ADDR_LEFT_CH, /*out*/ DMEM_ADDR_LEFT_CH);
DEBUG_PRINT("- dmem move");
aDMEMMove(cmd++, DMEM_ADDR_LEFT_CH, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_2CH);
}
cmd = synthesis_process_notes(aiBuf, bufLen, cmd);
@@ -586,6 +618,8 @@ u64 *synthesis_process_note(struct Note *note, struct NoteSubEu *noteSubEu, stru
UNUSED s32 pad0[3];
#else
u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) {
DEBUG_PRINT("synthesis_process_notes()");
s32 noteIndex; // sp174
struct Note *note; // s7
UNUSED u8 pad0[0x08];
@@ -669,49 +703,35 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) {
u16 noteSamplesDmemAddrBeforeResampling; // spD6, spAA
#ifndef VERSION_EU
for (noteIndex = 0; noteIndex < gMaxSimultaneousNotes; noteIndex++) {
DEBUG_PRINT("- for note index %d/%d", noteIndex, gMaxSimultaneousNotes);
DEBUG_PRINT("- getting note");
note = &gNotes[noteIndex];
#ifdef VERSION_US
//! This function requires note->enabled to be volatile, but it breaks other functions like note_enable.
//! Casting to a struct with just the volatile bitfield works, but there may be a better way to match.
DEBUG_PRINT("- if note is enabled but not loaded");
if (((struct vNote *)note)->enabled && IS_BANK_LOAD_COMPLETE(note->bankId) == FALSE) {
#else
if (IS_BANK_LOAD_COMPLETE(note->bankId) == FALSE) {
#endif
DEBUG_PRINT("- note is enabled but not loaded");
gAudioErrorFlags = (note->bankId << 8) + noteIndex + 0x1000000;
} else if (((struct vNote *)note)->enabled) {
#else
if (note->noteSubEu.enabled == FALSE) {
return cmd;
} else {
#endif
flags = 0;
#ifdef VERSION_EU
tempBufLen = bufLen;
#endif
continue;
}
#ifdef VERSION_EU
if (noteSubEu->needsInit == TRUE) {
#else
DEBUG_PRINT("- if note is enabled");
if (((struct vNote *)note)->enabled) {
DEBUG_PRINT("$ note is enabled!");
flags = 0;
DEBUG_PRINT("- if note needs to be init");
if (note->needsInit == TRUE) {
#endif
flags = A_INIT;
#ifndef VERSION_EU
note->samplePosInt = 0;
note->samplePosFrac = 0;
#else
synthesisState->restart = FALSE;
synthesisState->samplePosInt = 0;
synthesisState->samplePosFrac = 0;
synthesisState->curVolLeft = 1;
synthesisState->curVolRight = 1;
synthesisState->prevHeadsetPanRight = 0;
synthesisState->prevHeadsetPanLeft = 0;
#endif
}
#ifndef VERSION_EU
DEBUG_PRINT("- if note frequency is less than 2");
if (note->frequency < US_FLOAT(2.0)) {
nParts = 1;
if (note->frequency > US_FLOAT(1.99996)) {
@@ -730,43 +750,29 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) {
resamplingRateFixedPoint = (u16)(s32)(resamplingRate * 32768.0f);
samplesLenFixedPoint = note->samplePosFrac + (resamplingRateFixedPoint * bufLen) * 2;
note->samplePosFrac = samplesLenFixedPoint & 0xFFFF; // 16-bit store, can't reuse
#else
resamplingRateFixedPoint = noteSubEu->resamplingRateFixedPoint;
nParts = noteSubEu->hasTwoAdpcmParts + 1;
samplesLenFixedPoint = (resamplingRateFixedPoint * tempBufLen * 2) + synthesisState->samplePosFrac;
synthesisState->samplePosFrac = samplesLenFixedPoint & 0xFFFF;
#endif
#ifdef VERSION_EU
if (noteSubEu->isSyntheticWave) {
cmd = load_wave_samples(cmd, noteSubEu, synthesisState, samplesLenFixedPoint >> 0x10);
noteSamplesDmemAddrBeforeResampling = (synthesisState->samplePosInt * 2) + DMEM_ADDR_UNCOMPRESSED_NOTE;
synthesisState->samplePosInt += samplesLenFixedPoint >> 0x10;
}
#else
DEBUG_PRINT("- if note sound is null");
if (note->sound == NULL) {
// A wave synthesis note (not ADPCM)
DEBUG_PRINT("- note is null, do wave synthesis");
cmd = load_wave_samples(cmd, note, samplesLenFixedPoint >> 0x10);
noteSamplesDmemAddrBeforeResampling = DMEM_ADDR_UNCOMPRESSED_NOTE + note->samplePosInt * 2;
note->samplePosInt += (samplesLenFixedPoint >> 0x10);
flags = 0;
}
#endif
else {
// ADPCM note
DEBUG_PRINT("- @ handle adpcm note");
#ifdef VERSION_EU
audioBookSample = noteSubEu->sound.audioBankSound->sample;
#else
audioBookSample = note->sound->sample;
#endif
loopInfo = audioBookSample->loop;
endPos = loopInfo->end;
sampleAddr = audioBookSample->sampleAddr;
resampledTempLen = 0;
for (curPart = 0; curPart < nParts; curPart++) {
DEBUG_PRINT("- for part %d", curPart);
nAdpcmSamplesProcessed = 0; // s8
s5 = 0; // s4
@@ -782,21 +788,11 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) {
if (curLoadedBook != audioBookSample->book->book) {
u32 nEntries; // v1
curLoadedBook = audioBookSample->book->book;
#ifdef VERSION_EU
nEntries = 16 * audioBookSample->book->order * audioBookSample->book->npredictors;
aLoadADPCM(cmd++, nEntries, VIRTUAL_TO_PHYSICAL2(curLoadedBook + noteSubEu->bookOffset));
#else
nEntries = audioBookSample->book->order * audioBookSample->book->npredictors;
DEBUG_PRINT("- loading adpcm");
aLoadADPCM(cmd++, nEntries * 16, VIRTUAL_TO_PHYSICAL2(curLoadedBook));
#endif
}
#ifdef VERSION_EU
if (noteSubEu->bookOffset) {
curLoadedBook = euUnknownData_80301950; // what's this? never read
}
#endif
while (nAdpcmSamplesProcessed != samplesLenAdjusted) {
s32 samplesRemaining; // v1
s32 s0;
@@ -804,23 +800,12 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) {
noteFinished = FALSE;
restart = FALSE;
nSamplesToProcess = samplesLenAdjusted - nAdpcmSamplesProcessed;
#ifdef VERSION_EU
s2 = synthesisState->samplePosInt & 0xf;
samplesRemaining = endPos - synthesisState->samplePosInt;
#else
s2 = note->samplePosInt & 0xf;
samplesRemaining = endPos - note->samplePosInt;
#endif
#ifdef VERSION_EU
if (s2 == 0 && synthesisState->restart == FALSE) {
s2 = 16;
}
#else
if (s2 == 0 && note->restart == FALSE) {
s2 = 16;
}
#endif
s6 = 16 - s2; // a1
if (nSamplesToProcess < samplesRemaining) {
@@ -828,11 +813,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) {
s0 = t0 * 16;
s3 = s6 + s0 - nSamplesToProcess;
} else {
#ifndef VERSION_EU
s0 = samplesRemaining + s2 - 0x10;
#else
s0 = samplesRemaining - s6;
#endif
s3 = 0;
if (s0 <= 0) {
s0 = 0;
@@ -848,21 +829,10 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) {
}
if (t0 != 0) {
#ifdef VERSION_EU
temp = (synthesisState->samplePosInt - s2 + 0x10) / 16;
if (audioBookSample->loaded == 0x81) {
v0_2 = sampleAddr + temp * 9;
} else {
v0_2 = dma_sample_data(
(uintptr_t) (sampleAddr + temp * 9),
t0 * 9, flags, &synthesisState->sampleDmaIndex);
}
#else
temp = (note->samplePosInt - s2 + 0x10) / 16;
v0_2 = dma_sample_data(
(uintptr_t) (sampleAddr + temp * 9),
t0 * 9, flags, &note->sampleDmaIndex);
#endif
a3 = (u32)((uintptr_t) v0_2 & 0xf);
aSetBuffer(cmd++, 0, DMEM_ADDR_COMPRESSED_ADPCM_DATA, 0, t0 * 9 + a3);
aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(v0_2 - a3));
@@ -871,38 +841,14 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) {
a3 = 0;
}
#ifdef VERSION_EU
if (synthesisState->restart != FALSE) {
aSetLoop(cmd++, VIRTUAL_TO_PHYSICAL2(audioBookSample->loop->state));
flags = A_LOOP; // = 2
synthesisState->restart = FALSE;
}
#else
DEBUG_PRINT("- if not note restart");
if (note->restart != FALSE) {
aSetLoop(cmd++, VIRTUAL_TO_PHYSICAL2(audioBookSample->loop->state));
flags = A_LOOP; // = 2
note->restart = FALSE;
}
#endif
nSamplesInThisIteration = s0 + s6 - s3;
#ifdef VERSION_EU
if (nAdpcmSamplesProcessed == 0) {
aSetBuffer(cmd++, 0, DMEM_ADDR_COMPRESSED_ADPCM_DATA + a3,
DMEM_ADDR_UNCOMPRESSED_NOTE, s0 * 2);
aADPCMdec(cmd++, flags,
VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->adpcmdecState));
sp130 = s2 * 2;
} else {
s5Aligned = ALIGN(s5, 5);
aSetBuffer(cmd++, 0, DMEM_ADDR_COMPRESSED_ADPCM_DATA + a3,
DMEM_ADDR_UNCOMPRESSED_NOTE + s5Aligned, s0 * 2);
aADPCMdec(cmd++, flags,
VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->adpcmdecState));
aDMEMMove(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + s5Aligned + (s2 * 2),
DMEM_ADDR_UNCOMPRESSED_NOTE + s5, (nSamplesInThisIteration) * 2);
}
#else
if (nAdpcmSamplesProcessed == 0) {
aSetBuffer(cmd++, 0, DMEM_ADDR_COMPRESSED_ADPCM_DATA + a3, DMEM_ADDR_UNCOMPRESSED_NOTE, s0 * 2);
aADPCMdec(cmd++, flags, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->adpcmdecState));
@@ -912,7 +858,6 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) {
aADPCMdec(cmd++, flags, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->adpcmdecState));
aDMEMMove(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + ALIGN(s5, 5) + (s2 * 2), DMEM_ADDR_UNCOMPRESSED_NOTE + s5, (nSamplesInThisIteration) * 2);
}
#endif
nAdpcmSamplesProcessed += nSamplesInThisIteration;
@@ -936,35 +881,23 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) {
}
flags = 0;
DEBUG_PRINT("- if note finished");
if (noteFinished) {
aClearBuffer(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + s5,
(samplesLenAdjusted - nAdpcmSamplesProcessed) * 2);
#ifdef VERSION_EU
noteSubEu->finished = 1;
note->noteSubEu.finished = 1;
note->noteSubEu.enabled = 0;
#else
note->samplePosInt = 0;
note->finished = 1;
((struct vNote *)note)->enabled = 0;
#endif
break;
}
#ifdef VERSION_EU
if (restart) {
synthesisState->restart = TRUE;
synthesisState->samplePosInt = loopInfo->start;
} else {
synthesisState->samplePosInt += nSamplesToProcess;
}
#else
DEBUG_PRINT("- if restart");
if (restart) {
note->restart = TRUE;
note->samplePosInt = loopInfo->start;
} else {
note->samplePosInt += nSamplesToProcess;
}
#endif
}
switch (nParts) {
@@ -976,18 +909,10 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) {
switch (curPart) {
case 0:
aSetBuffer(cmd++, 0, DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, DMEM_ADDR_RESAMPLED, samplesLenAdjusted + 4);
#ifdef VERSION_EU
aResample(cmd++, A_INIT, 0xff60, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->dummyResampleState));
#else
aResample(cmd++, A_INIT, 0xff60, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->dummyResampleState));
#endif
resampledTempLen = samplesLenAdjusted + 4;
noteSamplesDmemAddrBeforeResampling = DMEM_ADDR_RESAMPLED + 4;
#ifdef VERSION_EU
if (noteSubEu->finished != FALSE) {
#else
if (note->finished != FALSE) {
#endif
aClearBuffer(cmd++, DMEM_ADDR_RESAMPLED + resampledTempLen, samplesLenAdjusted + 0x10);
}
break;
@@ -996,15 +921,9 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) {
aSetBuffer(cmd++, 0, DMEM_ADDR_UNCOMPRESSED_NOTE + sp130,
DMEM_ADDR_RESAMPLED2,
samplesLenAdjusted + 8);
#ifdef VERSION_EU
aResample(cmd++, A_INIT, 0xff60,
VIRTUAL_TO_PHYSICAL2(
synthesisState->synthesisBuffers->dummyResampleState));
#else
aResample(cmd++, A_INIT, 0xff60,
VIRTUAL_TO_PHYSICAL2(
note->synthesisBuffers->dummyResampleState));
#endif
aDMEMMove(cmd++, DMEM_ADDR_RESAMPLED2 + 4,
DMEM_ADDR_RESAMPLED + resampledTempLen,
samplesLenAdjusted + 4);
@@ -1012,11 +931,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) {
}
}
#ifdef VERSION_EU
if (noteSubEu->finished != FALSE) {
#else
if (note->finished != FALSE) {
#endif
break;
}
}
@@ -1024,15 +939,6 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) {
flags = 0;
#ifdef VERSION_EU
if (noteSubEu->needsInit == TRUE) {
flags = A_INIT;
noteSubEu->needsInit = FALSE;
}
cmd = final_resample(cmd, synthesisState, bufLen * 2, resamplingRateFixedPoint,
noteSamplesDmemAddrBeforeResampling, flags);
#else
if (note->needsInit == TRUE) {
flags = A_INIT;
note->needsInit = FALSE;
@@ -1040,75 +946,41 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) {
cmd = final_resample(cmd, note, bufLen * 2, resamplingRateFixedPoint,
noteSamplesDmemAddrBeforeResampling, flags);
#endif
#ifdef VERSION_EU
if (noteSubEu->headsetPanRight != 0 || synthesisState->prevHeadsetPanRight != 0) {
leftRight = 1;
} else if (noteSubEu->headsetPanLeft != 0 || synthesisState->prevHeadsetPanLeft != 0) {
leftRight = 2;
#else
if (note->headsetPanRight != 0 || note->prevHeadsetPanRight != 0) {
leftRight = 1;
} else if (note->headsetPanLeft != 0 || note->prevHeadsetPanLeft != 0) {
leftRight = 2;
#endif
} else {
leftRight = 0;
}
#ifdef VERSION_EU
cmd = process_envelope(cmd, noteSubEu, synthesisState, bufLen, 0, leftRight, flags);
#else
cmd = process_envelope(cmd, note, bufLen, 0, leftRight, flags);
#endif
#ifdef VERSION_EU
if (noteSubEu->usesHeadsetPanEffects) {
cmd = note_apply_headset_pan_effects(cmd, noteSubEu, synthesisState, bufLen * 2, flags, leftRight);
}
#else
if (note->usesHeadsetPanEffects) {
cmd = note_apply_headset_pan_effects(cmd, note, bufLen * 2, flags, leftRight);
}
#endif
}
#ifndef VERSION_EU
}
DEBUG_PRINT("- done handling notes");
DEBUG_PRINT("- setting buffer 1");
t9 = bufLen * 2;
aSetBuffer(cmd++, 0, 0, DMEM_ADDR_TEMP, t9);
DEBUG_PRINT("- interleaving");
aInterleave(cmd++, DMEM_ADDR_LEFT_CH, DMEM_ADDR_RIGHT_CH);
t9 *= 2;
DEBUG_PRINT("- setting buffer 2");
aSetBuffer(cmd++, 0, 0, DMEM_ADDR_TEMP, t9);
DEBUG_PRINT("- saving buffer");
aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(aiBuf));
#endif
DEBUG_PRINT("- returning from process notes");
return cmd;
}
#ifdef VERSION_EU
u64 *load_wave_samples(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s32 nSamplesToLoad) {
s32 a3;
s32 repeats;
s32 i;
aSetBuffer(cmd++, /*flags*/ 0, /*dmemin*/ DMEM_ADDR_UNCOMPRESSED_NOTE, /*dmemout*/ 0, /*count*/ 128);
aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(noteSubEu->sound.samples));
synthesisState->samplePosInt &= 0x3f;
a3 = 64 - synthesisState->samplePosInt;
if (a3 < nSamplesToLoad) {
repeats = (nSamplesToLoad - a3 + 63) / 64;
for (i = 0; i < repeats; i++) {
aDMEMMove(cmd++,
/*dmemin*/ DMEM_ADDR_UNCOMPRESSED_NOTE,
/*dmemout*/ DMEM_ADDR_UNCOMPRESSED_NOTE + (1 + i) * 128,
/*count*/ 128);
}
}
return cmd;
}
#else
u64 *load_wave_samples(u64 *cmd, struct Note *note, s32 nSamplesToLoad) {
s32 a3;
s32 i;
@@ -1124,21 +996,12 @@ u64 *load_wave_samples(u64 *cmd, struct Note *note, s32 nSamplesToLoad) {
}
return cmd;
}
#endif
#ifdef VERSION_EU
u64 *final_resample(u64 *cmd, struct NoteSynthesisState *synthesisState, s32 count, u16 pitch, u16 dmemIn, u32 flags) {
aSetBuffer(cmd++, /*flags*/ 0, dmemIn, /*dmemout*/ DMEM_ADDR_TEMP, count);
aResample(cmd++, flags, pitch, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->finalResampleState));
return cmd;
}
#else
u64 *final_resample(u64 *cmd, struct Note *note, s32 count, u16 pitch, u16 dmemIn, u32 flags) {
aSetBuffer(cmd++, /*flags*/ 0, dmemIn, /*dmemout*/ DMEM_ADDR_TEMP, count);
aResample(cmd++, flags, pitch, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->finalResampleState));
return cmd;
}
#endif
#ifndef VERSION_EU
u64 *process_envelope(u64 *cmd, struct Note *note, s32 nSamples, u16 inBuf, s32 headsetPanSettings,
+7 -1
View File
@@ -439,10 +439,14 @@ typedef short ENVMIX_STATE[40];
* s parameter to this command is the source in DRAM.
*/
#define aLoadBuffer(pkt, s) \
{ \
{ \
DEBUG_PRINT("aLoadBuffer()"); \
DEBUG_PRINT("- getting pkt"); \
Acmd *_a = (Acmd *)pkt; \
\
DEBUG_PRINT("- setting first word"); \
_a->words.w0 = _SHIFTL(A_LOADBUFF, 24, 8); \
DEBUG_PRINT("- setting second word"); \
_a->words.w1 = (uintptr_t)(s); \
}
@@ -558,6 +562,8 @@ typedef short ENVMIX_STATE[40];
*/
#define aSetBuffer(pkt, f, i, o, c) \
{ \
DEBUG_PRINT("aSetBuffer()"); \
DEBUG_PRINT("- getting pkt"); \
Acmd *_a = (Acmd *)pkt; \
\
_a->words.w0 = (_SHIFTL(A_SETBUFF, 24, 8) | _SHIFTL(f, 16, 8) | \
+7 -35
View File
@@ -2,49 +2,21 @@
#define _ULTRA64_LIBAUDIO_H_
#include "abi.h"
#include <stdlib.h>
typedef struct
{
u8 *offset;
s32 len;
#ifdef VERSION_SH
s8 medium;
s8 magic; // tbl: 0x04, otherwise: 0x03
// for ctl (else zeros):
union {
// unused, just for clarification (big endian)
struct {
u8 bank;
u8 ff;
u8 numInstruments;
u8 numDrums;
} as_u8;
// used
struct {
s16 bankAndFf;
s16 numInstrumentsAndDrums;
} as_s16;
} ctl;
#endif
u8 *offset __attribute__((aligned (8)));
s32 len __attribute__((aligned (8)));
} ALSeqData;
typedef struct
{
#ifndef VERSION_SH
s16 revision;
#endif
s16 seqCount;
#ifdef VERSION_SH
s16 unk2;
u8 *data;
#if !IS_64_BIT
s32 pad[2];
#endif
#endif
unsigned short revision;
unsigned short seqCount;
unsigned int pad;
ALSeqData seqArray[1];
} ALSeqFile;
} __attribute__((aligned (16))) ALSeqFile;
void alSeqFileNew(ALSeqFile *f, u8 *base);
+1 -1
View File
@@ -10,6 +10,6 @@
#define IS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
#endif
#define DOUBLE_SIZE_ON_64_BIT(size) ((size) * (sizeof(void *) / 4))
#define DOUBLE_SIZE_ON_64_BIT(size) ((size) * 2)
#endif // PLATFORM_INFO_H
+7
View File
@@ -1,12 +1,19 @@
#include "libultra_internal.h"
#include "libaudio_internal.h"
#include "../../debug_print.h"
#define PATCH(SRC, BASE, TYPE) //SRC = (TYPE)((uintptr_t) SRC + (uintptr_t) BASE)
void alSeqFileNew(ALSeqFile *f, u8 *base) {
DEBUG_PRINT("alSeqFileNew()");
int i;
DEBUG_PRINT("- patching %d entries", f->seqCount);
for (i = 0; i < f->seqCount; i++) {
DEBUG_PRINT("- handling entry %d", i);
DEBUG_PRINT("- patching offset (%x) with base (%x)", f->seqArray[i].offset, base);
PATCH(f->seqArray[i].offset, base, u8 *);
DEBUG_PRINT("- result is (%x)", f->seqArray[i].offset);
}
}
+3
View File
@@ -4,6 +4,7 @@
#include <ultra64.h>
#include "mixer.h"
#include "../../debug_print.h"
#ifdef __SSE4_1__
#include <immintrin.h>
@@ -147,6 +148,8 @@ void aSaveBufferImpl(uint16_t source_addr, int16_t *dest_addr, uint16_t nbytes)
}
#else
void aLoadBufferImpl(const void *source_addr) {
DEBUG_PRINT("aLoadBufferImpl()");
DEBUG_PRINT("- source_addr: %x", source_addr);
memcpy(BUF_U8(rspa.in), source_addr, ROUND_UP_8(rspa.nbytes));
}
+12
View File
@@ -1,6 +1,7 @@
#pragma once
#include "convUtils.h"
#include "../../debug_print.h"
#include "utils.h"
#include <stdlib.h>
#include <stdio.h>
@@ -21,6 +22,8 @@
unsigned char* gCtlSeqs;
struct seqFile* parse_seqfile(unsigned char* seq){ /* Read SeqFile data */
DEBUG_PRINT("parse_seqfile()");
short revision = read_u16_be(seq);
short bankCount = read_u16_be(seq + 2);
@@ -34,14 +37,20 @@ struct seqFile* parse_seqfile(unsigned char* seq){ /* Read SeqFile data */
seqFile->seqArray[i].len = read_u32_be((seq + 4 + i * 8 + 4));
}
DEBUG_PRINT("- revision: %d", revision);
if (revision == TYPE_CTL){
DEBUG_PRINT("- ctl!");
// CTL file, contains instrument and drum data, this is really the only one that needs to be parsed, the rest only needs a header change
gCtlSeqs = (unsigned char*)calloc(0x20B40, 1); // We only really need 0x20AD0 bytes but still
uintptr_t pos = (uintptr_t)gCtlSeqs;
DEBUG_PRINT("- bank count: %d", bankCount);
for (int i = 0; i < bankCount; i++){
DEBUG_PRINT("- ctl bank index: %d", i);
uintptr_t start = pos;
struct CTL* ptr = parse_ctl_data(seq+(seqFile->seqArray[i].offset), &pos);
DEBUG_PRINT("- read ptr: %x", ptr);
seqFile->seqArray[i].offset = ptr;
DEBUG_PRINT("- stored offset: %x", seqFile->seqArray[i].offset);
seqFile->seqArray[i].len = (unsigned int)(pos - start);
}
}else if (revision == TYPE_TBL){
@@ -247,6 +256,9 @@ struct SEQ* parse_seq_data(unsigned char* seq){
}
struct CTL* parse_ctl_data(unsigned char* ctlData, uintptr_t* pos){
DEBUG_PRINT("parse_ctl_data()");
DEBUG_PRINT("- ctlData: %x", ctlData);
DEBUG_PRINT("- pos: %x", pos);
int instruments=read_u32_be(ctlData);
unsigned int size = sizeof(struct CTL) + sizeof(struct CInstrument*) * (instruments-1);
struct CTL* ctl = (struct CTL*)(*pos);
+22 -2
View File
@@ -10,6 +10,7 @@
#include <string.h>
#include <math.h>
#include "decomp/audio/external.h"
#include "decomp/include/PR/os_cont.h"
#include "decomp/engine/math_util.h"
#include "decomp/include/sm64.h"
@@ -135,8 +136,27 @@ SM64_LIB_FN void sm64_global_terminate( void )
memory_terminate();
}
SM64_LIB_FN struct AudioBanks sm64_asset_load_audio_banks( uint8_t *rom ) {
return load_audio_banks( rom );
SM64_LIB_FN void sm64_audio_init( uint8_t *rom ) {
load_audio_banks( rom );
}
#define SAMPLES_HIGH 544
#define SAMPLES_LOW 528
extern SM64_LIB_FN uint32_t sm64_audio_tick( uint32_t numQueuedSamples, uint32_t numDesiredSamples, int16_t *audio_buffer ) {
DEBUG_PRINT("sm64_tick_audio()");
DEBUG_PRINT("- update game sound");
update_game_sound();
DEBUG_PRINT("- create next audio buffer");
u32 num_audio_samples = numQueuedSamples < numDesiredSamples ? SAMPLES_HIGH : SAMPLES_LOW;
for (int i = 0; i < 2; i++)
{
create_next_audio_buffer(audio_buffer + i * (2 * num_audio_samples), num_audio_samples);
}
return num_audio_samples;
}
SM64_LIB_FN void sm64_static_surfaces_load( const struct SM64Surface *surfaceArray, uint32_t numSurfaces )
+2 -1
View File
@@ -80,7 +80,8 @@ extern SM64_LIB_FN void sm64_register_play_sound_function( SM64PlaySoundFunction
extern SM64_LIB_FN void sm64_global_init( uint8_t *rom, uint8_t *outTexture );
extern SM64_LIB_FN void sm64_global_terminate( void );
extern SM64_LIB_FN struct AudioBanks sm64_asset_load_audio_banks( uint8_t *rom );
extern SM64_LIB_FN void sm64_audio_init( uint8_t *rom );
extern SM64_LIB_FN uint32_t sm64_audio_tick( uint32_t numQueuedSamples, uint32_t numDesiredSamples, int16_t *audio_buffer );
extern SM64_LIB_FN void sm64_static_surfaces_load( const struct SM64Surface *surfaceArray, uint32_t numSurfaces );
+16 -12
View File
@@ -1,32 +1,36 @@
#include "load_audio_data.h"
#include "debug_print.h"
#include "decomp/tools/convUtils.h"
#include "decomp/audio/load.h"
#include "decomp/audio/load_dat.h"
extern struct AudioBanks load_audio_banks( uint8_t *rom ) {
extern void load_audio_banks( uint8_t *rom ) {
DEBUG_PRINT("load_audio_banks()");
DEBUG_PRINT("- malloc");
uint8_t *rom2 = malloc(0x800000);
DEBUG_PRINT("- memcpy");
memcpy(rom2, rom, 0x800000);
rom = rom2;
DEBUG_PRINT("- parse ctl");
gSoundDataADSR = parse_seqfile(rom+0x57B720); //ctl
DEBUG_PRINT("- parse tbl");
gSoundDataRaw = parse_seqfile(rom+0x593560); //tbl
DEBUG_PRINT("- parse music");
gMusicData = parse_seqfile(rom+0x7B0860);
gBankSetsData = rom+0x7CC621;
DEBUG_PRINT("- memmove");
memmove(gBankSetsData+0x45,gBankSetsData+0x45-1,0x5B);
gBankSetsData[0x45]=0x00;
DEBUG_PRINT("- ptrs to offsets");
ptrs_to_offsets(gSoundDataADSR);
DEBUG_PRINT("- audio init");
audio_init();
int numBanks = 10;
for (int i = 0; i < 10; ++i) {
bank_load_immediate(i, 2);
}
struct AudioBanks audioBanks;
audioBanks.numCtlEntries = numBanks;
audioBanks.ctlEntries = gCtlEntries;
return audioBanks;
DEBUG_PRINT("- sound init");
sound_init();
DEBUG_PRINT("- sound reset");
sound_reset(0);
DEBUG_PRINT("- done with audio init!");
}
+1 -6
View File
@@ -2,9 +2,4 @@
#include <stdint.h>
struct AudioBanks {
int numCtlEntries;
struct CtlEntry * ctlEntries;
};
extern struct AudioBanks load_audio_banks( uint8_t *rom );
extern void load_audio_banks( uint8_t *rom );
+8
View File
@@ -1,8 +1,16 @@
#include "play_sound.h"
#include "decomp/audio/external.h"
#include "debug_print.h"
SM64PlaySoundFunctionPtr g_play_sound_func = NULL;
extern void play_sound( uint32_t soundBits, f32 *pos ) {
DEBUG_PRINT("$ play_sound(%d) request %d; pos %f %f %f\n", soundBits,sSoundRequestCount,pos[0],pos[1],pos[2]);
sSoundRequests[sSoundRequestCount].soundBits = soundBits;
sSoundRequests[sSoundRequestCount].position = pos;
sSoundRequestCount++;
if ( g_play_sound_func ) {
g_play_sound_func(soundBits, pos);
}