Merge pull request #25 from MeltyPlayer/audio
Exposed audio playback functionality by adding decomp logic into libsm64.
This commit is contained in:
@@ -7,9 +7,9 @@ else
|
||||
CC := cc
|
||||
LDFLAGS := -lm -shared
|
||||
endif
|
||||
CFLAGS := -g -Wall -fPIC -DSM64_LIB_EXPORT -DGBI_FLOATS
|
||||
CFLAGS := -g -Wall -fPIC -DSM64_LIB_EXPORT -DGBI_FLOATS -DVERSION_US -DNO_SEGMENTED_MEMORY
|
||||
|
||||
SRC_DIRS := src src/decomp src/decomp/engine src/decomp/game src/decomp/mario src/decomp/tools
|
||||
SRC_DIRS := src src/decomp src/decomp/engine src/decomp/include/PR src/decomp/game src/decomp/pc src/decomp/pc/audio src/decomp/mario src/decomp/tools src/decomp/audio
|
||||
BUILD_DIR := build
|
||||
DIST_DIR := dist
|
||||
ALL_DIRS := $(addprefix $(BUILD_DIR)/,$(SRC_DIRS))
|
||||
@@ -42,7 +42,7 @@ src/decomp/mario/geo.inc.c: ./import-mario-geo.py
|
||||
|
||||
$(BUILD_DIR)/%.o: %.c $(IMPORTED)
|
||||
@$(CC) $(CFLAGS) -MM -MP -MT $@ -MF $(BUILD_DIR)/$*.d $<
|
||||
$(CC) -c $(CFLAGS) -o $@ $<
|
||||
$(CC) -c $(CFLAGS) -I src/decomp/include -o $@ $<
|
||||
|
||||
$(LIB_FILE): $(O_FILES)
|
||||
$(CC) $(LDFLAGS) -o $@ $^
|
||||
|
||||
@@ -0,0 +1,500 @@
|
||||
//! Copt inlining for US/JP. Here be dragons
|
||||
// This version is basically identical to EU
|
||||
|
||||
#include <ultra64.h>
|
||||
#include <macros.h>
|
||||
|
||||
#include "../heap.h"
|
||||
#include "../data.h"
|
||||
#include "../load.h"
|
||||
#include "../seqplayer.h"
|
||||
#include "../external.h"
|
||||
#include "../effects.h"
|
||||
|
||||
#define PORTAMENTO_IS_SPECIAL(x) ((x).mode & 0x80)
|
||||
#define PORTAMENTO_MODE(x) ((x).mode & ~0x80)
|
||||
#define PORTAMENTO_MODE_1 1
|
||||
#define PORTAMENTO_MODE_2 2
|
||||
#define PORTAMENTO_MODE_3 3
|
||||
#define PORTAMENTO_MODE_4 4
|
||||
#define PORTAMENTO_MODE_5 5
|
||||
|
||||
#define COPT 0
|
||||
#if COPT
|
||||
#define M64_READ_U8(state, dst) \
|
||||
dst = m64_read_u8(state);
|
||||
#else
|
||||
#define M64_READ_U8(state, dst) \
|
||||
{ \
|
||||
u8 * _ptr_pc; \
|
||||
u8 _pc; \
|
||||
_ptr_pc = (*state).pc; \
|
||||
((*state).pc)++; \
|
||||
_pc = *_ptr_pc; \
|
||||
dst = _pc; \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if COPT
|
||||
#define M64_READ_S16(state, dst) \
|
||||
dst = m64_read_s16(state);
|
||||
#else
|
||||
#define M64_READ_S16(state, dst) \
|
||||
{ \
|
||||
s16 _ret; \
|
||||
_ret = *(*state).pc << 8; \
|
||||
((*state).pc)++; \
|
||||
_ret = *(*state).pc | _ret; \
|
||||
((*state).pc)++; \
|
||||
dst = _ret; \
|
||||
}
|
||||
#endif
|
||||
#if COPT
|
||||
#define M64_READ_COMPRESSED_U16(state, dst) \
|
||||
dst = m64_read_compressed_u16(state);
|
||||
#else
|
||||
#define M64_READ_COMPRESSED_U16(state, dst) \
|
||||
{ \
|
||||
u16 ret = *(state->pc++); \
|
||||
if (ret & 0x80) { \
|
||||
ret = (ret << 8) & 0x7f00; \
|
||||
ret = *(state->pc++) | ret; \
|
||||
} \
|
||||
dst = ret; \
|
||||
}
|
||||
#endif
|
||||
|
||||
#if COPT
|
||||
#define GET_INSTRUMENT(seqChannel, instId, _instOut, _adsr, dst, l) \
|
||||
dst = get_instrument(seqChannel, instId, _instOut, _adsr);
|
||||
#else
|
||||
#define GET_INSTRUMENT(seqChannel, instId, _instOut, _adsr, dst, l) \
|
||||
{ \
|
||||
struct AdsrSettings *adsr = _adsr; \
|
||||
struct Instrument **instOut = _instOut;\
|
||||
u8 _instId = instId; \
|
||||
struct Instrument *inst; \
|
||||
UNUSED u32 pad; \
|
||||
/* copt inlines instId here */ \
|
||||
if (instId >= gCtlEntries[(*seqChannel).bankId].numInstruments) { \
|
||||
_instId = gCtlEntries[(*seqChannel).bankId].numInstruments; \
|
||||
if (_instId == 0) { \
|
||||
dst = 0; \
|
||||
goto ret ## l; \
|
||||
} \
|
||||
_instId--; \
|
||||
} \
|
||||
inst = gCtlEntries[(*seqChannel).bankId].instruments[_instId]; \
|
||||
if (inst == NULL) { \
|
||||
while (_instId != 0xff) { \
|
||||
inst = gCtlEntries[(*seqChannel).bankId].instruments[_instId]; \
|
||||
if (inst != NULL) { \
|
||||
goto gi ## l; \
|
||||
} \
|
||||
_instId--; \
|
||||
} \
|
||||
gi ## l:; \
|
||||
} \
|
||||
if (((uintptr_t) gBankLoadedPool.persistent.pool.start <= (uintptr_t) inst \
|
||||
&& (uintptr_t) inst <= (uintptr_t)(gBankLoadedPool.persistent.pool.start \
|
||||
+ gBankLoadedPool.persistent.pool.size)) \
|
||||
|| ((uintptr_t) gBankLoadedPool.temporary.pool.start <= (uintptr_t) inst \
|
||||
&& (uintptr_t) inst <= (uintptr_t)(gBankLoadedPool.temporary.pool.start \
|
||||
+ gBankLoadedPool.temporary.pool.size))) { \
|
||||
(*adsr).envelope = (*inst).envelope; \
|
||||
(*adsr).releaseRate = (*inst).releaseRate; \
|
||||
*instOut = inst; \
|
||||
_instId++; \
|
||||
goto ret ## l; \
|
||||
} \
|
||||
gAudioErrorFlags = _instId + 0x20000; \
|
||||
*instOut = NULL; \
|
||||
ret ## l: ; \
|
||||
}
|
||||
#endif
|
||||
|
||||
void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) {
|
||||
struct SequencePlayer *seqPlayer; // sp5C, t4
|
||||
struct SequenceChannel *seqChannel; // sp58, t5
|
||||
struct M64ScriptState *state;
|
||||
struct Portamento *portamento;
|
||||
struct AudioBankSound *sound;
|
||||
struct Instrument *instrument;
|
||||
struct Drum *drum;
|
||||
s32 temp_a0_5;
|
||||
u8 sameSound;
|
||||
u8 cmd; // a0 sp3E, EU s2
|
||||
u8 cmdSemitone; // sp3D, t0
|
||||
u16 sp3A; // t2, a0, a1
|
||||
f32 tuning; // f0
|
||||
s32 vel; // sp30, t3
|
||||
s32 usedSemitone; // a1
|
||||
f32 freqScale; // sp28, f0
|
||||
f32 sp24;
|
||||
f32 temp_f12;
|
||||
f32 temp_f2;
|
||||
|
||||
//! Copt: manually inline these functions in the scope of this routine
|
||||
#ifdef __sgi
|
||||
#pragma inline routine(m64_read_u8)
|
||||
#pragma inline routine(m64_read_compressed_u16)
|
||||
#pragma inline routine(m64_read_s16)
|
||||
#pragma inline routine(get_instrument)
|
||||
#endif
|
||||
|
||||
sameSound = TRUE;
|
||||
if ((*layer).enabled == FALSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((*layer).delay > 1) {
|
||||
(*layer).delay--;
|
||||
if (!layer->stopSomething && layer->delay <= layer->duration) {
|
||||
seq_channel_layer_note_decay(layer);
|
||||
layer->stopSomething = TRUE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!layer->continuousNotes) {
|
||||
seq_channel_layer_note_decay(layer);
|
||||
}
|
||||
|
||||
if (PORTAMENTO_MODE(layer->portamento) == PORTAMENTO_MODE_1 ||
|
||||
PORTAMENTO_MODE(layer->portamento) == PORTAMENTO_MODE_2) {
|
||||
layer->portamento.mode = 0;
|
||||
}
|
||||
|
||||
seqChannel = (*layer).seqChannel;
|
||||
seqPlayer = (*seqChannel).seqPlayer;
|
||||
for (;;) {
|
||||
state = &layer->scriptState;
|
||||
//M64_READ_U8(state, cmd);
|
||||
{
|
||||
u8 *_ptr_pc;
|
||||
_ptr_pc = (*state).pc++;
|
||||
cmd = *_ptr_pc;
|
||||
}
|
||||
|
||||
if (cmd <= 0xc0) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case 0xff: // layer_end; function return or end of script
|
||||
if (state->depth == 0) {
|
||||
// N.B. this function call is *not* inlined even though it's
|
||||
// within the same file, unlike in the rest of this function.
|
||||
seq_channel_layer_disable(layer);
|
||||
return;
|
||||
}
|
||||
state->depth--, state->pc = state->stack[state->depth];
|
||||
break;
|
||||
|
||||
case 0xfc: // layer_call
|
||||
M64_READ_S16(state, sp3A);
|
||||
state->depth++, state->stack[state->depth - 1] = state->pc;
|
||||
state->pc = seqPlayer->seqData + sp3A;
|
||||
break;
|
||||
|
||||
case 0xf8: // layer_loop; loop start, N iterations (or 256 if N = 0)
|
||||
M64_READ_U8(state, state->remLoopIters[state->depth]);
|
||||
state->depth++, state->stack[state->depth - 1] = state->pc;
|
||||
break;
|
||||
|
||||
case 0xf7: // layer_loopend
|
||||
if (--state->remLoopIters[state->depth - 1] != 0) {
|
||||
state->pc = state->stack[state->depth - 1];
|
||||
} else {
|
||||
state->depth--;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xfb: // layer_jump
|
||||
M64_READ_S16(state, sp3A);
|
||||
state->pc = seqPlayer->seqData + sp3A;
|
||||
break;
|
||||
|
||||
case 0xc1: // layer_setshortnotevelocity
|
||||
case 0xca: // layer_setpan
|
||||
temp_a0_5 = *(state->pc++);
|
||||
if (cmd == 0xc1) {
|
||||
layer->velocitySquare = (f32)(temp_a0_5 * temp_a0_5);
|
||||
} else {
|
||||
layer->pan = (f32) temp_a0_5 / US_FLOAT(128.0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xc2: // layer_transpose; set transposition in semitones
|
||||
case 0xc9: // layer_setshortnoteduration
|
||||
temp_a0_5 = *(state->pc++);
|
||||
if (cmd == 0xc9) {
|
||||
layer->noteDuration = temp_a0_5;
|
||||
} else {
|
||||
layer->transposition = temp_a0_5;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xc4: // layer_somethingon
|
||||
case 0xc5: // layer_somethingoff
|
||||
//! copt needs a ternary:
|
||||
//layer->continuousNotes = (cmd == 0xc4) ? TRUE : FALSE;
|
||||
{
|
||||
u8 setting;
|
||||
if (cmd == 0xc4) {
|
||||
setting = TRUE;
|
||||
} else {
|
||||
setting = FALSE;
|
||||
}
|
||||
layer->continuousNotes = setting;
|
||||
seq_channel_layer_note_decay(layer);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xc3: // layer_setshortnotedefaultplaypercentage
|
||||
M64_READ_COMPRESSED_U16(state, sp3A);
|
||||
layer->shortNoteDefaultPlayPercentage = sp3A;
|
||||
break;
|
||||
|
||||
case 0xc6: // layer_setinstr
|
||||
M64_READ_U8(state, cmdSemitone);
|
||||
|
||||
if (cmdSemitone < 127) {
|
||||
GET_INSTRUMENT(seqChannel, cmdSemitone, &(*layer).instrument, &(*layer).adsr, cmdSemitone, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xc7: // layer_portamento
|
||||
M64_READ_U8(state, (*layer).portamento.mode);
|
||||
M64_READ_U8(state, cmdSemitone);
|
||||
|
||||
cmdSemitone = cmdSemitone + (*seqChannel).transposition;
|
||||
cmdSemitone += (*layer).transposition;
|
||||
cmdSemitone += (*seqPlayer).transposition;
|
||||
|
||||
if (cmdSemitone >= 0x80) {
|
||||
cmdSemitone = 0;
|
||||
}
|
||||
layer->portamentoTargetNote = cmdSemitone;
|
||||
|
||||
// If special, the next param is u8 instead of var
|
||||
if (PORTAMENTO_IS_SPECIAL((*layer).portamento)) {
|
||||
layer->portamentoTime = *((state)->pc++);
|
||||
break;
|
||||
}
|
||||
|
||||
M64_READ_COMPRESSED_U16(state, sp3A);
|
||||
layer->portamentoTime = sp3A;
|
||||
break;
|
||||
|
||||
case 0xc8: // layer_disableportamento
|
||||
layer->portamento.mode = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (cmd & 0xf0) {
|
||||
case 0xd0: // layer_setshortnotevelocityfromtable
|
||||
sp3A = seqPlayer->shortNoteVelocityTable[cmd & 0xf];
|
||||
(*layer).velocitySquare = (f32)(sp3A * sp3A);
|
||||
break;
|
||||
case 0xe0: // layer_setshortnotedurationfromtable
|
||||
(*layer).noteDuration = seqPlayer->shortNoteDurationTable[cmd & 0xf];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd == 0xc0) { // layer_delay
|
||||
M64_READ_COMPRESSED_U16(state, layer->delay);
|
||||
layer->stopSomething = TRUE;
|
||||
} else {
|
||||
layer->stopSomething = FALSE;
|
||||
|
||||
if (seqChannel->largeNotes == TRUE) {
|
||||
switch (cmd & 0xc0) {
|
||||
case 0x00: // layer_note0 (play percentage, velocity, duration)
|
||||
M64_READ_COMPRESSED_U16(state, sp3A);
|
||||
vel = *((*state).pc++);
|
||||
layer->noteDuration = *((*state).pc++);
|
||||
layer->playPercentage = sp3A;
|
||||
goto l1090;
|
||||
|
||||
case 0x40: // layer_note1 (play percentage, velocity)
|
||||
M64_READ_COMPRESSED_U16(state, sp3A);
|
||||
vel = *((*state).pc++);
|
||||
layer->noteDuration = 0;
|
||||
layer->playPercentage = sp3A;
|
||||
goto l1090;
|
||||
|
||||
case 0x80: // layer_note2 (velocity, duration; uses last play percentage)
|
||||
sp3A = layer->playPercentage;
|
||||
vel = *((*state).pc++);
|
||||
layer->noteDuration = *((*state).pc++);
|
||||
goto l1090;
|
||||
}
|
||||
l1090:
|
||||
cmdSemitone = cmd - (cmd & 0xc0);
|
||||
layer->velocitySquare = vel * vel;
|
||||
} else {
|
||||
switch (cmd & 0xc0) {
|
||||
case 0x00: // play note, type 0 (play percentage)
|
||||
M64_READ_COMPRESSED_U16(state, sp3A);
|
||||
layer->playPercentage = sp3A;
|
||||
goto l1138;
|
||||
|
||||
case 0x40: // play note, type 1 (uses default play percentage)
|
||||
sp3A = layer->shortNoteDefaultPlayPercentage;
|
||||
goto l1138;
|
||||
|
||||
case 0x80: // play note, type 2 (uses last play percentage)
|
||||
sp3A = layer->playPercentage;
|
||||
goto l1138;
|
||||
}
|
||||
l1138:
|
||||
|
||||
cmdSemitone = cmd - (cmd & 0xc0);
|
||||
}
|
||||
|
||||
layer->delay = sp3A;
|
||||
layer->duration = layer->noteDuration * sp3A / 256;
|
||||
if ((seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_STOP_NOTES) != 0)
|
||||
|| seqChannel->stopSomething2
|
||||
|| !seqChannel->hasInstrument
|
||||
) {
|
||||
layer->stopSomething = TRUE;
|
||||
} else {
|
||||
if (seqChannel->instOrWave == 0) { // drum
|
||||
cmdSemitone += (*seqChannel).transposition + (*layer).transposition;
|
||||
if (cmdSemitone >= gCtlEntries[seqChannel->bankId].numDrums) {
|
||||
cmdSemitone = gCtlEntries[seqChannel->bankId].numDrums;
|
||||
if (cmdSemitone == 0) {
|
||||
// this goto looks a bit like a function return...
|
||||
layer->stopSomething = TRUE;
|
||||
goto skip;
|
||||
}
|
||||
|
||||
cmdSemitone--;
|
||||
}
|
||||
|
||||
drum = gCtlEntries[seqChannel->bankId].drums[cmdSemitone];
|
||||
if (drum == NULL) {
|
||||
layer->stopSomething = TRUE;
|
||||
} else {
|
||||
layer->adsr.envelope = drum->envelope;
|
||||
layer->adsr.releaseRate = drum->releaseRate;
|
||||
layer->pan = FLOAT_CAST(drum->pan) / US_FLOAT(128.0);
|
||||
layer->sound = &drum->sound;
|
||||
layer->freqScale = layer->sound->tuning;
|
||||
}
|
||||
|
||||
skip:;
|
||||
} else { // instrument
|
||||
cmdSemitone += (*seqPlayer).transposition + (*seqChannel).transposition + (*layer).transposition;
|
||||
if (cmdSemitone >= 0x80) {
|
||||
layer->stopSomething = TRUE;
|
||||
} else {
|
||||
instrument = layer->instrument;
|
||||
if (instrument == NULL) {
|
||||
instrument = seqChannel->instrument;
|
||||
}
|
||||
|
||||
if (layer->portamento.mode != 0) {
|
||||
//! copt needs a ternary:
|
||||
//usedSemitone = (layer->portamentoTargetNote < cmdSemitone) ? cmdSemitone : layer->portamentoTargetNote;
|
||||
if (layer->portamentoTargetNote < cmdSemitone) {
|
||||
usedSemitone = cmdSemitone;
|
||||
} else {
|
||||
usedSemitone = layer->portamentoTargetNote;
|
||||
}
|
||||
|
||||
if (instrument != NULL) {
|
||||
sound = (u8) usedSemitone < instrument->normalRangeLo ? &instrument->lowNotesSound
|
||||
: (u8) usedSemitone <= instrument->normalRangeHi ?
|
||||
&instrument->normalNotesSound : &instrument->highNotesSound;
|
||||
|
||||
sameSound = (sound == (*layer).sound);
|
||||
layer->sound = sound;
|
||||
tuning = (*sound).tuning;
|
||||
} else {
|
||||
layer->sound = NULL;
|
||||
tuning = 1.0f;
|
||||
}
|
||||
|
||||
temp_f2 = gNoteFrequencies[cmdSemitone] * tuning;
|
||||
temp_f12 = gNoteFrequencies[layer->portamentoTargetNote] * tuning;
|
||||
|
||||
portamento = &layer->portamento;
|
||||
switch (PORTAMENTO_MODE(layer->portamento)) {
|
||||
case PORTAMENTO_MODE_1:
|
||||
case PORTAMENTO_MODE_3:
|
||||
case PORTAMENTO_MODE_5:
|
||||
sp24 = temp_f2;
|
||||
freqScale = temp_f12;
|
||||
goto l13cc;
|
||||
|
||||
case PORTAMENTO_MODE_2:
|
||||
case PORTAMENTO_MODE_4:
|
||||
freqScale = temp_f2;
|
||||
sp24 = temp_f12;
|
||||
goto l13cc;
|
||||
}
|
||||
l13cc:
|
||||
portamento->extent = sp24 / freqScale - US_FLOAT(1.0);
|
||||
if (PORTAMENTO_IS_SPECIAL((*layer).portamento)) {
|
||||
portamento->speed = US_FLOAT(32512.0) * FLOAT_CAST((*seqPlayer).tempo)
|
||||
/ ((f32)(*layer).delay * (f32) gTempoInternalToExternal
|
||||
* FLOAT_CAST((*layer).portamentoTime));
|
||||
} else {
|
||||
portamento->speed = US_FLOAT(127.0) / FLOAT_CAST((*layer).portamentoTime);
|
||||
}
|
||||
portamento->cur = 0.0f;
|
||||
layer->freqScale = freqScale;
|
||||
if (PORTAMENTO_MODE((*layer).portamento) == PORTAMENTO_MODE_5) {
|
||||
layer->portamentoTargetNote = cmdSemitone;
|
||||
}
|
||||
} else if (instrument != NULL) {
|
||||
sound = cmdSemitone < instrument->normalRangeLo ?
|
||||
&instrument->lowNotesSound : cmdSemitone <= instrument->normalRangeHi ?
|
||||
&instrument->normalNotesSound : &instrument->highNotesSound;
|
||||
|
||||
sameSound = (sound == (*layer).sound);
|
||||
layer->sound = sound;
|
||||
layer->freqScale = gNoteFrequencies[cmdSemitone] * (*sound).tuning;
|
||||
} else {
|
||||
layer->sound = NULL;
|
||||
layer->freqScale = gNoteFrequencies[cmdSemitone];
|
||||
}
|
||||
}
|
||||
}
|
||||
layer->delayUnused = layer->delay;
|
||||
}
|
||||
}
|
||||
|
||||
if (layer->stopSomething == TRUE) {
|
||||
if (layer->note != NULL || layer->continuousNotes) {
|
||||
seq_channel_layer_note_decay(layer);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
cmdSemitone = FALSE;
|
||||
if (!layer->continuousNotes) {
|
||||
cmdSemitone = TRUE;
|
||||
} else if (layer->note == NULL || layer->status == SOUND_LOAD_STATUS_NOT_LOADED) {
|
||||
cmdSemitone = TRUE;
|
||||
} else if (sameSound == FALSE) {
|
||||
seq_channel_layer_note_decay(layer);
|
||||
cmdSemitone = TRUE;
|
||||
} else if (layer->sound == NULL) {
|
||||
init_synthetic_wave(layer->note, layer);
|
||||
}
|
||||
|
||||
if (cmdSemitone != FALSE) {
|
||||
(*layer).note = alloc_note(layer);
|
||||
}
|
||||
|
||||
if (layer->note != NULL && layer->note->parentLayer == layer) {
|
||||
note_vibrato_init(layer->note);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,961 @@
|
||||
#include <ultra64.h>
|
||||
|
||||
#include "data.h"
|
||||
#include "effects.h"
|
||||
|
||||
extern struct OSMesgQueue OSMesgQueue0;
|
||||
extern struct OSMesgQueue OSMesgQueue1;
|
||||
extern struct OSMesgQueue OSMesgQueue2;
|
||||
extern struct OSMesgQueue OSMesgQueue3;
|
||||
|
||||
#ifdef VERSION_EU
|
||||
struct ReverbSettingsEU sReverbSettings[] = {
|
||||
{ 0x04, 0x0c, 0x2fff },
|
||||
{ 0x04, 0x0a, 0x47ff },
|
||||
{ 0x04, 0x10, 0x2fff },
|
||||
{ 0x04, 0x0e, 0x3fff },
|
||||
{ 0x04, 0x0c, 0x4fff },
|
||||
{ 0x04, 0x0a, 0x37ff }
|
||||
};
|
||||
struct AudioSessionSettingsEU gAudioSessionPresets[] = {
|
||||
{ 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[0], 0x7fff, 0x0000, 0x00003a40, 0x00006d00,
|
||||
0x00004400, 0x00002a00 },
|
||||
{ 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[1], 0x7fff, 0x0000, 0x00003a40, 0x00006d00,
|
||||
0x00004400, 0x00002a00 },
|
||||
{ 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[2], 0x7fff, 0x0000, 0x00003a40, 0x00006d00,
|
||||
0x00004400, 0x00002a00 },
|
||||
{ 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[3], 0x7fff, 0x0000, 0x00003a40, 0x00006d00,
|
||||
0x00004400, 0x00002a00 },
|
||||
{ 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[4], 0x7fff, 0x0000, 0x00003a40, 0x00006d00,
|
||||
0x00004400, 0x00002a00 },
|
||||
{ 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[0], 0x7fff, 0x0000, 0x00004000, 0x00006e00,
|
||||
0x00003f00, 0x00002a00 },
|
||||
{ 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[1], 0x7fff, 0x0000, 0x00004100, 0x00006e00,
|
||||
0x00004400, 0x00002a80 },
|
||||
{ 0x00007d00, 0x01, 0x14, 0x01, 0x00, &sReverbSettings[5], 0x7fff, 0x0000, 0x00003500, 0x00006280,
|
||||
0x00004000, 0x00001b00 }
|
||||
};
|
||||
#endif
|
||||
|
||||
// Format:
|
||||
// - frequency
|
||||
// - max number of simultaneous notes
|
||||
// - reverb downsample rate (makes the ring buffer be downsampled to save memory)
|
||||
// - reverb window size (ring buffer size, length affects reverb delay)
|
||||
// - reverb gain (0 = min reverb, 32767 = max reverb, 32769 to 65535 = louder and louder...)
|
||||
// - volume
|
||||
// - memory used for persistent sequences
|
||||
// - memory used for persistent banks
|
||||
// - memory used for temporary sequences
|
||||
// - memory used for temporary banks
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
struct AudioSessionSettings gAudioSessionPresets[18] = {
|
||||
#ifdef VERSION_JP
|
||||
{ 32000, 16, 1, 0x0800, 0x2FFF, 0x7FFF, 0x3900, 0x6000, 0x4400, 0x2A00 },
|
||||
{ 32000, 16, 1, 0x0A00, 0x47FF, 0x7FFF, 0x3900, 0x6000, 0x4400, 0x2A00 },
|
||||
{ 32000, 16, 1, 0x1000, 0x2FFF, 0x7FFF, 0x3900, 0x6000, 0x4400, 0x2A00 },
|
||||
{ 32000, 16, 1, 0x0E00, 0x3FFF, 0x7FFF, 0x3900, 0x6000, 0x4400, 0x2A00 },
|
||||
{ 32000, 16, 1, 0x0C00, 0x4FFF, 0x7FFF, 0x3900, 0x6000, 0x4400, 0x2A00 },
|
||||
{ 32000, 16, 1, 0x0800, 0x2FFF, 0x7FFF, 0x3E00, 0x6200, 0x3F00, 0x2A00 },
|
||||
{ 32000, 16, 1, 0x0A00, 0x47FF, 0x7FFF, 0x3F00, 0x6200, 0x4400, 0x2A80 },
|
||||
{ 32000, 20, 1, 0x0800, 0x37FF, 0x7FFF, 0x3300, 0x5500, 0x4000, 0x1B00 },
|
||||
#else
|
||||
{ 32000, 16, 1, 0x0C00, 0x2FFF, 0x7FFF, 0x3A00, 0x6D00, 0x4400, 0x2A00 },
|
||||
{ 32000, 16, 1, 0x0A00, 0x47FF, 0x7FFF, 0x3A00, 0x6D00, 0x4400, 0x2A00 },
|
||||
{ 32000, 16, 1, 0x1000, 0x2FFF, 0x7FFF, 0x3A00, 0x6D00, 0x4400, 0x2A00 },
|
||||
{ 32000, 16, 1, 0x0E00, 0x3FFF, 0x7FFF, 0x3A00, 0x6D00, 0x4400, 0x2A00 },
|
||||
{ 32000, 16, 1, 0x0C00, 0x4FFF, 0x7FFF, 0x3A00, 0x6D00, 0x4400, 0x2A00 },
|
||||
{ 32000, 16, 1, 0x0C00, 0x2FFF, 0x7FFF, 0x4000, 0x6E00, 0x3F00, 0x2A00 },
|
||||
{ 32000, 16, 1, 0x0A00, 0x47FF, 0x7FFF, 0x4100, 0x6E00, 0x4400, 0x2A80 },
|
||||
{ 32000, 20, 1, 0x0800, 0x37FF, 0x7FFF, 0x34C0, 0x6280, 0x4000, 0x1B00 },
|
||||
#endif
|
||||
{ 27000, 16, 1, 0x0800, 0x2FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 },
|
||||
{ 27000, 16, 1, 0x0800, 0x3FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 },
|
||||
{ 27000, 16, 1, 0x1000, 0x2FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 },
|
||||
{ 27000, 16, 1, 0x1000, 0x3FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 },
|
||||
{ 27000, 16, 1, 0x0C00, 0x4FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 },
|
||||
{ 32000, 14, 1, 0x0800, 0x2FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 },
|
||||
{ 32000, 12, 1, 0x0800, 0x2FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 },
|
||||
{ 32000, 10, 1, 0x0800, 0x2FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 },
|
||||
{ 32000, 8, 1, 0x0800, 0x2FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
#endif
|
||||
// gAudioCosineTable[k] = round((2**15 - 1) * cos(pi/2 * k / 127)). Unused.
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
u16 gAudioCosineTable[128] = {
|
||||
0x7FFF, 32764, 32757, 32744, 32727, 32704, 32677, 32644, 32607, 32564, 32517, 32464, 32407,
|
||||
32344, 32277, 32205, 32127, 32045, 31958, 31866, 31770, 31668, 31561, 31450, 31334, 31213,
|
||||
31087, 30957, 30822, 30682, 30537, 30388, 30234, 30075, 29912, 29744, 29572, 29395, 29214,
|
||||
29028, 28838, 28643, 28444, 28241, 28033, 27821, 27605, 27385, 27160, 26931, 26698, 26461,
|
||||
26220, 25975, 25726, 25473, 25216, 24956, 24691, 24423, 24151, 23875, 23596, 23313, 23026,
|
||||
22736, 22442, 22145, 21845, 21541, 21234, 20924, 20610, 20294, 19974, 19651, 19325, 18997,
|
||||
18665, 18331, 17993, 17653, 17310, 16965, 16617, 16266, 15913, 15558, 15200, 14840, 14477,
|
||||
14113, 13746, 13377, 13006, 12633, 12258, 11881, 11503, 11122, 10740, 10357, 9971, 9584,
|
||||
9196, 8806, 8415, 8023, 7630, 7235, 6839, 6442, 6044, 5646, 5246, 4845, 4444,
|
||||
4042, 3640, 3237, 2833, 2429, 2025, 1620, 1216, 810, 405, 0,
|
||||
};
|
||||
#endif
|
||||
|
||||
// Transforms a pitch scale factor in -127..127 into a frequency scale factor
|
||||
// between -1 and +1 octave.
|
||||
// gPitchBendFrequencyScale[k] = 0.5 * 2^(k/127)
|
||||
#ifndef VERSION_SH
|
||||
#if defined(VERSION_EU)
|
||||
f32 gPitchBendFrequencyScale[256] = {
|
||||
0.5f,
|
||||
#else
|
||||
f32 gPitchBendFrequencyScale[255] = {
|
||||
#endif
|
||||
0.5f, 0.502736f, 0.505488f, 0.508254f, 0.511036f, 0.513833f, 0.516645f, 0.519472f, 0.522315f,
|
||||
0.525174f, 0.528048f, 0.530938f, 0.533843f, 0.536765f, 0.539702f, 0.542656f, 0.545626f, 0.548612f,
|
||||
0.551614f, 0.554633f, 0.557669f, 0.560721f, 0.563789f, 0.566875f, 0.569977f, 0.573097f, 0.576233f,
|
||||
0.579387f, 0.582558f, 0.585746f, 0.588951f, 0.592175f, 0.595415f, 0.598674f, 0.601950f, 0.605245f,
|
||||
0.608557f, 0.611888f, 0.615236f, 0.618603f, 0.621989f, 0.625393f, 0.628815f, 0.632257f, 0.635717f,
|
||||
0.639196f, 0.642694f, 0.646212f, 0.649748f, 0.653304f, 0.656880f, 0.660475f, 0.664089f, 0.667724f,
|
||||
0.671378f, 0.675052f, 0.678747f, 0.682461f, 0.686196f, 0.689952f, 0.693727f, 0.697524f, 0.701341f,
|
||||
0.705180f, 0.709039f, 0.712919f, 0.716821f, 0.720744f, 0.724689f, 0.728655f, 0.732642f, 0.736652f,
|
||||
0.740684f, 0.744737f, 0.748813f, 0.752911f, 0.757031f, 0.761175f, 0.765340f, 0.769529f, 0.773740f,
|
||||
0.777975f, 0.782232f, 0.786513f, 0.790818f, 0.795146f, 0.799497f, 0.803873f, 0.808272f, 0.812696f,
|
||||
0.817144f, 0.821616f, 0.826112f, 0.830633f, 0.835179f, 0.839750f, 0.844346f, 0.848966f, 0.853613f,
|
||||
0.858284f, 0.862982f, 0.867704f, 0.872453f, 0.877228f, 0.882029f, 0.886856f, 0.891709f, 0.896590f,
|
||||
0.901496f, 0.906430f, 0.911391f, 0.916379f, 0.921394f, 0.926436f, 0.931507f, 0.936604f, 0.941730f,
|
||||
0.946884f, 0.952066f, 0.957277f, 0.962516f, 0.967783f, 0.973080f, 0.978405f, 0.983760f, 0.989144f,
|
||||
0.994557f, 1.0f, 1.005473f, 1.010975f, 1.016508f, 1.022071f, 1.027665f, 1.033289f, 1.038944f,
|
||||
1.044630f, 1.050347f, 1.056095f, 1.061875f, 1.067687f, 1.073530f, 1.079405f, 1.085312f, 1.091252f,
|
||||
1.097224f, 1.103229f, 1.109267f, 1.115337f, 1.121441f, 1.127579f, 1.133750f, 1.139955f, 1.146193f,
|
||||
1.152466f, 1.158773f, 1.165115f, 1.171491f, 1.177903f, 1.184349f, 1.190831f, 1.197348f, 1.203901f,
|
||||
1.210489f, 1.217114f, 1.223775f, 1.230473f, 1.237207f, 1.243978f, 1.250786f, 1.257631f, 1.264514f,
|
||||
1.271434f, 1.278392f, 1.285389f, 1.292423f, 1.299497f, 1.306608f, 1.313759f, 1.320949f, 1.328178f,
|
||||
1.335447f, 1.342756f, 1.350104f, 1.357493f, 1.364922f, 1.372392f, 1.379903f, 1.387455f, 1.395048f,
|
||||
1.402683f, 1.410360f, 1.418078f, 1.425839f, 1.433642f, 1.441488f, 1.449377f, 1.457309f, 1.465285f,
|
||||
1.473304f, 1.481367f, 1.489474f, 1.497626f, 1.505822f, 1.514063f, 1.522349f, 1.530681f, 1.539058f,
|
||||
1.547481f, 1.555950f, 1.564465f, 1.573027f, 1.581636f, 1.590292f, 1.598995f, 1.607746f, 1.616545f,
|
||||
1.625392f, 1.634287f, 1.643231f, 1.652224f, 1.661266f, 1.670358f, 1.679500f, 1.688691f, 1.697933f,
|
||||
1.707225f, 1.716569f, 1.725963f, 1.735409f, 1.744906f, 1.754456f, 1.764058f, 1.773712f, 1.783419f,
|
||||
1.793179f, 1.802993f, 1.812860f, 1.822782f, 1.832757f, 1.842788f, 1.852873f, 1.863013f, 1.873209f,
|
||||
1.883461f, 1.893768f, 1.904132f, 1.914553f, 1.925031f, 1.935567f, 1.946159f, 1.956810f, 1.967520f,
|
||||
1.978287f, 1.989114f, 2.0f
|
||||
};
|
||||
|
||||
// Frequencies for notes using the standard twelve-tone equal temperament scale.
|
||||
// For indices 0..116, gNoteFrequencies[k] = 2^((k-39)/12).
|
||||
// For indices 117..128, gNoteFrequencies[k] = 0.5 * 2^((k-39)/12).
|
||||
// The 39 in the formula refers to piano key 40 (middle C, at 256 Hz) being
|
||||
// the reference frequency, which is assigned value 1.
|
||||
// clang-format off
|
||||
f32 gNoteFrequencies[128] = {
|
||||
0.105112f, 0.111362f, 0.117984f, 0.125f, 0.132433f, 0.140308f, 0.148651f, 0.15749f, 0.166855f, 0.176777f, 0.187288f, 0.198425f,
|
||||
0.210224f, 0.222725f, 0.235969f, 0.25f, 0.264866f, 0.280616f, 0.297302f, 0.31498f, 0.33371f, 0.353553f, 0.374577f, 0.39685f,
|
||||
0.420448f, 0.445449f, 0.471937f, 0.5f, 0.529732f, 0.561231f, 0.594604f, 0.629961f, 0.66742f, 0.707107f, 0.749154f, 0.793701f,
|
||||
0.840897f, 0.890899f, 0.943875f, 1.0f, 1.059463f, 1.122462f, 1.189207f, 1.259921f, 1.33484f, 1.414214f, 1.498307f, 1.587401f,
|
||||
1.681793f, 1.781798f, 1.887749f, 2.0f, 2.118926f, 2.244924f, 2.378414f, 2.519842f, 2.66968f, 2.828428f, 2.996615f, 3.174803f,
|
||||
3.363586f, 3.563596f, 3.775498f, 4.0f, 4.237853f, 4.489849f, 4.756829f, 5.039685f, 5.33936f, 5.656855f, 5.993229f, 6.349606f,
|
||||
6.727173f, 7.127192f, 7.550996f, 8.0f, 8.475705f, 8.979697f, 9.513658f, 10.07937f, 10.67872f, 11.31371f, 11.986459f, 12.699211f,
|
||||
13.454346f, 14.254383f, 15.101993f, 16.0f, 16.95141f, 17.959394f, 19.027315f, 20.15874f, 21.35744f, 22.62742f, 23.972918f, 25.398422f,
|
||||
26.908691f, 28.508766f, 30.203985f, 32.0f, 33.90282f, 35.91879f, 38.05463f, 40.31748f, 42.71488f, 45.25484f, 47.945835f, 50.796844f,
|
||||
53.817383f, 57.017532f, 60.40797f, 64.0f, 67.80564f, 71.83758f, 76.10926f, 80.63496f, 85.42976f, 45.25484f, 47.945835f, 50.796844f,
|
||||
53.817383f, 57.017532f, 60.40797f, 64.0f, 67.80564f, 71.83758f, 76.10926f, 80.63496f
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
// goes up by ~12 at each step for the first 4 values (starting from 0), then by ~6
|
||||
u8 gDefaultShortNoteVelocityTable[16] = {
|
||||
12, 25, 38, 51, 57, 64, 71, 76, 83, 89, 96, 102, 109, 115, 121, 127,
|
||||
};
|
||||
|
||||
// goes down by 26 at each step for the first 4 values (starting from 255), then by ~12
|
||||
u8 gDefaultShortNoteDurationTable[16] = {
|
||||
229, 203, 177, 151, 139, 126, 113, 100, 87, 74, 61, 48, 36, 23, 10, 0,
|
||||
};
|
||||
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
// gVibratoCurve[k] = k*8
|
||||
s8 gVibratoCurve[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120 };
|
||||
#endif
|
||||
|
||||
struct AdsrEnvelope gDefaultEnvelope[] = {
|
||||
{ BSWAP16(4), BSWAP16(32000) }, // go from 0 to 32000 over the course of 16ms
|
||||
{ BSWAP16(1000), BSWAP16(32000) }, // stay there for 4.16 seconds
|
||||
{ BSWAP16(ADSR_HANG), 0 } // then continue staying there
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef VERSION_EU
|
||||
struct NoteSubEu gZeroNoteSub = { 0 };
|
||||
struct NoteSubEu gDefaultNoteSub = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { NULL } };
|
||||
#endif
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
s16 sSawtoothWaves[256] = {
|
||||
0, 1023, 2047, 3071, 4095, 5119, 6143, 7167, 8191, 9215, 10239,
|
||||
11263, 0x2FFF, 13311, 0x37FF, 15359, 0x3FFF, 17407, 0x47FF, 19455, 0x4FFF, 21503,
|
||||
22527, 23551, 24575, 25599, 26623, 27647, 28671, 29695, 30719, 31743, -0x7FFF,
|
||||
-31743, -30719, -29695, -28671, -27647, -26623, -25599, -24575, -23551, -22527, -21503,
|
||||
-0x4FFF, -19455, -0x47FF, -17407, -0x3FFF, -15359, -0x37FF, -13311, -0x2FFF, -11263, -10239,
|
||||
-9215, -8191, -7167, -6143, -5119, -4095, -3071, -2047, -1023,
|
||||
0, 0x7FF, 0xFFF, 0x17FF, 0x1FFF, 0x27FF, 0x2FFF, 0x37FF, 0x3FFF, 0x47FF, 0x4FFF,
|
||||
0x57FF, 0x5FFF, 0x67FF, 0x6FFF, 0x77FF, 0x8001, 0x8801, 0x9001, 0x9801, 0xa001, 0xa801,
|
||||
0xb001, 0xb801, 0xc001, 0xc801, 0xd001, 0xd801, 0xe001, 0xe801, 0xf001, 0xf801, 0x0000,
|
||||
0x07ff, 0x0fff, 0x17ff, 0x1fff, 0x27ff, 0x2fff, 0x37ff, 0x3fff, 0x47ff, 0x4fff, 0x57ff,
|
||||
0x5fff, 0x67ff, 0x6fff, 0x77ff, 0x8001, 0x8801, 0x9001, 0x9801, 0xa001, 0xa801, 0xb001,
|
||||
0xb801, 0xc001, 0xc801, 0xd001, 0xd801, 0xe001, 0xe801, 0xf001, 0xf801,
|
||||
0x0000, 0x0fff, 0x1fff, 0x2fff, 0x3fff, 0x4fff, 0x5fff, 0x6fff,
|
||||
0x8001, 0x9001, 0xa001, 0xb001, 0xc001, 0xd001, 0xe001, 0xf001,
|
||||
0x0000, 0x0fff, 0x1fff, 0x2fff, 0x3fff, 0x4fff, 0x5fff, 0x6fff,
|
||||
0x8001, 0x9001, 0xa001, 0xb001, 0xc001, 0xd001, 0xe001, 0xf001,
|
||||
0x0000, 0x0fff, 0x1fff, 0x2fff, 0x3fff, 0x4fff, 0x5fff, 0x6fff,
|
||||
0x8001, 0x9001, 0xa001, 0xb001, 0xc001, 0xd001, 0xe001, 0xf001,
|
||||
0x0000, 0x0fff, 0x1fff, 0x2fff, 0x3fff, 0x4fff, 0x5fff, 0x6fff,
|
||||
0x8001, 0x9001, 0xa001, 0xb001, 0xc001, 0xd001, 0xe001, 0xf001,
|
||||
0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001,
|
||||
0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001,
|
||||
0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001,
|
||||
0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001,
|
||||
0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001,
|
||||
0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001,
|
||||
0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001,
|
||||
0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001
|
||||
};
|
||||
s16 sTriangleWaves[256] = {
|
||||
0x0000, 0x07ff, 0x0fff, 0x17ff, 0x1fff, 0x27ff, 0x2fff, 0x37ff, 0x3fff, 0x47ff, 0x4fff, 0x57ff,
|
||||
0x5fff, 0x67ff, 0x6fff, 0x77ff, 0x7fff, 0x77ff, 0x6fff, 0x67ff, 0x5fff, 0x57ff, 0x4fff, 0x47ff,
|
||||
0x3fff, 0x37ff, 0x2fff, 0x27ff, 0x1fff, 0x17ff, 0x0fff, 0x07ff, 0x0000, 0xf801, 0xf001, 0xe801,
|
||||
0xe001, 0xd801, 0xd001, 0xc801, 0xc001, 0xb801, 0xb001, 0xa801, 0xa001, 0x9801, 0x9001, 0x8801,
|
||||
0x8001, 0x8801, 0x9001, 0x9801, 0xa001, 0xa801, 0xb001, 0xb801, 0xc001, 0xc801, 0xd001, 0xd801,
|
||||
0xe001, 0xe801, 0xf001, 0xf801, 0x0000, 0x0fff, 0x1fff, 0x2fff, 0x3fff, 0x4fff, 0x5fff, 0x6fff,
|
||||
0x7fff, 0x6fff, 0x5fff, 0x4fff, 0x3fff, 0x2fff, 0x1fff, 0x0fff, 0x0000, 0xf001, 0xe001, 0xd001,
|
||||
0xc001, 0xb001, 0xa001, 0x9001, 0x8001, 0x9001, 0xa001, 0xb001, 0xc001, 0xd001, 0xe001, 0xf001,
|
||||
0x0000, 0x0fff, 0x1fff, 0x2fff, 0x3fff, 0x4fff, 0x5fff, 0x6fff, 0x7fff, 0x6fff, 0x5fff, 0x4fff,
|
||||
0x3fff, 0x2fff, 0x1fff, 0x0fff, 0x0000, 0xf001, 0xe001, 0xd001, 0xc001, 0xb001, 0xa001, 0x9001,
|
||||
0x8001, 0x9001, 0xa001, 0xb001, 0xc001, 0xd001, 0xe001, 0xf001, 0x0000, 0x1fff, 0x3fff, 0x5fff,
|
||||
0x7fff, 0x5fff, 0x3fff, 0x1fff, 0x0000, 0xe001, 0xc001, 0xa001, 0x8001, 0xa001, 0xc001, 0xe001,
|
||||
0x0000, 0x1fff, 0x3fff, 0x5fff, 0x7fff, 0x5fff, 0x3fff, 0x1fff, 0x0000, 0xe001, 0xc001, 0xa001,
|
||||
0x8001, 0xa001, 0xc001, 0xe001, 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x7fff, 0x5fff, 0x3fff, 0x1fff,
|
||||
0x0000, 0xe001, 0xc001, 0xa001, 0x8001, 0xa001, 0xc001, 0xe001, 0x0000, 0x1fff, 0x3fff, 0x5fff,
|
||||
0x7fff, 0x5fff, 0x3fff, 0x1fff, 0x0000, 0xe001, 0xc001, 0xa001, 0x8001, 0xa001, 0xc001, 0xe001,
|
||||
0x0000, 0x3fff, 0x7fff, 0x3fff, 0x0000, 0xc001, 0x8001, 0xc001, 0x0000, 0x3fff, 0x7fff, 0x3fff,
|
||||
0x0000, 0xc001, 0x8001, 0xc001, 0x0000, 0x3fff, 0x7fff, 0x3fff, 0x0000, 0xc001, 0x8001, 0xc001,
|
||||
0x0000, 0x3fff, 0x7fff, 0x3fff, 0x0000, 0xc001, 0x8001, 0xc001, 0x0000, 0x3fff, 0x7fff, 0x3fff,
|
||||
0x0000, 0xc001, 0x8001, 0xc001, 0x0000, 0x3fff, 0x7fff, 0x3fff, 0x0000, 0xc001, 0x8001, 0xc001,
|
||||
0x0000, 0x3fff, 0x7fff, 0x3fff, 0x0000, 0xc001, 0x8001, 0xc001, 0x0000, 0x3fff, 0x7fff, 0x3fff,
|
||||
0x0000, 0xc001, 0x8001, 0xc001,
|
||||
};
|
||||
s16 sSineWaves[256] = {
|
||||
0x0000, 0x0c8b, 0x18f8, 0x2527, 0x30fb, 0x3c56, 0x471c, 0x5133, 0x5a81, 0x62f1, 0x6a6c, 0x70e1,
|
||||
0x7640, 0x7a7c, 0x7d89, 0x7f61, 0x7fff, 0x7f61, 0x7d89, 0x7a7c, 0x7640, 0x70e1, 0x6a6c, 0x62f1,
|
||||
0x5a81, 0x5133, 0x471c, 0x3c56, 0x30fb, 0x2527, 0x18f8, 0x0c8b, 0x0000, 0xf375, 0xe708, 0xdad9,
|
||||
0xcf05, 0xc3aa, 0xb8e4, 0xaecd, 0xa57f, 0x9d0f, 0x9594, 0x8f1f, 0x89c0, 0x8584, 0x8277, 0x809f,
|
||||
0x8001, 0x809f, 0x8277, 0x8584, 0x89c0, 0x8f1f, 0x9594, 0x9d0f, 0xa57f, 0xaecd, 0xb8e4, 0xc3aa,
|
||||
0xcf05, 0xdad9, 0xe708, 0xf375, 0x0000, 0x18f8, 0x30fb, 0x471c, 0x5a81, 0x6a6c, 0x7640, 0x7d89,
|
||||
0x7fff, 0x7d89, 0x7640, 0x6a6c, 0x5a81, 0x471c, 0x30fb, 0x18f8, 0x0000, 0xe708, 0xcf05, 0xb8e4,
|
||||
0xa57f, 0x9594, 0x89c0, 0x8277, 0x8001, 0x8277, 0x89c0, 0x9594, 0xa57f, 0xb8e4, 0xcf05, 0xe708,
|
||||
0x0000, 0x18f8, 0x30fb, 0x471c, 0x5a81, 0x6a6c, 0x7640, 0x7d89, 0x7fff, 0x7d89, 0x7640, 0x6a6c,
|
||||
0x5a81, 0x471c, 0x30fb, 0x18f8, 0x0000, 0xe708, 0xcf05, 0xb8e4, 0xa57f, 0x9594, 0x89c0, 0x8277,
|
||||
0x8001, 0x8277, 0x89c0, 0x9594, 0xa57f, 0xb8e4, 0xcf05, 0xe708, 0x0000, 0x30fb, 0x5a81, 0x7640,
|
||||
0x7fff, 0x7640, 0x5a81, 0x30fb, 0x0000, 0xcf05, 0xa57f, 0x89c0, 0x8001, 0x89c0, 0xa57f, 0xcf05,
|
||||
0x0000, 0x30fb, 0x5a81, 0x7640, 0x7fff, 0x7640, 0x5a81, 0x30fb, 0x0000, 0xcf05, 0xa57f, 0x89c0,
|
||||
0x8001, 0x89c0, 0xa57f, 0xcf05, 0x0000, 0x30fb, 0x5a81, 0x7640, 0x7fff, 0x7640, 0x5a81, 0x30fb,
|
||||
0x0000, 0xcf05, 0xa57f, 0x89c0, 0x8001, 0x89c0, 0xa57f, 0xcf05, 0x0000, 0x30fb, 0x5a81, 0x7640,
|
||||
0x7fff, 0x7640, 0x5a81, 0x30fb, 0x0000, 0xcf05, 0xa57f, 0x89c0, 0x8001, 0x89c0, 0xa57f, 0xcf05,
|
||||
0x0000, 0x5a81, 0x7fff, 0x5a81, 0x0000, 0xa57f, 0x8001, 0xa57f, 0x0000, 0x5a81, 0x7fff, 0x5a81,
|
||||
0x0000, 0xa57f, 0x8001, 0xa57f, 0x0000, 0x5a81, 0x7fff, 0x5a81, 0x0000, 0xa57f, 0x8001, 0xa57f,
|
||||
0x0000, 0x5a81, 0x7fff, 0x5a81, 0x0000, 0xa57f, 0x8001, 0xa57f, 0x0000, 0x5a81, 0x7fff, 0x5a81,
|
||||
0x0000, 0xa57f, 0x8001, 0xa57f, 0x0000, 0x5a81, 0x7fff, 0x5a81, 0x0000, 0xa57f, 0x8001, 0xa57f,
|
||||
0x0000, 0x5a81, 0x7fff, 0x5a81, 0x0000, 0xa57f, 0x8001, 0xa57f, 0x0000, 0x5a81, 0x7fff, 0x5a81,
|
||||
0x0000, 0xa57f, 0x8001, 0xa57f,
|
||||
};
|
||||
s16 sSquareWaves[256] = {
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
|
||||
0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001,
|
||||
0x8001, 0x8001, 0x8001, 0x8001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
|
||||
0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x8001, 0x8001, 0x8001, 0x8001,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x8001, 0x8001, 0x8001, 0x8001, 0x0000, 0x0000, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x8001, 0x8001, 0x8001, 0x8001, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x8001, 0x8001, 0x8001, 0x8001,
|
||||
0x0000, 0x0000, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x8001, 0x8001, 0x0000, 0x0000, 0x7fff, 0x7fff,
|
||||
0x0000, 0x0000, 0x8001, 0x8001, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x8001, 0x8001,
|
||||
0x0000, 0x0000, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x8001, 0x8001, 0x0000, 0x0000, 0x7fff, 0x7fff,
|
||||
0x0000, 0x0000, 0x8001, 0x8001, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x8001, 0x8001,
|
||||
0x0000, 0x0000, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x8001, 0x8001, 0x0000, 0x0000, 0x7fff, 0x7fff,
|
||||
0x0000, 0x0000, 0x8001, 0x8001,
|
||||
};
|
||||
s16 sEuUnknownWave6[256] = {
|
||||
0x0000, 0x9ba7, 0x9b41, 0x6c9b, 0x9450, 0xadda, 0x569e, 0x189a, 0x69bf, 0xb79d, 0x6fe9, 0x08ec,
|
||||
0x0d34, 0x1aea, 0xce76, 0xad86, 0x2710, 0xa038, 0x7e28, 0x2fd8, 0x3af8, 0x3bfa, 0xd10b, 0x84c7,
|
||||
0xcd7f, 0x18f4, 0xd4c8, 0x76f8, 0x8994, 0xaa11, 0x73fb, 0x6c01, 0x0000, 0x93ff, 0x8c05, 0x55ef,
|
||||
0x766c, 0x8907, 0x2b38, 0xe70d, 0x3281, 0x7b38, 0x2ef5, 0xc407, 0xc508, 0xd027, 0x81d8, 0x5fc9,
|
||||
0xd8f0, 0x5279, 0x318a, 0xe517, 0xf2cc, 0xf713, 0x9017, 0x4864, 0x9641, 0xe765, 0xa962, 0x5227,
|
||||
0x6bb0, 0x9364, 0x64bf, 0x645a, 0x0000, 0x9b41, 0x9450, 0x569e, 0x69bf, 0x6fe9, 0x0d34, 0xce76,
|
||||
0x2710, 0x7e28, 0x3af8, 0xd10b, 0xcd7f, 0xd4c8, 0x8994, 0x73fb, 0x0000, 0x8c05, 0x766c, 0x2b38,
|
||||
0x3281, 0x2ef5, 0xc508, 0x81d8, 0xd8f0, 0x318a, 0xf2cc, 0x9017, 0x9641, 0xa962, 0x6bb0, 0x64bf,
|
||||
0x0000, 0x9b41, 0x9450, 0x569e, 0x69bf, 0x6fe9, 0x0d34, 0xce76, 0x2710, 0x7e28, 0x3af8, 0xd10b,
|
||||
0xcd7f, 0xd4c8, 0x8994, 0x73fb, 0x0000, 0x8c05, 0x766c, 0x2b38, 0x3281, 0x2ef5, 0xc508, 0x81d8,
|
||||
0xd8f0, 0x318a, 0xf2cc, 0x9017, 0x9641, 0xa962, 0x6bb0, 0x64bf, 0x0000, 0x9450, 0x69bf, 0x0d34,
|
||||
0x2710, 0x3af8, 0xcd7f, 0x8994, 0x0000, 0x766c, 0x3281, 0xc508, 0xd8f0, 0xf2cc, 0x9641, 0x6bb0,
|
||||
0x0000, 0x9450, 0x69bf, 0x0d34, 0x2710, 0x3af8, 0xcd7f, 0x8994, 0x0000, 0x766c, 0x3281, 0xc508,
|
||||
0xd8f0, 0xf2cc, 0x9641, 0x6bb0, 0x0000, 0x9450, 0x69bf, 0x0d34, 0x2710, 0x3af8, 0xcd7f, 0x8994,
|
||||
0x0000, 0x766c, 0x3281, 0xc508, 0xd8f0, 0xf2cc, 0x9641, 0x6bb0, 0x0000, 0x9450, 0x69bf, 0x0d34,
|
||||
0x2710, 0x3af8, 0xcd7f, 0x8994, 0x0000, 0x766c, 0x3281, 0xc508, 0xd8f0, 0xf2cc, 0x9641, 0x6bb0,
|
||||
0x0000, 0x69bf, 0x2710, 0xcd7f, 0x0000, 0x3281, 0xd8f0, 0x9641, 0x0000, 0x69bf, 0x2710, 0xcd7f,
|
||||
0x0000, 0x3281, 0xd8f0, 0x9641, 0x0000, 0x69bf, 0x2710, 0xcd7f, 0x0000, 0x3281, 0xd8f0, 0x9641,
|
||||
0x0000, 0x69bf, 0x2710, 0xcd7f, 0x0000, 0x3281, 0xd8f0, 0x9641, 0x0000, 0x69bf, 0x2710, 0xcd7f,
|
||||
0x0000, 0x3281, 0xd8f0, 0x9641, 0x0000, 0x69bf, 0x2710, 0xcd7f, 0x0000, 0x3281, 0xd8f0, 0x9641,
|
||||
0x0000, 0x69bf, 0x2710, 0xcd7f, 0x0000, 0x3281, 0xd8f0, 0x9641, 0x0000, 0x69bf, 0x2710, 0xcd7f,
|
||||
0x0000, 0x3281, 0xd8f0, 0x9641,
|
||||
};
|
||||
s16 gEuUnknownWave7[256] = {
|
||||
0x0000, 0x3fbc, 0x4eb4, 0x4f21, 0x6a49, 0x806f, 0x7250, 0x6a7b, 0x8d2e, 0xac0a, 0x98d6, 0x7832,
|
||||
0x7551, 0x71ca, 0x4eee, 0x3731, 0x4e20, 0x644d, 0x4a50, 0x23ba, 0x1b09, 0x119a, 0xe914, 0xccbe,
|
||||
0xe14e, 0xf8a3, 0xe47e, 0xc937, 0xd181, 0xde39, 0xcfc6, 0xcf94, 0x0000, 0x306c, 0x303a, 0x21c7,
|
||||
0x2e7f, 0x36c8, 0x1b82, 0x075e, 0x1eb2, 0x3341, 0x16ec, 0xee67, 0xe4f7, 0xdc45, 0xb5b0, 0x9bb4,
|
||||
0xb1e0, 0xc8ce, 0xb112, 0x8e37, 0x8aaf, 0x87cd, 0x672a, 0x53f7, 0x72d2, 0x9584, 0x8db0, 0x7f92,
|
||||
0x95b7, 0xb0de, 0xb14c, 0xc045, 0x0000, 0x4eb4, 0x6a49, 0x7250, 0x8d2e, 0x98d6, 0x7551, 0x4eee,
|
||||
0x4e20, 0x4a50, 0x1b09, 0xe914, 0xe14e, 0xe47e, 0xd181, 0xcfc6, 0x0000, 0x303a, 0x2e7f, 0x1b82,
|
||||
0x1eb2, 0x16ec, 0xe4f7, 0xb5b0, 0xb1e0, 0xb112, 0x8aaf, 0x672a, 0x72d2, 0x8db0, 0x95b7, 0xb14c,
|
||||
0x0000, 0x4eb4, 0x6a49, 0x7250, 0x8d2e, 0x98d6, 0x7551, 0x4eee, 0x4e20, 0x4a50, 0x1b09, 0xe914,
|
||||
0xe14e, 0xe47e, 0xd181, 0xcfc6, 0x0000, 0x303a, 0x2e7f, 0x1b82, 0x1eb2, 0x16ec, 0xe4f7, 0xb5b0,
|
||||
0xb1e0, 0xb112, 0x8aaf, 0x672a, 0x72d2, 0x8db0, 0x95b7, 0xb14c, 0x0000, 0x6a49, 0x8d2e, 0x7551,
|
||||
0x4e20, 0x1b09, 0xe14e, 0xd181, 0x0000, 0x2e7f, 0x1eb2, 0xe4f7, 0xb1e0, 0x8aaf, 0x72d2, 0x95b7,
|
||||
0x0000, 0x6a49, 0x8d2e, 0x7551, 0x4e20, 0x1b09, 0xe14e, 0xd181, 0x0000, 0x2e7f, 0x1eb2, 0xe4f7,
|
||||
0xb1e0, 0x8aaf, 0x72d2, 0x95b7, 0x0000, 0x6a49, 0x8d2e, 0x7551, 0x4e20, 0x1b09, 0xe14e, 0xd181,
|
||||
0x0000, 0x2e7f, 0x1eb2, 0xe4f7, 0xb1e0, 0x8aaf, 0x72d2, 0x95b7, 0x0000, 0x6a49, 0x8d2e, 0x7551,
|
||||
0x4e20, 0x1b09, 0xe14e, 0xd181, 0x0000, 0x2e7f, 0x1eb2, 0xe4f7, 0xb1e0, 0x8aaf, 0x72d2, 0x95b7,
|
||||
0x0000, 0x8d2e, 0x4e20, 0xe14e, 0x0000, 0x1eb2, 0xb1e0, 0x72d2, 0x0000, 0x8d2e, 0x4e20, 0xe14e,
|
||||
0x0000, 0x1eb2, 0xb1e0, 0x72d2, 0x0000, 0x8d2e, 0x4e20, 0xe14e, 0x0000, 0x1eb2, 0xb1e0, 0x72d2,
|
||||
0x0000, 0x8d2e, 0x4e20, 0xe14e, 0x0000, 0x1eb2, 0xb1e0, 0x72d2, 0x0000, 0x8d2e, 0x4e20, 0xe14e,
|
||||
0x0000, 0x1eb2, 0xb1e0, 0x72d2, 0x0000, 0x8d2e, 0x4e20, 0xe14e, 0x0000, 0x1eb2, 0xb1e0, 0x72d2,
|
||||
0x0000, 0x8d2e, 0x4e20, 0xe14e, 0x0000, 0x1eb2, 0xb1e0, 0x72d2, 0x0000, 0x8d2e, 0x4e20, 0xe14e,
|
||||
0x0000, 0x1eb2, 0xb1e0, 0x72d2,
|
||||
};
|
||||
s16 *gWaveSamples[6] = { sSawtoothWaves, sTriangleWaves, sSineWaves, sSquareWaves, sEuUnknownWave6, gEuUnknownWave7 };
|
||||
|
||||
#else
|
||||
// !VERSION_EU
|
||||
|
||||
s16 sSineWave[0x40] = {
|
||||
0, 3211, 6392, 9511, 12539, 15446, 18204, 20787, 23169, 25329, 27244,
|
||||
28897, 30272, 31356, 32137, 32609, 0x7FFF, 32609, 32137, 31356, 30272, 28897,
|
||||
27244, 25329, 23169, 20787, 18204, 15446, 12539, 9511, 6392, 3211, 0,
|
||||
-3211, -6392, -9511, -12539, -15446, -18204, -20787, -23169, -25329, -27244, -28897,
|
||||
-30272, -31356, -32137, -32609, -0x7FFF, -32609, -32137, -31356, -30272, -28897, -27244,
|
||||
-25329, -23169, -20787, -18204, -15446, -12539, -9511, -6392, -3211,
|
||||
};
|
||||
|
||||
s16 sSquareWave[0x40] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF,
|
||||
0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF,
|
||||
-0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF,
|
||||
};
|
||||
s16 sTriangleWave[0x40] = {
|
||||
0, 0x7FF, 0xFFF, 0x17FF, 0x1FFF, 0x27FF, 0x2FFF, 0x37FF, 0x3FFF, 0x47FF, 0x4FFF,
|
||||
0x57FF, 0x5FFF, 0x67FF, 0x6FFF, 0x77FF, 0x7FFF, 0x77FF, 0x6FFF, 0x67FF, 0x5FFF, 0x57FF,
|
||||
0x4FFF, 0x47FF, 0x3FFF, 0x37FF, 0x2FFF, 0x27FF, 0x1FFF, 0x17FF, 0xFFF, 0x7FF, 0,
|
||||
-0x7FF, -0xFFF, -0x17FF, -0x1FFF, -10239, -0x2FFF, -0x37FF, -0x3FFF, -0x47FF, -0x4FFF, -22527,
|
||||
-24575, -26623, -28671, -30719, -0x7FFF, -30719, -28671, -26623, -24575, -22527, -0x4FFF,
|
||||
-0x47FF, -0x3FFF, -0x37FF, -0x2FFF, -0x27FF, -0x1FFF, -0x17FF, -0xFFF, -0x7FF,
|
||||
};
|
||||
|
||||
s16 sSawtoothWave[0x40] = {
|
||||
0, 1023, 2047, 3071, 4095, 5119, 6143, 7167, 8191, 9215, 10239,
|
||||
11263, 0x2FFF, 13311, 0x37FF, 15359, 0x3FFF, 17407, 0x47FF, 19455, 0x4FFF, 21503,
|
||||
22527, 23551, 24575, 25599, 26623, 27647, 28671, 29695, 30719, 31743, -0x7FFF,
|
||||
-31743, -30719, -29695, -28671, -27647, -26623, -25599, -24575, -23551, -22527, -21503,
|
||||
-0x4FFF, -19455, -0x47FF, -17407, -0x3FFF, -15359, -0x37FF, -13311, -0x2FFF, -11263, -10239,
|
||||
-9215, -8191, -7167, -6143, -5119, -4095, -3071, -2047, -1023,
|
||||
};
|
||||
s16 *gWaveSamples[4] = { sSawtoothWave, sTriangleWave, sSineWave, sSquareWave };
|
||||
#endif
|
||||
|
||||
#ifdef VERSION_SH
|
||||
s32 unk_sh_data_0[2] = {0, 0};
|
||||
f32 gPitchBendFrequencyScale[256] = {
|
||||
0.5f, 0.5f, 0.502736f, 0.505488f, 0.508254f, 0.511036f, 0.513833f, 0.516645f, 0.519472f,
|
||||
0.522315f, 0.525174f, 0.528048f, 0.530938f, 0.533843f, 0.536765f, 0.539702f, 0.542656f, 0.545626f,
|
||||
0.548612f, 0.551614f, 0.554633f, 0.557669f, 0.560721f, 0.563789f, 0.566875f, 0.569977f, 0.573097f,
|
||||
0.576233f, 0.579387f, 0.582558f, 0.585746f, 0.588951f, 0.592175f, 0.595415f, 0.598674f, 0.601950f,
|
||||
0.605245f, 0.608557f, 0.611888f, 0.615236f, 0.618603f, 0.621989f, 0.625393f, 0.628815f, 0.632257f,
|
||||
0.635717f, 0.639196f, 0.642694f, 0.646212f, 0.649748f, 0.653304f, 0.656880f, 0.660475f, 0.664089f,
|
||||
0.667724f, 0.671378f, 0.675052f, 0.678747f, 0.682461f, 0.686196f, 0.689952f, 0.693727f, 0.697524f,
|
||||
0.701341f, 0.705180f, 0.709039f, 0.712919f, 0.716821f, 0.720744f, 0.724689f, 0.728655f, 0.732642f,
|
||||
0.736652f, 0.740684f, 0.744737f, 0.748813f, 0.752911f, 0.757031f, 0.761175f, 0.765340f, 0.769529f,
|
||||
0.773740f, 0.777975f, 0.782232f, 0.786513f, 0.790818f, 0.795146f, 0.799497f, 0.803873f, 0.808272f,
|
||||
0.812696f, 0.817144f, 0.821616f, 0.826112f, 0.830633f, 0.835179f, 0.839750f, 0.844346f, 0.848966f,
|
||||
0.853613f, 0.858284f, 0.862982f, 0.867704f, 0.872453f, 0.877228f, 0.882029f, 0.886856f, 0.891709f,
|
||||
0.896590f, 0.901496f, 0.906430f, 0.911391f, 0.916379f, 0.921394f, 0.926436f, 0.931507f, 0.936604f,
|
||||
0.941730f, 0.946884f, 0.952066f, 0.957277f, 0.962516f, 0.967783f, 0.973080f, 0.978405f, 0.983760f,
|
||||
0.989144f, 0.994557f, 1.0f, 1.005473f, 1.010975f, 1.016508f, 1.022071f, 1.027665f, 1.033289f,
|
||||
1.038944f, 1.044630f, 1.050347f, 1.056095f, 1.061875f, 1.067687f, 1.073530f, 1.079405f, 1.085312f,
|
||||
1.091252f, 1.097224f, 1.103229f, 1.109267f, 1.115337f, 1.121441f, 1.127579f, 1.133750f, 1.139955f,
|
||||
1.146193f, 1.152466f, 1.158773f, 1.165115f, 1.171491f, 1.177903f, 1.184349f, 1.190831f, 1.197348f,
|
||||
1.203901f, 1.210489f, 1.217114f, 1.223775f, 1.230473f, 1.237207f, 1.243978f, 1.250786f, 1.257631f,
|
||||
1.264514f, 1.271434f, 1.278392f, 1.285389f, 1.292423f, 1.299497f, 1.306608f, 1.313759f, 1.320949f,
|
||||
1.328178f, 1.335447f, 1.342756f, 1.350104f, 1.357493f, 1.364922f, 1.372392f, 1.379903f, 1.387455f,
|
||||
1.395048f, 1.402683f, 1.410360f, 1.418078f, 1.425839f, 1.433642f, 1.441488f, 1.449377f, 1.457309f,
|
||||
1.465285f, 1.473304f, 1.481367f, 1.489474f, 1.497626f, 1.505822f, 1.514063f, 1.522349f, 1.530681f,
|
||||
1.539058f, 1.547481f, 1.555950f, 1.564465f, 1.573027f, 1.581636f, 1.590292f, 1.598995f, 1.607746f,
|
||||
1.616545f, 1.625392f, 1.634287f, 1.643231f, 1.652224f, 1.661266f, 1.670358f, 1.679500f, 1.688691f,
|
||||
1.697933f, 1.707225f, 1.716569f, 1.725963f, 1.735409f, 1.744906f, 1.754456f, 1.764058f, 1.773712f,
|
||||
1.783419f, 1.793179f, 1.802993f, 1.812860f, 1.822782f, 1.832757f, 1.842788f, 1.852873f, 1.863013f,
|
||||
1.873209f, 1.883461f, 1.893768f, 1.904132f, 1.914553f, 1.925031f, 1.935567f, 1.946159f, 1.956810f,
|
||||
1.967520f, 1.978287f, 1.989114f, 2.0f
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef VERSION_SH
|
||||
f32 unk_sh_data_1[] = {
|
||||
0.890899f, 0.890899f, 0.89171f, 0.892521f, 0.893333f, 0.894146f, 0.89496f, 0.895774f,
|
||||
0.89659f, 0.897406f, 0.898222f, 0.89904f, 0.899858f, 0.900677f, 0.901496f, 0.902317f,
|
||||
0.903138f, 0.90396f, 0.904783f, 0.905606f, 0.90643f, 0.907255f, 0.908081f, 0.908907f,
|
||||
0.909734f, 0.910562f, 0.911391f, 0.91222f, 0.91305f, 0.913881f, 0.914713f, 0.915545f,
|
||||
0.916379f, 0.917213f, 0.918047f, 0.918883f, 0.919719f, 0.920556f, 0.921394f, 0.922232f,
|
||||
0.923072f, 0.923912f, 0.924752f, 0.925594f, 0.926436f, 0.927279f, 0.928123f, 0.928968f,
|
||||
0.929813f, 0.93066f, 0.931507f, 0.932354f, 0.933203f, 0.934052f, 0.934902f, 0.935753f,
|
||||
0.936604f, 0.937457f, 0.93831f, 0.939164f, 0.940019f, 0.940874f, 0.94173f, 0.942587f,
|
||||
0.943445f, 0.944304f, 0.945163f, 0.946023f, 0.946884f, 0.947746f, 0.948608f, 0.949472f,
|
||||
0.950336f, 0.951201f, 0.952066f, 0.952933f, 0.9538f, 0.954668f, 0.955537f, 0.956406f,
|
||||
0.957277f, 0.958148f, 0.95902f, 0.959893f, 0.960766f, 0.961641f, 0.962516f, 0.963392f,
|
||||
0.964268f, 0.965146f, 0.966024f, 0.966903f, 0.967783f, 0.968664f, 0.969546f, 0.970428f,
|
||||
0.971311f, 0.972195f, 0.97308f, 0.973965f, 0.974852f, 0.975739f, 0.976627f, 0.977516f,
|
||||
0.978405f, 0.979296f, 0.980187f, 0.981079f, 0.981972f, 0.982865f, 0.98376f, 0.984655f,
|
||||
0.985551f, 0.986448f, 0.987346f, 0.988244f, 0.989144f, 0.990044f, 0.990945f, 0.991847f,
|
||||
0.992749f, 0.993653f, 0.994557f, 0.995462f, 0.996368f, 0.997275f, 0.998182f, 0.999091f,
|
||||
1.0f, 1.00091f, 1.001821f, 1.002733f, 1.003645f, 1.004559f, 1.005473f, 1.006388f,
|
||||
1.007304f, 1.00822f, 1.009138f, 1.010056f, 1.010975f, 1.011896f, 1.012816f, 1.013738f,
|
||||
1.014661f, 1.015584f, 1.016508f, 1.017433f, 1.018359f, 1.019286f, 1.020214f, 1.021142f,
|
||||
1.022071f, 1.023002f, 1.023933f, 1.024864f, 1.025797f, 1.026731f, 1.027665f, 1.0286f,
|
||||
1.029536f, 1.030473f, 1.031411f, 1.03235f, 1.033289f, 1.03423f, 1.035171f, 1.036113f,
|
||||
1.037056f, 1.038f, 1.038944f, 1.03989f, 1.040836f, 1.041783f, 1.042731f, 1.04368f,
|
||||
1.04463f, 1.045581f, 1.046532f, 1.047485f, 1.048438f, 1.049392f, 1.050347f, 1.051303f,
|
||||
1.05226f, 1.053217f, 1.054176f, 1.055135f, 1.056095f, 1.057056f, 1.058018f, 1.058981f,
|
||||
1.059945f, 1.06091f, 1.061875f, 1.062842f, 1.063809f, 1.064777f, 1.065746f, 1.066716f,
|
||||
1.067687f, 1.068658f, 1.069631f, 1.070604f, 1.071578f, 1.072554f, 1.07353f, 1.074507f,
|
||||
1.075485f, 1.076463f, 1.077443f, 1.078424f, 1.079405f, 1.080387f, 1.08137f, 1.082355f,
|
||||
1.08334f, 1.084325f, 1.085312f, 1.0863f, 1.087289f, 1.088278f, 1.089268f, 1.09026f,
|
||||
1.091252f, 1.092245f, 1.093239f, 1.094234f, 1.09523f, 1.096226f, 1.097224f, 1.098223f,
|
||||
1.099222f, 1.100222f, 1.101224f, 1.102226f, 1.103229f, 1.104233f, 1.105238f, 1.106244f,
|
||||
1.10725f, 1.108258f, 1.109267f, 1.110276f, 1.111287f, 1.112298f, 1.11331f, 1.114323f,
|
||||
1.115337f, 1.116352f, 1.117368f, 1.118385f, 1.119403f, 1.120422f, 1.121441f, 1.122462f,
|
||||
};
|
||||
|
||||
// Shindou moved these variables down here. :/
|
||||
// clang-format off
|
||||
f32 gNoteFrequencies[128] = {
|
||||
0.105112f, 0.111362f, 0.117984f, 0.125f, 0.132433f, 0.140308f, 0.148651f, 0.15749f, 0.166855f, 0.176777f, 0.187288f, 0.198425f,
|
||||
0.210224f, 0.222725f, 0.235969f, 0.25f, 0.264866f, 0.280616f, 0.297302f, 0.31498f, 0.33371f, 0.353553f, 0.374577f, 0.39685f,
|
||||
0.420448f, 0.445449f, 0.471937f, 0.5f, 0.529732f, 0.561231f, 0.594604f, 0.629961f, 0.66742f, 0.707107f, 0.749154f, 0.793701f,
|
||||
0.840897f, 0.890899f, 0.943875f, 1.0f, 1.059463f, 1.122462f, 1.189207f, 1.259921f, 1.33484f, 1.414214f, 1.498307f, 1.587401f,
|
||||
1.681793f, 1.781798f, 1.887749f, 2.0f, 2.118926f, 2.244924f, 2.378414f, 2.519842f, 2.66968f, 2.828428f, 2.996615f, 3.174803f,
|
||||
3.363586f, 3.563596f, 3.775498f, 4.0f, 4.237853f, 4.489849f, 4.756829f, 5.039685f, 5.33936f, 5.656855f, 5.993229f, 6.349606f,
|
||||
6.727173f, 7.127192f, 7.550996f, 8.0f, 8.475705f, 8.979697f, 9.513658f, 10.07937f, 10.67872f, 11.31371f, 11.986459f, 12.699211f,
|
||||
13.454346f, 14.254383f, 15.101993f, 16.0f, 16.95141f, 17.959394f, 19.027315f, 20.15874f, 21.35744f, 22.62742f, 23.972918f, 25.398422f,
|
||||
26.908691f, 28.508766f, 30.203985f, 32.0f, 33.90282f, 35.91879f, 38.05463f, 40.31748f, 42.71488f, 45.25484f, 47.945835f, 50.796844f,
|
||||
53.817383f, 57.017532f, 60.40797f, 64.0f, 67.80564f, 71.83758f, 76.10926f, 80.63496f, 85.42976f, 45.25484f, 47.945835f, 50.796844f,
|
||||
53.817383f, 57.017532f, 60.40797f, 64.0f, 67.80564f, 71.83758f, 76.10926f, 80.63496f
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
u8 gDefaultShortNoteVelocityTable[16] = {
|
||||
12, 25, 38, 51, 57, 64, 71, 76, 83, 89, 96, 102, 109, 115, 121, 127,
|
||||
};
|
||||
|
||||
u8 gDefaultShortNoteDurationTable[16] = {
|
||||
229, 203, 177, 151, 139, 126, 113, 100, 87, 74, 61, 48, 36, 23, 10, 0,
|
||||
};
|
||||
|
||||
struct AdsrEnvelope gDefaultEnvelope[] = {
|
||||
{ BSWAP16(4), BSWAP16(32000) }, // go from 0 to 32000 over the course of 16ms
|
||||
{ BSWAP16(1000), BSWAP16(32000) }, // stay there for 4.16 seconds
|
||||
{ BSWAP16(ADSR_HANG), 0 } // then continue staying there
|
||||
};
|
||||
|
||||
u8 unk_sh_data2[4] = { 0, 0, 0, 0 };
|
||||
|
||||
struct NoteSubEu gZeroNoteSub = { 0 };
|
||||
struct NoteSubEu gDefaultNoteSub = {
|
||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { NULL },
|
||||
#ifdef VERSION_SH
|
||||
0
|
||||
#endif
|
||||
};
|
||||
|
||||
u16 gHeadsetPanQuantization[0x40] = {
|
||||
0x3C, 0x3A, 0x38, 0x36, 0x34, 0x32, 0x30, 0x2E,
|
||||
0x2C, 0x2A, 0x28, 0x26, 0x24, 0x22, 0x20, 0x1E,
|
||||
0x1C, 0x1A, 0x18, 0x16, 0x14, 0x12, 0x10, 0x0E,
|
||||
0x0C, 0x0A, 0x08, 0x06, 0x04, 0x02,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef VERSION_EU
|
||||
u8 euUnknownData_8030194c[4] = { 0x40, 0x20, 0x10, 0x08 };
|
||||
u16 gHeadsetPanQuantization[0x10] = {
|
||||
0x40, 0x40, 0x30, 0x30, 0x20, 0x20, 0x10, 0, 0, 0,
|
||||
};
|
||||
#elif !defined(VERSION_SH)
|
||||
u16 gHeadsetPanQuantization[10] = { 0x40, 0x30, 0x20, 0x10, 0, 0, 0, 0, 0, 0 };
|
||||
#endif
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
s16 euUnknownData_80301950[64] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 500, 0, 0, 0, 0, 0, 0, 0, 500, 0, 0, 0, 0, 0, 0, 0, 500, 0, 0, 0, 0, 0, 0, 0, 500, 0, 0, 0, 0,
|
||||
};
|
||||
#endif
|
||||
|
||||
// Linearly interpolated between
|
||||
// f(0/2 * 127) = 1
|
||||
// f(1/2 * 127) = 1/sqrt(2)
|
||||
// f(2/2 * 127) = 0
|
||||
f32 gHeadsetPanVolume[128] = {
|
||||
1.0f, 0.995386f, 0.990772f, 0.986157f, 0.981543f, 0.976929f, 0.972315f, 0.967701f, 0.963087f,
|
||||
0.958472f, 0.953858f, 0.949244f, 0.94463f, 0.940016f, 0.935402f, 0.930787f, 0.926173f, 0.921559f,
|
||||
0.916945f, 0.912331f, 0.907717f, 0.903102f, 0.898488f, 0.893874f, 0.88926f, 0.884646f, 0.880031f,
|
||||
0.875417f, 0.870803f, 0.866189f, 0.861575f, 0.856961f, 0.852346f, 0.847732f, 0.843118f, 0.838504f,
|
||||
0.83389f, 0.829276f, 0.824661f, 0.820047f, 0.815433f, 0.810819f, 0.806205f, 0.801591f, 0.796976f,
|
||||
0.792362f, 0.787748f, 0.783134f, 0.77852f, 0.773906f, 0.769291f, 0.764677f, 0.760063f, 0.755449f,
|
||||
0.750835f, 0.74622f, 0.741606f, 0.736992f, 0.732378f, 0.727764f, 0.72315f, 0.718535f, 0.713921f,
|
||||
0.709307f, 0.70537f, 0.70211f, 0.69885f, 0.695591f, 0.692331f, 0.689071f, 0.685811f, 0.682551f,
|
||||
0.679291f, 0.676031f, 0.672772f, 0.669512f, 0.666252f, 0.662992f, 0.659732f, 0.656472f, 0.653213f,
|
||||
0.649953f, 0.646693f, 0.643433f, 0.640173f, 0.636913f, 0.633654f, 0.630394f, 0.627134f, 0.623874f,
|
||||
0.620614f, 0.617354f, 0.614094f, 0.610835f, 0.607575f, 0.604315f, 0.601055f, 0.597795f, 0.594535f,
|
||||
0.591276f, 0.588016f, 0.584756f, 0.581496f, 0.578236f, 0.574976f, 0.571717f, 0.568457f, 0.565197f,
|
||||
0.561937f, 0.558677f, 0.555417f, 0.552157f, 0.548898f, 0.545638f, 0.542378f, 0.539118f, 0.535858f,
|
||||
0.532598f, 0.529339f, 0.526079f, 0.522819f, 0.519559f, 0.516299f, 0.513039f, 0.50978f, 0.50652f,
|
||||
0.50326f, 0.5f
|
||||
};
|
||||
|
||||
// Linearly interpolated between
|
||||
// f(0/4 * 127) = 1/sqrt(2)
|
||||
// f(1/4 * 127) = 1
|
||||
// f(2/4 * 127) = 1/sqrt(2)
|
||||
// f(3/4 * 127) = 0
|
||||
// f(4/4 * 127) = 1/sqrt(8)
|
||||
f32 gStereoPanVolume[128] = {
|
||||
0.707f, 0.716228f, 0.725457f, 0.734685f, 0.743913f, 0.753142f, 0.76237f, 0.771598f, 0.780827f,
|
||||
0.790055f, 0.799283f, 0.808512f, 0.81774f, 0.826968f, 0.836197f, 0.845425f, 0.854654f, 0.863882f,
|
||||
0.87311f, 0.882339f, 0.891567f, 0.900795f, 0.910024f, 0.919252f, 0.92848f, 0.937709f, 0.946937f,
|
||||
0.956165f, 0.965394f, 0.974622f, 0.98385f, 0.993079f, 0.997693f, 0.988465f, 0.979236f, 0.970008f,
|
||||
0.960779f, 0.951551f, 0.942323f, 0.933095f, 0.923866f, 0.914638f, 0.905409f, 0.896181f, 0.886953f,
|
||||
0.877724f, 0.868496f, 0.859268f, 0.850039f, 0.840811f, 0.831583f, 0.822354f, 0.813126f, 0.803898f,
|
||||
0.794669f, 0.785441f, 0.776213f, 0.766984f, 0.757756f, 0.748528f, 0.739299f, 0.730071f, 0.720843f,
|
||||
0.711614f, 0.695866f, 0.673598f, 0.651331f, 0.629063f, 0.606795f, 0.584528f, 0.56226f, 0.539992f,
|
||||
0.517724f, 0.495457f, 0.473189f, 0.450921f, 0.428654f, 0.406386f, 0.384118f, 0.36185f, 0.339583f,
|
||||
0.317315f, 0.295047f, 0.27278f, 0.250512f, 0.228244f, 0.205976f, 0.183709f, 0.161441f, 0.139173f,
|
||||
0.116905f, 0.094638f, 0.07237f, 0.050102f, 0.027835f, 0.005567f, 0.00835f, 0.019484f, 0.030618f,
|
||||
0.041752f, 0.052886f, 0.06402f, 0.075154f, 0.086287f, 0.097421f, 0.108555f, 0.119689f, 0.130823f,
|
||||
0.141957f, 0.153091f, 0.164224f, 0.175358f, 0.186492f, 0.197626f, 0.20876f, 0.219894f, 0.231028f,
|
||||
0.242161f, 0.253295f, 0.264429f, 0.275563f, 0.286697f, 0.297831f, 0.308965f, 0.320098f, 0.331232f,
|
||||
0.342366f, 0.3535f
|
||||
};
|
||||
|
||||
// gDefaultVolume[k] = cos(pi/2 * k / 127)
|
||||
f32 gDefaultPanVolume[128] = {
|
||||
1.0f, 0.999924f, 0.999694f, 0.999312f, 0.998776f, 0.998088f, 0.997248f, 0.996254f, 0.995109f,
|
||||
0.993811f, 0.992361f, 0.990759f, 0.989006f, 0.987101f, 0.985045f, 0.982839f, 0.980482f, 0.977976f,
|
||||
0.97532f, 0.972514f, 0.96956f, 0.966457f, 0.963207f, 0.959809f, 0.956265f, 0.952574f, 0.948737f,
|
||||
0.944755f, 0.940629f, 0.936359f, 0.931946f, 0.92739f, 0.922692f, 0.917853f, 0.912873f, 0.907754f,
|
||||
0.902497f, 0.897101f, 0.891567f, 0.885898f, 0.880093f, 0.874153f, 0.868079f, 0.861873f, 0.855535f,
|
||||
0.849066f, 0.842467f, 0.835739f, 0.828884f, 0.821901f, 0.814793f, 0.807561f, 0.800204f, 0.792725f,
|
||||
0.785125f, 0.777405f, 0.769566f, 0.76161f, 0.753536f, 0.745348f, 0.737045f, 0.72863f, 0.720103f,
|
||||
0.711466f, 0.70272f, 0.693867f, 0.684908f, 0.675843f, 0.666676f, 0.657406f, 0.648036f, 0.638567f,
|
||||
0.629f, 0.619337f, 0.609579f, 0.599728f, 0.589785f, 0.579752f, 0.56963f, 0.559421f, 0.549126f,
|
||||
0.538748f, 0.528287f, 0.517745f, 0.507124f, 0.496425f, 0.485651f, 0.474802f, 0.46388f, 0.452888f,
|
||||
0.441826f, 0.430697f, 0.419502f, 0.408243f, 0.396921f, 0.385538f, 0.374097f, 0.362598f, 0.351044f,
|
||||
0.339436f, 0.327776f, 0.316066f, 0.304308f, 0.292503f, 0.280653f, 0.268761f, 0.256827f, 0.244854f,
|
||||
0.232844f, 0.220798f, 0.208718f, 0.196606f, 0.184465f, 0.172295f, 0.160098f, 0.147877f, 0.135634f,
|
||||
0.12337f, 0.111087f, 0.098786f, 0.086471f, 0.074143f, 0.061803f, 0.049454f, 0.037097f, 0.024734f,
|
||||
0.012368f, 0.0f
|
||||
};
|
||||
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
// gVolRampingLhs136[k] = 2^16 * max(1, (256*k)^(1/17)
|
||||
f32 gVolRampingLhs136[128] = {
|
||||
65536.0f, 90811.555f, 94590.766f, 96873.96f, 98527.26f, 99829.06f, 100905.47f,
|
||||
101824.61f, 102627.57f, 103341.086f, 103983.55f, 104568.164f, 105104.75f, 105600.8f,
|
||||
106062.14f, 106493.46f, 106898.52f, 107280.414f, 107641.73f, 107984.62f, 108310.93f,
|
||||
108622.23f, 108919.875f, 109205.055f, 109478.8f, 109742.0f, 109995.48f, 110239.94f,
|
||||
110476.02f, 110704.305f, 110925.3f, 111139.45f, 111347.21f, 111548.945f, 111745.0f,
|
||||
111935.7f, 112121.35f, 112302.2f, 112478.51f, 112650.51f, 112818.4f, 112982.38f,
|
||||
113142.66f, 113299.37f, 113452.69f, 113602.766f, 113749.734f, 113893.73f, 114034.87f,
|
||||
114173.26f, 114309.02f, 114442.26f, 114573.055f, 114701.5f, 114827.69f, 114951.695f,
|
||||
115073.6f, 115193.47f, 115311.375f, 115427.39f, 115541.56f, 115653.96f, 115764.63f,
|
||||
115873.64f, 115981.04f, 116086.86f, 116191.164f, 116293.99f, 116395.38f, 116495.38f,
|
||||
116594.02f, 116691.34f, 116787.39f, 116882.19f, 116975.77f, 117068.17f, 117159.414f,
|
||||
117249.54f, 117338.57f, 117426.53f, 117513.45f, 117599.35f, 117684.266f, 117768.2f,
|
||||
117851.195f, 117933.266f, 118014.44f, 118094.72f, 118174.14f, 118252.71f, 118330.46f,
|
||||
118407.4f, 118483.55f, 118558.914f, 118633.53f, 118707.4f, 118780.54f, 118852.97f,
|
||||
118924.695f, 118995.74f, 119066.11f, 119135.82f, 119204.88f, 119273.31f, 119341.125f,
|
||||
119408.32f, 119474.92f, 119540.93f, 119606.36f, 119671.22f, 119735.52f, 119799.28f,
|
||||
119862.5f, 119925.195f, 119987.36f, 120049.02f, 120110.18f, 120170.84f, 120231.016f,
|
||||
120290.71f, 120349.945f, 120408.7f, 120467.016f, 120524.875f, 120582.3f, 120639.28f,
|
||||
120695.84f, 120751.984f
|
||||
};
|
||||
|
||||
// gVolRampingRhs136[k] = 1 / max(1, (256*k)^(1/17))
|
||||
f32 gVolRampingRhs136[128] = {
|
||||
1.0f, 0.72167f, 0.692837f, 0.676508f, 0.665156f, 0.656482f, 0.649479f, 0.643616f, 0.638581f,
|
||||
0.634172f, 0.630254f, 0.62673f, 0.62353f, 0.620601f, 0.617902f, 0.615399f, 0.613067f, 0.610885f,
|
||||
0.608835f, 0.606901f, 0.605073f, 0.603339f, 0.60169f, 0.600119f, 0.598618f, 0.597183f, 0.595806f,
|
||||
0.594485f, 0.593215f, 0.591991f, 0.590812f, 0.589674f, 0.588573f, 0.587509f, 0.586478f, 0.585479f,
|
||||
0.58451f, 0.583568f, 0.582654f, 0.581764f, 0.580898f, 0.580055f, 0.579233f, 0.578432f, 0.57765f,
|
||||
0.576887f, 0.576142f, 0.575414f, 0.574701f, 0.574005f, 0.573323f, 0.572656f, 0.572002f, 0.571361f,
|
||||
0.570733f, 0.570118f, 0.569514f, 0.568921f, 0.568339f, 0.567768f, 0.567207f, 0.566656f, 0.566114f,
|
||||
0.565582f, 0.565058f, 0.564543f, 0.564036f, 0.563537f, 0.563046f, 0.562563f, 0.562087f, 0.561618f,
|
||||
0.561156f, 0.560701f, 0.560253f, 0.559811f, 0.559375f, 0.558945f, 0.558521f, 0.558102f, 0.557689f,
|
||||
0.557282f, 0.55688f, 0.556483f, 0.556091f, 0.555704f, 0.555322f, 0.554944f, 0.554571f, 0.554203f,
|
||||
0.553839f, 0.553479f, 0.553123f, 0.552772f, 0.552424f, 0.55208f, 0.55174f, 0.551404f, 0.551071f,
|
||||
0.550742f, 0.550417f, 0.550095f, 0.549776f, 0.549461f, 0.549148f, 0.548839f, 0.548534f, 0.548231f,
|
||||
0.547931f, 0.547634f, 0.54734f, 0.547048f, 0.54676f, 0.546474f, 0.546191f, 0.54591f, 0.545632f,
|
||||
0.545357f, 0.545084f, 0.544813f, 0.544545f, 0.54428f, 0.544016f, 0.543755f, 0.543496f, 0.543239f,
|
||||
0.542985f, 0.542732f
|
||||
};
|
||||
|
||||
// gVolRampingLhs144[k] = 2^16 * max(1, (256*k)^(1/18))
|
||||
f32 gVolRampingLhs144[128] = {
|
||||
65536.0f, 89180.734f, 92681.9f, 94793.33f, 96320.52f, 97522.02f, 98514.84f,
|
||||
99362.14f, 100101.99f, 100759.16f, 101350.664f, 101888.74f, 102382.46f, 102838.75f,
|
||||
103263.016f, 103659.58f, 104031.914f, 104382.89f, 104714.88f, 105029.89f, 105329.61f,
|
||||
105615.5f, 105888.81f, 106150.63f, 106401.914f, 106643.49f, 106876.12f, 107100.44f,
|
||||
107317.05f, 107526.47f, 107729.17f, 107925.6f, 108116.125f, 108301.12f, 108480.88f,
|
||||
108655.72f, 108825.91f, 108991.68f, 109153.28f, 109310.914f, 109464.77f, 109615.04f,
|
||||
109761.88f, 109905.46f, 110045.92f, 110183.41f, 110318.02f, 110449.91f, 110579.17f,
|
||||
110705.914f, 110830.234f, 110952.234f, 111071.99f, 111189.59f, 111305.12f, 111418.64f,
|
||||
111530.23f, 111639.95f, 111747.875f, 111854.05f, 111958.54f, 112061.4f, 112162.67f,
|
||||
112262.42f, 112360.68f, 112457.51f, 112552.93f, 112647.0f, 112739.76f, 112831.23f,
|
||||
112921.46f, 113010.484f, 113098.33f, 113185.02f, 113270.61f, 113355.11f, 113438.555f,
|
||||
113520.97f, 113602.375f, 113682.805f, 113762.27f, 113840.81f, 113918.44f, 113995.18f,
|
||||
114071.055f, 114146.08f, 114220.266f, 114293.65f, 114366.24f, 114438.06f, 114509.12f,
|
||||
114579.44f, 114649.02f, 114717.91f, 114786.086f, 114853.586f, 114920.42f, 114986.6f,
|
||||
115052.14f, 115117.055f, 115181.34f, 115245.04f, 115308.13f, 115370.65f, 115432.59f,
|
||||
115493.98f, 115554.81f, 115615.11f, 115674.875f, 115734.12f, 115792.85f, 115851.08f,
|
||||
115908.82f, 115966.07f, 116022.85f, 116079.16f, 116135.01f, 116190.4f, 116245.35f,
|
||||
116299.87f, 116353.945f, 116407.6f, 116460.84f, 116513.67f, 116566.09f, 116618.125f,
|
||||
116669.76f, 116721.01f
|
||||
};
|
||||
|
||||
// gVolRampingRhs144[k] = 1 / max(1, (256*k)^(1/18))
|
||||
f32 gVolRampingRhs144[128] = {
|
||||
1.0f, 0.734867f, 0.707107f, 0.691357f, 0.680395f, 0.672012f, 0.66524f, 0.659567f, 0.654692f,
|
||||
0.650422f, 0.646626f, 0.643211f, 0.64011f, 0.637269f, 0.634651f, 0.632223f, 0.629961f, 0.627842f,
|
||||
0.625852f, 0.623975f, 0.622199f, 0.620515f, 0.618913f, 0.617387f, 0.615929f, 0.614533f, 0.613196f,
|
||||
0.611912f, 0.610677f, 0.609487f, 0.60834f, 0.607233f, 0.606163f, 0.605128f, 0.604125f, 0.603153f,
|
||||
0.60221f, 0.601294f, 0.600403f, 0.599538f, 0.598695f, 0.597874f, 0.597074f, 0.596294f, 0.595533f,
|
||||
0.59479f, 0.594064f, 0.593355f, 0.592661f, 0.591983f, 0.591319f, 0.590669f, 0.590032f, 0.589408f,
|
||||
0.588796f, 0.588196f, 0.587608f, 0.58703f, 0.586463f, 0.585906f, 0.58536f, 0.584822f, 0.584294f,
|
||||
0.583775f, 0.583265f, 0.582762f, 0.582268f, 0.581782f, 0.581303f, 0.580832f, 0.580368f, 0.579911f,
|
||||
0.57946f, 0.579017f, 0.578579f, 0.578148f, 0.577722f, 0.577303f, 0.576889f, 0.576481f, 0.576078f,
|
||||
0.575681f, 0.575289f, 0.574902f, 0.574519f, 0.574142f, 0.573769f, 0.5734f, 0.573036f, 0.572677f,
|
||||
0.572321f, 0.57197f, 0.571623f, 0.57128f, 0.57094f, 0.570605f, 0.570273f, 0.569945f, 0.56962f,
|
||||
0.569299f, 0.568981f, 0.568667f, 0.568355f, 0.568047f, 0.567743f, 0.567441f, 0.567142f, 0.566846f,
|
||||
0.566553f, 0.566263f, 0.565976f, 0.565692f, 0.56541f, 0.565131f, 0.564854f, 0.56458f, 0.564309f,
|
||||
0.56404f, 0.563773f, 0.563509f, 0.563247f, 0.562987f, 0.56273f, 0.562475f, 0.562222f, 0.561971f,
|
||||
0.561722f, 0.561476f
|
||||
};
|
||||
|
||||
// gVolRampingLhs128[k] = 2^16 * max(1, (256*k)^(1/16))
|
||||
f32 gVolRampingLhs128[128] = {
|
||||
65536.0f, 92681.9f, 96785.28f, 99269.31f, 101070.33f, 102489.78f, 103664.336f,
|
||||
104667.914f, 105545.09f, 106324.92f, 107027.39f, 107666.84f, 108253.95f, 108796.87f,
|
||||
109301.95f, 109774.29f, 110217.98f, 110636.39f, 111032.33f, 111408.164f, 111765.9f,
|
||||
112107.234f, 112433.66f, 112746.46f, 113046.766f, 113335.555f, 113613.72f, 113882.02f,
|
||||
114141.164f, 114391.77f, 114634.414f, 114869.58f, 115097.74f, 115319.31f, 115534.68f,
|
||||
115744.19f, 115948.16f, 116146.875f, 116340.625f, 116529.66f, 116714.195f, 116894.46f,
|
||||
117070.64f, 117242.945f, 117411.52f, 117576.55f, 117738.17f, 117896.54f, 118051.77f,
|
||||
118204.0f, 118353.35f, 118499.92f, 118643.83f, 118785.16f, 118924.01f, 119060.47f,
|
||||
119194.625f, 119326.555f, 119456.336f, 119584.03f, 119709.71f, 119833.445f, 119955.29f,
|
||||
120075.31f, 120193.555f, 120310.08f, 120424.94f, 120538.17f, 120649.836f, 120759.97f,
|
||||
120868.62f, 120975.82f, 121081.62f, 121186.05f, 121289.14f, 121390.94f, 121491.47f,
|
||||
121590.766f, 121688.87f, 121785.79f, 121881.57f, 121976.24f, 122069.82f, 122162.33f,
|
||||
122253.805f, 122344.266f, 122433.73f, 122522.23f, 122609.77f, 122696.4f, 122782.11f,
|
||||
122866.93f, 122950.89f, 123033.99f, 123116.26f, 123197.72f, 123278.37f, 123358.24f,
|
||||
123437.34f, 123515.69f, 123593.3f, 123670.19f, 123746.36f, 123821.84f, 123896.63f,
|
||||
123970.76f, 124044.23f, 124117.04f, 124189.23f, 124260.78f, 124331.73f, 124402.07f,
|
||||
124471.83f, 124540.99f, 124609.59f, 124677.63f, 124745.12f, 124812.055f, 124878.47f,
|
||||
124944.34f, 125009.71f, 125074.57f, 125138.92f, 125202.79f, 125266.164f, 125329.06f,
|
||||
125391.5f, 125453.47f
|
||||
};
|
||||
|
||||
// gVolRampingRhs128[k] = 1 / max(1, (256*k)^(1/16))
|
||||
f32 gVolRampingRhs128[128] = {
|
||||
1.0f, 0.707107f, 0.677128f, 0.660184f, 0.64842f, 0.639439f, 0.632194f, 0.626133f, 0.620929f,
|
||||
0.616375f, 0.612329f, 0.608693f, 0.605391f, 0.60237f, 0.599587f, 0.597007f, 0.594604f, 0.592355f,
|
||||
0.590243f, 0.588251f, 0.586369f, 0.584583f, 0.582886f, 0.581269f, 0.579725f, 0.578247f, 0.576832f,
|
||||
0.575473f, 0.574166f, 0.572908f, 0.571696f, 0.570525f, 0.569394f, 0.5683f, 0.567241f, 0.566214f,
|
||||
0.565218f, 0.564251f, 0.563311f, 0.562398f, 0.561508f, 0.560642f, 0.559799f, 0.558976f, 0.558173f,
|
||||
0.55739f, 0.556625f, 0.555877f, 0.555146f, 0.554431f, 0.553732f, 0.553047f, 0.552376f, 0.551719f,
|
||||
0.551075f, 0.550443f, 0.549823f, 0.549216f, 0.548619f, 0.548033f, 0.547458f, 0.546892f, 0.546337f,
|
||||
0.545791f, 0.545254f, 0.544726f, 0.544206f, 0.543695f, 0.543192f, 0.542696f, 0.542209f, 0.541728f,
|
||||
0.541255f, 0.540788f, 0.540329f, 0.539876f, 0.539429f, 0.538988f, 0.538554f, 0.538125f, 0.537702f,
|
||||
0.537285f, 0.536873f, 0.536467f, 0.536065f, 0.535669f, 0.535277f, 0.534891f, 0.534509f, 0.534131f,
|
||||
0.533759f, 0.53339f, 0.533026f, 0.532666f, 0.53231f, 0.531958f, 0.53161f, 0.531266f, 0.530925f,
|
||||
0.530588f, 0.530255f, 0.529926f, 0.529599f, 0.529277f, 0.528957f, 0.528641f, 0.528328f, 0.528018f,
|
||||
0.527711f, 0.527407f, 0.527106f, 0.526808f, 0.526513f, 0.52622f, 0.525931f, 0.525644f, 0.525359f,
|
||||
0.525077f, 0.524798f, 0.524522f, 0.524247f, 0.523975f, 0.523706f, 0.523439f, 0.523174f, 0.522911f,
|
||||
0.522651f, 0.522393f
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef VERSION_SH
|
||||
u16 unk_sh_data_3[] = {
|
||||
// 30 entries
|
||||
// pattern:
|
||||
// A B
|
||||
// C D
|
||||
// C B
|
||||
// A E
|
||||
0x1000, 0x1000,
|
||||
0x1000, 0x1000,
|
||||
0x1000, 0x1000,
|
||||
0x1000, 0x1000,
|
||||
|
||||
0x0E6F, 0x1091,
|
||||
0x11EF, 0x1267,
|
||||
0x11EF, 0x1091,
|
||||
0x0E6F, 0x0BB8,
|
||||
|
||||
0x0C1D, 0x111D,
|
||||
0x1494, 0x15D2,
|
||||
0x1494, 0x111D,
|
||||
0x0C1D, 0x068E,
|
||||
|
||||
0x0838, 0x116E,
|
||||
0x18A6, 0x1B61,
|
||||
0x18A6, 0x116E,
|
||||
0x0838, 0x0001,
|
||||
|
||||
0x0227, 0x0F42,
|
||||
0x1B75, 0x206B,
|
||||
0x1B75, 0x0F42,
|
||||
0x0227, 0xFA2B,
|
||||
|
||||
0xFC28, 0x0AAE,
|
||||
0x1BE7, 0x2394,
|
||||
0x1BE7, 0x0AAE,
|
||||
0xFC28, 0xF874,
|
||||
|
||||
0xF809, 0x0582,
|
||||
0x1C36, 0x2788,
|
||||
0x1C36, 0x0582,
|
||||
0xF809, 0xFAEB,
|
||||
|
||||
0xF5F0, 0x0001,
|
||||
0x1E34, 0x2F71,
|
||||
0x1E34, 0x0001,
|
||||
0xF5F0, 0x0000,
|
||||
|
||||
0xF8AD, 0xFAF3,
|
||||
0x19ED, 0x2EB6,
|
||||
0x19ED, 0xFAF3,
|
||||
0xF8AD, 0x04AC,
|
||||
|
||||
0xFCC0, 0xF6FF,
|
||||
0x178B, 0x3207,
|
||||
0x178B, 0xF6FF,
|
||||
0xFCC0, 0x065F,
|
||||
|
||||
0x01A5, 0xF44E,
|
||||
0x1510, 0x36B4,
|
||||
0x1510, 0xF44E,
|
||||
0x01A5, 0x047B,
|
||||
|
||||
0x05C1, 0xF3CC,
|
||||
0x1145, 0x3988,
|
||||
0x1145, 0xF3CC,
|
||||
0x05C1, 0x0001,
|
||||
|
||||
0x07B9, 0xF517,
|
||||
0x0D20, 0x3C4C,
|
||||
0x0D20, 0xF517,
|
||||
0x07B9, 0xFBD4,
|
||||
|
||||
0x07C0, 0xF71C,
|
||||
0x09A1, 0x4528,
|
||||
0x09A1, 0xF71C,
|
||||
0x07C0, 0xF9B7,
|
||||
|
||||
0x058F, 0xFA43,
|
||||
0x05DC, 0x585F,
|
||||
0x05DC, 0xFA43,
|
||||
0x058F, 0xFAB3,
|
||||
};
|
||||
|
||||
u16 unk_sh_data_4[] = {
|
||||
0xFA73, 0xFA42,
|
||||
0xFA27, 0x5866,
|
||||
0xFA27, 0xFA42,
|
||||
0xFA73, 0xFAB2,
|
||||
|
||||
0xF842, 0xF71B,
|
||||
0xF661, 0x452B,
|
||||
0xF661, 0xF71B,
|
||||
0xF842, 0xF9B5,
|
||||
|
||||
0xF848, 0xF516,
|
||||
0xF2E1, 0x3C4D,
|
||||
0xF2E1, 0xF516,
|
||||
0xF848, 0xFBD2,
|
||||
|
||||
0xFA3F, 0xF3CA,
|
||||
0xEEBD, 0x3989,
|
||||
0xEEBD, 0xF3CA,
|
||||
0xFA3F, 0xFFFF,
|
||||
|
||||
0xFE5B, 0xF44C,
|
||||
0xEAF2, 0x36B5,
|
||||
0xEAF2, 0xF44C,
|
||||
0xFE5B, 0x0479,
|
||||
|
||||
0x0340, 0xF6FD,
|
||||
0xE877, 0x3207,
|
||||
0xE877, 0xF6FD,
|
||||
0x0340, 0x065E,
|
||||
|
||||
0x0753, 0xFAF1,
|
||||
0xE615, 0x2EB5,
|
||||
0xE615, 0xFAF1,
|
||||
0x0753, 0x04AB,
|
||||
|
||||
0x0A12, 0xFFFF,
|
||||
0xE1CD, 0x2F71,
|
||||
0xE1CD, 0xFFFF,
|
||||
0x0A12, 0x0000,
|
||||
|
||||
0x07FA, 0x057F,
|
||||
0xE3CA, 0x2789,
|
||||
0xE3CA, 0x057F,
|
||||
0x07FA, 0xFAEA,
|
||||
|
||||
0x03DB, 0x0AAC,
|
||||
0xE41A, 0x2394,
|
||||
0xE41A, 0x0AAC,
|
||||
0x03DB, 0xF873,
|
||||
|
||||
0xFDDC, 0x0F41,
|
||||
0xE489, 0x206E,
|
||||
0xE489, 0x0F41,
|
||||
0xFDDC, 0xFA28,
|
||||
|
||||
0xF7CA, 0x116E,
|
||||
0xE758, 0x1B63,
|
||||
0xE758, 0x116E,
|
||||
0xF7CA, 0xFFFF,
|
||||
|
||||
0xF3E4, 0x111D,
|
||||
0xEB6A, 0x15D4,
|
||||
0xEB6A, 0x111D,
|
||||
0xF3E4, 0x068B,
|
||||
|
||||
0xF192, 0x1092,
|
||||
0xEE11, 0x1268,
|
||||
0xEE11, 0x1092,
|
||||
0xF192, 0x0BB6,
|
||||
|
||||
0xF05F, 0x1026,
|
||||
0xEF89, 0x1093,
|
||||
0xEF89, 0x1026,
|
||||
0xF05F, 0x0EEB,
|
||||
|
||||
0x0000, 0x0000,
|
||||
0x0000, 0x0000,
|
||||
0x7FFF, 0xD001,
|
||||
0x3FFF, 0xF001,
|
||||
0x5FFF, 0x9001,
|
||||
0x7FFF, 0x8001
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef VERSION_SH
|
||||
s16 gTatumsPerBeat = TATUMS_PER_BEAT;
|
||||
s8 gUnusedCount80333EE8 = UNUSED_COUNT_80333EE8;
|
||||
s32 gAudioHeapSize = DOUBLE_SIZE_ON_64_BIT(AUDIO_HEAP_SIZE);
|
||||
s32 gAudioInitPoolSize = DOUBLE_SIZE_ON_64_BIT(AUDIO_INIT_POOL_SIZE);
|
||||
volatile s32 gAudioLoadLock = AUDIO_LOCK_UNINITIALIZED;
|
||||
#endif
|
||||
|
||||
#if defined(VERSION_EU)
|
||||
u8 bufferDelete2[12] = { 0 };
|
||||
u8 D_EU_80302010 = 0;
|
||||
u8 D_EU_80302014 = 0;
|
||||
|
||||
struct OSMesgQueue *OSMesgQueues[4] = { &OSMesgQueue0, &OSMesgQueue1, &OSMesgQueue2, &OSMesgQueue3 };
|
||||
#elif defined(VERSION_JP) || defined(VERSION_US)
|
||||
s8 sUnused8033EF8 = 24;
|
||||
#endif
|
||||
|
||||
// .bss
|
||||
|
||||
volatile s32 gAudioFrameCount;
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
s32 gCurrAudioFrameDmaCount;
|
||||
#else
|
||||
volatile s32 gCurrAudioFrameDmaCount;
|
||||
#endif
|
||||
|
||||
s32 gAudioTaskIndex;
|
||||
s32 gCurrAiBufferIndex;
|
||||
|
||||
u64 *gAudioCmdBuffers[2];
|
||||
u64 *gAudioCmd;
|
||||
|
||||
struct SPTask *gAudioTask;
|
||||
struct SPTask gAudioTasks[2];
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
f32 D_EU_802298D0;
|
||||
s32 gRefreshRate;
|
||||
#endif
|
||||
|
||||
s16 *gAiBuffers[NUMAIBUFFERS];
|
||||
s16 gAiBufferLengths[NUMAIBUFFERS];
|
||||
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
u32 gUnused80226E58[0x10];
|
||||
u16 gUnused80226E98[0x10];
|
||||
#endif
|
||||
|
||||
u32 gAudioRandom;
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
s32 gAudioErrorFlags;
|
||||
#endif
|
||||
|
||||
#ifdef VERSION_SH
|
||||
volatile u32 gAudioLoadLockSH;
|
||||
struct EuAudioCmd sAudioCmd[0x100];
|
||||
u8 D_SH_80350F18;
|
||||
u8 D_SH_80350F19;
|
||||
|
||||
OSMesg D_SH_80350F1C[1];
|
||||
OSMesgQueue D_SH_80350F20; // address written to D_SH_80350F38
|
||||
OSMesgQueue *D_SH_80350F38;
|
||||
|
||||
OSMesg D_SH_80350F40[4];
|
||||
OSMesgQueue D_SH_80350F50; // address written to D_SH_80350F68
|
||||
OSMesgQueue *D_SH_80350F68;
|
||||
|
||||
OSMesg D_SH_80350F6C[1];
|
||||
OSMesgQueue D_SH_80350F70; // address written to D_SH_80350F88
|
||||
OSMesgQueue *D_SH_80350F88;
|
||||
|
||||
OSMesg D_SH_80350F8C[1];
|
||||
OSMesgQueue D_SH_80350F90; // address written to D_SH_80350F90
|
||||
OSMesgQueue *D_SH_80350FA8;
|
||||
#endif
|
||||
|
||||
u64 gAudioGlobalsEndMarker;
|
||||
@@ -0,0 +1,154 @@
|
||||
#ifndef AUDIO_DATA_H
|
||||
#define AUDIO_DATA_H
|
||||
|
||||
#include <PR/ultratypes.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include <types.h>
|
||||
|
||||
#define AUDIO_LOCK_UNINITIALIZED 0
|
||||
#define AUDIO_LOCK_NOT_LOADING 0x76557364
|
||||
#define AUDIO_LOCK_LOADING 0x19710515
|
||||
|
||||
#define NUMAIBUFFERS 3
|
||||
|
||||
// constant .data
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
extern struct AudioSessionSettingsEU gAudioSessionPresets[];
|
||||
#else
|
||||
extern struct AudioSessionSettings gAudioSessionPresets[18];
|
||||
#endif
|
||||
extern u16 D_80332388[128]; // unused
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
extern f32 gPitchBendFrequencyScale[256];
|
||||
#else
|
||||
extern f32 gPitchBendFrequencyScale[255];
|
||||
#endif
|
||||
extern f32 gNoteFrequencies[128];
|
||||
|
||||
extern u8 gDefaultShortNoteVelocityTable[16];
|
||||
extern u8 gDefaultShortNoteDurationTable[16];
|
||||
extern s8 gVibratoCurve[16];
|
||||
extern struct AdsrEnvelope gDefaultEnvelope[3];
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
extern s16 gEuUnknownWave7[256];
|
||||
extern s16 *gWaveSamples[6];
|
||||
#else
|
||||
extern s16 *gWaveSamples[4];
|
||||
#endif
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
extern u8 euUnknownData_8030194c[4];
|
||||
#ifdef VERSION_EU
|
||||
extern u16 gHeadsetPanQuantization[0x10];
|
||||
#else
|
||||
extern u16 gHeadsetPanQuantization[0x40];
|
||||
#endif
|
||||
extern s16 euUnknownData_80301950[64];
|
||||
extern struct NoteSubEu gZeroNoteSub;
|
||||
extern struct NoteSubEu gDefaultNoteSub;
|
||||
#else
|
||||
extern u16 gHeadsetPanQuantization[10];
|
||||
#endif
|
||||
extern f32 gHeadsetPanVolume[128];
|
||||
extern f32 gStereoPanVolume[128];
|
||||
extern f32 gDefaultPanVolume[128];
|
||||
|
||||
extern f32 gVolRampingLhs136[128];
|
||||
extern f32 gVolRampingRhs136[128];
|
||||
extern f32 gVolRampingLhs144[128];
|
||||
extern f32 gVolRampingRhs144[128];
|
||||
extern f32 gVolRampingLhs128[128];
|
||||
extern f32 gVolRampingRhs128[128];
|
||||
|
||||
// non-constant .data
|
||||
extern s16 gTatumsPerBeat;
|
||||
extern s8 gUnusedCount80333EE8;
|
||||
extern s32 gAudioHeapSize; // AUDIO_HEAP_SIZE
|
||||
extern s32 gAudioInitPoolSize; // AUDIO_INIT_POOL_SIZE
|
||||
extern volatile s32 gAudioLoadLock;
|
||||
|
||||
// .bss
|
||||
extern volatile s32 gAudioFrameCount;
|
||||
|
||||
// number of DMAs performed during this frame
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
extern s32 gCurrAudioFrameDmaCount;
|
||||
#else
|
||||
extern volatile s32 gCurrAudioFrameDmaCount;
|
||||
#endif
|
||||
|
||||
extern s32 gAudioTaskIndex;
|
||||
extern s32 gCurrAiBufferIndex;
|
||||
|
||||
extern u64 *gAudioCmdBuffers[2];
|
||||
extern u64 *gAudioCmd;
|
||||
|
||||
extern struct SPTask *gAudioTask;
|
||||
extern struct SPTask gAudioTasks[2];
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
extern f32 D_EU_802298D0;
|
||||
extern s32 gRefreshRate;
|
||||
#endif
|
||||
|
||||
extern s16 *gAiBuffers[NUMAIBUFFERS];
|
||||
extern s16 gAiBufferLengths[NUMAIBUFFERS];
|
||||
#if defined(VERSION_SH)
|
||||
#define AIBUFFER_LEN 0xb00
|
||||
#elif defined(VERSION_EU)
|
||||
#define AIBUFFER_LEN (0xa0 * 17)
|
||||
#else
|
||||
#define AIBUFFER_LEN (0xa0 * 16)
|
||||
#endif
|
||||
|
||||
extern u32 gUnused80226E58[0x10];
|
||||
extern u16 gUnused80226E98[0x10];
|
||||
|
||||
extern u32 gAudioRandom;
|
||||
|
||||
#ifdef VERSION_SH
|
||||
extern f32 unk_sh_data_1[];
|
||||
|
||||
extern volatile u32 gAudioLoadLockSH;
|
||||
|
||||
extern u8 D_SH_80350F18;
|
||||
extern u8 D_SH_80350F19;
|
||||
|
||||
extern OSMesg D_SH_80350F1C[1];
|
||||
extern OSMesgQueue D_SH_80350F20; // address written to D_SH_80350F38
|
||||
extern OSMesgQueue *D_SH_80350F38;
|
||||
|
||||
extern OSMesg D_SH_80350F40[4];
|
||||
extern OSMesgQueue D_SH_80350F50; // address written to D_SH_80350F68
|
||||
extern OSMesgQueue *D_SH_80350F68;
|
||||
|
||||
extern OSMesg D_SH_80350F6C[1];
|
||||
extern OSMesgQueue D_SH_80350F70; // address written to D_SH_80350F88
|
||||
extern OSMesgQueue *D_SH_80350F88;
|
||||
|
||||
extern OSMesg D_SH_80350F8C[1];
|
||||
extern OSMesgQueue D_SH_80350F90; // address written to D_SH_80350F90
|
||||
extern OSMesgQueue *D_SH_80350FA8;
|
||||
#endif
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
#define UNUSED_COUNT_80333EE8 24
|
||||
#define AUDIO_HEAP_SIZE 0x2c500
|
||||
#define AUDIO_INIT_POOL_SIZE 0x2c00
|
||||
#else
|
||||
#define UNUSED_COUNT_80333EE8 16
|
||||
#define AUDIO_HEAP_SIZE 0x31150
|
||||
#define AUDIO_INIT_POOL_SIZE 0x2500
|
||||
#endif
|
||||
|
||||
#ifdef VERSION_SH
|
||||
extern u32 D_SH_80315EF0;
|
||||
extern u16 D_SH_80315EF4;
|
||||
extern u16 D_SH_80315EF8;
|
||||
extern u16 D_SH_80315EFC;
|
||||
#endif
|
||||
|
||||
#endif // AUDIO_DATA_H
|
||||
@@ -0,0 +1,545 @@
|
||||
#include <ultra64.h>
|
||||
|
||||
#include "effects.h"
|
||||
#include "load.h"
|
||||
#include "data.h"
|
||||
#include "seqplayer.h"
|
||||
|
||||
#ifdef VERSION_JP
|
||||
#define US_FLOAT2(x) x##.0
|
||||
#else
|
||||
#define US_FLOAT2(x) x
|
||||
#endif
|
||||
|
||||
f32 gTrackVolume = 1.0f;
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
void sequence_channel_process_sound(struct SequenceChannel *seqChannel, s32 recalculateVolume) {
|
||||
f32 channelVolume;
|
||||
s32 i;
|
||||
|
||||
if (seqChannel->changes.as_bitfields.volume || recalculateVolume) {
|
||||
channelVolume = seqChannel->volume * seqChannel->volumeScale * seqChannel->seqPlayer->appliedFadeVolume;
|
||||
if (seqChannel->seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_SOFTEN) != 0) {
|
||||
channelVolume = seqChannel->seqPlayer->muteVolumeScale * channelVolume;
|
||||
}
|
||||
#ifdef VERSION_SH
|
||||
seqChannel->appliedVolume = channelVolume * channelVolume;
|
||||
#else
|
||||
seqChannel->appliedVolume = channelVolume;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (seqChannel->changes.as_bitfields.pan) {
|
||||
seqChannel->pan = seqChannel->newPan * seqChannel->panChannelWeight;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
struct SequenceChannelLayer *layer = seqChannel->layers[i];
|
||||
if (layer != NULL && layer->enabled && layer->note != NULL) {
|
||||
if (layer->notePropertiesNeedInit) {
|
||||
layer->noteFreqScale = layer->freqScale * seqChannel->freqScale;
|
||||
layer->noteVelocity = layer->velocitySquare * seqChannel->appliedVolume;
|
||||
layer->notePan = (seqChannel->pan + layer->pan * (0x80 - seqChannel->panChannelWeight)) >> 7;
|
||||
layer->notePropertiesNeedInit = FALSE;
|
||||
} else {
|
||||
if (seqChannel->changes.as_bitfields.freqScale) {
|
||||
layer->noteFreqScale = layer->freqScale * seqChannel->freqScale;
|
||||
}
|
||||
if (seqChannel->changes.as_bitfields.volume || recalculateVolume) {
|
||||
layer->noteVelocity = layer->velocitySquare * seqChannel->appliedVolume;
|
||||
}
|
||||
if (seqChannel->changes.as_bitfields.pan) {
|
||||
layer->notePan = (seqChannel->pan + layer->pan * (0x80 - seqChannel->panChannelWeight)) >> 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
seqChannel->changes.as_u8 = 0;
|
||||
}
|
||||
#else
|
||||
static void sequence_channel_process_sound(struct SequenceChannel *seqChannel) {
|
||||
f32 channelVolume;
|
||||
f32 panLayerWeight;
|
||||
f32 panFromChannel;
|
||||
s32 i;
|
||||
|
||||
channelVolume = seqChannel->volume * seqChannel->volumeScale * seqChannel->seqPlayer->fadeVolume;
|
||||
if (seqChannel->seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_SOFTEN) != 0) {
|
||||
channelVolume *= seqChannel->seqPlayer->muteVolumeScale;
|
||||
}
|
||||
|
||||
panFromChannel = seqChannel->pan * seqChannel->panChannelWeight;
|
||||
panLayerWeight = US_FLOAT(1.0) - seqChannel->panChannelWeight;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
struct SequenceChannelLayer *layer = seqChannel->layers[i];
|
||||
if (layer != NULL && layer->enabled && layer->note != NULL) {
|
||||
layer->noteFreqScale = layer->freqScale * seqChannel->freqScale;
|
||||
layer->noteVelocity = layer->velocitySquare * (channelVolume * gTrackVolume);
|
||||
layer->notePan = (layer->pan * panLayerWeight) + panFromChannel;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void sequence_player_process_sound(struct SequencePlayer *seqPlayer) {
|
||||
s32 i;
|
||||
|
||||
if (seqPlayer->fadeRemainingFrames != 0) {
|
||||
seqPlayer->fadeVolume += seqPlayer->fadeVelocity;
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
seqPlayer->recalculateVolume = TRUE;
|
||||
#endif
|
||||
|
||||
if (seqPlayer->fadeVolume > US_FLOAT2(1)) {
|
||||
seqPlayer->fadeVolume = US_FLOAT2(1);
|
||||
}
|
||||
if (seqPlayer->fadeVolume < 0) {
|
||||
seqPlayer->fadeVolume = 0;
|
||||
}
|
||||
|
||||
if (--seqPlayer->fadeRemainingFrames == 0) {
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
if (seqPlayer->state == 2) {
|
||||
sequence_player_disable(seqPlayer);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
switch (seqPlayer->state) {
|
||||
case SEQUENCE_PLAYER_STATE_FADE_OUT:
|
||||
sequence_player_disable(seqPlayer);
|
||||
return;
|
||||
|
||||
case SEQUENCE_PLAYER_STATE_2:
|
||||
case SEQUENCE_PLAYER_STATE_3:
|
||||
seqPlayer->state = SEQUENCE_PLAYER_STATE_0;
|
||||
break;
|
||||
|
||||
case SEQUENCE_PLAYER_STATE_4:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
if (seqPlayer->recalculateVolume) {
|
||||
seqPlayer->appliedFadeVolume = seqPlayer->fadeVolume * seqPlayer->fadeVolumeScale;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Process channels
|
||||
for (i = 0; i < CHANNELS_MAX; i++) {
|
||||
if (IS_SEQUENCE_CHANNEL_VALID(seqPlayer->channels[i]) == TRUE
|
||||
&& seqPlayer->channels[i]->enabled == TRUE) {
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
sequence_channel_process_sound(seqPlayer->channels[i], seqPlayer->recalculateVolume);
|
||||
#else
|
||||
sequence_channel_process_sound(seqPlayer->channels[i]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
seqPlayer->recalculateVolume = FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
f32 get_portamento_freq_scale(struct Portamento *p) {
|
||||
u32 v0;
|
||||
f32 result;
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
if (p->mode == 0) {
|
||||
return 1.0f;
|
||||
}
|
||||
#endif
|
||||
|
||||
p->cur += p->speed;
|
||||
v0 = (u32) p->cur;
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
if (v0 > 127)
|
||||
#else
|
||||
if (v0 >= 127)
|
||||
#endif
|
||||
{
|
||||
v0 = 127;
|
||||
}
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
result = US_FLOAT(1.0) + p->extent * (gPitchBendFrequencyScale[v0 + 128] - US_FLOAT(1.0));
|
||||
#else
|
||||
result = US_FLOAT(1.0) + p->extent * (gPitchBendFrequencyScale[v0 + 127] - US_FLOAT(1.0));
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
s16 get_vibrato_pitch_change(struct VibratoState *vib) {
|
||||
s32 index;
|
||||
vib->time += (s32) vib->rate;
|
||||
index = (vib->time >> 10) & 0x3F;
|
||||
return vib->curve[index] >> 8;
|
||||
}
|
||||
#else
|
||||
s8 get_vibrato_pitch_change(struct VibratoState *vib) {
|
||||
s32 index;
|
||||
vib->time += vib->rate;
|
||||
|
||||
index = (vib->time >> 10) & 0x3F;
|
||||
|
||||
switch (index & 0x30) {
|
||||
case 0x10:
|
||||
index = 31 - index;
|
||||
|
||||
case 0x00:
|
||||
return vib->curve[index];
|
||||
|
||||
case 0x20:
|
||||
index -= 0x20;
|
||||
break;
|
||||
|
||||
case 0x30:
|
||||
index = 63 - index;
|
||||
break;
|
||||
}
|
||||
|
||||
return -vib->curve[index];
|
||||
}
|
||||
#endif
|
||||
|
||||
f32 get_vibrato_freq_scale(struct VibratoState *vib) {
|
||||
s32 pitchChange;
|
||||
f32 extent;
|
||||
f32 result;
|
||||
|
||||
if (vib->delay != 0) {
|
||||
vib->delay--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (vib->extentChangeTimer) {
|
||||
if (vib->extentChangeTimer == 1) {
|
||||
vib->extent = (s32) vib->seqChannel->vibratoExtentTarget;
|
||||
} else {
|
||||
vib->extent +=
|
||||
((s32) vib->seqChannel->vibratoExtentTarget - vib->extent) / (s32) vib->extentChangeTimer;
|
||||
}
|
||||
|
||||
vib->extentChangeTimer--;
|
||||
} else if (vib->seqChannel->vibratoExtentTarget != (s32) vib->extent) {
|
||||
if ((vib->extentChangeTimer = vib->seqChannel->vibratoExtentChangeDelay) == 0) {
|
||||
vib->extent = (s32) vib->seqChannel->vibratoExtentTarget;
|
||||
}
|
||||
}
|
||||
|
||||
if (vib->rateChangeTimer) {
|
||||
if (vib->rateChangeTimer == 1) {
|
||||
vib->rate = (s32) vib->seqChannel->vibratoRateTarget;
|
||||
} else {
|
||||
vib->rate += ((s32) vib->seqChannel->vibratoRateTarget - vib->rate) / (s32) vib->rateChangeTimer;
|
||||
}
|
||||
|
||||
vib->rateChangeTimer--;
|
||||
} else if (vib->seqChannel->vibratoRateTarget != (s32) vib->rate) {
|
||||
if ((vib->rateChangeTimer = vib->seqChannel->vibratoRateChangeDelay) == 0) {
|
||||
vib->rate = (s32) vib->seqChannel->vibratoRateTarget;
|
||||
}
|
||||
}
|
||||
|
||||
if (vib->extent == 0) {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
pitchChange = get_vibrato_pitch_change(vib);
|
||||
extent = (f32) vib->extent / US_FLOAT(4096.0);
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
result = US_FLOAT(1.0) + extent * (gPitchBendFrequencyScale[pitchChange + 128] - US_FLOAT(1.0));
|
||||
#else
|
||||
result = US_FLOAT(1.0) + extent * (gPitchBendFrequencyScale[pitchChange + 127] - US_FLOAT(1.0));
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
void note_vibrato_update(struct Note *note) {
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
if (note->portamento.mode != 0) {
|
||||
note->portamentoFreqScale = get_portamento_freq_scale(¬e->portamento);
|
||||
}
|
||||
if (note->vibratoState.active && note->parentLayer != NO_LAYER) {
|
||||
note->vibratoFreqScale = get_vibrato_freq_scale(¬e->vibratoState);
|
||||
}
|
||||
#else
|
||||
if (note->vibratoState.active) {
|
||||
note->portamentoFreqScale = get_portamento_freq_scale(¬e->portamento);
|
||||
if (note->parentLayer != NO_LAYER) {
|
||||
note->vibratoFreqScale = get_vibrato_freq_scale(¬e->vibratoState);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void note_vibrato_init(struct Note *note) {
|
||||
struct VibratoState *vib;
|
||||
UNUSED struct SequenceChannel *seqChannel;
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
struct NotePlaybackState *seqPlayerState = (struct NotePlaybackState *) ¬e->priority;
|
||||
#endif
|
||||
|
||||
note->vibratoFreqScale = 1.0f;
|
||||
note->portamentoFreqScale = 1.0f;
|
||||
|
||||
vib = ¬e->vibratoState;
|
||||
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
if (note->parentLayer->seqChannel->vibratoExtentStart == 0
|
||||
&& note->parentLayer->seqChannel->vibratoExtentTarget == 0
|
||||
&& note->parentLayer->portamento.mode == 0) {
|
||||
vib->active = FALSE;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
vib->active = TRUE;
|
||||
vib->time = 0;
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
vib->curve = gWaveSamples[2];
|
||||
vib->seqChannel = note->parentLayer->seqChannel;
|
||||
if ((vib->extentChangeTimer = vib->seqChannel->vibratoExtentChangeDelay) == 0) {
|
||||
vib->extent = FLOAT_CAST(vib->seqChannel->vibratoExtentTarget);
|
||||
} else {
|
||||
vib->extent = FLOAT_CAST(vib->seqChannel->vibratoExtentStart);
|
||||
}
|
||||
|
||||
if ((vib->rateChangeTimer = vib->seqChannel->vibratoRateChangeDelay) == 0) {
|
||||
vib->rate = FLOAT_CAST(vib->seqChannel->vibratoRateTarget);
|
||||
} else {
|
||||
vib->rate = FLOAT_CAST(vib->seqChannel->vibratoRateStart);
|
||||
}
|
||||
vib->delay = vib->seqChannel->vibratoDelay;
|
||||
|
||||
seqPlayerState->portamento = seqPlayerState->parentLayer->portamento;
|
||||
#else
|
||||
vib->curve = gVibratoCurve;
|
||||
vib->seqChannel = note->parentLayer->seqChannel;
|
||||
seqChannel = vib->seqChannel;
|
||||
|
||||
if ((vib->extentChangeTimer = seqChannel->vibratoExtentChangeDelay) == 0) {
|
||||
vib->extent = seqChannel->vibratoExtentTarget;
|
||||
} else {
|
||||
vib->extent = seqChannel->vibratoExtentStart;
|
||||
}
|
||||
|
||||
if ((vib->rateChangeTimer = seqChannel->vibratoRateChangeDelay) == 0) {
|
||||
vib->rate = seqChannel->vibratoRateTarget;
|
||||
} else {
|
||||
vib->rate = seqChannel->vibratoRateStart;
|
||||
}
|
||||
vib->delay = seqChannel->vibratoDelay;
|
||||
|
||||
note->portamento = note->parentLayer->portamento;
|
||||
#endif
|
||||
}
|
||||
|
||||
void adsr_init(struct AdsrState *adsr, struct AdsrEnvelope *envelope, UNUSED s16 *volOut) {
|
||||
adsr->action = 0;
|
||||
adsr->state = ADSR_STATE_DISABLED;
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
adsr->delay = 0;
|
||||
adsr->envelope = envelope;
|
||||
#ifdef VERSION_SH
|
||||
adsr->sustain = 0.0f;
|
||||
#endif
|
||||
adsr->current = 0.0f;
|
||||
#else
|
||||
adsr->initial = 0;
|
||||
adsr->delay = 0;
|
||||
adsr->velocity = 0;
|
||||
adsr->envelope = envelope;
|
||||
adsr->volOut = volOut;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
f32 adsr_update(struct AdsrState *adsr) {
|
||||
#else
|
||||
s32 adsr_update(struct AdsrState *adsr) {
|
||||
#endif
|
||||
u8 action = adsr->action;
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
u8 state = adsr->state;
|
||||
switch (state) {
|
||||
#else
|
||||
switch (adsr->state) {
|
||||
#endif
|
||||
case ADSR_STATE_DISABLED:
|
||||
return 0;
|
||||
|
||||
case ADSR_STATE_INITIAL: {
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
adsr->current = adsr->initial;
|
||||
adsr->target = adsr->initial;
|
||||
#endif
|
||||
if (action & ADSR_ACTION_HANG) {
|
||||
adsr->state = ADSR_STATE_HANG;
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
}
|
||||
|
||||
case ADSR_STATE_START_LOOP:
|
||||
adsr->envIndex = 0;
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
adsr->currentHiRes = adsr->current << 0x10;
|
||||
#endif
|
||||
adsr->state = ADSR_STATE_LOOP;
|
||||
// fallthrough
|
||||
|
||||
#ifdef VERSION_SH
|
||||
restart:
|
||||
#endif
|
||||
case ADSR_STATE_LOOP:
|
||||
adsr->delay = BSWAP16(adsr->envelope[adsr->envIndex].delay);
|
||||
switch (adsr->delay) {
|
||||
case ADSR_DISABLE:
|
||||
adsr->state = ADSR_STATE_DISABLED;
|
||||
break;
|
||||
case ADSR_HANG:
|
||||
adsr->state = ADSR_STATE_HANG;
|
||||
break;
|
||||
case ADSR_GOTO:
|
||||
adsr->envIndex = BSWAP16(adsr->envelope[adsr->envIndex].arg);
|
||||
#ifdef VERSION_SH
|
||||
goto restart;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
case ADSR_RESTART:
|
||||
adsr->state = ADSR_STATE_INITIAL;
|
||||
break;
|
||||
|
||||
default:
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
if (adsr->delay >= 4) {
|
||||
adsr->delay = adsr->delay * gAudioBufferParameters.updatesPerFrame
|
||||
#ifdef VERSION_SH
|
||||
/ gAudioBufferParameters.presetUnk4
|
||||
#endif
|
||||
/ 4;
|
||||
}
|
||||
#if defined(VERSION_SH)
|
||||
if (adsr->delay == 0) {
|
||||
adsr->delay = 1;
|
||||
}
|
||||
adsr->target = (f32) BSWAP16(adsr->envelope[adsr->envIndex].arg) / 32767.0f;
|
||||
#elif defined(VERSION_EU)
|
||||
adsr->target = (f32) BSWAP16(adsr->envelope[adsr->envIndex].arg) / 32767.0;
|
||||
#endif
|
||||
adsr->target = adsr->target * adsr->target;
|
||||
adsr->velocity = (adsr->target - adsr->current) / adsr->delay;
|
||||
#else
|
||||
adsr->target = BSWAP16(adsr->envelope[adsr->envIndex].arg);
|
||||
adsr->velocity = ((adsr->target - adsr->current) << 0x10) / adsr->delay;
|
||||
#endif
|
||||
adsr->state = ADSR_STATE_FADE;
|
||||
adsr->envIndex++;
|
||||
break;
|
||||
}
|
||||
if (adsr->state != ADSR_STATE_FADE) {
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
|
||||
case ADSR_STATE_FADE:
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
adsr->current += adsr->velocity;
|
||||
#else
|
||||
adsr->currentHiRes += adsr->velocity;
|
||||
adsr->current = adsr->currentHiRes >> 0x10;
|
||||
#endif
|
||||
if (--adsr->delay <= 0) {
|
||||
adsr->state = ADSR_STATE_LOOP;
|
||||
}
|
||||
// fallthrough
|
||||
|
||||
case ADSR_STATE_HANG:
|
||||
break;
|
||||
|
||||
case ADSR_STATE_DECAY:
|
||||
case ADSR_STATE_RELEASE: {
|
||||
adsr->current -= adsr->fadeOutVel;
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
if (adsr->sustain != 0.0f && state == ADSR_STATE_DECAY) {
|
||||
#else
|
||||
if (adsr->sustain != 0 && adsr->state == ADSR_STATE_DECAY) {
|
||||
#endif
|
||||
if (adsr->current < adsr->sustain) {
|
||||
adsr->current = adsr->sustain;
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
adsr->delay = 128;
|
||||
#else
|
||||
adsr->delay = adsr->sustain / 16;
|
||||
#endif
|
||||
adsr->state = ADSR_STATE_SUSTAIN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(VERSION_SH)
|
||||
if (adsr->current < 0.00001f) {
|
||||
adsr->current = 0.0f;
|
||||
adsr->state = ADSR_STATE_DISABLED;
|
||||
}
|
||||
#elif defined(VERSION_EU)
|
||||
if (adsr->current < 0) {
|
||||
adsr->current = 0.0f;
|
||||
adsr->state = ADSR_STATE_DISABLED;
|
||||
}
|
||||
#else
|
||||
if (adsr->current < 100) {
|
||||
adsr->current = 0;
|
||||
adsr->state = ADSR_STATE_DISABLED;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case ADSR_STATE_SUSTAIN:
|
||||
adsr->delay -= 1;
|
||||
if (adsr->delay == 0) {
|
||||
adsr->state = ADSR_STATE_RELEASE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ((action & ADSR_ACTION_DECAY)) {
|
||||
adsr->state = ADSR_STATE_DECAY;
|
||||
adsr->action = action & ~ADSR_ACTION_DECAY;
|
||||
}
|
||||
|
||||
if ((action & ADSR_ACTION_RELEASE)) {
|
||||
adsr->state = ADSR_STATE_RELEASE;
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
adsr->action = action & ~ADSR_ACTION_RELEASE;
|
||||
#else
|
||||
adsr->action = action & ~(ADSR_ACTION_RELEASE | ADSR_ACTION_DECAY);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
if (adsr->current < 0.0f) {
|
||||
return 0.0f;
|
||||
}
|
||||
if (adsr->current > 1.0f) {
|
||||
eu_stubbed_printf_1("Audio:Envp: overflow %f\n", adsr->current);
|
||||
return 1.0f;
|
||||
}
|
||||
return adsr->current;
|
||||
#else
|
||||
*adsr->volOut = adsr->current;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#ifndef AUDIO_EFFECTS_H
|
||||
#define AUDIO_EFFECTS_H
|
||||
|
||||
#include <PR/ultratypes.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include <platform_info.h>
|
||||
|
||||
#define ADSR_STATE_DISABLED 0
|
||||
#define ADSR_STATE_INITIAL 1
|
||||
#define ADSR_STATE_START_LOOP 2
|
||||
#define ADSR_STATE_LOOP 3
|
||||
#define ADSR_STATE_FADE 4
|
||||
#define ADSR_STATE_HANG 5
|
||||
#define ADSR_STATE_DECAY 6
|
||||
#define ADSR_STATE_RELEASE 7
|
||||
#define ADSR_STATE_SUSTAIN 8
|
||||
|
||||
#define ADSR_ACTION_RELEASE 0x10
|
||||
#define ADSR_ACTION_DECAY 0x20
|
||||
#define ADSR_ACTION_HANG 0x40
|
||||
|
||||
#define ADSR_DISABLE 0
|
||||
#define ADSR_HANG -1
|
||||
#define ADSR_GOTO -2
|
||||
#define ADSR_RESTART -3
|
||||
|
||||
// Envelopes are always stored as big endian, to match sequence files which are
|
||||
// byte blobs and can embed envelopes. Hence this byteswapping macro.
|
||||
#if IS_BIG_ENDIAN
|
||||
#define BSWAP16(x) (x)
|
||||
#else
|
||||
#define BSWAP16(x) (((x) & 0xff) << 8 | (((x) >> 8) & 0xff))
|
||||
#endif
|
||||
|
||||
extern f32 gTrackVolume;
|
||||
|
||||
void sequence_player_process_sound(struct SequencePlayer *seqPlayer);
|
||||
void note_vibrato_update(struct Note *note);
|
||||
void note_vibrato_init(struct Note *note);
|
||||
void adsr_init(struct AdsrState *adsr, struct AdsrEnvelope *envelope, s16 *volOut);
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
f32 adsr_update(struct AdsrState *adsr);
|
||||
#else
|
||||
s32 adsr_update(struct AdsrState *adsr);
|
||||
#endif
|
||||
|
||||
#endif // AUDIO_EFFECTS_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,81 @@
|
||||
#ifndef AUDIO_EXTERNAL_H
|
||||
#define AUDIO_EXTERNAL_H
|
||||
|
||||
#include <PR/ultratypes.h>
|
||||
|
||||
#include <types.h>
|
||||
|
||||
// Sequence arguments, passed to seq_player_play_sequence. seqId may be bit-OR'ed with
|
||||
// SEQ_VARIATION; this will load the same sequence, but set a variation
|
||||
// bit which may be read by the sequence script.
|
||||
#define SEQUENCE_ARGS(priority, seqId) ((priority << 8) | seqId)
|
||||
|
||||
#define SOUND_MODE_STEREO 0
|
||||
#define SOUND_MODE_MONO 3
|
||||
#define SOUND_MODE_HEADSET 1
|
||||
|
||||
#define SEQ_PLAYER_LEVEL 0 // Level background music
|
||||
#define SEQ_PLAYER_ENV 1 // Misc music like the puzzle jingle
|
||||
#define SEQ_PLAYER_SFX 2 // Sound effects
|
||||
|
||||
extern s32 gAudioErrorFlags;
|
||||
extern f32 gGlobalSoundSource[3];
|
||||
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);
|
||||
void seq_player_unlower_volume(u8 player, u16 fadeDuration);
|
||||
void set_audio_muted(u8 muted);
|
||||
void sound_init(void);
|
||||
void get_currently_playing_sound(u8 bank, u8 *numPlayingSounds, u8 *numSoundsInBank, u8 *soundId);
|
||||
void stop_sound(u32 soundBits, f32 *pos);
|
||||
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 set_sound_moving_speed(u8 bank, u8 speed);
|
||||
void play_dialog_sound(u8 dialogID);
|
||||
void play_music(u8 player, u16 seqArgs, u16 fadeTimer);
|
||||
void stop_background_music(u16 seqId);
|
||||
void fadeout_background_music(u16 arg0, u16 fadeOut);
|
||||
void drop_queued_background_music(void);
|
||||
u16 get_current_background_music(void);
|
||||
void play_secondary_music(u8 seqId, u8 bgMusicVolume, u8 volume, u16 fadeTimer);
|
||||
void func_80321080(u16 fadeTimer);
|
||||
void func_803210D4(u16 fadeOutTime);
|
||||
void play_course_clear(void);
|
||||
void play_peachs_jingle(void);
|
||||
void play_puzzle_jingle(void);
|
||||
void play_star_fanfare(void);
|
||||
void play_power_star_jingle(u8 arg0);
|
||||
void play_race_fanfare(void);
|
||||
void play_toads_jingle(void);
|
||||
void sound_reset(u8 presetId);
|
||||
void audio_set_sound_mode(u8 arg0);
|
||||
|
||||
void audio_init(void); // in load.c
|
||||
void seq_player_play_sequence(u8 player, u8 seqId, u16 arg2);
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
struct SPTask *unused_80321460();
|
||||
struct SPTask *unused_80321460(void);
|
||||
#endif
|
||||
|
||||
#endif // AUDIO_EXTERNAL_H
|
||||
@@ -0,0 +1,3 @@
|
||||
#include <ultra64.h>
|
||||
|
||||
u64 gAudioGlobalsStartMarker;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,144 @@
|
||||
#ifndef AUDIO_HEAP_H
|
||||
#define AUDIO_HEAP_H
|
||||
|
||||
#include <PR/ultratypes.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#define SOUND_LOAD_STATUS_NOT_LOADED 0
|
||||
#define SOUND_LOAD_STATUS_IN_PROGRESS 1
|
||||
#define SOUND_LOAD_STATUS_COMPLETE 2
|
||||
#define SOUND_LOAD_STATUS_DISCARDABLE 3
|
||||
#define SOUND_LOAD_STATUS_4 4
|
||||
#define SOUND_LOAD_STATUS_5 5
|
||||
|
||||
#define IS_BANK_LOAD_COMPLETE(bankId) (gBankLoadStatus[bankId] >= SOUND_LOAD_STATUS_COMPLETE)
|
||||
#define IS_SEQ_LOAD_COMPLETE(seqId) (gSeqLoadStatus[seqId] >= SOUND_LOAD_STATUS_COMPLETE)
|
||||
|
||||
struct SoundAllocPool
|
||||
{
|
||||
u8 *start;
|
||||
u8 *cur;
|
||||
u32 size;
|
||||
s32 numAllocatedEntries;
|
||||
}; // size = 0x10
|
||||
|
||||
struct SeqOrBankEntry {
|
||||
u8 *ptr;
|
||||
u32 size;
|
||||
#ifdef VERSION_SH
|
||||
s16 poolIndex;
|
||||
s16 id;
|
||||
#else
|
||||
s32 id; // seqId or bankId
|
||||
#endif
|
||||
}; // size = 0xC
|
||||
|
||||
struct PersistentPool
|
||||
{
|
||||
/*0x00*/ u32 numEntries;
|
||||
/*0x04*/ struct SoundAllocPool pool;
|
||||
/*0x14*/ struct SeqOrBankEntry entries[32];
|
||||
}; // size = 0x194
|
||||
|
||||
struct TemporaryPool
|
||||
{
|
||||
/*EU, SH*/
|
||||
/*0x00, 0x00*/ u32 nextSide;
|
||||
/*0x04, */ struct SoundAllocPool pool;
|
||||
/*0x04, pool.start */
|
||||
/*0x08, pool.cur */
|
||||
/*0x0C, 0x0C pool.size */
|
||||
/*0x10, 0x10 pool.numAllocatedEntries */
|
||||
/*0x14, */ struct SeqOrBankEntry entries[2];
|
||||
/*0x14, 0x14 entries[0].ptr */
|
||||
/*0x18, entries[0].size*/
|
||||
/*0x1C, 0x1E entries[0].id */
|
||||
/*0x20, 0x20 entries[1].ptr */
|
||||
/*0x24, entries[1].size*/
|
||||
/*0x28, 0x2A entries[1].id */
|
||||
}; // size = 0x2C
|
||||
|
||||
struct SoundMultiPool
|
||||
{
|
||||
/*0x000*/ struct PersistentPool persistent;
|
||||
/*0x194*/ struct TemporaryPool temporary;
|
||||
/* */ u32 pad2[4];
|
||||
}; // size = 0x1D0
|
||||
|
||||
struct Unk1Pool
|
||||
{
|
||||
struct SoundAllocPool pool;
|
||||
struct SeqOrBankEntry entries[32];
|
||||
};
|
||||
|
||||
struct UnkEntry
|
||||
{
|
||||
s8 used;
|
||||
s8 medium;
|
||||
s8 bankId;
|
||||
u32 pad;
|
||||
u8 *srcAddr;
|
||||
u8 *dstAddr;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct UnkPool
|
||||
{
|
||||
/*0x00*/ struct SoundAllocPool pool;
|
||||
/*0x10*/ struct UnkEntry entries[64];
|
||||
/*0x510*/ s32 numEntries;
|
||||
/*0x514*/ u32 unk514;
|
||||
};
|
||||
|
||||
extern u8 gAudioHeap[];
|
||||
extern s16 gVolume;
|
||||
extern s8 gReverbDownsampleRate;
|
||||
extern struct SoundAllocPool gAudioInitPool;
|
||||
extern struct SoundAllocPool gNotesAndBuffersPool;
|
||||
extern struct SoundAllocPool gPersistentCommonPool;
|
||||
extern struct SoundAllocPool gTemporaryCommonPool;
|
||||
extern struct SoundMultiPool gSeqLoadedPool;
|
||||
extern struct SoundMultiPool gBankLoadedPool;
|
||||
#ifdef VERSION_SH
|
||||
extern struct Unk1Pool gUnkPool1;
|
||||
extern struct UnkPool gUnkPool2;
|
||||
extern struct UnkPool gUnkPool3;
|
||||
#endif
|
||||
extern u8 gBankLoadStatus[64];
|
||||
extern u8 gSeqLoadStatus[256];
|
||||
extern volatile u8 gAudioResetStatus;
|
||||
extern u8 gAudioResetPresetIdToLoad;
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
extern volatile u8 gAudioResetStatus;
|
||||
#endif
|
||||
|
||||
void *soundAlloc(struct SoundAllocPool *pool, u32 size);
|
||||
void *sound_alloc_uninitialized(struct SoundAllocPool *pool, u32 size);
|
||||
void sound_init_main_pools(s32 sizeForAudioInitPool);
|
||||
void sound_alloc_pool_init(struct SoundAllocPool *pool, void *memAddr, u32 size);
|
||||
#ifdef VERSION_SH
|
||||
void *alloc_bank_or_seq(s32 poolIdx, s32 size, s32 arg3, s32 id);
|
||||
void *get_bank_or_seq(s32 poolIdx, s32 arg1, s32 id);
|
||||
#else
|
||||
void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg3, s32 id);
|
||||
void *get_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 id);
|
||||
#endif
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
s32 audio_shut_down_and_reset_step(void);
|
||||
void audio_reset_session(void);
|
||||
#else
|
||||
void audio_reset_session(struct AudioSessionSettings *preset);
|
||||
#endif
|
||||
void discard_bank(s32 bankId);
|
||||
|
||||
#ifdef VERSION_SH
|
||||
void fill_filter(s16 filter[8], s32 arg1, s32 arg2);
|
||||
u8 *func_sh_802f1d40(u32 size, s32 bank, u8 *arg2, s8 medium);
|
||||
u8 *func_sh_802f1d90(u32 size, s32 bank, u8 *arg2, s8 medium);
|
||||
void *unk_pool1_lookup(s32 poolIdx, s32 id);
|
||||
void *unk_pool1_alloc(s32 poolIndex, s32 arg1, u32 size);
|
||||
#endif
|
||||
|
||||
#endif // AUDIO_HEAP_H
|
||||
@@ -0,0 +1,886 @@
|
||||
#ifndef AUDIO_INTERNAL_H
|
||||
#define AUDIO_INTERNAL_H
|
||||
|
||||
#include <ultra64.h>
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
#define SEQUENCE_PLAYERS 4
|
||||
#define SEQUENCE_CHANNELS 48
|
||||
#define SEQUENCE_LAYERS 64
|
||||
#else
|
||||
#define SEQUENCE_PLAYERS 3
|
||||
#define SEQUENCE_CHANNELS 32
|
||||
#ifdef VERSION_JP
|
||||
#define SEQUENCE_LAYERS 48
|
||||
#else
|
||||
#define SEQUENCE_LAYERS 52
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define LAYERS_MAX 4
|
||||
#define CHANNELS_MAX 16
|
||||
|
||||
#define NO_LAYER ((struct SequenceChannelLayer *)(-1))
|
||||
|
||||
#define MUTE_BEHAVIOR_STOP_SCRIPT 0x80 // stop processing sequence/channel scripts
|
||||
#define MUTE_BEHAVIOR_STOP_NOTES 0x40 // prevent further notes from playing
|
||||
#define MUTE_BEHAVIOR_SOFTEN 0x20 // lower volume, by default to half
|
||||
|
||||
#define SEQUENCE_PLAYER_STATE_0 0
|
||||
#define SEQUENCE_PLAYER_STATE_FADE_OUT 1
|
||||
#define SEQUENCE_PLAYER_STATE_2 2
|
||||
#define SEQUENCE_PLAYER_STATE_3 3
|
||||
#define SEQUENCE_PLAYER_STATE_4 4
|
||||
|
||||
#define NOTE_PRIORITY_DISABLED 0
|
||||
#define NOTE_PRIORITY_STOPPING 1
|
||||
#define NOTE_PRIORITY_MIN 2
|
||||
#define NOTE_PRIORITY_DEFAULT 3
|
||||
|
||||
#define TATUMS_PER_BEAT 48
|
||||
|
||||
// abi.h contains more details about the ADPCM and S8 codecs, "skip" skips codec processing
|
||||
#define CODEC_ADPCM 0
|
||||
#define CODEC_S8 1
|
||||
#define CODEC_SKIP 2
|
||||
|
||||
#ifdef VERSION_JP
|
||||
#define TEMPO_SCALE 1
|
||||
#else
|
||||
#define TEMPO_SCALE TATUMS_PER_BEAT
|
||||
#endif
|
||||
|
||||
// TODO: US_FLOAT should probably be renamed to JP_DOUBLE since eu seems to use floats too
|
||||
#ifdef VERSION_JP
|
||||
#define US_FLOAT(x) x
|
||||
#else
|
||||
#define US_FLOAT(x) x ## f
|
||||
#endif
|
||||
|
||||
// Convert u8 or u16 to f32. On JP, this uses a u32->f32 conversion,
|
||||
// resulting in more bloated codegen, while on US it goes through s32.
|
||||
// Since u8 and u16 fit losslessly in both, behavior is the same.
|
||||
#ifdef VERSION_JP
|
||||
#define FLOAT_CAST(x) (f32) (x)
|
||||
#else
|
||||
#define FLOAT_CAST(x) (f32) (s32) (x)
|
||||
#endif
|
||||
|
||||
// No-op printf macro which leaves string literals in rodata in IDO. IDO
|
||||
// doesn't support variadic macros, so instead we let the parameter list
|
||||
// expand to a no-op comma expression. Another possibility is that it might
|
||||
// have expanded to something with "if (0)". See also goddard/gd_main.h.
|
||||
// On US/JP, -sopt optimizes away these except for external.c.
|
||||
#ifdef __sgi
|
||||
#define stubbed_printf
|
||||
#else
|
||||
#define stubbed_printf(...)
|
||||
#endif
|
||||
|
||||
#ifdef VERSION_EU
|
||||
#define eu_stubbed_printf_0(msg) stubbed_printf(msg)
|
||||
#define eu_stubbed_printf_1(msg, a) stubbed_printf(msg, a)
|
||||
#define eu_stubbed_printf_2(msg, a, b) stubbed_printf(msg, a, b)
|
||||
#define eu_stubbed_printf_3(msg, a, b, c) stubbed_printf(msg, a, b, c)
|
||||
#else
|
||||
#define eu_stubbed_printf_0(msg)
|
||||
#define eu_stubbed_printf_1(msg, a)
|
||||
#define eu_stubbed_printf_2(msg, a, b)
|
||||
#define eu_stubbed_printf_3(msg, a, b, c)
|
||||
#endif
|
||||
|
||||
struct NotePool;
|
||||
|
||||
struct AudioListItem
|
||||
{
|
||||
// A node in a circularly linked list. Each node is either a head or an item:
|
||||
// - Items can be either detached (prev = NULL), or attached to a list.
|
||||
// 'value' points to something of interest.
|
||||
// - List heads are always attached; if a list is empty, its head points
|
||||
// to itself. 'count' contains the size of the list.
|
||||
// If the list holds notes, 'pool' points back to the pool where it lives.
|
||||
// Otherwise, that member is NULL.
|
||||
struct AudioListItem *prev;
|
||||
struct AudioListItem *next;
|
||||
union {
|
||||
void *value; // either Note* or SequenceChannelLayer*
|
||||
s32 count;
|
||||
} u;
|
||||
struct NotePool *pool;
|
||||
}; // size = 0x10
|
||||
|
||||
struct NotePool
|
||||
{
|
||||
struct AudioListItem disabled;
|
||||
struct AudioListItem decaying;
|
||||
struct AudioListItem releasing;
|
||||
struct AudioListItem active;
|
||||
};
|
||||
|
||||
struct VibratoState {
|
||||
/*0x00, 0x00*/ struct SequenceChannel *seqChannel;
|
||||
/*0x04, 0x04*/ u32 time;
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
/* , 0x08*/ s16 *curve;
|
||||
/* , 0x0C*/ f32 extent;
|
||||
/* , 0x10*/ f32 rate;
|
||||
/* , 0x14*/ u8 active;
|
||||
#else
|
||||
/*0x08, */ s8 *curve;
|
||||
/*0x0C, */ u8 active;
|
||||
/*0x0E, */ u16 rate;
|
||||
/*0x10, */ u16 extent;
|
||||
#endif
|
||||
/*0x12, 0x16*/ u16 rateChangeTimer;
|
||||
/*0x14, 0x18*/ u16 extentChangeTimer;
|
||||
/*0x16, 0x1A*/ u16 delay;
|
||||
}; // size = 0x18, 0x1C on EU
|
||||
|
||||
// Pitch sliding by up to one octave in the positive direction. Negative
|
||||
// direction is "supported" by setting extent to be negative. The code
|
||||
// extrapolates exponentially in the wrong direction in that case, but that
|
||||
// doesn't prevent seqplayer from doing it, AFAICT.
|
||||
struct Portamento {
|
||||
u8 mode; // bit 0x80 denotes something; the rest are an index 0-5
|
||||
f32 cur;
|
||||
f32 speed;
|
||||
f32 extent;
|
||||
}; // size = 0x10
|
||||
|
||||
struct AdsrEnvelope {
|
||||
s16 delay;
|
||||
s16 arg;
|
||||
}; // size = 0x4
|
||||
|
||||
struct AdpcmLoop
|
||||
{
|
||||
u32 start;
|
||||
u32 end;
|
||||
u32 count;
|
||||
u32 pad;
|
||||
s16 state[16]; // only exists if count != 0. 8-byte aligned
|
||||
};
|
||||
|
||||
struct AdpcmBook
|
||||
{
|
||||
s32 order;
|
||||
s32 npredictors;
|
||||
s16 book[1]; // size 8 * order * npredictors. 8-byte aligned
|
||||
};
|
||||
|
||||
struct AudioBankSample
|
||||
{
|
||||
#ifdef VERSION_SH
|
||||
#if !IS_BIG_ENDIAN
|
||||
u32 size : 24;
|
||||
#endif
|
||||
/* 0x00 */ u32 codec : 4;
|
||||
/* 0x00 */ u32 medium : 2;
|
||||
/* 0x00 */ u32 bit1 : 1;
|
||||
/* 0x00 */ u32 isPatched : 1;
|
||||
#if IS_BIG_ENDIAN
|
||||
/* 0x01 */ u32 size : 24;
|
||||
#endif
|
||||
#else
|
||||
u8 unused;
|
||||
u8 loaded;
|
||||
#endif
|
||||
u8 *sampleAddr;
|
||||
struct AdpcmLoop *loop;
|
||||
struct AdpcmBook *book;
|
||||
#ifndef VERSION_SH
|
||||
u32 sampleSize; // never read. either 0 or 1 mod 9, depending on padding
|
||||
#endif
|
||||
};
|
||||
|
||||
struct AudioBankSound
|
||||
{
|
||||
struct AudioBankSample *sample;
|
||||
f32 tuning; // frequency scale factor
|
||||
}; // size = 0x8
|
||||
|
||||
struct Instrument
|
||||
{
|
||||
/*0x00*/ u8 loaded;
|
||||
/*0x01*/ u8 normalRangeLo;
|
||||
/*0x02*/ u8 normalRangeHi;
|
||||
/*0x03*/ u8 releaseRate;
|
||||
/*0x04*/ struct AdsrEnvelope *envelope;
|
||||
/*0x08*/ struct AudioBankSound lowNotesSound;
|
||||
/*0x10*/ struct AudioBankSound normalNotesSound;
|
||||
/*0x18*/ struct AudioBankSound highNotesSound;
|
||||
}; // size = 0x20
|
||||
|
||||
struct Drum
|
||||
{
|
||||
u8 releaseRate;
|
||||
u8 pan;
|
||||
u8 loaded;
|
||||
struct AudioBankSound sound;
|
||||
struct AdsrEnvelope *envelope;
|
||||
};
|
||||
|
||||
struct AudioBank
|
||||
{
|
||||
struct Drum **drums;
|
||||
struct Instrument *instruments[1];
|
||||
}; // dynamic size
|
||||
|
||||
struct CtlEntry
|
||||
{
|
||||
#ifndef VERSION_SH
|
||||
u8 unused;
|
||||
#endif
|
||||
u8 numInstruments;
|
||||
u8 numDrums;
|
||||
#ifdef VERSION_SH
|
||||
u8 bankId1;
|
||||
u8 bankId2;
|
||||
#endif
|
||||
struct Instrument **instruments;
|
||||
struct Drum **drums;
|
||||
}; // size = 0xC
|
||||
|
||||
struct M64ScriptState {
|
||||
u8 *pc;
|
||||
u8 *stack[4];
|
||||
u8 remLoopIters[4];
|
||||
u8 depth;
|
||||
}; // size = 0x1C
|
||||
|
||||
// Also known as a Group, according to debug strings.
|
||||
struct SequencePlayer
|
||||
{
|
||||
/*US/JP, EU, SH */
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
/*0x000, 0x000, 0x000*/ u8 enabled : 1;
|
||||
#else
|
||||
/*0x000, 0x000*/ volatile u8 enabled : 1;
|
||||
#endif
|
||||
/*0x000, 0x000*/ u8 finished : 1; // never read
|
||||
/*0x000, 0x000*/ u8 muted : 1;
|
||||
/*0x000, 0x000*/ u8 seqDmaInProgress : 1;
|
||||
/*0x000, 0x000*/ u8 bankDmaInProgress : 1;
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
/* 0x000*/ u8 recalculateVolume : 1;
|
||||
#endif
|
||||
#ifdef VERSION_SH
|
||||
/* 0x000*/ u8 unkSh: 1;
|
||||
#endif
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
/*0x001 */ s8 seqVariation;
|
||||
#endif
|
||||
/*0x002, 0x001, 0x001*/ u8 state;
|
||||
/*0x003, 0x002*/ u8 noteAllocPolicy;
|
||||
/*0x004, 0x003*/ u8 muteBehavior;
|
||||
/*0x005, 0x004*/ u8 seqId;
|
||||
/*0x006, 0x005*/ u8 defaultBank[1]; // must be an array to get a comparison
|
||||
// to match; other u8's might also be part of that array
|
||||
/*0x007, 0x006*/ u8 loadingBankId;
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
/*0x008, ?????*/ u8 loadingBankNumInstruments;
|
||||
/*0x009, ?????*/ u8 loadingBankNumDrums;
|
||||
#endif
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
/* , 0x007, 0x007*/ s8 seqVariationEu[1];
|
||||
#endif
|
||||
/*0x00A, 0x008*/ u16 tempo; // beats per minute in JP, tatums per minute in US/EU
|
||||
/*0x00C, 0x00A*/ u16 tempoAcc;
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
/*0x00E, 0x010*/ u16 fadeRemainingFrames;
|
||||
#endif
|
||||
#ifdef VERSION_SH
|
||||
/* 0x00C*/ s16 tempoAdd;
|
||||
#endif
|
||||
/*0x010, 0x00C, 0x00E*/ s16 transposition;
|
||||
/*0x012, 0x00E, 0x010*/ u16 delay;
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
/*0x00E, 0x010, 0x012*/ u16 fadeRemainingFrames;
|
||||
/* , 0x012, 0x014*/ u16 fadeTimerUnkEu;
|
||||
#endif
|
||||
/*0x014, 0x014*/ u8 *seqData; // buffer of some sort
|
||||
/*0x018, 0x018, 0x1C*/ f32 fadeVolume; // set to 1.0f
|
||||
/*0x01C, 0x01C*/ f32 fadeVelocity; // set to 0.0f
|
||||
/*0x020, 0x020, 0x024*/ f32 volume; // set to 0.0f
|
||||
/*0x024, 0x024*/ f32 muteVolumeScale; // set to 0.5f
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
/* , 0x028, 0x02C*/ f32 fadeVolumeScale;
|
||||
/* , 0x02C*/ f32 appliedFadeVolume;
|
||||
#else
|
||||
/* */ u8 pad2[4];
|
||||
#endif
|
||||
/*0x02C, 0x030, 0x034*/ struct SequenceChannel *channels[CHANNELS_MAX];
|
||||
/*0x06C, 0x070*/ struct M64ScriptState scriptState;
|
||||
/*0x088, 0x08C*/ u8 *shortNoteVelocityTable;
|
||||
/*0x08C, 0x090*/ u8 *shortNoteDurationTable;
|
||||
/*0x090, 0x094*/ struct NotePool notePool;
|
||||
/*0x0D0, 0x0D4*/ OSMesgQueue seqDmaMesgQueue;
|
||||
/*0x0E8, 0x0EC*/ OSMesg seqDmaMesg;
|
||||
/*0x0EC, 0x0F0*/ OSIoMesg seqDmaIoMesg;
|
||||
/*0x100, 0x108*/ OSMesgQueue bankDmaMesgQueue;
|
||||
/*0x118, 0x120*/ OSMesg bankDmaMesg;
|
||||
/*0x11C, 0x124*/ OSIoMesg bankDmaIoMesg;
|
||||
/*0x130, 0x13C*/ u8 *bankDmaCurrMemAddr;
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
/*0x134, ?????*/ struct AudioBank *loadingBank;
|
||||
#endif
|
||||
/*0x138, 0x140*/ uintptr_t bankDmaCurrDevAddr;
|
||||
/*0x13C, 0x144*/ ssize_t bankDmaRemaining;
|
||||
}; // size = 0x140, 0x148 on EU, 0x14C on SH
|
||||
|
||||
struct AdsrSettings
|
||||
{
|
||||
u8 releaseRate;
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
u8 sustain;
|
||||
#else
|
||||
u16 sustain; // sustain level, 2^16 = max
|
||||
#endif
|
||||
struct AdsrEnvelope *envelope;
|
||||
}; // size = 0x8
|
||||
|
||||
struct AdsrState {
|
||||
/*0x00, 0x00*/ u8 action;
|
||||
/*0x01, 0x01*/ u8 state;
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
/*0x02, */ s16 initial; // always 0
|
||||
/*0x04, */ s16 target;
|
||||
/*0x06, */ s16 current;
|
||||
#endif
|
||||
/*0x08, 0x02*/ s16 envIndex;
|
||||
/*0x0A, 0x04*/ s16 delay;
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
/* , 0x08*/ f32 sustain;
|
||||
/* , 0x0C*/ f32 velocity;
|
||||
/* , 0x10*/ f32 fadeOutVel;
|
||||
/* , 0x14*/ f32 current;
|
||||
/* , 0x18*/ f32 target;
|
||||
s32 pad1C;
|
||||
#else
|
||||
/*0x0C, */ s16 sustain;
|
||||
/*0x0E, */ s16 fadeOutVel;
|
||||
/*0x10, */ s32 velocity;
|
||||
/*0x14, */ s32 currentHiRes;
|
||||
/*0x18, */ s16 *volOut;
|
||||
#endif
|
||||
/*0x1C, 0x20*/ struct AdsrEnvelope *envelope;
|
||||
}; // size = 0x20, 0x24 in EU
|
||||
|
||||
struct ReverbBitsData {
|
||||
/* 0x00 */ u8 bit0 : 1;
|
||||
/* 0x00 */ u8 bit1 : 1;
|
||||
/* 0x00 */ u8 bit2 : 1;
|
||||
/* 0x00 */ u8 usesHeadsetPanEffects : 1;
|
||||
/* 0x00 */ u8 stereoHeadsetEffects : 2;
|
||||
/* 0x00 */ u8 strongRight : 1;
|
||||
/* 0x00 */ u8 strongLeft : 1;
|
||||
};
|
||||
|
||||
union ReverbBits {
|
||||
/* 0x00 */ struct ReverbBitsData s;
|
||||
/* 0x00 */ u8 asByte;
|
||||
};
|
||||
struct ReverbInfo {
|
||||
u8 reverbVol;
|
||||
u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1
|
||||
u8 pan;
|
||||
union ReverbBits reverbBits;
|
||||
f32 freqScale;
|
||||
f32 velocity;
|
||||
s32 unused;
|
||||
s16 *filter;
|
||||
};
|
||||
|
||||
struct NoteAttributes
|
||||
{
|
||||
u8 reverbVol;
|
||||
#ifdef VERSION_SH
|
||||
u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1
|
||||
#endif
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
u8 pan;
|
||||
#endif
|
||||
#ifdef VERSION_SH
|
||||
union ReverbBits reverbBits;
|
||||
#endif
|
||||
f32 freqScale;
|
||||
f32 velocity;
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
f32 pan;
|
||||
#endif
|
||||
#ifdef VERSION_SH
|
||||
s16 *filter;
|
||||
#endif
|
||||
}; // size = 0x10
|
||||
|
||||
// Also known as a SubTrack, according to debug strings.
|
||||
// Confusingly, a SubTrack is a container of Tracks.
|
||||
struct SequenceChannel
|
||||
{
|
||||
/* U/J, EU, SH */
|
||||
/*0x00, 0x00*/ u8 enabled : 1;
|
||||
/*0x00, 0x00*/ u8 finished : 1;
|
||||
/*0x00, 0x00*/ u8 stopScript : 1;
|
||||
/*0x00, 0x00*/ u8 stopSomething2 : 1; // sets SequenceChannelLayer.stopSomething
|
||||
/*0x00, 0x00*/ u8 hasInstrument : 1;
|
||||
/*0x00, 0x00*/ u8 stereoHeadsetEffects : 1;
|
||||
/*0x00, ????*/ u8 largeNotes : 1; // notes specify duration and velocity
|
||||
/*0x00, ????*/ u8 unused : 1; // never read, set to 0
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
/* , 0x01*/ union {
|
||||
struct {
|
||||
u8 freqScale : 1;
|
||||
u8 volume : 1;
|
||||
u8 pan : 1;
|
||||
} as_bitfields;
|
||||
u8 as_u8;
|
||||
} changes;
|
||||
#endif
|
||||
/*0x01, 0x02*/ u8 noteAllocPolicy;
|
||||
/*0x02, 0x03, 0x03*/ u8 muteBehavior;
|
||||
/*0x03, 0x04, 0x04*/ u8 reverbVol; // until EU: Q1.7, after EU: UQ0.8
|
||||
/*0x04, ????*/ u8 notePriority; // 0-3
|
||||
#ifdef VERSION_SH
|
||||
u8 unkSH06; // some priority
|
||||
#endif
|
||||
/*0x05, 0x06*/ u8 bankId;
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
/* , 0x07*/ u8 reverbIndex;
|
||||
/* , 0x08, 0x09*/ u8 bookOffset;
|
||||
/* , 0x09*/ u8 newPan;
|
||||
/* , 0x0A*/ u8 panChannelWeight; // proportion of pan that comes from the channel (0..128)
|
||||
#else
|
||||
/*0x06, */ u8 updatesPerFrameUnused;
|
||||
#endif
|
||||
#ifdef VERSION_SH
|
||||
/* 0x0C*/ u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1
|
||||
#endif
|
||||
/*0x08, 0x0C, 0x0E*/ u16 vibratoRateStart; // initially 0x800
|
||||
/*0x0A, 0x0E, 0x10*/ u16 vibratoExtentStart;
|
||||
/*0x0C, 0x10, 0x12*/ u16 vibratoRateTarget; // initially 0x800
|
||||
/*0x0E, 0x12, 0x14*/ u16 vibratoExtentTarget;
|
||||
/*0x10, 0x14, 0x16*/ u16 vibratoRateChangeDelay;
|
||||
/*0x12, 0x16, 0x18*/ u16 vibratoExtentChangeDelay;
|
||||
/*0x14, 0x18, 0x1A*/ u16 vibratoDelay;
|
||||
/*0x16, 0x1A, 0x1C*/ u16 delay;
|
||||
/*0x18, 0x1C, 0x1E*/ s16 instOrWave; // either 0 (none), instrument index + 1, or
|
||||
// 0x80..0x83 for sawtooth/triangle/sine/square waves.
|
||||
/*0x1A, 0x1E, 0x20*/ s16 transposition;
|
||||
/*0x1C, 0x20, 0x24*/ f32 volumeScale;
|
||||
/*0x20, 0x24, 0x28*/ f32 volume;
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
/*0x24, */ f32 pan;
|
||||
/*0x28, */ f32 panChannelWeight; // proportion of pan that comes from the channel (0..1)
|
||||
#else
|
||||
/* , 0x28*/ s32 pan;
|
||||
/* , 0x2C*/ f32 appliedVolume;
|
||||
#endif
|
||||
/*0x2C, 0x30*/ f32 freqScale;
|
||||
/*0x30, 0x34*/ u8 (*dynTable)[][2];
|
||||
/*0x34, ????*/ struct Note *noteUnused; // never read
|
||||
/*0x38, ????*/ struct SequenceChannelLayer *layerUnused; // never read
|
||||
/*0x3C, 0x40*/ struct Instrument *instrument;
|
||||
/*0x40, 0x44*/ struct SequencePlayer *seqPlayer;
|
||||
/*0x44, 0x48*/ struct SequenceChannelLayer *layers[LAYERS_MAX];
|
||||
#ifndef VERSION_SH
|
||||
/*0x54, 0x58 */ s8 soundScriptIO[8]; // bridge between sound script and audio lib. For player 2,
|
||||
// [0] contains enabled, [4] contains sound ID, [5] contains reverb adjustment
|
||||
#endif
|
||||
/*0x5C, 0x60*/ struct M64ScriptState scriptState;
|
||||
/*0x78, 0x7C*/ struct AdsrSettings adsr;
|
||||
/*0x80, 0x84*/ struct NotePool notePool;
|
||||
#ifdef VERSION_SH
|
||||
/* 0xC0*/ s8 soundScriptIO[8]; // bridge between sound script and audio lib. For player 2,
|
||||
// [0] contains enabled, [4] contains sound ID, [5] contains reverb adjustment
|
||||
/* 0xC8*/ u16 unkC8;
|
||||
/* 0xCC*/ s16 *filter;
|
||||
#endif
|
||||
}; // size = 0xC0, 0xC4 in EU, 0xD0 in SH
|
||||
|
||||
// Also known as a Track, according to debug strings.
|
||||
struct SequenceChannelLayer
|
||||
{
|
||||
/* U/J, EU, SH */
|
||||
/*0x00, 0x00*/ u8 enabled : 1;
|
||||
/*0x00, 0x00*/ u8 finished : 1;
|
||||
/*0x00, 0x00*/ u8 stopSomething : 1; // ?
|
||||
/*0x00, 0x00*/ u8 continuousNotes : 1; // keep the same note for consecutive notes with the same sound
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
/* , 0x00*/ u8 unusedEu0b8 : 1;
|
||||
/* , 0x00*/ u8 notePropertiesNeedInit : 1;
|
||||
/* , 0x00*/ u8 ignoreDrumPan : 1;
|
||||
#ifdef VERSION_SH
|
||||
/* , , 0x01 */ union ReverbBits reverbBits;
|
||||
#endif
|
||||
/* , 0x01, 0x02*/ u8 instOrWave;
|
||||
#endif
|
||||
/*0x01, 0x02, 0x03*/ u8 status; // 0x03 in SH
|
||||
/*0x02, 0x03*/ u8 noteDuration; // set to 0x80
|
||||
/*0x03, 0x04*/ u8 portamentoTargetNote;
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
/* , 0x05*/ u8 pan; // 0..128
|
||||
/* , 0x06, 0x07*/ u8 notePan;
|
||||
#endif
|
||||
/*0x04, 0x08*/ struct Portamento portamento;
|
||||
/*0x14, 0x18*/ struct AdsrSettings adsr;
|
||||
/*0x1C, 0x20*/ u16 portamentoTime;
|
||||
/*0x1E, 0x22*/ s16 transposition; // #semitones added to play commands
|
||||
// (m64 instruction encoding only allows referring to the limited range
|
||||
// 0..0x3f; this makes 0x40..0x7f accessible as well)
|
||||
/*0x20, 0x24, 0x24*/ f32 freqScale;
|
||||
#ifdef VERSION_SH
|
||||
/* 0x28*/ f32 freqScaleMultiplier;
|
||||
#endif
|
||||
/*0x24, 0x28, 0x2C*/ f32 velocitySquare;
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
/*0x28, */ f32 pan; // 0..1
|
||||
#endif
|
||||
/*0x2C, 0x2C, 0x30*/ f32 noteVelocity;
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
/*0x30*/ f32 notePan;
|
||||
#endif
|
||||
/*0x34, 0x30, 0x34*/ f32 noteFreqScale;
|
||||
/*0x38, 0x34*/ s16 shortNoteDefaultPlayPercentage;
|
||||
/*0x3A, 0x36*/ s16 playPercentage; // it's not really a percentage...
|
||||
/*0x3C, 0x38*/ s16 delay;
|
||||
/*0x3E, 0x3A*/ s16 duration;
|
||||
/*0x40, 0x3C*/ s16 delayUnused; // set to 'delay', never read
|
||||
/*0x44, 0x40, 0x44*/ struct Note *note;
|
||||
/*0x48, 0x44*/ struct Instrument *instrument;
|
||||
/*0x4C, 0x48*/ struct AudioBankSound *sound;
|
||||
/*0x50, 0x4C, 0x50*/ struct SequenceChannel *seqChannel;
|
||||
/*0x54, 0x50*/ struct M64ScriptState scriptState;
|
||||
/*0x70, 0x6C*/ struct AudioListItem listItem;
|
||||
#if defined(VERSION_EU)
|
||||
u8 pad2[4];
|
||||
#endif
|
||||
}; // size = 0x80
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
struct NoteSynthesisState
|
||||
{
|
||||
/*0x00*/ u8 restart;
|
||||
/*0x01*/ u8 sampleDmaIndex;
|
||||
/*0x02*/ u8 prevHeadsetPanRight;
|
||||
/*0x03*/ u8 prevHeadsetPanLeft;
|
||||
#ifdef VERSION_SH
|
||||
/* 0x04*/ u8 reverbVol;
|
||||
/* 0x05*/ u8 unk5;
|
||||
#endif
|
||||
/*0x04, 0x06*/ u16 samplePosFrac;
|
||||
/*0x08*/ s32 samplePosInt;
|
||||
/*0x0C*/ struct NoteSynthesisBuffers *synthesisBuffers;
|
||||
/*0x10*/ s16 curVolLeft; // UQ0.16 (EU Q1.15)
|
||||
/*0x12*/ s16 curVolRight; // UQ0.16 (EU Q1.15)
|
||||
};
|
||||
struct NotePlaybackState
|
||||
{
|
||||
/* U/J, EU, SH */
|
||||
/*0x04, 0x00, 0x00*/ u8 priority;
|
||||
/* 0x01, 0x01*/ u8 waveId;
|
||||
/* 0x02, 0x02*/ u8 sampleCountIndex;
|
||||
#ifdef VERSION_SH
|
||||
/* 0x03*/ u8 bankId;
|
||||
/* 0x04*/ u8 unkSH34;
|
||||
#endif
|
||||
/*0x08, 0x04, 0x06*/ s16 adsrVolScale;
|
||||
/*0x18, 0x08, 0x08*/ f32 portamentoFreqScale;
|
||||
/*0x1C, 0x0C, 0x0C*/ f32 vibratoFreqScale;
|
||||
/*0x28, 0x10, */ struct SequenceChannelLayer *prevParentLayer;
|
||||
/*0x2C, 0x14, 0x14*/ struct SequenceChannelLayer *parentLayer;
|
||||
/*0x30, 0x18, 0x18*/ struct SequenceChannelLayer *wantedParentLayer;
|
||||
/* , 0x1C, 0x1C*/ struct NoteAttributes attributes;
|
||||
/*0x54, 0x28, 0x2C*/ struct AdsrState adsr;
|
||||
/*0x74, 0x4C, */ struct Portamento portamento;
|
||||
/*0x84, 0x5C, */ struct VibratoState vibratoState;
|
||||
};
|
||||
struct NoteSubEu
|
||||
{
|
||||
/*0x00*/ volatile u8 enabled : 1;
|
||||
/*0x00*/ u8 needsInit : 1;
|
||||
/*0x00*/ u8 finished : 1;
|
||||
/*0x00*/ u8 envMixerNeedsInit : 1;
|
||||
/*0x00*/ u8 stereoStrongRight : 1;
|
||||
/*0x00*/ u8 stereoStrongLeft : 1;
|
||||
/*0x00*/ u8 stereoHeadsetEffects : 1;
|
||||
/*0x00*/ u8 usesHeadsetPanEffects : 1;
|
||||
/*0x01*/ u8 reverbIndex : 3;
|
||||
/*0x01*/ u8 bookOffset : 3;
|
||||
/*0x01*/ u8 isSyntheticWave : 1;
|
||||
/*0x01*/ u8 hasTwoAdpcmParts : 1;
|
||||
#ifdef VERSION_EU
|
||||
/*0x02*/ u8 bankId;
|
||||
#else
|
||||
/*0x02*/ u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1
|
||||
#endif
|
||||
/*0x03*/ u8 headsetPanRight;
|
||||
/*0x04*/ u8 headsetPanLeft;
|
||||
/*0x05*/ u8 reverbVol; // UQ0.7 (EU Q1.7)
|
||||
/*0x06*/ u16 targetVolLeft; // UQ0.12 (EU UQ0.10)
|
||||
/*0x08*/ u16 targetVolRight; // UQ0.12 (EU UQ0.10)
|
||||
/*0x0A*/ u16 resamplingRateFixedPoint; // stored as signed but loaded as u16
|
||||
/*0x0C*/ union {
|
||||
s16 *samples;
|
||||
struct AudioBankSound *audioBankSound;
|
||||
} sound;
|
||||
#ifdef VERSION_SH
|
||||
/*0x10*/ s16 *filter;
|
||||
#endif
|
||||
};
|
||||
struct Note
|
||||
{
|
||||
/* U/J, EU, SH */
|
||||
/*0xA4, 0x00, 0x00*/ struct AudioListItem listItem;
|
||||
/* 0x10, 0x10*/ struct NoteSynthesisState synthesisState;
|
||||
// The next members are actually part of a struct (NotePlaybackState), but
|
||||
// that results in messy US/EU ifdefs. Instead we cast to a struct pointer
|
||||
// when needed... This breaks alignment on non-N64 platforms, which we hack
|
||||
// around by skipping the padding in that case.
|
||||
// TODO: use macros or something instead.
|
||||
#ifdef TARGET_N64
|
||||
u8 pad0[12];
|
||||
#endif
|
||||
|
||||
/*0x04, 0x30, 0x30*/ u8 priority;
|
||||
/* 0x31, 0x31*/ u8 waveId;
|
||||
/* 0x32, 0x32*/ u8 sampleCountIndex;
|
||||
#ifdef VERSION_SH
|
||||
/* 0x33*/ u8 bankId;
|
||||
/* 0x34*/ u8 unkSH34;
|
||||
#endif
|
||||
/*0x08, 0x34, 0x36*/ s16 adsrVolScale;
|
||||
/*0x18, 0x38, */ f32 portamentoFreqScale;
|
||||
/*0x1C, 0x3C, */ f32 vibratoFreqScale;
|
||||
/*0x28, 0x40, */ struct SequenceChannelLayer *prevParentLayer;
|
||||
/*0x2C, 0x44, 0x44*/ struct SequenceChannelLayer *parentLayer;
|
||||
/*0x30, 0x48, 0x48*/ struct SequenceChannelLayer *wantedParentLayer;
|
||||
/* , 0x4C, 0x4C*/ struct NoteAttributes attributes;
|
||||
/*0x54, 0x58, 0x5C*/ struct AdsrState adsr;
|
||||
/*0x74, 0x7C*/ struct Portamento portamento;
|
||||
/*0x84, 0x8C*/ struct VibratoState vibratoState;
|
||||
u8 pad3[8];
|
||||
/* , 0xB0, 0xB4*/ struct NoteSubEu noteSubEu;
|
||||
}; // size = 0xC0, known to be 0xC8 on SH
|
||||
#else
|
||||
// volatile Note, needed in synthesis_process_notes
|
||||
struct vNote
|
||||
{
|
||||
/* U/J, EU */
|
||||
/*0x00*/ volatile u8 enabled : 1;
|
||||
long long int force_structure_alignment;
|
||||
}; // size = 0xC0
|
||||
struct Note
|
||||
{
|
||||
/* U/J, EU */
|
||||
/*0x00*/ u8 enabled : 1;
|
||||
/*0x00*/ u8 needsInit : 1;
|
||||
/*0x00*/ u8 restart : 1;
|
||||
/*0x00*/ u8 finished : 1;
|
||||
/*0x00*/ u8 envMixerNeedsInit : 1;
|
||||
/*0x00*/ u8 stereoStrongRight : 1;
|
||||
/*0x00*/ u8 stereoStrongLeft : 1;
|
||||
/*0x00*/ u8 stereoHeadsetEffects : 1;
|
||||
/*0x01*/ u8 usesHeadsetPanEffects;
|
||||
/*0x02*/ u8 unk2;
|
||||
/*0x03*/ u8 sampleDmaIndex;
|
||||
/*0x04, 0x30*/ u8 priority;
|
||||
/*0x05*/ u8 sampleCount; // 0, 8, 16, 32 or 64
|
||||
/*0x06*/ u8 instOrWave;
|
||||
/*0x07*/ u8 bankId; // in NoteSubEu on EU
|
||||
/*0x08*/ s16 adsrVolScale;
|
||||
/* */ u8 pad1[2];
|
||||
/*0x0C, 0xB3*/ u16 headsetPanRight;
|
||||
/*0x0E, 0xB4*/ u16 headsetPanLeft;
|
||||
/*0x10*/ u16 prevHeadsetPanRight;
|
||||
/*0x12*/ u16 prevHeadsetPanLeft;
|
||||
/*0x14*/ s32 samplePosInt;
|
||||
/*0x18, 0x38*/ f32 portamentoFreqScale;
|
||||
/*0x1C, 0x3C*/ f32 vibratoFreqScale;
|
||||
/*0x20*/ u16 samplePosFrac;
|
||||
/*0x24*/ struct AudioBankSound *sound;
|
||||
/*0x28, 0x40*/ struct SequenceChannelLayer *prevParentLayer;
|
||||
/*0x2C, 0x44*/ struct SequenceChannelLayer *parentLayer;
|
||||
/*0x30, 0x48*/ struct SequenceChannelLayer *wantedParentLayer;
|
||||
/*0x34*/ struct NoteSynthesisBuffers *synthesisBuffers;
|
||||
/*0x38*/ f32 frequency;
|
||||
/*0x3C*/ u16 targetVolLeft; // Q1.15, but will always be non-negative
|
||||
/*0x3E*/ u16 targetVolRight; // Q1.15, but will always be non-negative
|
||||
/*0x40*/ u8 reverbVol; // Q1.7
|
||||
/*0x41*/ u8 unused1; // never read, set to 0x3f
|
||||
/*0x44*/ struct NoteAttributes attributes;
|
||||
/*0x54, 0x58*/ struct AdsrState adsr;
|
||||
/*0x74, 0x7C*/ struct Portamento portamento;
|
||||
/*0x84, 0x8C*/ struct VibratoState vibratoState;
|
||||
/*0x9C*/ s16 curVolLeft; // Q1.15, but will always be non-negative
|
||||
/*0x9E*/ s16 curVolRight; // Q1.15, but will always be non-negative
|
||||
/*0xA0*/ s16 reverbVolShifted; // Q1.15
|
||||
/*0xA2*/ s16 unused2; // never read, set to 0
|
||||
/*0xA4, 0x00*/ struct AudioListItem listItem;
|
||||
/* */ u8 pad2[0xc];
|
||||
}; // size = 0xC0
|
||||
#endif
|
||||
|
||||
struct NoteSynthesisBuffers
|
||||
{
|
||||
s16 adpcmdecState[0x10];
|
||||
s16 finalResampleState[0x10];
|
||||
#ifdef VERSION_SH
|
||||
s16 unk[0x10];
|
||||
s16 filterBuffer[0x20];
|
||||
s16 panSamplesBuffer[0x20];
|
||||
#else
|
||||
s16 mixEnvelopeState[0x28];
|
||||
s16 panResampleState[0x10];
|
||||
s16 panSamplesBuffer[0x20];
|
||||
s16 dummyResampleState[0x10];
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
s16 samples[0x40];
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef VERSION_EU
|
||||
struct ReverbSettingsEU
|
||||
{
|
||||
u8 downsampleRate;
|
||||
u8 windowSize; // To be multiplied by 64
|
||||
u16 gain;
|
||||
};
|
||||
#else
|
||||
struct ReverbSettingsEU
|
||||
{
|
||||
u8 downsampleRate; // always 1
|
||||
u8 windowSize; // To be multiplied by 16
|
||||
u16 gain;
|
||||
u16 unk4; // always zero
|
||||
u16 unk6; // always zero
|
||||
s8 unk8; // always -1
|
||||
u16 unkA; // always 0x3000
|
||||
s16 unkC; // always zero
|
||||
s16 unkE; // always zero
|
||||
};
|
||||
#endif
|
||||
|
||||
struct AudioSessionSettingsEU
|
||||
{
|
||||
/* 0x00 */ u32 frequency;
|
||||
/* 0x04 */ u8 unk1; // always 1
|
||||
/* 0x05 */ u8 maxSimultaneousNotes;
|
||||
/* 0x06 */ u8 numReverbs; // always 1
|
||||
/* 0x07 */ u8 unk2; // always 0
|
||||
/* 0x08 */ struct ReverbSettingsEU *reverbSettings;
|
||||
/* 0x0C */ u16 volume;
|
||||
/* 0x0E */ u16 unk3; // always 0
|
||||
/* 0x10 */ u32 persistentSeqMem;
|
||||
/* 0x14 */ u32 persistentBankMem;
|
||||
#ifdef VERSION_SH
|
||||
/* 0x18 */ u32 unk18; // always 0
|
||||
#endif
|
||||
/* 0x18, 0x1C */ u32 temporarySeqMem;
|
||||
/* 0x1C, 0x20 */ u32 temporaryBankMem;
|
||||
#ifdef VERSION_SH
|
||||
/* 0x24 */ u32 unk24; // always 0
|
||||
/* 0x28 */ u32 unkMem28; // always 0
|
||||
/* 0x2C */ u32 unkMem2C; // always 0
|
||||
#endif
|
||||
}; // 0x30 on shindou
|
||||
|
||||
struct AudioSessionSettings
|
||||
{
|
||||
/*0x00*/ u32 frequency;
|
||||
/*0x04*/ u8 maxSimultaneousNotes;
|
||||
/*0x05*/ u8 reverbDownsampleRate; // always 1
|
||||
/*0x06*/ u16 reverbWindowSize;
|
||||
/*0x08*/ u16 reverbGain;
|
||||
/*0x0A*/ u16 volume;
|
||||
/*0x0C*/ u32 persistentSeqMem;
|
||||
/*0x10*/ u32 persistentBankMem;
|
||||
/*0x14*/ u32 temporarySeqMem;
|
||||
/*0x18*/ u32 temporaryBankMem;
|
||||
}; // size = 0x1C
|
||||
|
||||
struct AudioBufferParametersEU {
|
||||
/*0x00*/ s16 presetUnk4; // audio frames per vsync?
|
||||
/*0x02*/ u16 frequency;
|
||||
/*0x04*/ u16 aiFrequency; // ?16
|
||||
/*0x06*/ s16 samplesPerFrameTarget;
|
||||
/*0x08*/ s16 maxAiBufferLength;
|
||||
/*0x0A*/ s16 minAiBufferLength;
|
||||
/*0x0C*/ s16 updatesPerFrame;
|
||||
/*0x0E*/ s16 samplesPerUpdate;
|
||||
/*0x10*/ s16 samplesPerUpdateMax;
|
||||
/*0x12*/ s16 samplesPerUpdateMin;
|
||||
/*0x14*/ f32 resampleRate; // contains 32000.0f / frequency
|
||||
/*0x18*/ f32 updatesPerFrameInv; // 1.0f / updatesPerFrame
|
||||
/*0x1C*/ f32 unkUpdatesPerFrameScaled; // 3.0f / (1280.0f * updatesPerFrame)
|
||||
};
|
||||
|
||||
struct EuAudioCmd {
|
||||
union {
|
||||
#if IS_BIG_ENDIAN
|
||||
struct {
|
||||
u8 op;
|
||||
u8 arg1;
|
||||
u8 arg2;
|
||||
u8 arg3;
|
||||
} s;
|
||||
#else
|
||||
struct {
|
||||
u8 arg3;
|
||||
u8 arg2;
|
||||
u8 arg1;
|
||||
u8 op;
|
||||
} s;
|
||||
#endif
|
||||
s32 first;
|
||||
} u;
|
||||
union {
|
||||
s32 as_s32;
|
||||
u32 as_u32;
|
||||
f32 as_f32;
|
||||
#if IS_BIG_ENDIAN
|
||||
u8 as_u8;
|
||||
s8 as_s8;
|
||||
#else
|
||||
struct {
|
||||
u8 pad0[3];
|
||||
u8 as_u8;
|
||||
};
|
||||
struct {
|
||||
u8 pad1[3];
|
||||
s8 as_s8;
|
||||
};
|
||||
#endif
|
||||
} u2;
|
||||
};
|
||||
|
||||
#ifdef VERSION_SH
|
||||
struct PendingDmaSample {
|
||||
u8 medium;
|
||||
u8 bankId;
|
||||
u8 idx;
|
||||
uintptr_t devAddr;
|
||||
void *vAddr;
|
||||
u8 *resultSampleAddr;
|
||||
s32 state;
|
||||
s32 remaining;
|
||||
s8 *io;
|
||||
/*0x1C*/ struct AudioBankSample sample;
|
||||
/*0x2C*/ OSMesgQueue queue;
|
||||
/*0x44*/ OSMesg mesgs[1];
|
||||
/*0x48*/ OSIoMesg ioMesg;
|
||||
};
|
||||
|
||||
struct UnkStruct80343D00 {
|
||||
u32 someIndex; // array into one of the two slots below
|
||||
struct PendingDmaSample arr[2];
|
||||
};
|
||||
|
||||
// in external.c
|
||||
extern s32 D_SH_80343CF0;
|
||||
extern struct UnkStruct80343D00 D_SH_80343D00;
|
||||
#endif
|
||||
|
||||
#endif // AUDIO_INTERNAL_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,116 @@
|
||||
#ifndef AUDIO_LOAD_H
|
||||
#define AUDIO_LOAD_H
|
||||
|
||||
#include <PR/ultratypes.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#define AUDIO_FRAME_DMA_QUEUE_SIZE 0x40
|
||||
|
||||
#define PRELOAD_BANKS 2
|
||||
#define PRELOAD_SEQUENCE 1
|
||||
|
||||
#define IS_SEQUENCE_CHANNEL_VALID(ptr) ((uintptr_t)(ptr) != (uintptr_t)&gSequenceChannelNone)
|
||||
|
||||
extern struct Note *gNotes;
|
||||
|
||||
// Music in SM64 is played using 3 players:
|
||||
// gSequencePlayers[0] is level background music
|
||||
// gSequencePlayers[1] is misc music, like the puzzle jingle
|
||||
// gSequencePlayers[2] is sound
|
||||
extern struct SequencePlayer gSequencePlayers[SEQUENCE_PLAYERS];
|
||||
|
||||
extern struct SequenceChannel gSequenceChannels[SEQUENCE_CHANNELS];
|
||||
extern struct SequenceChannelLayer gSequenceLayers[SEQUENCE_LAYERS];
|
||||
|
||||
extern struct SequenceChannel gSequenceChannelNone;
|
||||
|
||||
extern struct AudioListItem gLayerFreeList;
|
||||
extern struct NotePool gNoteFreeLists;
|
||||
|
||||
extern OSMesgQueue gCurrAudioFrameDmaQueue;
|
||||
extern u32 gSampleDmaNumListItems;
|
||||
extern ALSeqFile *gAlCtlHeader;
|
||||
extern ALSeqFile *gAlTbl;
|
||||
extern ALSeqFile *gSeqFileHeader;
|
||||
extern u8 *gAlBankSets;
|
||||
|
||||
extern struct CtlEntry *gCtlEntries;
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
extern struct AudioBufferParametersEU gAudioBufferParameters;
|
||||
#endif
|
||||
extern s32 gAiFrequency;
|
||||
#ifdef VERSION_SH
|
||||
extern s16 gCurrAiBufferLength;
|
||||
extern s32 D_SH_8034F68C;
|
||||
#endif
|
||||
extern s32 gMaxAudioCmds;
|
||||
|
||||
extern s32 gMaxSimultaneousNotes;
|
||||
extern s32 gSamplesPerFrameTarget;
|
||||
extern s32 gMinAiBufferLength;
|
||||
extern s16 gTempoInternalToExternal;
|
||||
extern s8 gAudioUpdatesPerFrame; // = 4
|
||||
extern s8 gSoundMode;
|
||||
|
||||
#ifdef VERSION_SH
|
||||
extern OSMesgQueue gUnkQueue1;
|
||||
|
||||
struct UnkStructSH8034EC88 {
|
||||
u8 *endAndMediumIdentification;
|
||||
struct AudioBankSample *sample;
|
||||
u8 *ramAddr;
|
||||
u32 encodedInfo;
|
||||
s32 isFree;
|
||||
};
|
||||
|
||||
struct PatchStruct {
|
||||
s32 bankId1;
|
||||
s32 bankId2;
|
||||
void *baseAddr1;
|
||||
void *baseAddr2;
|
||||
s32 medium1;
|
||||
s32 medium2;
|
||||
};
|
||||
|
||||
extern struct UnkStructSH8034EC88 D_SH_8034EC88[0x80];
|
||||
#endif
|
||||
|
||||
struct AudioBank *bank_load_immediate(s32 bankId, s32 arg1);
|
||||
|
||||
void audio_dma_partial_copy_async(uintptr_t *devAddr, u8 **vAddr, ssize_t *remaining, OSMesgQueue *queue, OSIoMesg *mesg);
|
||||
void decrease_sample_dma_ttls(void);
|
||||
#ifdef VERSION_SH
|
||||
void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef, s32 medium);
|
||||
#else
|
||||
void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef);
|
||||
#endif
|
||||
void init_sample_dma_buffers(s32 arg0);
|
||||
#if defined(VERSION_SH)
|
||||
void patch_audio_bank(s32 bankId, struct AudioBank *mem, struct PatchStruct *patchInfo);
|
||||
#else
|
||||
void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32 numDrums);
|
||||
#endif
|
||||
#ifdef VERSION_SH
|
||||
void preload_sequence(u32 seqId, s32 preloadMask);
|
||||
#else
|
||||
void preload_sequence(u32 seqId, u8 preloadMask);
|
||||
#endif
|
||||
void load_sequence(u32 player, u32 seqId, s32 loadAsync);
|
||||
|
||||
#ifdef VERSION_SH
|
||||
void func_sh_802f3158(s32 seqId, s32 arg1, s32 arg2, OSMesgQueue *retQueue);
|
||||
u8 *func_sh_802f3220(u32 seqId, u32 *a1);
|
||||
struct AudioBankSample *func_sh_802f4978(s32 bankId, s32 idx);
|
||||
s32 func_sh_802f47c8(s32 bankId, u8 idx, s8 *io);
|
||||
void *func_sh_802f3f08(s32 poolIdx, s32 arg1, s32 arg2, s32 arg3, OSMesgQueue *retQueue);
|
||||
void func_sh_802f41e4(s32 audioResetStatus);
|
||||
BAD_RETURN(s32) func_sh_802f3368(s32 bankId);
|
||||
void *func_sh_802f3764(s32 arg0, s32 idx, s32 *arg2);
|
||||
s32 func_sh_802f3024(s32 bankId, s32 instId, s32 arg2);
|
||||
void func_sh_802f30f4(s32 arg0, s32 arg1, s32 arg2, OSMesgQueue *arg3);
|
||||
void func_sh_802f3288(s32 idx);
|
||||
|
||||
#endif
|
||||
|
||||
#endif // AUDIO_LOAD_H
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "load_dat.h"
|
||||
|
||||
struct seqFile *gSoundDataADSR;
|
||||
|
||||
struct seqFile *gSoundDataRaw;
|
||||
|
||||
struct seqFile *gMusicData;
|
||||
|
||||
#ifndef VERSION_SH
|
||||
unsigned char* gBankSetsData;
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "../tools/convTypes.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
extern struct seqFile *gSoundDataADSR;
|
||||
|
||||
extern struct seqFile *gSoundDataRaw;
|
||||
|
||||
extern struct seqFile *gMusicData;
|
||||
|
||||
#ifndef VERSION_SH
|
||||
extern unsigned char *gBankSetsData;
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
||||
#ifndef AUDIO_PLAYBACK_H
|
||||
#define AUDIO_PLAYBACK_H
|
||||
|
||||
#include <PR/ultratypes.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
// Mask bits denoting where to allocate notes from, according to a channel's
|
||||
// noteAllocPolicy. Despite being checked as bitmask bits, the bits are not
|
||||
// orthogonal; rather, the smallest bit wins, except for NOTE_ALLOC_LAYER,
|
||||
// which *is* orthogonal to the other. SEQ implicitly includes CHANNEL.
|
||||
// If none of the CHANNEL/SEQ/GLOBAL_FREELIST bits are set, all three locations
|
||||
// are tried.
|
||||
#define NOTE_ALLOC_LAYER 1
|
||||
#define NOTE_ALLOC_CHANNEL 2
|
||||
#define NOTE_ALLOC_SEQ 4
|
||||
#define NOTE_ALLOC_GLOBAL_FREELIST 8
|
||||
|
||||
void process_notes(void);
|
||||
void seq_channel_layer_note_decay(struct SequenceChannelLayer *seqLayer);
|
||||
void seq_channel_layer_note_release(struct SequenceChannelLayer *seqLayer);
|
||||
void init_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer);
|
||||
void init_note_lists(struct NotePool *pool);
|
||||
void init_note_free_list(void);
|
||||
void note_pool_clear(struct NotePool *pool);
|
||||
void note_pool_fill(struct NotePool *pool, s32 count);
|
||||
void audio_list_push_front(struct AudioListItem *list, struct AudioListItem *item);
|
||||
void audio_list_remove(struct AudioListItem *item);
|
||||
struct Note *alloc_note(struct SequenceChannelLayer *seqLayer);
|
||||
void reclaim_notes(void);
|
||||
void note_init_all(void);
|
||||
|
||||
#if defined(VERSION_SH)
|
||||
void note_set_vel_pan_reverb(struct Note *note, struct ReverbInfo *reverbInfo);
|
||||
#elif defined(VERSION_EU)
|
||||
void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverbVol);
|
||||
#endif
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
struct AudioBankSound *instrument_get_audio_bank_sound(struct Instrument *instrument, s32 semitone);
|
||||
struct Instrument *get_instrument_inner(s32 bankId, s32 instId);
|
||||
struct Drum *get_drum(s32 bankId, s32 drumId);
|
||||
void note_init_volume(struct Note *note);
|
||||
void note_set_frequency(struct Note *note, f32 frequency);
|
||||
void note_enable(struct Note *note);
|
||||
void note_disable(struct Note *note);
|
||||
#endif
|
||||
|
||||
|
||||
#endif // AUDIO_PLAYBACK_H
|
||||
@@ -0,0 +1,351 @@
|
||||
#include <ultra64.h>
|
||||
#include "internal.h"
|
||||
#include "load.h"
|
||||
#include "data.h"
|
||||
#include "seqplayer.h"
|
||||
#include "synthesis.h"
|
||||
|
||||
#ifdef VERSION_EU
|
||||
|
||||
#ifdef __sgi
|
||||
#define stubbed_printf
|
||||
#else
|
||||
#define stubbed_printf(...)
|
||||
#endif
|
||||
|
||||
#define SAMPLES_TO_OVERPRODUCE 0x10
|
||||
#define EXTRA_BUFFERED_AI_SAMPLES_TARGET 0x40
|
||||
|
||||
#ifdef VERSION_JP
|
||||
typedef u16 FadeT;
|
||||
#else
|
||||
typedef s32 FadeT;
|
||||
#endif
|
||||
|
||||
extern volatile u8 gAudioResetStatus;
|
||||
extern u8 gAudioResetPresetIdToLoad;
|
||||
extern OSMesgQueue *OSMesgQueues[];
|
||||
extern struct EuAudioCmd sAudioCmd[0x100];
|
||||
|
||||
void func_8031D690(s32 player, FadeT fadeInTime);
|
||||
void seq_player_fade_to_zero_volume(s32 player, FadeT fadeOutTime);
|
||||
void decrease_sample_dma_ttls(void);
|
||||
s32 audio_shut_down_and_reset_step(void);
|
||||
void func_802ad7ec(u32);
|
||||
|
||||
#ifdef TARGET_N64
|
||||
struct SPTask *create_next_audio_frame_task(void) {
|
||||
u32 samplesRemainingInAI;
|
||||
s32 writtenCmds;
|
||||
s32 index;
|
||||
OSTask_t *task;
|
||||
s32 flags;
|
||||
s16 *currAiBuffer;
|
||||
s32 oldDmaCount;
|
||||
OSMesg sp30;
|
||||
OSMesg sp2C;
|
||||
|
||||
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();
|
||||
if (osRecvMesg(OSMesgQueues[2], &sp30, 0) != -1) {
|
||||
gAudioResetPresetIdToLoad = (u8) (s32) sp30;
|
||||
gAudioResetStatus = 5;
|
||||
}
|
||||
|
||||
if (gAudioResetStatus != 0) {
|
||||
if (audio_shut_down_and_reset_step() == 0) {
|
||||
if (gAudioResetStatus == 0) {
|
||||
osSendMesg(OSMesgQueues[3], (OSMesg) (s32) gAudioResetPresetIdToLoad, OS_MESG_NOBLOCK);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
gAudioTask = &gAudioTasks[gAudioTaskIndex];
|
||||
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) {
|
||||
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 + 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;
|
||||
}
|
||||
#else
|
||||
struct SPTask *create_next_audio_frame_task(void) {
|
||||
return NULL;
|
||||
}
|
||||
void create_next_audio_buffer(s16 *samples, u32 num_samples) {
|
||||
s32 writtenCmds;
|
||||
OSMesg msg;
|
||||
gAudioFrameCount++;
|
||||
decrease_sample_dma_ttls();
|
||||
if (osRecvMesg(OSMesgQueues[2], &msg, 0) != -1) {
|
||||
gAudioResetPresetIdToLoad = (u8) (intptr_t) msg;
|
||||
gAudioResetStatus = 5;
|
||||
}
|
||||
|
||||
if (gAudioResetStatus != 0) {
|
||||
audio_reset_session();
|
||||
gAudioResetStatus = 0;
|
||||
}
|
||||
if (osRecvMesg(OSMesgQueues[1], &msg, OS_MESG_NOBLOCK) != -1) {
|
||||
func_802ad7ec((u32) msg);
|
||||
}
|
||||
synthesis_execute(gAudioCmdBuffers[0], &writtenCmds, samples, num_samples);
|
||||
gAudioRandom = ((gAudioRandom + gAudioFrameCount) * gAudioFrameCount);
|
||||
gAudioRandom = gAudioRandom + writtenCmds / 8;
|
||||
}
|
||||
#endif
|
||||
|
||||
void eu_process_audio_cmd(struct EuAudioCmd *cmd) {
|
||||
s32 i;
|
||||
|
||||
switch (cmd->u.s.op) {
|
||||
case 0x81:
|
||||
preload_sequence(cmd->u.s.arg2, 3);
|
||||
break;
|
||||
|
||||
case 0x82:
|
||||
case 0x88:
|
||||
load_sequence(cmd->u.s.arg1, cmd->u.s.arg2, cmd->u.s.arg3);
|
||||
func_8031D690(cmd->u.s.arg1, cmd->u2.as_s32);
|
||||
break;
|
||||
|
||||
case 0x83:
|
||||
if (gSequencePlayers[cmd->u.s.arg1].enabled != FALSE) {
|
||||
if (cmd->u2.as_s32 == 0) {
|
||||
sequence_player_disable(&gSequencePlayers[cmd->u.s.arg1]);
|
||||
}
|
||||
else {
|
||||
seq_player_fade_to_zero_volume(cmd->u.s.arg1, cmd->u2.as_s32);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xf0:
|
||||
gSoundMode = cmd->u2.as_s32;
|
||||
break;
|
||||
|
||||
case 0xf1:
|
||||
for (i = 0; i < 4; i++) {
|
||||
gSequencePlayers[i].muted = TRUE;
|
||||
gSequencePlayers[i].recalculateVolume = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xf2:
|
||||
for (i = 0; i < 4; i++) {
|
||||
gSequencePlayers[i].muted = FALSE;
|
||||
gSequencePlayers[i].recalculateVolume = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const char undefportcmd[] = "Undefined Port Command %d\n";
|
||||
|
||||
extern OSMesgQueue *OSMesgQueues[];
|
||||
extern u8 D_EU_80302010;
|
||||
extern u8 D_EU_80302014;
|
||||
extern OSMesg OSMesg0;
|
||||
extern OSMesg OSMesg1;
|
||||
extern OSMesg OSMesg2;
|
||||
extern OSMesg OSMesg3;
|
||||
|
||||
void seq_player_fade_to_zero_volume(s32 player, FadeT fadeOutTime) {
|
||||
if (fadeOutTime == 0) {
|
||||
fadeOutTime = 1;
|
||||
}
|
||||
gSequencePlayers[player].fadeVelocity = -(gSequencePlayers[player].fadeVolume / fadeOutTime);
|
||||
gSequencePlayers[player].state = 2;
|
||||
gSequencePlayers[player].fadeRemainingFrames = fadeOutTime;
|
||||
|
||||
}
|
||||
|
||||
void func_8031D690(s32 player, FadeT fadeInTime) {
|
||||
if (fadeInTime != 0) {
|
||||
gSequencePlayers[player].state = 1;
|
||||
gSequencePlayers[player].fadeTimerUnkEu = fadeInTime;
|
||||
gSequencePlayers[player].fadeRemainingFrames = fadeInTime;
|
||||
gSequencePlayers[player].fadeVolume = 0.0f;
|
||||
gSequencePlayers[player].fadeVelocity = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void port_eu_init_queues(void) {
|
||||
D_EU_80302010 = 0;
|
||||
D_EU_80302014 = 0;
|
||||
osCreateMesgQueue(OSMesgQueues[0], &OSMesg0, 1);
|
||||
osCreateMesgQueue(OSMesgQueues[1], &OSMesg1, 4);
|
||||
osCreateMesgQueue(OSMesgQueues[2], &OSMesg2, 1);
|
||||
osCreateMesgQueue(OSMesgQueues[3], &OSMesg3, 1);
|
||||
}
|
||||
|
||||
void func_802ad6f0(s32 arg0, s32 *arg1) {
|
||||
struct EuAudioCmd *cmd = &sAudioCmd[D_EU_80302010 & 0xff];
|
||||
cmd->u.first = arg0;
|
||||
cmd->u2.as_u32 = *arg1;
|
||||
D_EU_80302010++;
|
||||
}
|
||||
|
||||
void func_802ad728(u32 arg0, f32 arg1) {
|
||||
func_802ad6f0(arg0, (s32*) &arg1);
|
||||
}
|
||||
|
||||
void func_802ad74c(u32 arg0, u32 arg1) {
|
||||
func_802ad6f0(arg0, (s32*) &arg1);
|
||||
}
|
||||
|
||||
void func_802ad770(u32 arg0, s8 arg1) {
|
||||
s32 sp1C = arg1 << 24;
|
||||
func_802ad6f0(arg0, &sp1C);
|
||||
}
|
||||
|
||||
void func_802ad7a0(void) {
|
||||
osSendMesg(OSMesgQueues[1],
|
||||
(OSMesg)(u32)((D_EU_80302014 & 0xff) << 8 | (D_EU_80302010 & 0xff)),
|
||||
OS_MESG_NOBLOCK);
|
||||
D_EU_80302014 = D_EU_80302010;
|
||||
}
|
||||
|
||||
void func_802ad7ec(u32 arg0) {
|
||||
struct EuAudioCmd *cmd;
|
||||
struct SequencePlayer *seqPlayer;
|
||||
struct SequenceChannel *chan;
|
||||
u8 end = arg0 & 0xff;
|
||||
u8 i = (arg0 >> 8) & 0xff;
|
||||
|
||||
for (;;) {
|
||||
if (i == end) break;
|
||||
cmd = &sAudioCmd[i++ & 0xff];
|
||||
|
||||
if (cmd->u.s.arg1 < SEQUENCE_PLAYERS) {
|
||||
seqPlayer = &gSequencePlayers[cmd->u.s.arg1];
|
||||
if ((cmd->u.s.op & 0x80) != 0) {
|
||||
eu_process_audio_cmd(cmd);
|
||||
}
|
||||
else if ((cmd->u.s.op & 0x40) != 0) {
|
||||
switch (cmd->u.s.op) {
|
||||
case 0x41:
|
||||
seqPlayer->fadeVolumeScale = cmd->u2.as_f32;
|
||||
seqPlayer->recalculateVolume = TRUE;
|
||||
break;
|
||||
|
||||
case 0x47:
|
||||
seqPlayer->tempo = cmd->u2.as_s32 * TATUMS_PER_BEAT;
|
||||
break;
|
||||
|
||||
case 0x48:
|
||||
seqPlayer->transposition = cmd->u2.as_s8;
|
||||
break;
|
||||
|
||||
case 0x46:
|
||||
seqPlayer->seqVariationEu[cmd->u.s.arg3] = cmd->u2.as_s8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (seqPlayer->enabled != FALSE && cmd->u.s.arg2 < 0x10) {
|
||||
chan = seqPlayer->channels[cmd->u.s.arg2];
|
||||
if (IS_SEQUENCE_CHANNEL_VALID(chan))
|
||||
{
|
||||
switch (cmd->u.s.op) {
|
||||
case 1:
|
||||
chan->volumeScale = cmd->u2.as_f32;
|
||||
chan->changes.as_bitfields.volume = TRUE;
|
||||
break;
|
||||
case 2:
|
||||
chan->volume = cmd->u2.as_f32;
|
||||
chan->changes.as_bitfields.volume = TRUE;
|
||||
break;
|
||||
case 3:
|
||||
chan->newPan = cmd->u2.as_s8;
|
||||
chan->changes.as_bitfields.pan = TRUE;
|
||||
break;
|
||||
case 4:
|
||||
chan->freqScale = cmd->u2.as_f32;
|
||||
chan->changes.as_bitfields.freqScale = TRUE;
|
||||
break;
|
||||
case 5:
|
||||
chan->reverbVol = cmd->u2.as_s8;
|
||||
break;
|
||||
case 6:
|
||||
if (cmd->u.s.arg3 < 8) {
|
||||
chan->soundScriptIO[cmd->u.s.arg3] = cmd->u2.as_s8;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
chan->stopSomething2 = cmd->u2.as_s8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmd->u.s.op = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void port_eu_init(void) {
|
||||
port_eu_init_queues();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,597 @@
|
||||
#ifdef VERSION_SH
|
||||
// TODO: merge this with port_eu.c?
|
||||
|
||||
#include <ultra64.h>
|
||||
|
||||
#include "data.h"
|
||||
#include "heap.h"
|
||||
#include "load.h"
|
||||
#include "synthesis.h"
|
||||
#include "internal.h"
|
||||
#include "seqplayer.h"
|
||||
|
||||
#define EXTRA_BUFFERED_AI_SAMPLES_TARGET 0x80
|
||||
#define SAMPLES_TO_OVERPRODUCE 0x10
|
||||
|
||||
extern s32 D_SH_80314FC8;
|
||||
extern struct SPTask *D_SH_80314FCC;
|
||||
extern u8 D_SH_80315098;
|
||||
extern u8 D_SH_8031509C;
|
||||
extern OSMesgQueue *D_SH_80350F68;
|
||||
|
||||
void func_8031D690(s32 playerIndex, s32 numFrames);
|
||||
void seq_player_fade_to_zero_volume(s32 arg0, s32 numFrames);
|
||||
void func_802ad7ec(u32 arg0);
|
||||
|
||||
#ifdef TARGET_N64
|
||||
struct SPTask *create_next_audio_frame_task(void) {
|
||||
u32 samplesRemainingInAI;
|
||||
s32 writtenCmds;
|
||||
s32 index;
|
||||
OSTask_t *task;
|
||||
s32 flags;
|
||||
s16 *currAiBuffer;
|
||||
s32 oldDmaCount;
|
||||
s32 sp38;
|
||||
s32 sp34;
|
||||
s32 writtenCmdsCopy;
|
||||
|
||||
gAudioFrameCount++;
|
||||
if (gAudioFrameCount % gAudioBufferParameters.presetUnk4 != 0) {
|
||||
if ((gAudioFrameCount % gAudioBufferParameters.presetUnk4) + 1 == gAudioBufferParameters.presetUnk4) {
|
||||
return D_SH_80314FCC;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
osSendMesg(D_SH_80350F38, (OSMesg) gAudioFrameCount, OS_MESG_NOBLOCK);
|
||||
|
||||
gAudioTaskIndex ^= 1;
|
||||
gCurrAiBufferIndex++;
|
||||
gCurrAiBufferIndex %= NUMAIBUFFERS;
|
||||
index = (gCurrAiBufferIndex - 2 + NUMAIBUFFERS) % NUMAIBUFFERS;
|
||||
samplesRemainingInAI = osAiGetLength() / 4;
|
||||
|
||||
if (gAudioLoadLockSH < 0x10U) {
|
||||
if (gAiBufferLengths[index] != 0) {
|
||||
osAiSetNextBuffer(gAiBuffers[index], gAiBufferLengths[index] * 4);
|
||||
}
|
||||
}
|
||||
|
||||
oldDmaCount = gCurrAudioFrameDmaCount;
|
||||
if (oldDmaCount > AUDIO_FRAME_DMA_QUEUE_SIZE) {
|
||||
}
|
||||
gCurrAudioFrameDmaCount = 0;
|
||||
|
||||
decrease_sample_dma_ttls();
|
||||
func_sh_802f41e4(gAudioResetStatus);
|
||||
if (osRecvMesg(D_SH_80350F88, (OSMesg *) &sp38, OS_MESG_NOBLOCK) != -1) {
|
||||
if (gAudioResetStatus == 0) {
|
||||
gAudioResetStatus = 5;
|
||||
}
|
||||
gAudioResetPresetIdToLoad = (u8) sp38;
|
||||
}
|
||||
|
||||
if (gAudioResetStatus != 0) {
|
||||
if (audio_shut_down_and_reset_step() == 0) {
|
||||
if (gAudioResetStatus == 0) {
|
||||
osSendMesg(D_SH_80350FA8, (OSMesg) (s32) gAudioResetPresetIdToLoad, OS_MESG_NOBLOCK);
|
||||
}
|
||||
D_SH_80314FCC = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (gAudioLoadLockSH >= 0x11U) {
|
||||
return NULL;
|
||||
}
|
||||
if (gAudioLoadLockSH != 0) {
|
||||
gAudioLoadLockSH++;
|
||||
}
|
||||
|
||||
gAudioTask = &gAudioTasks[gAudioTaskIndex];
|
||||
gAudioCmd = (u64 *) gAudioCmdBuffers[gAudioTaskIndex];
|
||||
index = gCurrAiBufferIndex;
|
||||
currAiBuffer = gAiBuffers[index];
|
||||
|
||||
gAiBufferLengths[index] = (s16) ((((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) {
|
||||
gAiBufferLengths[index] = gAudioBufferParameters.maxAiBufferLength;
|
||||
}
|
||||
|
||||
if (osRecvMesg(D_SH_80350F68, (OSMesg *) &sp34, 0) != -1) {
|
||||
do {
|
||||
func_802ad7ec(sp34);
|
||||
} while (osRecvMesg(D_SH_80350F68, (OSMesg *) &sp34, 0) != -1);
|
||||
}
|
||||
|
||||
flags = 0;
|
||||
gAudioCmd = synthesis_execute(gAudioCmd, &writtenCmds, currAiBuffer, gAiBufferLengths[index]);
|
||||
gAudioRandom = (u32) (osGetCount() * (gAudioRandom + gAudioFrameCount));
|
||||
gAudioRandom = (u32) (gAiBuffers[index][gAudioFrameCount & 0xFF] + gAudioRandom);
|
||||
|
||||
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 *) rspF3DStart - (u8 *) rspF3DBootStart;
|
||||
task->ucode = rspAspMainStart;
|
||||
task->ucode_data = rspAspMainDataStart;
|
||||
task->ucode_size = 0x1000;
|
||||
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;
|
||||
|
||||
writtenCmdsCopy = writtenCmds;
|
||||
if (D_SH_80314FC8 < writtenCmdsCopy) {
|
||||
D_SH_80314FC8 = writtenCmdsCopy;
|
||||
}
|
||||
|
||||
if (gAudioBufferParameters.presetUnk4 == 1) {
|
||||
return gAudioTask;
|
||||
} else {
|
||||
D_SH_80314FCC = gAudioTask;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#else
|
||||
struct SPTask *create_next_audio_frame_task(void) {
|
||||
return NULL;
|
||||
}
|
||||
void create_next_audio_buffer(s16 *samples, u32 num_samples) {
|
||||
s32 writtenCmds;
|
||||
OSMesg msg;
|
||||
gAudioFrameCount++;
|
||||
decrease_sample_dma_ttls();
|
||||
if (osRecvMesg(D_SH_80350F88, &msg, 0) != -1) {
|
||||
gAudioResetPresetIdToLoad = (u8) (intptr_t) msg;
|
||||
if (gAudioResetStatus == 0) {
|
||||
gAudioResetStatus = 5;
|
||||
}
|
||||
}
|
||||
|
||||
if (gAudioResetStatus != 0) {
|
||||
audio_reset_session();
|
||||
gAudioResetStatus = 0;
|
||||
}
|
||||
while (osRecvMesg(D_SH_80350F68, &msg, OS_MESG_NOBLOCK) != -1) {
|
||||
func_802ad7ec((u32) msg);
|
||||
}
|
||||
synthesis_execute(gAudioCmdBuffers[0], &writtenCmds, samples, num_samples);
|
||||
gAudioRandom = ((gAudioRandom + gAudioFrameCount) * gAudioFrameCount);
|
||||
gAudioRandom = gAudioRandom + writtenCmds / 8;
|
||||
gCurrAudioFrameDmaCount = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void eu_process_audio_cmd(struct EuAudioCmd *cmd) {
|
||||
s32 i;
|
||||
struct Note *note;
|
||||
struct NoteSubEu *sub;
|
||||
|
||||
switch (cmd->u.s.op) {
|
||||
case 0x81:
|
||||
preload_sequence(cmd->u.s.arg2, 3);
|
||||
break;
|
||||
|
||||
case 0x82:
|
||||
case 0x88:
|
||||
load_sequence(cmd->u.s.arg1, cmd->u.s.arg2, cmd->u.s.arg3);
|
||||
func_8031D690(cmd->u.s.arg1, cmd->u2.as_s32);
|
||||
break;
|
||||
|
||||
case 0x83:
|
||||
if (gSequencePlayers[cmd->u.s.arg1].enabled != FALSE) {
|
||||
if (cmd->u2.as_s32 == 0) {
|
||||
sequence_player_disable(&gSequencePlayers[cmd->u.s.arg1]);
|
||||
}
|
||||
else {
|
||||
seq_player_fade_to_zero_volume(cmd->u.s.arg1, cmd->u2.as_s32);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x84:
|
||||
break;
|
||||
|
||||
case 0xf0:
|
||||
gSoundMode = cmd->u2.as_s32;
|
||||
break;
|
||||
|
||||
case 0xf1:
|
||||
for (i = 0; i < 4; i++) {
|
||||
gSequencePlayers[i].muted = TRUE;
|
||||
gSequencePlayers[i].recalculateVolume = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xf2:
|
||||
if (cmd->u2.as_s32 == 1) {
|
||||
for (i = 0; i < gMaxSimultaneousNotes; i++) {
|
||||
note = &gNotes[i];
|
||||
sub = ¬e->noteSubEu;
|
||||
if (note->noteSubEu.enabled && note->unkSH34 == 0) {
|
||||
if ((note->parentLayer->seqChannel->muteBehavior & 8) != 0) {
|
||||
sub->finished = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
gSequencePlayers[i].muted = FALSE;
|
||||
gSequencePlayers[i].recalculateVolume = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xf3:
|
||||
func_sh_802f3024(cmd->u.s.arg1, cmd->u.s.arg2, cmd->u.s.arg3);
|
||||
break;
|
||||
|
||||
case 0xf4:
|
||||
func_sh_802f30f4(cmd->u.s.arg1, cmd->u.s.arg2, cmd->u.s.arg3, &gUnkQueue1);
|
||||
break;
|
||||
|
||||
case 0xf5:
|
||||
func_sh_802f3158(cmd->u.s.arg1, cmd->u.s.arg2, cmd->u.s.arg3, &gUnkQueue1);
|
||||
break;
|
||||
|
||||
case 0xf6:
|
||||
func_sh_802f3288(cmd->u.s.arg2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void seq_player_fade_to_zero_volume(s32 arg0, s32 fadeOutTime) {
|
||||
struct SequencePlayer *player;
|
||||
|
||||
if (fadeOutTime == 0) {
|
||||
fadeOutTime = 1;
|
||||
}
|
||||
player = &gSequencePlayers[arg0];
|
||||
player->state = 2;
|
||||
player->fadeRemainingFrames = fadeOutTime;
|
||||
player->fadeVelocity = -(player->fadeVolume / (f32) fadeOutTime);
|
||||
}
|
||||
|
||||
void func_8031D690(s32 playerIndex, s32 fadeInTime) {
|
||||
struct SequencePlayer *player;
|
||||
|
||||
if (fadeInTime != 0) {
|
||||
player = &gSequencePlayers[playerIndex];
|
||||
player->state = 1;
|
||||
player->fadeTimerUnkEu = fadeInTime;
|
||||
player->fadeRemainingFrames = fadeInTime;
|
||||
player->fadeVolume = 0.0f;
|
||||
player->fadeVelocity = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void port_eu_init_queues(void) {
|
||||
D_SH_80350F18 = 0;
|
||||
D_SH_80350F19 = 0;
|
||||
D_SH_80350F38 = &D_SH_80350F20;
|
||||
D_SH_80350F68 = &D_SH_80350F50;
|
||||
D_SH_80350F88 = &D_SH_80350F70;
|
||||
D_SH_80350FA8 = &D_SH_80350F90;
|
||||
osCreateMesgQueue(D_SH_80350F38, D_SH_80350F1C, 1);
|
||||
osCreateMesgQueue(D_SH_80350F68, D_SH_80350F40, 4);
|
||||
osCreateMesgQueue(D_SH_80350F88, D_SH_80350F6C, 1);
|
||||
osCreateMesgQueue(D_SH_80350FA8, D_SH_80350F8C, 1);
|
||||
}
|
||||
|
||||
extern struct EuAudioCmd sAudioCmd[0x100];
|
||||
void func_802ad6f0(s32 arg0, s32 *arg1) {
|
||||
struct EuAudioCmd *cmd = &sAudioCmd[D_SH_80350F18 & 0xff];
|
||||
cmd->u.first = arg0;
|
||||
cmd->u2.as_u32 = *arg1;
|
||||
D_SH_80350F18++;
|
||||
if (D_SH_80350F18 == D_SH_80350F19) {
|
||||
D_SH_80350F18--;
|
||||
}
|
||||
}
|
||||
|
||||
void func_802ad728(u32 arg0, f32 arg1) {
|
||||
func_802ad6f0(arg0, (s32 *) &arg1);
|
||||
}
|
||||
|
||||
void func_802ad74c(u32 arg0, u32 arg1) {
|
||||
func_802ad6f0(arg0, (s32 *) &arg1);
|
||||
}
|
||||
|
||||
void func_802ad770(u32 arg0, s8 arg1) {
|
||||
s32 sp1C = arg1 << 24;
|
||||
func_802ad6f0(arg0, &sp1C);
|
||||
}
|
||||
|
||||
char shindouDebugPrint133[] = "AudioSend: %d -> %d (%d)\n";
|
||||
|
||||
void func_sh_802F64C8(void) {
|
||||
static s32 D_SH_8031503C = 0;
|
||||
s32 mesg;
|
||||
|
||||
if (((D_SH_80350F18 - D_SH_80350F19 + 0x100) & 0xff) > D_SH_8031503C) {
|
||||
D_SH_8031503C = (D_SH_80350F18 - D_SH_80350F19 + 0x100) & 0xff;
|
||||
}
|
||||
mesg = ((D_SH_80350F19 & 0xff) << 8) | (D_SH_80350F18 & 0xff);
|
||||
osSendMesg(D_SH_80350F68, (OSMesg)mesg, OS_MESG_NOBLOCK);
|
||||
D_SH_80350F19 = D_SH_80350F18;
|
||||
}
|
||||
|
||||
void func_sh_802f6540(void) {
|
||||
D_SH_80350F19 = D_SH_80350F18;
|
||||
}
|
||||
|
||||
void func_802ad7ec(u32 arg0) {
|
||||
struct EuAudioCmd *cmd;
|
||||
struct SequencePlayer *seqPlayer;
|
||||
struct SequenceChannel *chan;
|
||||
u8 end;
|
||||
|
||||
UNUSED static char shindouDebugPrint134[] = "Continue Port\n";
|
||||
UNUSED static char shindouDebugPrint135[] = "%d -> %d\n";
|
||||
UNUSED static char shindouDebugPrint136[] = "Sync-Frame Break. (Remain %d)\n";
|
||||
UNUSED static char shindouDebugPrint137[] = "Undefined Port Command %d\n";
|
||||
|
||||
static u8 D_SH_80315098 = 0;
|
||||
static u8 D_SH_8031509C = 0;
|
||||
|
||||
if (D_SH_8031509C == 0) {
|
||||
D_SH_80315098 = (arg0 >> 8) & 0xff;
|
||||
}
|
||||
|
||||
end = arg0 & 0xff;
|
||||
|
||||
for (;;) {
|
||||
if (D_SH_80315098 == end) {
|
||||
D_SH_8031509C = 0;
|
||||
break;
|
||||
}
|
||||
cmd = &sAudioCmd[D_SH_80315098 & 0xff];
|
||||
D_SH_80315098++;
|
||||
if (cmd->u.s.op == 0xf8) {
|
||||
D_SH_8031509C = 1;
|
||||
break;
|
||||
}
|
||||
else if ((cmd->u.s.op & 0xf0) == 0xf0) {
|
||||
eu_process_audio_cmd(cmd);
|
||||
}
|
||||
else if (cmd->u.s.arg1 < SEQUENCE_PLAYERS) {
|
||||
seqPlayer = &gSequencePlayers[cmd->u.s.arg1];
|
||||
if ((cmd->u.s.op & 0x80) != 0) {
|
||||
eu_process_audio_cmd(cmd);
|
||||
}
|
||||
else if ((cmd->u.s.op & 0x40) != 0) {
|
||||
switch (cmd->u.s.op) {
|
||||
case 0x41:
|
||||
if (seqPlayer->fadeVolumeScale != cmd->u2.as_f32) {
|
||||
seqPlayer->fadeVolumeScale = cmd->u2.as_f32;
|
||||
seqPlayer->recalculateVolume = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x47:
|
||||
seqPlayer->tempo = cmd->u2.as_s32 * TATUMS_PER_BEAT;
|
||||
break;
|
||||
|
||||
case 0x49:
|
||||
seqPlayer->tempoAdd = cmd->u2.as_s32 * TEMPO_SCALE;
|
||||
break;
|
||||
|
||||
case 0x48:
|
||||
seqPlayer->transposition = cmd->u2.as_s8;
|
||||
break;
|
||||
|
||||
case 0x46:
|
||||
seqPlayer->seqVariationEu[cmd->u.s.arg3] = cmd->u2.as_s8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (seqPlayer->enabled != FALSE && cmd->u.s.arg2 < 0x10) {
|
||||
chan = seqPlayer->channels[cmd->u.s.arg2];
|
||||
if (IS_SEQUENCE_CHANNEL_VALID(chan))
|
||||
{
|
||||
switch (cmd->u.s.op) {
|
||||
case 1:
|
||||
if (chan->volumeScale != cmd->u2.as_f32) {
|
||||
chan->volumeScale = cmd->u2.as_f32;
|
||||
chan->changes.as_bitfields.volume = TRUE;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (chan->volume != cmd->u2.as_f32) {
|
||||
chan->volume = cmd->u2.as_f32;
|
||||
chan->changes.as_bitfields.volume = TRUE;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (chan->newPan != cmd->u2.as_s8) {
|
||||
chan->newPan = cmd->u2.as_s8;
|
||||
chan->changes.as_bitfields.pan = TRUE;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (chan->freqScale != cmd->u2.as_f32) {
|
||||
chan->freqScale = cmd->u2.as_f32;
|
||||
chan->changes.as_bitfields.freqScale = TRUE;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
//! @bug u8 s8 comparison (but harmless)
|
||||
if (chan->reverbVol != cmd->u2.as_s8) {
|
||||
chan->reverbVol = cmd->u2.as_s8;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if (cmd->u.s.arg3 < 8) {
|
||||
chan->soundScriptIO[cmd->u.s.arg3] = cmd->u2.as_s8;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
chan->stopSomething2 = cmd->u2.as_s8;
|
||||
break;
|
||||
case 9:
|
||||
chan->muteBehavior = cmd->u2.as_s8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmd->u.s.op = 0;
|
||||
}
|
||||
}
|
||||
|
||||
u32 func_sh_802f6878(s32 *arg0) {
|
||||
u32 sp1C;
|
||||
|
||||
if (osRecvMesg(&gUnkQueue1, (OSMesg *) &sp1C, 0) == -1) {
|
||||
*arg0 = 0;
|
||||
return 0U;
|
||||
}
|
||||
*arg0 = (s32) (sp1C & 0xFFFFFF);
|
||||
return sp1C >> 0x18;
|
||||
}
|
||||
|
||||
u8 *func_sh_802f68e0(u32 index, u32 *a1) {
|
||||
return func_sh_802f3220(index, a1);
|
||||
}
|
||||
|
||||
s32 func_sh_802f6900(void) {
|
||||
s32 ret;
|
||||
s32 sp18;
|
||||
|
||||
ret = osRecvMesg(D_SH_80350FA8, (OSMesg *) &sp18, 0);
|
||||
|
||||
if (ret == -1) {
|
||||
return 0;
|
||||
}
|
||||
if (sp18 != gAudioResetPresetIdToLoad) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: (Scrub C)
|
||||
void func_sh_802f6958(OSMesg mesg) {
|
||||
s32 a;
|
||||
OSMesg recvMesg;
|
||||
|
||||
do {
|
||||
a = -1;
|
||||
} while (osRecvMesg(D_SH_80350FA8, &recvMesg, OS_MESG_NOBLOCK) != a);
|
||||
func_sh_802f6540();
|
||||
osSendMesg(D_SH_80350F88, mesg, OS_MESG_NOBLOCK);
|
||||
}
|
||||
|
||||
void func_sh_802f69cc(void) {
|
||||
gAudioLoadLockSH = 1;
|
||||
func_sh_802f6958(0);
|
||||
gAudioResetStatus = 0;
|
||||
}
|
||||
|
||||
s32 func_sh_802f6a08(s32 playerIndex, s32 channelIndex, s32 soundScriptIOIndex) {
|
||||
struct SequenceChannel *seqChannel;
|
||||
struct SequencePlayer *player;
|
||||
|
||||
player = &gSequencePlayers[playerIndex];
|
||||
if (player->enabled) {
|
||||
seqChannel = player->channels[channelIndex];
|
||||
if (IS_SEQUENCE_CHANNEL_VALID(seqChannel)) {
|
||||
return seqChannel->soundScriptIO[soundScriptIOIndex];
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
s8 func_sh_802f6a6c(s32 playerIndex, s32 index) {
|
||||
return gSequencePlayers[playerIndex].seqVariationEu[index];
|
||||
}
|
||||
|
||||
void port_eu_init(void) {
|
||||
port_eu_init_queues();
|
||||
}
|
||||
|
||||
char shindouDebugPrint138[] = "specchg conjunction error (Msg:%d Cur:%d)\n";
|
||||
char shindouDebugPrint139[] = "Error : Queue is not empty ( %x ) \n";
|
||||
char shindouDebugPrint140[] = "Audio: setvol: volume minus %f\n";
|
||||
char shindouDebugPrint141[] = "Audio: setvol: volume overflow %f\n";
|
||||
char shindouDebugPrint142[] = "Audio: setpitch: pitch zero or minus %f\n";
|
||||
char shindouDebugPrint143[] = "----------------------Double-Error CH: %x %f\n";
|
||||
char shindouDebugPrint144[] = "----------------------Double-Error NT: %x\n";
|
||||
char shindouDebugPrint145[] = "CAUTION:SUB IS SEPARATED FROM GROUP\n";
|
||||
char shindouDebugPrint146[] = "CAUTION:PAUSE EMERGENCY\n";
|
||||
char shindouDebugPrint147[] = "Error:Wait Track disappear\n";
|
||||
char shindouDebugPrint148[] = "Audio: voiceman: No bank error %d\n";
|
||||
char shindouDebugPrint149[] = "Audio: voiceman: progNo. overflow %d,%d\n";
|
||||
char shindouDebugPrint150[] = "ptr2 %x\n";
|
||||
char shindouDebugPrint151[] = "Audio: voiceman: progNo. undefined %d,%d\n";
|
||||
char shindouDebugPrint152[] = "Audio: voiceman: No bank error %d\n";
|
||||
char shindouDebugPrint153[] = "Audio: voiceman: Percussion Overflow %d,%d\n";
|
||||
char shindouDebugPrint154[] = "Audio: voiceman: Percussion table pointer (bank %d) is irregular %x.\n";
|
||||
char shindouDebugPrint155[] = "Audio: voiceman: Percpointer NULL %d,%d\n";
|
||||
char shindouDebugPrint156[] = "--4 %x\n";
|
||||
char shindouDebugPrint157[] = "NoteOff Comes during wait release %x (note %x)\n";
|
||||
char shindouDebugPrint158[] = "Slow Release Batting\n";
|
||||
u8 euUnknownData_8030194c[4] = { 0x40, 0x20, 0x10, 0x08 };
|
||||
char shindouDebugPrint159[] = "Audio:Wavemem: Bad voiceno (%d)\n";
|
||||
char shindouDebugPrint160[] = "Audio: C-Alloc : Dealloc voice is NULL\n";
|
||||
char shindouDebugPrint161[] = "Alloc Error:Dim voice-Alloc %d";
|
||||
char shindouDebugPrint162[] = "Error:Same List Add\n";
|
||||
char shindouDebugPrint163[] = "Already Cut\n";
|
||||
char shindouDebugPrint164[] = "Audio: C-Alloc : lowerPrio is NULL\n";
|
||||
char shindouDebugPrint165[] = "Intterupt UseStop %d (Kill %d)\n";
|
||||
char shindouDebugPrint166[] = "Intterupt RelWait %d (Kill %d)\n";
|
||||
char shindouDebugPrint167[] = "Drop Voice (Prio %x)\n";
|
||||
s32 D_SH_803154CC = 0; // file boundary
|
||||
|
||||
// effects.c
|
||||
char shindouDebugPrint168[] = "Audio:Envp: overflow %f\n";
|
||||
s32 D_SH_803154EC = 0; // file boundary
|
||||
|
||||
// seqplayer.c
|
||||
char shindouDebugPrint169[] = "Audio:Track:Warning: No Free Notetrack\n";
|
||||
char shindouDebugPrint170[] = "SUBTRACK DIM\n";
|
||||
char shindouDebugPrint171[] = "Audio:Track: Warning :SUBTRACK had been stolen by other Group.\n";
|
||||
char shindouDebugPrint172[] = "SEQID %d,BANKID %d\n";
|
||||
char shindouDebugPrint173[] = "ERR:SUBTRACK %d NOT ALLOCATED\n";
|
||||
char shindouDebugPrint174[] = "Stop Release\n";
|
||||
char shindouDebugPrint175[] = "Error:Same List Add\n";
|
||||
char shindouDebugPrint176[] = "Wait Time out!\n";
|
||||
char shindouDebugPrint177[] = "Macro Level Over Error!\n";
|
||||
char shindouDebugPrint178[] = "Macro Level Over Error!\n"; // Again
|
||||
char shindouDebugPrint179[] = "WARNING: NPRG: cannot change %d\n";
|
||||
char shindouDebugPrint180[] = "Audio:Track:NOTE:UNDEFINED NOTE COM. %x\n";
|
||||
char shindouDebugPrint181[] = "Error: Subtrack no prg.\n";
|
||||
char shindouDebugPrint182[] = "ERR %x\n";
|
||||
char shindouDebugPrint183[] = "Note OverFlow %d\n";
|
||||
char shindouDebugPrint184[] = "trs %d , %d, %d\n";
|
||||
char shindouDebugPrint185[] = "Audio: Note:Velocity Error %d\n";
|
||||
char shindouDebugPrint186[] = "Audio:Track :Call Macro Level Over Error!\n";
|
||||
char shindouDebugPrint187[] = "Audio:Track :Loops Macro Level Over Error!\n";
|
||||
char shindouDebugPrint188[] = "SUB:ERR:BANK %d NOT CACHED.\n";
|
||||
char shindouDebugPrint189[] = "SUB:ERR:BANK %d NOT CACHED.\n";
|
||||
char shindouDebugPrint190[] = "Audio:Track: CTBLCALL Macro Level Over Error!\n";
|
||||
char shindouDebugPrint191[] = "Set Noise %d\n";
|
||||
char shindouDebugPrint192[] = "[%2x] \n";
|
||||
char shindouDebugPrint193[] = "Err :Sub %x ,address %x:Undefined SubTrack Function %x";
|
||||
char shindouDebugPrint194[] = "VoiceLoad Error Bank:%d,Prog:%d\n";
|
||||
char shindouDebugPrint195[] = "Disappear Sequence or Bank %d\n";
|
||||
char shindouDebugPrint196[] = "[FIN] group.\n";
|
||||
char shindouDebugPrint197[] = "Macro Level Over Error!\n";
|
||||
char shindouDebugPrint198[] = "Macro Level Over Error!\n";
|
||||
char shindouDebugPrint199[] = "Group:Undefine upper C0h command (%x)\n";
|
||||
char shindouDebugPrint200[] = "Group:Undefined Command\n";
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
#ifndef AUDIO_SEQPLAYER_H
|
||||
#define AUDIO_SEQPLAYER_H
|
||||
|
||||
#include <PR/ultratypes.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "playback.h"
|
||||
|
||||
void seq_channel_layer_disable(struct SequenceChannelLayer *seqPlayer);
|
||||
void sequence_channel_disable(struct SequenceChannel *seqPlayer);
|
||||
void sequence_player_disable(struct SequencePlayer* seqPlayer);
|
||||
void audio_list_push_back(struct AudioListItem *list, struct AudioListItem *item);
|
||||
void *audio_list_pop_back(struct AudioListItem *list);
|
||||
void process_sequences(s32 iterationsRemaining);
|
||||
void init_sequence_player(u32 player);
|
||||
void init_sequence_players(void);
|
||||
|
||||
#endif // AUDIO_SEQPLAYER_H
|
||||
@@ -0,0 +1,148 @@
|
||||
#include <ultra64.h>
|
||||
|
||||
#ifdef VERSION_SH
|
||||
// synthesis.c
|
||||
char shindouDebugPrint1[] = "Terminate-Canceled Channel %d,Phase %d\n";
|
||||
char shindouDebugPrint2[] = "S->W\n";
|
||||
char shindouDebugPrint3[] = "W->S\n";
|
||||
char shindouDebugPrint4[] = "S-Resample Pitch %x (old %d -> delay %d)\n";
|
||||
s32 shindouDebugPrintPadding1[] = {0,0,0};
|
||||
|
||||
// heap.c
|
||||
char shindouDebugPrint5[] = "Warning:Kill Note %x \n";
|
||||
char shindouDebugPrint6[] = "Kill Voice %d (ID %d) %d\n";
|
||||
char shindouDebugPrint7[] = "Warning: Running Sequence's data disappear!\n";
|
||||
char shindouDebugPrint8[] = "%x %x %x\n";
|
||||
char shindouDebugPrint9[] = "Audio:Memory:Heap OverFlow : Not Allocate %d!\n";
|
||||
char shindouDebugPrint10[] = "%x %x %x\n"; // Again
|
||||
char shindouDebugPrint11[] = "Audio:Memory:Heap OverFlow : Not Allocate %d!\n"; // Again
|
||||
char shindouDebugPrint12[] = "Audio:Memory:DataHeap Not Allocate \n";
|
||||
char shindouDebugPrint13[] = "StayHeap Not Allocate %d\n";
|
||||
char shindouDebugPrint14[] = "AutoHeap Not Allocate %d\n";
|
||||
char shindouDebugPrint15[] = "Status ID0 : %d ID1 : %d\n";
|
||||
char shindouDebugPrint16[] = "id 0 is Stopping\n";
|
||||
char shindouDebugPrint17[] = "id 0 is Stop\n";
|
||||
char shindouDebugPrint18[] = "id 1 is Stopping\n";
|
||||
char shindouDebugPrint19[] = "id 1 is Stop\n";
|
||||
char shindouDebugPrint20[] = "WARNING: NO FREE AUTOSEQ AREA.\n";
|
||||
char shindouDebugPrint21[] = "WARNING: NO STOP AUTO AREA.\n";
|
||||
char shindouDebugPrint22[] = " AND TRY FORCE TO STOP SIDE \n";
|
||||
char shindouDebugPrint23[] = "Check ID0 (seq ID %d) Useing ...\n";
|
||||
char shindouDebugPrint24[] = "Check ID1 (seq ID %d) Useing ...\n";
|
||||
char shindouDebugPrint25[] = "No Free Seq area.\n";
|
||||
char shindouDebugPrint26[] = "CH %d: ID %d\n";
|
||||
char shindouDebugPrint27[] = "TWO SIDES ARE LOADING... ALLOC CANCELED.\n";
|
||||
char shindouDebugPrint28[] = "WARNING: Before Area Overlaid After.";
|
||||
char shindouDebugPrint29[] = "WARNING: After Area Overlaid Before.";
|
||||
char shindouDebugPrint30[] = "MEMORY:SzHeapAlloc ERROR: sza->side %d\n";
|
||||
char shindouDebugPrint31[] = "Audio:MEMORY:SzHeap Overflow error. (%d bytes)\n";
|
||||
char shindouDebugPrint32[] = "Auto Heap Unhit for ID %d\n";
|
||||
char shindouDebugPrint33[] = "Heap Reconstruct Start %x\n";
|
||||
char shindouDebugPrint34[] = "---------------------------------------TEMPO %d %f\n";
|
||||
char shindouDebugPrint35[] = "%f \n";
|
||||
char shindouDebugPrint36[] = "%f \n"; // Again
|
||||
char shindouDebugPrint37[] = "AHPBASE %x\n";
|
||||
char shindouDebugPrint38[] = "AHPCUR %x\n";
|
||||
char shindouDebugPrint39[] = "HeapTop %x\n";
|
||||
char shindouDebugPrint40[] = "SynoutRate %d / %d \n";
|
||||
char shindouDebugPrint41[] = "FXSIZE %d\n";
|
||||
char shindouDebugPrint42[] = "FXCOMP %d\n";
|
||||
char shindouDebugPrint43[] = "FXDOWN %d\n";
|
||||
char shindouDebugPrint44[] = "WaveCacheLen: %d\n";
|
||||
char shindouDebugPrint45[] = "SpecChange Finished\n";
|
||||
char shindouDebugPrint46[] = "Warning:Emem Over,not alloc %d\n";
|
||||
char shindouDebugPrint47[] = "Single AutoSize %d\n";
|
||||
char shindouDebugPrint48[] = "Single Ptr %x\n";
|
||||
char shindouDebugPrint49[] = "Request--------Single-Auto, %d\n";
|
||||
char shindouDebugPrint50[] = "Retry %x, %x, len %x\n";
|
||||
char shindouDebugPrint51[] = "DMAing list %d is killed.\n";
|
||||
char shindouDebugPrint52[] = "Try Kill %d \n";
|
||||
char shindouDebugPrint53[] = "Try Kill %x %x\n";
|
||||
char shindouDebugPrint54[] = "Try Kill %x %x %x\n";
|
||||
char shindouDebugPrint55[] = "Rom back %x %x \n";
|
||||
char shindouDebugPrint56[] = "Error sw NULL \n";
|
||||
char shindouDebugPrint57[] = "Request--------Single-Stay, %d\n";
|
||||
char shindouDebugPrint58[] = "Try Kill %d \n";
|
||||
char shindouDebugPrint59[] = "Try Kill %x %x\n";
|
||||
char shindouDebugPrint60[] = "Try Kill %x %x %x\n";
|
||||
s32 shindouDebugPrintPadding[] = {0, 0, 0};
|
||||
|
||||
// load.c
|
||||
char shindouDebugPrint61[] = "CAUTION:WAVE CACHE FULL %d";
|
||||
char shindouDebugPrint62[] = "SUPERDMA";
|
||||
char shindouDebugPrint63[] = "Bank Change... top %d lba %d\n";
|
||||
char shindouDebugPrint64[] = "BankCount %d\n";
|
||||
char shindouDebugPrint65[] = "BANK LOAD MISS! FOR %d\n";
|
||||
char shindouDebugPrint66[] = "BankCount %d\n";
|
||||
char shindouDebugPrint67[] = "Flush Start\n";
|
||||
char shindouDebugPrint68[] = "%d ->%d\n";
|
||||
char shindouDebugPrint69[] = "useflag %d\n";
|
||||
char shindouDebugPrint70[] = "BankCount %d\n";
|
||||
char shindouDebugPrint71[] = "%2x ";
|
||||
char shindouDebugPrint72[] = "StartSeq (Group %d,Seq %d) Process finish\n";
|
||||
char shindouDebugPrint73[] = "LoadCtrl, Ptr %x and Media is %d\n";
|
||||
char shindouDebugPrint74[] = "Load Bank, Type %d , ID %d\n";
|
||||
char shindouDebugPrint75[] = "get auto\n";
|
||||
char shindouDebugPrint76[] = "get s-auto %x\n";
|
||||
char shindouDebugPrint77[] = "Seq %d Write ID OK %d!\n";
|
||||
char shindouDebugPrint78[] = "Banknumber %d\n";
|
||||
char shindouDebugPrint79[] = "Bank Offset %x %d %d\n";
|
||||
char shindouDebugPrint80[] = "PEP Touch %x \n";
|
||||
char shindouDebugPrint81[] = "FastCopy";
|
||||
char shindouDebugPrint82[] = "FastCopy";
|
||||
char shindouDebugPrint83[] = "Error: Cannot DMA Media [%d]\n";
|
||||
char shindouDebugPrint84[] = "Warning: size not align 16 %x (%s)\n";
|
||||
char shindouDebugPrint85[] = "Load Bank BG, Type %d , ID %d\n";
|
||||
char shindouDebugPrint86[] = "get auto\n";
|
||||
char shindouDebugPrint87[] = "get s-auto %x\n";
|
||||
char shindouDebugPrint88[] = "Clear Workarea %x -%x size %x \n";
|
||||
char shindouDebugPrint89[] = "AudioHeap is %x\n";
|
||||
char shindouDebugPrint90[] = "Heap reset.Synth Change %x \n";
|
||||
char shindouDebugPrint91[] = "Heap %x %x %x\n";
|
||||
char shindouDebugPrint92[] = "Main Heap Initialize.\n";
|
||||
char shindouDebugPrint93[] = "%d :WaveA %d WaveB %d Inst %d,Perc %d\n";
|
||||
char shindouDebugPrint94[] = "---------- Init Completed. ------------\n";
|
||||
char shindouDebugPrint95[] = " Syndrv :[%6d]\n";
|
||||
char shindouDebugPrint96[] = " Seqdrv :[%6d]\n";
|
||||
char shindouDebugPrint97[] = " audiodata :[%6d]\n";
|
||||
char shindouDebugPrint98[] = "---------------------------------------\n";
|
||||
char shindouDebugPrint99[] = "Entry--- %d %d\n";
|
||||
char shindouDebugPrint100[] = "---Block LPS here\n";
|
||||
char shindouDebugPrint101[] = "===Block LPS end\n";
|
||||
char shindouDebugPrint102[] = "SLOWCOPY";
|
||||
char shindouDebugPrint103[] = "Req: Src %x Dest %x Len %x,media %d,retcode %d\n";
|
||||
char shindouDebugPrint104[] = "Remain Size %d\n";
|
||||
char shindouDebugPrint105[] = "---Block BG here\n";
|
||||
char shindouDebugPrint106[] = "===Block BG end\n";
|
||||
char shindouDebugPrint107[] = "Retcode %x\n";
|
||||
char shindouDebugPrint108[] = "Other Type: Not Write ID.\n";
|
||||
char shindouDebugPrint109[] = "BGLOAD:Error: dma length 0\n";
|
||||
char shindouDebugPrint110[] = "BGCOPY";
|
||||
char shindouDebugPrint111[] = "Error: Already wavetable is touched %x.\n";
|
||||
char shindouDebugPrint112[] = "Touch Warning: Length zero %x\n";
|
||||
char shindouDebugPrint113[] = "It's busy now!!!!! %d\n"; // This one's my favorite
|
||||
char shindouDebugPrint114[] = "BG LOAD BUFFER is OVER.\n";
|
||||
char shindouDebugPrint115[] = "Warning: Length zero %x\n";
|
||||
char shindouDebugPrint116[] = "Wave Load %d \n";
|
||||
char shindouDebugPrint117[] = "Total Bg Wave Load %d \n";
|
||||
char shindouDebugPrint118[] = "Receive %d\n";
|
||||
char shindouDebugPrint119[] = "============Error: Magic is Broken after loading.\n";
|
||||
char shindouDebugPrint120[] = "Remain DMA: %d\n";
|
||||
char shindouDebugPrint121[] = "N start %d\n";
|
||||
char shindouDebugPrint122[] = "============Error: Magic is Broken: %x\n";
|
||||
char shindouDebugPrint123[] = "Error: No Handle.\n";
|
||||
char shindouDebugPrint124[] = "Success: %x\n";
|
||||
|
||||
// port_eu.c
|
||||
char shindouDebugPrint125[] = "DAC:Lost 1 Frame.\n";
|
||||
char shindouDebugPrint126[] = "DMA: Request queue over.( %d )\n";
|
||||
char shindouDebugPrint127[] = "Spec Change Override. %d -> %d\n";
|
||||
char shindouDebugPrint128[] = "Audio:now-max tasklen is %d / %d\n";
|
||||
char shindouDebugPrint129[] = "Audio:Warning:ABI Tasklist length over (%d)\n";
|
||||
s32 D_SH_80314FC8 = 0x80;
|
||||
struct SPTask *D_SH_80314FCC = NULL;
|
||||
char shindouDebugPrint130[] = "BGLOAD Start %d\n";
|
||||
char shindouDebugPrint131[] = "Error: OverFlow Your Request\n";
|
||||
char shindouDebugPrint132[] = "---AudioSending (%d->%d) \n";
|
||||
// These continue in unk_shindou_audio_file.c
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,99 @@
|
||||
#ifndef AUDIO_SYNTHESIS_H
|
||||
#define AUDIO_SYNTHESIS_H
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#ifdef VERSION_SH
|
||||
#define DEFAULT_LEN_1CH 0x180
|
||||
#define DEFAULT_LEN_2CH 0x300
|
||||
#else
|
||||
#define DEFAULT_LEN_1CH 0x140
|
||||
#define DEFAULT_LEN_2CH 0x280
|
||||
#endif
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
#define MAX_UPDATES_PER_FRAME 5
|
||||
#else
|
||||
#define MAX_UPDATES_PER_FRAME 4
|
||||
#endif
|
||||
|
||||
struct ReverbRingBufferItem
|
||||
{
|
||||
s16 numSamplesAfterDownsampling;
|
||||
s16 chunkLen; // never read
|
||||
s16 *toDownsampleLeft;
|
||||
s16 *toDownsampleRight; // data pointed to by left and right are adjacent in memory
|
||||
s32 startPos; // start pos in ring buffer
|
||||
s16 lengthA; // first length in ring buffer (from startPos, at most until end)
|
||||
s16 lengthB; // second length in ring buffer (from pos 0)
|
||||
}; // size = 0x14
|
||||
|
||||
struct SynthesisReverb
|
||||
{
|
||||
/*0x00, 0x00, 0x00*/ u8 resampleFlags;
|
||||
/*0x01, 0x01, 0x01*/ u8 useReverb;
|
||||
/*0x02, 0x02, 0x02*/ u8 framesLeftToIgnore;
|
||||
/*0x03, 0x03, 0x03*/ u8 curFrame;
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
/* 0x04, 0x04*/ u8 downsampleRate;
|
||||
#ifdef VERSION_SH
|
||||
/* 0x05*/ s8 unk5;
|
||||
#endif
|
||||
/* 0x06, 0x06*/ u16 windowSize; // same as bufSizePerChannel
|
||||
#endif
|
||||
#ifdef VERSION_SH
|
||||
/* 0x08*/ u16 unk08;
|
||||
#endif
|
||||
/*0x04, 0x08, 0x0A*/ u16 reverbGain;
|
||||
/*0x06, 0x0A, 0x0C*/ u16 resampleRate;
|
||||
#ifdef VERSION_SH
|
||||
/* 0x0E*/ u16 panRight;
|
||||
/* 0x10*/ u16 panLeft;
|
||||
#endif
|
||||
/*0x08, 0x0C, 0x14*/ s32 nextRingBufferPos;
|
||||
/*0x0C, 0x10, 0x18*/ s32 unkC; // never read
|
||||
/*0x10, 0x14, 0x1C*/ s32 bufSizePerChannel;
|
||||
struct
|
||||
{
|
||||
s16 *left;
|
||||
s16 *right;
|
||||
} ringBuffer;
|
||||
/*0x1C, 0x20, 0x28*/ s16 *resampleStateLeft;
|
||||
/*0x20, 0x24, 0x2C*/ s16 *resampleStateRight;
|
||||
/*0x24, 0x28, 0x30*/ s16 *unk24; // never read
|
||||
/*0x28, 0x2C, 0x34*/ s16 *unk28; // never read
|
||||
/*0x2C, 0x30, 0x38*/ struct ReverbRingBufferItem items[2][MAX_UPDATES_PER_FRAME];
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
// Only used in sh:
|
||||
/* 0x100*/ s16 *unk100;
|
||||
/* 0x104*/ s16 *unk104;
|
||||
/* 0x108*/ s16 *unk108;
|
||||
/* 0x10C*/ s16 *unk10C;
|
||||
#endif
|
||||
}; // 0xCC <= size <= 0x100
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
extern struct SynthesisReverb gSynthesisReverbs[4];
|
||||
extern s8 gNumSynthesisReverbs;
|
||||
extern struct NoteSubEu *gNoteSubsEu;
|
||||
extern f32 gLeftVolRampings[3][1024];
|
||||
extern f32 gRightVolRampings[3][1024];
|
||||
extern f32 *gCurrentLeftVolRamping; // Points to any of the three left buffers above
|
||||
extern f32 *gCurrentRightVolRamping; // Points to any of the three right buffers above
|
||||
#else
|
||||
extern struct SynthesisReverb gSynthesisReverb;
|
||||
#endif
|
||||
|
||||
#ifdef VERSION_SH
|
||||
extern s16 D_SH_803479B4;
|
||||
#endif
|
||||
|
||||
u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen);
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
void note_init_volume(struct Note *note);
|
||||
void note_set_vel_pan_reverb(struct Note *note, f32 velocity, f32 pan, u8 reverbVol);
|
||||
void note_set_frequency(struct Note *note, f32 frequency);
|
||||
void note_enable(struct Note *note);
|
||||
void note_disable(struct Note *note);
|
||||
#endif
|
||||
|
||||
#endif // AUDIO_SYNTHESIS_H
|
||||
@@ -0,0 +1,914 @@
|
||||
#ifdef VERSION_SH
|
||||
#include <ultra64.h>
|
||||
|
||||
#include "synthesis.h"
|
||||
#include "heap.h"
|
||||
#include "data.h"
|
||||
#include "load.h"
|
||||
#include "seqplayer.h"
|
||||
#include "internal.h"
|
||||
#include "external.h"
|
||||
|
||||
#ifndef TARGET_N64
|
||||
#include "../pc/mixer.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define DMEM_ADDR_TEMP 0x450
|
||||
#define DMEM_ADDR_RESAMPLED 0x470
|
||||
#define DMEM_ADDR_RESAMPLED2 0x5f0
|
||||
#define DMEM_ADDR_UNCOMPRESSED_NOTE 0x5f0
|
||||
#define DMEM_ADDR_NOTE_PAN_TEMP 0x650
|
||||
#define DMEM_ADDR_COMPRESSED_ADPCM_DATA 0x990
|
||||
#define DMEM_ADDR_LEFT_CH 0x990
|
||||
#define DMEM_ADDR_RIGHT_CH 0xb10
|
||||
#define DMEM_ADDR_WET_LEFT_CH 0xc90
|
||||
#define DMEM_ADDR_WET_RIGHT_CH 0xe10
|
||||
|
||||
#define aSetLoadBufferPair(pkt, c, off) \
|
||||
aSetBuffer(pkt, 0, c + DMEM_ADDR_WET_LEFT_CH, 0, DEFAULT_LEN_1CH - c); \
|
||||
aLoadBuffer(pkt, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.ringBuffer.left + (off))); \
|
||||
aSetBuffer(pkt, 0, c + DMEM_ADDR_WET_RIGHT_CH, 0, DEFAULT_LEN_1CH - c); \
|
||||
aLoadBuffer(pkt, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.ringBuffer.right + (off)))
|
||||
|
||||
#define aSetSaveBufferPair(pkt, c, d, off) \
|
||||
aSetBuffer(pkt, 0, 0, c + DMEM_ADDR_WET_LEFT_CH, d); \
|
||||
aSaveBuffer(pkt, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.ringBuffer.left + (off))); \
|
||||
aSetBuffer(pkt, 0, 0, c + DMEM_ADDR_WET_RIGHT_CH, d); \
|
||||
aSaveBuffer(pkt, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.ringBuffer.right + (off)));
|
||||
|
||||
#define ALIGN(val, amnt) (((val) + (1 << amnt) - 1) & ~((1 << amnt) - 1))
|
||||
|
||||
struct VolumeChange {
|
||||
u16 sourceLeft;
|
||||
u16 sourceRight;
|
||||
u16 targetLeft;
|
||||
u16 targetRight;
|
||||
};
|
||||
|
||||
u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex);
|
||||
u64 *synthesis_process_note(s32 noteIndex, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex);
|
||||
u64 *load_wave_samples(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s32 nSamplesToLoad);
|
||||
u64 *final_resample(u64 *cmd, struct NoteSynthesisState *synthesisState, s32 count, u16 pitch, u16 dmemIn, u32 flags);
|
||||
u64 *process_envelope(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s32 nSamples, u16 inBuf, s32 headsetPanSettings, u32 flags);
|
||||
u64 *note_apply_headset_pan_effects(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *note, s32 bufLen, s32 flags, s32 leftRight);
|
||||
|
||||
struct SynthesisReverb gSynthesisReverbs[4];
|
||||
u8 sAudioSynthesisPad[0x10];
|
||||
|
||||
s16 gVolume;
|
||||
s8 gUseReverb;
|
||||
s8 gNumSynthesisReverbs;
|
||||
s16 D_SH_803479B4; // contains 4096
|
||||
struct NoteSubEu *gNoteSubsEu;
|
||||
|
||||
// Equivalent functionality as the US/JP version,
|
||||
// just that the reverb structure is chosen from an array with index
|
||||
// Identical in EU.
|
||||
void prepare_reverb_ring_buffer(s32 chunkLen, u32 updateIndex, s32 reverbIndex) {
|
||||
struct ReverbRingBufferItem *item;
|
||||
struct SynthesisReverb *reverb = &gSynthesisReverbs[reverbIndex];
|
||||
s32 srcPos;
|
||||
s32 dstPos;
|
||||
s32 nSamples;
|
||||
s32 excessiveSamples;
|
||||
s32 UNUSED pad[3];
|
||||
if (reverb->downsampleRate != 1) {
|
||||
if (reverb->framesLeftToIgnore == 0) {
|
||||
// Now that the RSP has finished, downsample the samples produced two frames ago by skipping
|
||||
// samples.
|
||||
item = &reverb->items[reverb->curFrame][updateIndex];
|
||||
|
||||
// Touches both left and right since they are adjacent in memory
|
||||
osInvalDCache(item->toDownsampleLeft, DEFAULT_LEN_2CH);
|
||||
|
||||
for (srcPos = 0, dstPos = 0; dstPos < item->lengthA / 2;
|
||||
srcPos += reverb->downsampleRate, dstPos++) {
|
||||
reverb->ringBuffer.left[item->startPos + dstPos] =
|
||||
item->toDownsampleLeft[srcPos];
|
||||
reverb->ringBuffer.right[item->startPos + dstPos] =
|
||||
item->toDownsampleRight[srcPos];
|
||||
}
|
||||
for (dstPos = 0; dstPos < item->lengthB / 2; srcPos += reverb->downsampleRate, dstPos++) {
|
||||
reverb->ringBuffer.left[dstPos] = item->toDownsampleLeft[srcPos];
|
||||
reverb->ringBuffer.right[dstPos] = item->toDownsampleRight[srcPos];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item = &reverb->items[reverb->curFrame][updateIndex];
|
||||
nSamples = chunkLen / reverb->downsampleRate;
|
||||
excessiveSamples = (nSamples + reverb->nextRingBufferPos) - reverb->bufSizePerChannel;
|
||||
if (excessiveSamples < 0) {
|
||||
// There is space in the ring buffer before it wraps around
|
||||
item->lengthA = nSamples * 2;
|
||||
item->lengthB = 0;
|
||||
item->startPos = (s32) reverb->nextRingBufferPos;
|
||||
reverb->nextRingBufferPos += nSamples;
|
||||
} else {
|
||||
// Ring buffer wrapped around
|
||||
item->lengthA = (nSamples - excessiveSamples) * 2;
|
||||
item->lengthB = excessiveSamples * 2;
|
||||
item->startPos = reverb->nextRingBufferPos;
|
||||
reverb->nextRingBufferPos = excessiveSamples;
|
||||
}
|
||||
// These fields are never read later
|
||||
item->numSamplesAfterDownsampling = nSamples;
|
||||
item->chunkLen = chunkLen;
|
||||
}
|
||||
|
||||
u64 *synthesis_load_reverb_ring_buffer(u64 *cmd, u16 addr, u16 srcOffset, s32 len, s32 reverbIndex) {
|
||||
aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(&gSynthesisReverbs[reverbIndex].ringBuffer.left[srcOffset]),
|
||||
addr, len);
|
||||
aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(&gSynthesisReverbs[reverbIndex].ringBuffer.right[srcOffset]),
|
||||
addr + DEFAULT_LEN_1CH, len);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
u64 *synthesis_save_reverb_ring_buffer(u64 *cmd, u16 addr, u16 destOffset, s32 len, s32 reverbIndex) {
|
||||
aSaveBuffer(cmd++, addr,
|
||||
VIRTUAL_TO_PHYSICAL2(&gSynthesisReverbs[reverbIndex].ringBuffer.left[destOffset]), len);
|
||||
aSaveBuffer(cmd++, addr + DEFAULT_LEN_1CH,
|
||||
VIRTUAL_TO_PHYSICAL2(&gSynthesisReverbs[reverbIndex].ringBuffer.right[destOffset]), len);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void func_sh_802ed644(s32 updateIndexStart, s32 noteIndex) {
|
||||
s32 i;
|
||||
|
||||
for (i = updateIndexStart + 1; i < gAudioBufferParameters.updatesPerFrame; i++) {
|
||||
if (!gNoteSubsEu[gMaxSimultaneousNotes * i + noteIndex].needsInit) {
|
||||
gNoteSubsEu[gMaxSimultaneousNotes * i + noteIndex].enabled = FALSE;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void synthesis_load_note_subs_eu(s32 updateIndex) {
|
||||
struct NoteSubEu *src;
|
||||
struct NoteSubEu *dest;
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < gMaxSimultaneousNotes; i++) {
|
||||
src = &gNotes[i].noteSubEu;
|
||||
dest = &gNoteSubsEu[gMaxSimultaneousNotes * updateIndex + i];
|
||||
if (src->enabled) {
|
||||
*dest = *src;
|
||||
src->needsInit = FALSE;
|
||||
} else {
|
||||
dest->enabled = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: (Scrub C) pointless mask and whitespace
|
||||
u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen) {
|
||||
s32 i, j;
|
||||
u32 *aiBufPtr;
|
||||
u64 *cmd = cmdBuf;
|
||||
s32 chunkLen;
|
||||
|
||||
for (i = gAudioBufferParameters.updatesPerFrame; i > 0; i--) {
|
||||
process_sequences(i - 1);
|
||||
synthesis_load_note_subs_eu(gAudioBufferParameters.updatesPerFrame - i);
|
||||
}
|
||||
aiBufPtr = (u32 *) aiBuf;
|
||||
for (i = gAudioBufferParameters.updatesPerFrame; i > 0; i--) {
|
||||
if (i == 1) {
|
||||
chunkLen = bufLen;
|
||||
} else {
|
||||
if (bufLen / i >= gAudioBufferParameters.samplesPerUpdateMax) {
|
||||
chunkLen = gAudioBufferParameters.samplesPerUpdateMax;
|
||||
} else if (bufLen / i <= gAudioBufferParameters.samplesPerUpdateMin) {
|
||||
chunkLen = gAudioBufferParameters.samplesPerUpdateMin;
|
||||
} else {
|
||||
chunkLen = gAudioBufferParameters.samplesPerUpdate;
|
||||
}
|
||||
}
|
||||
for (j = 0; j < gNumSynthesisReverbs; j++) {
|
||||
if (gSynthesisReverbs[j].useReverb != 0) {
|
||||
prepare_reverb_ring_buffer(chunkLen, gAudioBufferParameters.updatesPerFrame - i, j);
|
||||
}
|
||||
}
|
||||
cmd = synthesis_do_one_audio_update((s16 *) aiBufPtr, chunkLen, cmd, gAudioBufferParameters.updatesPerFrame - i);
|
||||
bufLen -= chunkLen;
|
||||
aiBufPtr += chunkLen;
|
||||
}
|
||||
|
||||
for (j = 0; j < gNumSynthesisReverbs; j++) {
|
||||
if (gSynthesisReverbs[j].framesLeftToIgnore != 0) {
|
||||
gSynthesisReverbs[j].framesLeftToIgnore--;
|
||||
}
|
||||
gSynthesisReverbs[j].curFrame ^= 1;
|
||||
}
|
||||
*writtenCmds = cmd - cmdBuf;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
u64 *synthesis_resample_and_mix_reverb(u64 *cmd, s32 bufLen, s16 reverbIndex, s16 updateIndex) {
|
||||
struct ReverbRingBufferItem *item;
|
||||
s16 startPad;
|
||||
s16 paddedLengthA;
|
||||
|
||||
item = &gSynthesisReverbs[reverbIndex].items[gSynthesisReverbs[reverbIndex].curFrame][updateIndex];
|
||||
|
||||
if (gSynthesisReverbs[reverbIndex].downsampleRate == 1) {
|
||||
cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH, item->startPos, item->lengthA, reverbIndex);
|
||||
if (item->lengthB != 0) {
|
||||
cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH + item->lengthA, 0, item->lengthB, reverbIndex);
|
||||
}
|
||||
aAddMixer(cmd++, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_LEFT_CH, DEFAULT_LEN_2CH);
|
||||
aMix(cmd++, 0x8000 + gSynthesisReverbs[reverbIndex].reverbGain, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_2CH);
|
||||
} else {
|
||||
startPad = (item->startPos % 8u) * 2;
|
||||
paddedLengthA = ALIGN(startPad + item->lengthA, 4);
|
||||
|
||||
cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_RESAMPLED, (item->startPos - startPad / 2), DEFAULT_LEN_1CH, reverbIndex);
|
||||
if (item->lengthB != 0) {
|
||||
cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_RESAMPLED + paddedLengthA, 0, DEFAULT_LEN_1CH - paddedLengthA, reverbIndex);
|
||||
}
|
||||
|
||||
aSetBuffer(cmd++, 0, DMEM_ADDR_RESAMPLED + startPad, DMEM_ADDR_WET_LEFT_CH, bufLen * 2);
|
||||
aResample(cmd++, gSynthesisReverbs[reverbIndex].resampleFlags, gSynthesisReverbs[reverbIndex].resampleRate, VIRTUAL_TO_PHYSICAL2(gSynthesisReverbs[reverbIndex].resampleStateLeft));
|
||||
|
||||
aSetBuffer(cmd++, 0, DMEM_ADDR_RESAMPLED2 + startPad, DMEM_ADDR_WET_RIGHT_CH, bufLen * 2);
|
||||
aResample(cmd++, gSynthesisReverbs[reverbIndex].resampleFlags, gSynthesisReverbs[reverbIndex].resampleRate, VIRTUAL_TO_PHYSICAL2(gSynthesisReverbs[reverbIndex].resampleStateRight));
|
||||
|
||||
aAddMixer(cmd++, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_LEFT_CH, DEFAULT_LEN_2CH);
|
||||
aMix(cmd++, 0x8000 + gSynthesisReverbs[reverbIndex].reverbGain, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_2CH);
|
||||
}
|
||||
if (gSynthesisReverbs[reverbIndex].panRight != 0 || gSynthesisReverbs[reverbIndex].panLeft != 0) {
|
||||
// Leak some audio from the left reverb channel into the right reverb channel and vice versa (pan)
|
||||
aDMEMMove(cmd++, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_RESAMPLED, DEFAULT_LEN_1CH);
|
||||
aMix(cmd++, gSynthesisReverbs[reverbIndex].panRight, DMEM_ADDR_WET_RIGHT_CH, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_1CH);
|
||||
aMix(cmd++, gSynthesisReverbs[reverbIndex].panLeft, DMEM_ADDR_RESAMPLED, DMEM_ADDR_WET_RIGHT_CH, DEFAULT_LEN_1CH);
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
u64 *synthesis_load_reverb_samples(u64 *cmd, s16 reverbIndex, s16 updateIndex) {
|
||||
struct ReverbRingBufferItem *item;
|
||||
struct SynthesisReverb *reverb;
|
||||
|
||||
reverb = &gSynthesisReverbs[reverbIndex];
|
||||
item = &reverb->items[reverb->curFrame][updateIndex];
|
||||
// Get the oldest samples in the ring buffer into the wet channels
|
||||
cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_RESAMPLED, item->startPos, item->lengthA, reverbIndex);
|
||||
if (item->lengthB != 0) {
|
||||
// Ring buffer wrapped
|
||||
cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_RESAMPLED + item->lengthA, 0, item->lengthB, reverbIndex);
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
u64 *synthesis_save_reverb_samples(u64 *cmd, s16 reverbIndex, s16 updateIndex) {
|
||||
struct ReverbRingBufferItem *item;
|
||||
|
||||
item = &gSynthesisReverbs[reverbIndex].items[gSynthesisReverbs[reverbIndex].curFrame][updateIndex];
|
||||
switch (gSynthesisReverbs[reverbIndex].downsampleRate) {
|
||||
case 1:
|
||||
// Put the oldest samples in the ring buffer into the wet channels
|
||||
cmd = synthesis_save_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH, item->startPos, item->lengthA, reverbIndex);
|
||||
if (item->lengthB != 0) {
|
||||
// Ring buffer wrapped
|
||||
cmd = synthesis_save_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH + item->lengthA, 0, item->lengthB, reverbIndex);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Downsampling is done later by CPU when RSP is done, therefore we need to have double
|
||||
// buffering. Left and right buffers are adjacent in memory.
|
||||
aSaveBuffer(cmd++, DMEM_ADDR_WET_LEFT_CH,
|
||||
VIRTUAL_TO_PHYSICAL2(gSynthesisReverbs[reverbIndex].items[gSynthesisReverbs[reverbIndex].curFrame][updateIndex].toDownsampleLeft), DEFAULT_LEN_2CH);
|
||||
break;
|
||||
}
|
||||
gSynthesisReverbs[reverbIndex].resampleFlags = 0;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
u64 *func_sh_802EDF24(u64 *cmd, s16 reverbIndex, s16 updateIndex) {
|
||||
struct ReverbRingBufferItem *item;
|
||||
struct SynthesisReverb *reverb;
|
||||
|
||||
reverb = &gSynthesisReverbs[reverbIndex];
|
||||
item = &reverb->items[reverb->curFrame][updateIndex];
|
||||
// Put the oldest samples in the ring buffer into the wet channels
|
||||
cmd = synthesis_save_reverb_ring_buffer(cmd, DMEM_ADDR_RESAMPLED, item->startPos, item->lengthA, reverbIndex);
|
||||
if (item->lengthB != 0) {
|
||||
// Ring buffer wrapped
|
||||
cmd = synthesis_save_reverb_ring_buffer(cmd, DMEM_ADDR_RESAMPLED + item->lengthA, 0, item->lengthB, reverbIndex);
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex) {
|
||||
struct NoteSubEu *noteSubEu;
|
||||
u8 noteIndices[56];
|
||||
s32 temp;
|
||||
s32 i;
|
||||
s16 j;
|
||||
s16 notePos = 0;
|
||||
|
||||
if (gNumSynthesisReverbs == 0) {
|
||||
for (i = 0; i < gMaxSimultaneousNotes; i++) {
|
||||
if (gNoteSubsEu[gMaxSimultaneousNotes * updateIndex + i].enabled) {
|
||||
noteIndices[notePos++] = i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < gNumSynthesisReverbs; j++) {
|
||||
for (i = 0; i < gMaxSimultaneousNotes; i++) {
|
||||
noteSubEu = &gNoteSubsEu[gMaxSimultaneousNotes * updateIndex + i];
|
||||
if (noteSubEu->enabled && j == noteSubEu->reverbIndex) {
|
||||
noteIndices[notePos++] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < gMaxSimultaneousNotes; i++) {
|
||||
noteSubEu = &gNoteSubsEu[gMaxSimultaneousNotes * updateIndex + i];
|
||||
if (noteSubEu->enabled && noteSubEu->reverbIndex >= gNumSynthesisReverbs) {
|
||||
noteIndices[notePos++] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
aClearBuffer(cmd++, DMEM_ADDR_LEFT_CH, DEFAULT_LEN_2CH);
|
||||
i = 0;
|
||||
for (j = 0; j < gNumSynthesisReverbs; j++) {
|
||||
gUseReverb = gSynthesisReverbs[j].useReverb;
|
||||
if (gUseReverb != 0) {
|
||||
cmd = synthesis_resample_and_mix_reverb(cmd, bufLen, j, updateIndex);
|
||||
}
|
||||
for (; i < notePos; i++) {
|
||||
temp = updateIndex * gMaxSimultaneousNotes;
|
||||
if (j == gNoteSubsEu[temp + noteIndices[i]].reverbIndex) {
|
||||
cmd = synthesis_process_note(noteIndices[i],
|
||||
&gNoteSubsEu[temp + noteIndices[i]],
|
||||
&gNotes[noteIndices[i]].synthesisState,
|
||||
aiBuf, bufLen, cmd, updateIndex);
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gSynthesisReverbs[j].useReverb != 0) {
|
||||
if (gSynthesisReverbs[j].unk100 != NULL) {
|
||||
aFilter(cmd++, 0x02, bufLen * 2, gSynthesisReverbs[j].unk100);
|
||||
aFilter(cmd++, gSynthesisReverbs[j].resampleFlags, DMEM_ADDR_WET_LEFT_CH, gSynthesisReverbs[j].unk108);
|
||||
}
|
||||
if (gSynthesisReverbs[j].unk104 != NULL) {
|
||||
aFilter(cmd++, 0x02, bufLen * 2, gSynthesisReverbs[j].unk104);
|
||||
aFilter(cmd++, gSynthesisReverbs[j].resampleFlags, DMEM_ADDR_WET_RIGHT_CH, gSynthesisReverbs[j].unk10C);
|
||||
}
|
||||
cmd = synthesis_save_reverb_samples(cmd, j, updateIndex);
|
||||
if (gSynthesisReverbs[j].unk5 != -1) {
|
||||
if (gSynthesisReverbs[gSynthesisReverbs[j].unk5].downsampleRate == 1) {
|
||||
cmd = synthesis_load_reverb_samples(cmd, gSynthesisReverbs[j].unk5, updateIndex);
|
||||
aMix(cmd++, gSynthesisReverbs[j].unk08, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_RESAMPLED, DEFAULT_LEN_2CH);
|
||||
cmd = func_sh_802EDF24(cmd++, gSynthesisReverbs[j].unk5, updateIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (; i < notePos; i++) {
|
||||
struct NoteSubEu *noteSubEu2 = &gNoteSubsEu[updateIndex * gMaxSimultaneousNotes + noteIndices[i]];
|
||||
cmd = synthesis_process_note(noteIndices[i],
|
||||
noteSubEu2,
|
||||
&gNotes[noteIndices[i]].synthesisState,
|
||||
aiBuf, bufLen, cmd, updateIndex);
|
||||
}
|
||||
|
||||
temp = bufLen * 2;
|
||||
aInterleave(cmd++, DMEM_ADDR_TEMP, DMEM_ADDR_LEFT_CH, DMEM_ADDR_RIGHT_CH, temp);
|
||||
aSaveBuffer(cmd++, DMEM_ADDR_TEMP, VIRTUAL_TO_PHYSICAL2(aiBuf), temp * 2);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
u64 *synthesis_process_note(s32 noteIndex, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, UNUSED s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex) {
|
||||
UNUSED s32 pad0[3];
|
||||
struct AudioBankSample *audioBookSample; // sp164, sp138
|
||||
struct AdpcmLoop *loopInfo; // sp160, sp134
|
||||
s16 *curLoadedBook; // sp154, sp130
|
||||
UNUSED u8 padEU[0x04];
|
||||
UNUSED u8 pad8[0x04];
|
||||
s32 noteFinished; // 150 t2, sp124
|
||||
s32 restart; // 14c t3, sp120
|
||||
s32 flags; // sp148, sp11C, t8
|
||||
u16 resamplingRateFixedPoint; // sp5c, sp11A
|
||||
s32 nSamplesToLoad; //s0, Ec
|
||||
UNUSED u8 pad7[0x0c]; // sp100
|
||||
s32 sp130; //sp128, sp104
|
||||
UNUSED s32 tempBufLen;
|
||||
UNUSED u32 pad9;
|
||||
s32 t0;
|
||||
u8 *sampleAddr; // sp120, spF4
|
||||
s32 s6;
|
||||
s32 samplesLenAdjusted; // 108, spEC
|
||||
s32 nAdpcmSamplesProcessed; // signed required for US // spc0
|
||||
s32 endPos; // sp110, spE4
|
||||
s32 nSamplesToProcess; // sp10c/a0, spE0
|
||||
// Might have been used to store (samplesLenFixedPoint >> 0x10), but doing so causes strange
|
||||
// behavior with the break near the end of the loop, causing US and JP to need a goto instead
|
||||
UNUSED s32 samplesLenInt;
|
||||
s32 s2;
|
||||
s32 leftRight; //s0
|
||||
s32 s5; //s4
|
||||
u32 samplesLenFixedPoint; // v1_1
|
||||
s32 s3; // spA0
|
||||
s32 nSamplesInThisIteration; // v1_2
|
||||
u32 a3;
|
||||
u8 *v0_2;
|
||||
s32 unk_s6; // sp90
|
||||
s32 s5Aligned;
|
||||
s32 sp88;
|
||||
s32 sp84;
|
||||
u32 temp;
|
||||
s32 nParts; // spE8, spBC
|
||||
s32 curPart; // spE4, spB8
|
||||
s32 aligned;
|
||||
UNUSED u32 padSH1;
|
||||
s32 resampledTempLen; // spD8, spAC, sp6c
|
||||
u16 noteSamplesDmemAddrBeforeResampling; // spD6, spAA, sp6a -- 6C
|
||||
UNUSED u32 padSH2;
|
||||
UNUSED u32 padSH3;
|
||||
UNUSED u32 padSH4;
|
||||
struct Note *note; // sp58
|
||||
u16 sp56; // sp56
|
||||
u16 addr;
|
||||
u8 synthesisVolume;
|
||||
|
||||
curLoadedBook = NULL;
|
||||
note = &gNotes[noteIndex];
|
||||
flags = 0;
|
||||
if (noteSubEu->needsInit == TRUE) {
|
||||
flags = A_INIT;
|
||||
synthesisState->restart = 0;
|
||||
synthesisState->samplePosInt = 0;
|
||||
synthesisState->samplePosFrac = 0;
|
||||
synthesisState->curVolLeft = 0;
|
||||
synthesisState->curVolRight = 0;
|
||||
synthesisState->prevHeadsetPanRight = 0;
|
||||
synthesisState->prevHeadsetPanLeft = 0;
|
||||
synthesisState->reverbVol = noteSubEu->reverbVol;
|
||||
synthesisState->unk5 = 0;
|
||||
note->noteSubEu.finished = 0;
|
||||
}
|
||||
|
||||
resamplingRateFixedPoint = noteSubEu->resamplingRateFixedPoint;
|
||||
nParts = noteSubEu->hasTwoAdpcmParts + 1;
|
||||
samplesLenFixedPoint = (resamplingRateFixedPoint * bufLen * 2) + synthesisState->samplePosFrac;
|
||||
nSamplesToLoad = (samplesLenFixedPoint >> 0x10);
|
||||
synthesisState->samplePosFrac = samplesLenFixedPoint & 0xFFFF;
|
||||
|
||||
if ((synthesisState->unk5 == 1) && (nParts == 2)) {
|
||||
nSamplesToLoad += 2;
|
||||
sp56 = 2;
|
||||
} else if ((synthesisState->unk5 == 2) && (nParts == 1)) {
|
||||
nSamplesToLoad -= 4;
|
||||
sp56 = 4;
|
||||
} else {
|
||||
sp56 = 0;
|
||||
}
|
||||
|
||||
|
||||
synthesisState->unk5 = nParts;
|
||||
|
||||
if (noteSubEu->isSyntheticWave) {
|
||||
cmd = load_wave_samples(cmd, noteSubEu, synthesisState, nSamplesToLoad);
|
||||
noteSamplesDmemAddrBeforeResampling = (synthesisState->samplePosInt * 2) + DMEM_ADDR_UNCOMPRESSED_NOTE;
|
||||
synthesisState->samplePosInt += nSamplesToLoad;
|
||||
} else {
|
||||
// ADPCM note
|
||||
audioBookSample = noteSubEu->sound.audioBankSound->sample;
|
||||
loopInfo = audioBookSample->loop;
|
||||
endPos = loopInfo->end;
|
||||
sampleAddr = audioBookSample->sampleAddr;
|
||||
resampledTempLen = 0;
|
||||
for (curPart = 0; curPart < nParts; curPart++) {
|
||||
nAdpcmSamplesProcessed = 0; // s8
|
||||
s5 = 0; // s4
|
||||
|
||||
if (nParts == 1) {
|
||||
samplesLenAdjusted = nSamplesToLoad;
|
||||
} else if (nSamplesToLoad & 1) {
|
||||
samplesLenAdjusted = (nSamplesToLoad & ~1) + (curPart * 2);
|
||||
} else {
|
||||
samplesLenAdjusted = nSamplesToLoad;
|
||||
}
|
||||
|
||||
if (audioBookSample->codec == CODEC_ADPCM) {
|
||||
if (curLoadedBook != (*audioBookSample->book).book) {
|
||||
u32 nEntries;
|
||||
switch (noteSubEu->bookOffset) {
|
||||
case 1:
|
||||
curLoadedBook = euUnknownData_80301950 + 1;
|
||||
break;
|
||||
case 2:
|
||||
curLoadedBook = euUnknownData_80301950 + 2;
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
curLoadedBook = audioBookSample->book->book;
|
||||
break;
|
||||
}
|
||||
nEntries = 16 * audioBookSample->book->order * audioBookSample->book->npredictors;
|
||||
aLoadADPCM(cmd++, nEntries, VIRTUAL_TO_PHYSICAL2(curLoadedBook));
|
||||
}
|
||||
}
|
||||
|
||||
while (nAdpcmSamplesProcessed != samplesLenAdjusted) {
|
||||
s32 samplesRemaining; // v1
|
||||
s32 s0;
|
||||
|
||||
noteFinished = FALSE;
|
||||
restart = FALSE;
|
||||
s2 = synthesisState->samplePosInt & 0xf;
|
||||
samplesRemaining = endPos - synthesisState->samplePosInt;
|
||||
nSamplesToProcess = samplesLenAdjusted - nAdpcmSamplesProcessed;
|
||||
|
||||
if (s2 == 0 && synthesisState->restart == FALSE) {
|
||||
s2 = 16;
|
||||
}
|
||||
s6 = 16 - s2; // a1
|
||||
if (nSamplesToProcess < samplesRemaining) {
|
||||
t0 = (nSamplesToProcess - s6 + 0xf) / 16;
|
||||
s0 = t0 * 16;
|
||||
s3 = s6 + s0 - nSamplesToProcess;
|
||||
} else {
|
||||
s0 = samplesRemaining - s6;
|
||||
s3 = 0;
|
||||
if (s0 <= 0) {
|
||||
s0 = 0;
|
||||
s6 = samplesRemaining;
|
||||
}
|
||||
t0 = (s0 + 0xf) / 16;
|
||||
if (loopInfo->count != 0) {
|
||||
// Loop around and restart
|
||||
restart = 1;
|
||||
} else {
|
||||
noteFinished = 1;
|
||||
}
|
||||
}
|
||||
switch (audioBookSample->codec) {
|
||||
case CODEC_ADPCM:
|
||||
unk_s6 = 9;
|
||||
sp88 = 0x10;
|
||||
sp84 = 0;
|
||||
break;
|
||||
case CODEC_S8:
|
||||
unk_s6 = 0x10;
|
||||
sp88 = 0x10;
|
||||
sp84 = 0;
|
||||
break;
|
||||
case CODEC_SKIP: goto skip;
|
||||
}
|
||||
if (t0 != 0) {
|
||||
temp = (synthesisState->samplePosInt + sp88 - s2) / 16;
|
||||
if (audioBookSample->medium == 0) {
|
||||
v0_2 = sp84 + (temp * unk_s6) + sampleAddr;
|
||||
} else {
|
||||
v0_2 = dma_sample_data((uintptr_t)(sp84 + (temp * unk_s6) + sampleAddr),
|
||||
ALIGN(t0 * unk_s6 + 16, 4), flags, &synthesisState->sampleDmaIndex, audioBookSample->medium);
|
||||
}
|
||||
|
||||
a3 = ((uintptr_t)v0_2 & 0xf);
|
||||
aligned = ALIGN(t0 * unk_s6 + 16, 4);
|
||||
addr = (DMEM_ADDR_COMPRESSED_ADPCM_DATA - aligned) & 0xffff;
|
||||
aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(v0_2 - a3), addr, ALIGN(t0 * unk_s6 + 16, 4));
|
||||
} else {
|
||||
s0 = 0;
|
||||
a3 = 0;
|
||||
}
|
||||
if (synthesisState->restart != FALSE) {
|
||||
aSetLoop(cmd++, VIRTUAL_TO_PHYSICAL2(audioBookSample->loop->state));
|
||||
flags = A_LOOP; // = 2
|
||||
synthesisState->restart = FALSE;
|
||||
}
|
||||
nSamplesInThisIteration = s0 + s6 - s3;
|
||||
if (nAdpcmSamplesProcessed == 0) {
|
||||
switch (audioBookSample->codec) {
|
||||
case CODEC_ADPCM:
|
||||
aligned = ALIGN(t0 * unk_s6 + 16, 4);
|
||||
addr = (DMEM_ADDR_COMPRESSED_ADPCM_DATA - aligned) & 0xffff;
|
||||
aSetBuffer(cmd++, 0, addr + a3, DMEM_ADDR_UNCOMPRESSED_NOTE, s0 * 2);
|
||||
aADPCMdec(cmd++, flags, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->adpcmdecState));
|
||||
break;
|
||||
case CODEC_S8:
|
||||
aligned = ALIGN(t0 * unk_s6 + 16, 4);
|
||||
addr = (DMEM_ADDR_COMPRESSED_ADPCM_DATA - aligned) & 0xffff;
|
||||
aSetBuffer(cmd++, 0, addr + a3, DMEM_ADDR_UNCOMPRESSED_NOTE, s0 * 2);
|
||||
aS8Dec(cmd++, flags, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->adpcmdecState));
|
||||
break;
|
||||
}
|
||||
sp130 = s2 * 2;
|
||||
} else {
|
||||
s5Aligned = ALIGN(s5 + 16, 4);
|
||||
switch (audioBookSample->codec) {
|
||||
case CODEC_ADPCM:
|
||||
aligned = ALIGN(t0 * unk_s6 + 16, 4);
|
||||
addr = (DMEM_ADDR_COMPRESSED_ADPCM_DATA - aligned) & 0xffff;
|
||||
aSetBuffer(cmd++, 0, addr + a3, DMEM_ADDR_UNCOMPRESSED_NOTE + s5Aligned, s0 * 2);
|
||||
aADPCMdec(cmd++, flags, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->adpcmdecState));
|
||||
break;
|
||||
case CODEC_S8:
|
||||
aligned = ALIGN(t0 * unk_s6 + 16, 4);
|
||||
addr = (DMEM_ADDR_COMPRESSED_ADPCM_DATA - aligned) & 0xffff;
|
||||
aSetBuffer(cmd++, 0, addr + a3, DMEM_ADDR_UNCOMPRESSED_NOTE + s5Aligned, s0 * 2);
|
||||
aS8Dec(cmd++, flags, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->adpcmdecState));
|
||||
break;
|
||||
}
|
||||
aDMEMMove(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + s5Aligned + (s2 * 2), DMEM_ADDR_UNCOMPRESSED_NOTE + s5, (nSamplesInThisIteration) * 2);
|
||||
}
|
||||
nAdpcmSamplesProcessed += nSamplesInThisIteration;
|
||||
switch (flags) {
|
||||
case A_INIT: // = 1
|
||||
sp130 = 0x20;
|
||||
s5 = (s0 + 0x10) * 2;
|
||||
break;
|
||||
case A_LOOP: // = 2
|
||||
s5 = (nSamplesInThisIteration) * 2 + s5;
|
||||
break;
|
||||
default:
|
||||
if (s5 != 0) {
|
||||
s5 = (nSamplesInThisIteration) * 2 + s5;
|
||||
} else {
|
||||
s5 = (s2 + (nSamplesInThisIteration)) * 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
flags = 0;
|
||||
skip:
|
||||
if (noteFinished) {
|
||||
aClearBuffer(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + s5,
|
||||
(samplesLenAdjusted - nAdpcmSamplesProcessed) * 2);
|
||||
noteSubEu->finished = 1;
|
||||
note->noteSubEu.finished = 1;
|
||||
func_sh_802ed644(updateIndex, noteIndex);
|
||||
break;
|
||||
}
|
||||
if (restart != 0) {
|
||||
synthesisState->restart = TRUE;
|
||||
synthesisState->samplePosInt = loopInfo->start;
|
||||
} else {
|
||||
synthesisState->samplePosInt += nSamplesToProcess;
|
||||
}
|
||||
}
|
||||
|
||||
switch (nParts) {
|
||||
case 1:
|
||||
noteSamplesDmemAddrBeforeResampling = DMEM_ADDR_UNCOMPRESSED_NOTE + sp130;
|
||||
break;
|
||||
case 2:
|
||||
switch (curPart) {
|
||||
case 0:
|
||||
aDownsampleHalf(cmd++, ALIGN(samplesLenAdjusted / 2, 3), DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, DMEM_ADDR_RESAMPLED);
|
||||
resampledTempLen = samplesLenAdjusted;
|
||||
noteSamplesDmemAddrBeforeResampling = DMEM_ADDR_RESAMPLED;
|
||||
if (noteSubEu->finished != FALSE) {
|
||||
aClearBuffer(cmd++, noteSamplesDmemAddrBeforeResampling + resampledTempLen, samplesLenAdjusted + 0x10);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
aDownsampleHalf(cmd++, ALIGN(samplesLenAdjusted / 2, 3), DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, resampledTempLen + DMEM_ADDR_RESAMPLED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (noteSubEu->finished != FALSE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
flags = 0;
|
||||
if (noteSubEu->needsInit == TRUE) {
|
||||
flags = A_INIT;
|
||||
noteSubEu->needsInit = FALSE;
|
||||
}
|
||||
flags = flags | sp56;
|
||||
cmd = final_resample(cmd, synthesisState, bufLen * 2, resamplingRateFixedPoint,
|
||||
noteSamplesDmemAddrBeforeResampling, flags);
|
||||
if ((flags & 1) != 0) {
|
||||
flags = 1;
|
||||
}
|
||||
|
||||
if (noteSubEu->filter) {
|
||||
aFilter(cmd++, 0x02, bufLen * 2, noteSubEu->filter);
|
||||
aFilter(cmd++, flags, DMEM_ADDR_TEMP, synthesisState->synthesisBuffers->filterBuffer);
|
||||
|
||||
}
|
||||
|
||||
if (noteSubEu->bookOffset == 3) {
|
||||
aUnknown25(cmd++, 0, bufLen * 2, DMEM_ADDR_TEMP, DMEM_ADDR_TEMP);
|
||||
}
|
||||
|
||||
synthesisVolume = noteSubEu->synthesisVolume;
|
||||
if (synthesisVolume != 0) {
|
||||
if (synthesisVolume < 0x10) {
|
||||
synthesisVolume = 0x10;
|
||||
}
|
||||
|
||||
aHiLoGain(cmd++, synthesisVolume, (bufLen + 0x10) * 2, DMEM_ADDR_TEMP);
|
||||
}
|
||||
|
||||
if (noteSubEu->headsetPanRight != 0 || synthesisState->prevHeadsetPanRight != 0) {
|
||||
leftRight = 1;
|
||||
} else if (noteSubEu->headsetPanLeft != 0 || synthesisState->prevHeadsetPanLeft != 0) {
|
||||
leftRight = 2;
|
||||
} else {
|
||||
leftRight = 0;
|
||||
}
|
||||
cmd = process_envelope(cmd, noteSubEu, synthesisState, bufLen, DMEM_ADDR_TEMP, leftRight, flags);
|
||||
if (noteSubEu->usesHeadsetPanEffects) {
|
||||
if ((flags & 1) == 0) {
|
||||
flags = 0;
|
||||
}
|
||||
cmd = note_apply_headset_pan_effects(cmd, noteSubEu, synthesisState, bufLen * 2, flags, leftRight);
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
u64 *load_wave_samples(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s32 nSamplesToLoad) {
|
||||
s32 a3;
|
||||
s32 repeats;
|
||||
aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(noteSubEu->sound.samples),
|
||||
DMEM_ADDR_UNCOMPRESSED_NOTE, 128);
|
||||
|
||||
synthesisState->samplePosInt &= 0x3f;
|
||||
a3 = 64 - synthesisState->samplePosInt;
|
||||
if (a3 < nSamplesToLoad) {
|
||||
repeats = (nSamplesToLoad - a3 + 63) / 64;
|
||||
if (repeats != 0) {
|
||||
aDuplicate(cmd++,
|
||||
/*dmemin*/ DMEM_ADDR_UNCOMPRESSED_NOTE,
|
||||
/*dmemout*/ DMEM_ADDR_UNCOMPRESSED_NOTE + 128,
|
||||
/*copies*/ repeats);
|
||||
}
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
u64 *final_resample(u64 *cmd, struct NoteSynthesisState *synthesisState, s32 count, u16 pitch, u16 dmemIn, u32 flags) {
|
||||
if (pitch == 0) {
|
||||
aClearBuffer(cmd++, DMEM_ADDR_TEMP, count);
|
||||
} else {
|
||||
aSetBuffer(cmd++, /*flags*/ 0, dmemIn, /*dmemout*/ DMEM_ADDR_TEMP, count);
|
||||
aResample(cmd++, flags, pitch, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->finalResampleState));
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
u64 *process_envelope(u64 *cmd, struct NoteSubEu *note, struct NoteSynthesisState *synthesisState, s32 nSamples, u16 inBuf, s32 headsetPanSettings, UNUSED u32 flags) {
|
||||
u16 sourceRight;
|
||||
u16 sourceLeft;
|
||||
u16 targetLeft;
|
||||
u16 targetRight;
|
||||
s16 rampLeft;
|
||||
s16 rampRight;
|
||||
s32 sourceReverbVol;
|
||||
s16 rampReverb;
|
||||
s32 reverbVolDiff = 0;
|
||||
|
||||
sourceLeft = synthesisState->curVolLeft;
|
||||
sourceRight = synthesisState->curVolRight;
|
||||
targetLeft = note->targetVolLeft;
|
||||
targetRight = note->targetVolRight;
|
||||
targetLeft <<= 4;
|
||||
targetRight <<= 4;
|
||||
|
||||
if (targetLeft != sourceLeft) {
|
||||
rampLeft = (targetLeft - sourceLeft) / (nSamples >> 3);
|
||||
} else {
|
||||
rampLeft = 0;
|
||||
}
|
||||
if (targetRight != sourceRight) {
|
||||
rampRight = (targetRight - sourceRight) / (nSamples >> 3);
|
||||
} else {
|
||||
rampRight = 0;
|
||||
}
|
||||
|
||||
sourceReverbVol = synthesisState->reverbVol;
|
||||
if (note->reverbVol != sourceReverbVol) {
|
||||
reverbVolDiff = ((note->reverbVol & 0x7f) - (sourceReverbVol & 0x7f)) << 9;
|
||||
rampReverb = reverbVolDiff / (nSamples >> 3);
|
||||
synthesisState->reverbVol = note->reverbVol;
|
||||
} else {
|
||||
rampReverb = 0;
|
||||
}
|
||||
synthesisState->curVolLeft = sourceLeft + rampLeft * (nSamples >> 3);
|
||||
synthesisState->curVolRight = sourceRight + rampRight * (nSamples >> 3);
|
||||
|
||||
if (note->usesHeadsetPanEffects) {
|
||||
aClearBuffer(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, DEFAULT_LEN_1CH);
|
||||
aEnvSetup1(cmd++, (sourceReverbVol & 0x7f) * 2, rampReverb, rampLeft, rampRight);
|
||||
aEnvSetup2(cmd++, sourceLeft, sourceRight);
|
||||
|
||||
switch (headsetPanSettings) {
|
||||
case 1:
|
||||
aEnvMixer(cmd++,
|
||||
inBuf, nSamples,
|
||||
(sourceReverbVol & 0x80) >> 7,
|
||||
note->stereoStrongRight, note->stereoStrongLeft,
|
||||
DMEM_ADDR_NOTE_PAN_TEMP,
|
||||
DMEM_ADDR_RIGHT_CH,
|
||||
DMEM_ADDR_WET_LEFT_CH,
|
||||
DMEM_ADDR_WET_RIGHT_CH);
|
||||
break;
|
||||
case 2:
|
||||
aEnvMixer(cmd++,
|
||||
inBuf, nSamples,
|
||||
(sourceReverbVol & 0x80) >> 7,
|
||||
note->stereoStrongRight, note->stereoStrongLeft,
|
||||
DMEM_ADDR_LEFT_CH,
|
||||
DMEM_ADDR_NOTE_PAN_TEMP,
|
||||
DMEM_ADDR_WET_LEFT_CH,
|
||||
DMEM_ADDR_WET_RIGHT_CH);
|
||||
break;
|
||||
default:
|
||||
aEnvMixer(cmd++,
|
||||
inBuf, nSamples,
|
||||
(sourceReverbVol & 0x80) >> 7,
|
||||
note->stereoStrongRight, note->stereoStrongLeft,
|
||||
DMEM_ADDR_LEFT_CH,
|
||||
DMEM_ADDR_RIGHT_CH,
|
||||
DMEM_ADDR_WET_LEFT_CH,
|
||||
DMEM_ADDR_WET_RIGHT_CH);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
aEnvSetup1(cmd++, (sourceReverbVol & 0x7f) * 2, rampReverb, rampLeft, rampRight);
|
||||
aEnvSetup2(cmd++, sourceLeft, sourceRight);
|
||||
aEnvMixer(cmd++,
|
||||
inBuf, nSamples,
|
||||
(sourceReverbVol & 0x80) >> 7,
|
||||
note->stereoStrongRight, note->stereoStrongLeft,
|
||||
DMEM_ADDR_LEFT_CH,
|
||||
DMEM_ADDR_RIGHT_CH,
|
||||
DMEM_ADDR_WET_LEFT_CH,
|
||||
DMEM_ADDR_WET_RIGHT_CH);
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
u64 *note_apply_headset_pan_effects(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *note, s32 bufLen, s32 flags, s32 leftRight) {
|
||||
u16 dest;
|
||||
u16 pitch;
|
||||
u8 prevPanShift;
|
||||
u8 panShift;
|
||||
UNUSED u8 unkDebug;
|
||||
|
||||
switch (leftRight) {
|
||||
case 1:
|
||||
dest = DMEM_ADDR_LEFT_CH;
|
||||
panShift = noteSubEu->headsetPanRight;
|
||||
note->prevHeadsetPanLeft = 0;
|
||||
prevPanShift = note->prevHeadsetPanRight;
|
||||
note->prevHeadsetPanRight = panShift;
|
||||
break;
|
||||
case 2:
|
||||
dest = DMEM_ADDR_RIGHT_CH;
|
||||
panShift = noteSubEu->headsetPanLeft;
|
||||
note->prevHeadsetPanRight = 0;
|
||||
|
||||
prevPanShift = note->prevHeadsetPanLeft;
|
||||
note->prevHeadsetPanLeft = panShift;
|
||||
break;
|
||||
default:
|
||||
return cmd;
|
||||
}
|
||||
|
||||
if (flags != 1) { // A_INIT?
|
||||
// Slightly adjust the sample rate in order to fit a change in pan shift
|
||||
if (panShift != prevPanShift) {
|
||||
pitch = (((bufLen << 0xf) / 2) - 1) / ((bufLen + panShift - prevPanShift - 2) / 2);
|
||||
aSetBuffer(cmd++, 0, DMEM_ADDR_NOTE_PAN_TEMP, DMEM_ADDR_TEMP, (bufLen + panShift) - prevPanShift);
|
||||
aResampleZoh(cmd++, pitch, 0);
|
||||
} else {
|
||||
aDMEMMove(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, DMEM_ADDR_TEMP, bufLen);
|
||||
}
|
||||
|
||||
if (prevPanShift != 0) {
|
||||
aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panSamplesBuffer),
|
||||
DMEM_ADDR_NOTE_PAN_TEMP, ALIGN(prevPanShift, 4));
|
||||
aDMEMMove(cmd++, DMEM_ADDR_TEMP, DMEM_ADDR_NOTE_PAN_TEMP + prevPanShift, bufLen + panShift - prevPanShift);
|
||||
} else {
|
||||
aDMEMMove(cmd++, DMEM_ADDR_TEMP, DMEM_ADDR_NOTE_PAN_TEMP, bufLen + panShift);
|
||||
}
|
||||
} else {
|
||||
// Just shift right
|
||||
aDMEMMove(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, DMEM_ADDR_TEMP, bufLen);
|
||||
aClearBuffer(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, panShift);
|
||||
aDMEMMove(cmd++, DMEM_ADDR_TEMP, DMEM_ADDR_NOTE_PAN_TEMP + panShift, bufLen);
|
||||
}
|
||||
|
||||
if (panShift) {
|
||||
// Save excessive samples for next iteration
|
||||
aSaveBuffer(cmd++, DMEM_ADDR_NOTE_PAN_TEMP + bufLen,
|
||||
VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panSamplesBuffer), ALIGN(panShift, 4));
|
||||
}
|
||||
|
||||
aAddMixer(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, dest, (bufLen + 0x3f) & 0xffc0);
|
||||
|
||||
return cmd;
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
#ifndef _ULTRA64_LIBAUDIO_H_
|
||||
#define _ULTRA64_LIBAUDIO_H_
|
||||
|
||||
#include "abi.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 *offset __attribute__((aligned (8)));
|
||||
s32 len __attribute__((aligned (8)));
|
||||
} ALSeqData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short revision;
|
||||
unsigned short seqCount;
|
||||
unsigned int pad;
|
||||
ALSeqData seqArray[1];
|
||||
} __attribute__((aligned (16))) ALSeqFile;
|
||||
|
||||
void alSeqFileNew(ALSeqFile *f, u8 *base);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef _LIBULTRA_H
|
||||
#define _LIBULTRA_H
|
||||
|
||||
#define TV_TYPE_NTSC 1
|
||||
#define TV_TYPE_PAL 0
|
||||
#define TV_TYPE_MPAL 2
|
||||
|
||||
#define RESET_TYPE_COLD_RESET 0
|
||||
#define RESET_TYPE_NMI 1
|
||||
#define RESET_TYPE_BOOT_DISK 2
|
||||
|
||||
extern u32 osTvType;
|
||||
extern u32 osRomBase;
|
||||
extern u32 osResetType;
|
||||
extern u32 osMemSize;
|
||||
extern u8 osAppNmiBuffer[64];
|
||||
|
||||
#endif /* _LIBULTRA_H */
|
||||
@@ -0,0 +1,800 @@
|
||||
|
||||
/*====================================================================
|
||||
* os.h
|
||||
*
|
||||
* Copyright 1995, Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics,
|
||||
* Inc.; the contents of this file may not be disclosed to third
|
||||
* parties, copied or duplicated in any form, in whole or in part,
|
||||
* without the prior written permission of Silicon Graphics, Inc.
|
||||
*
|
||||
* RESTRICTED RIGHTS LEGEND:
|
||||
* Use, duplication or disclosure by the Government is subject to
|
||||
* restrictions as set forth in subdivision (c)(1)(ii) of the Rights
|
||||
* in Technical Data and Computer Software clause at DFARS
|
||||
* 252.227-7013, and/or in similar or successor clauses in the FAR,
|
||||
* DOD or NASA FAR Supplement. Unpublished - rights reserved under the
|
||||
* Copyright Laws of the United States.
|
||||
*====================================================================*/
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* $Revision: 1.149 $
|
||||
* $Date: 1997/12/15 04:30:52 $
|
||||
* $Source: /disk6/Master/cvsmdev2/PR/include/os.h,v $
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifndef _OS_H_
|
||||
#define _OS_H_
|
||||
|
||||
#ifdef _LANGUAGE_C_PLUS_PLUS
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ultratypes.h"
|
||||
#include "PR/os_message.h"
|
||||
|
||||
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Type definitions
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Structure for device manager block
|
||||
*/
|
||||
typedef struct {
|
||||
s32 active; /* Status flag */
|
||||
OSThread *thread; /* Calling thread */
|
||||
OSMesgQueue *cmdQueue; /* Command queue */
|
||||
OSMesgQueue *evtQueue; /* Event queue */
|
||||
OSMesgQueue *acsQueue; /* Access queue */
|
||||
/* Raw DMA routine */
|
||||
s32 (*dma)(s32, u32, void *, u32);
|
||||
s32 (*edma)(OSPiHandle *, s32, u32, void *, u32);
|
||||
} OSDevMgr;
|
||||
|
||||
/*
|
||||
* Structure for file system
|
||||
*/
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
int status;
|
||||
OSMesgQueue *queue;
|
||||
int channel;
|
||||
u8 id[32];
|
||||
u8 label[32];
|
||||
int version;
|
||||
int dir_size;
|
||||
int inode_table; /* block location */
|
||||
int minode_table; /* mirrioring inode_table */
|
||||
int dir_table; /* block location */
|
||||
int inode_start_page; /* page # */
|
||||
u8 banks;
|
||||
u8 activebank;
|
||||
} OSPfs;
|
||||
|
||||
|
||||
typedef struct {
|
||||
u32 file_size; /* bytes */
|
||||
u32 game_code;
|
||||
u16 company_code;
|
||||
char ext_name[4];
|
||||
char game_name[16];
|
||||
} OSPfsState;
|
||||
|
||||
/*
|
||||
* Structure for Profiler
|
||||
*/
|
||||
typedef struct {
|
||||
u16 *histo_base; /* histogram base */
|
||||
u32 histo_size; /* histogram size */
|
||||
u32 *text_start; /* start of text segment */
|
||||
u32 *text_end; /* end of text segment */
|
||||
} OSProf;
|
||||
|
||||
#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Global definitions
|
||||
*
|
||||
*/
|
||||
|
||||
/* Thread states */
|
||||
|
||||
#define OS_STATE_STOPPED 1
|
||||
#define OS_STATE_RUNNABLE 2
|
||||
#define OS_STATE_RUNNING 4
|
||||
#define OS_STATE_WAITING 8
|
||||
|
||||
/* Events */
|
||||
#ifdef _FINALROM
|
||||
#define OS_NUM_EVENTS 15
|
||||
#else
|
||||
#define OS_NUM_EVENTS 23
|
||||
#endif
|
||||
|
||||
#define OS_EVENT_SW1 0 /* CPU SW1 interrupt */
|
||||
#define OS_EVENT_SW2 1 /* CPU SW2 interrupt */
|
||||
#define OS_EVENT_CART 2 /* Cartridge interrupt: used by rmon */
|
||||
#define OS_EVENT_COUNTER 3 /* Counter int: used by VI/Timer Mgr */
|
||||
#define OS_EVENT_SP 4 /* SP task done interrupt */
|
||||
#define OS_EVENT_SI 5 /* SI (controller) interrupt */
|
||||
#define OS_EVENT_AI 6 /* AI interrupt */
|
||||
#define OS_EVENT_VI 7 /* VI interrupt: used by VI/Timer Mgr */
|
||||
#define OS_EVENT_PI 8 /* PI interrupt: used by PI Manager */
|
||||
#define OS_EVENT_DP 9 /* DP full sync interrupt */
|
||||
#define OS_EVENT_CPU_BREAK 10 /* CPU breakpoint: used by rmon */
|
||||
#define OS_EVENT_SP_BREAK 11 /* SP breakpoint: used by rmon */
|
||||
#define OS_EVENT_FAULT 12 /* CPU fault event: used by rmon */
|
||||
#define OS_EVENT_THREADSTATUS 13 /* CPU thread status: used by rmon */
|
||||
#define OS_EVENT_PRENMI 14 /* Pre NMI interrupt */
|
||||
#ifndef _FINALROM
|
||||
#define OS_EVENT_RDB_READ_DONE 15 /* RDB read ok event: used by rmon */
|
||||
#define OS_EVENT_RDB_LOG_DONE 16 /* read of log data complete */
|
||||
#define OS_EVENT_RDB_DATA_DONE 17 /* read of hostio data complete */
|
||||
#define OS_EVENT_RDB_REQ_RAMROM 18 /* host needs ramrom access */
|
||||
#define OS_EVENT_RDB_FREE_RAMROM 19 /* host is done with ramrom access */
|
||||
#define OS_EVENT_RDB_DBG_DONE 20
|
||||
#define OS_EVENT_RDB_FLUSH_PROF 21
|
||||
#define OS_EVENT_RDB_ACK_PROF 22
|
||||
#endif
|
||||
|
||||
/* Flags for debugging purpose */
|
||||
|
||||
#define OS_FLAG_CPU_BREAK 1 /* Break exception has occurred */
|
||||
#define OS_FLAG_FAULT 2 /* CPU fault has occurred */
|
||||
|
||||
/* Interrupt masks */
|
||||
|
||||
#define OS_IM_NONE 0x00000001
|
||||
#define OS_IM_SW1 0x00000501
|
||||
#define OS_IM_SW2 0x00000601
|
||||
#define OS_IM_CART 0x00000c01
|
||||
#define OS_IM_PRENMI 0x00001401
|
||||
#define OS_IM_RDBWRITE 0x00002401
|
||||
#define OS_IM_RDBREAD 0x00004401
|
||||
#define OS_IM_COUNTER 0x00008401
|
||||
#define OS_IM_CPU 0x0000ff01
|
||||
#define OS_IM_SP 0x00010401
|
||||
#define OS_IM_SI 0x00020401
|
||||
#define OS_IM_AI 0x00040401
|
||||
#define OS_IM_VI 0x00080401
|
||||
#define OS_IM_PI 0x00100401
|
||||
#define OS_IM_DP 0x00200401
|
||||
#define OS_IM_ALL 0x003fff01
|
||||
#define RCP_IMASK 0x003f0000
|
||||
#define RCP_IMASKSHIFT 16
|
||||
|
||||
/* Recommended thread priorities for the system threads */
|
||||
|
||||
#define OS_PRIORITY_MAX 255
|
||||
#define OS_PRIORITY_VIMGR 254
|
||||
#define OS_PRIORITY_RMON 250
|
||||
#define OS_PRIORITY_RMONSPIN 200
|
||||
#define OS_PRIORITY_PIMGR 150
|
||||
#define OS_PRIORITY_SIMGR 140
|
||||
#define OS_PRIORITY_APPMAX 127
|
||||
#define OS_PRIORITY_IDLE 0 /* Must be 0 */
|
||||
|
||||
|
||||
/* Flags to turn blocking on/off when sending/receiving message */
|
||||
|
||||
#define OS_MESG_NOBLOCK 0
|
||||
#define OS_MESG_BLOCK 1
|
||||
|
||||
/* Flags to indicate direction of data transfer */
|
||||
|
||||
#define OS_READ 0 /* device -> RDRAM */
|
||||
#define OS_WRITE 1 /* device <- RDRAM */
|
||||
#define OS_OTHERS 2 /* for Leo disk only */
|
||||
|
||||
/*
|
||||
* I/O message types
|
||||
*/
|
||||
#define OS_MESG_TYPE_BASE (10)
|
||||
#define OS_MESG_TYPE_LOOPBACK (OS_MESG_TYPE_BASE+0)
|
||||
#define OS_MESG_TYPE_DMAREAD (OS_MESG_TYPE_BASE+1)
|
||||
#define OS_MESG_TYPE_DMAWRITE (OS_MESG_TYPE_BASE+2)
|
||||
#define OS_MESG_TYPE_VRETRACE (OS_MESG_TYPE_BASE+3)
|
||||
#define OS_MESG_TYPE_COUNTER (OS_MESG_TYPE_BASE+4)
|
||||
#define OS_MESG_TYPE_EDMAREAD (OS_MESG_TYPE_BASE+5)
|
||||
#define OS_MESG_TYPE_EDMAWRITE (OS_MESG_TYPE_BASE+6)
|
||||
|
||||
/*
|
||||
* I/O message priority
|
||||
*/
|
||||
#define OS_MESG_PRI_NORMAL 0
|
||||
#define OS_MESG_PRI_HIGH 1
|
||||
|
||||
/*
|
||||
* Page size argument for TLB routines
|
||||
*/
|
||||
#define OS_PM_4K 0x0000000
|
||||
#define OS_PM_16K 0x0006000
|
||||
#define OS_PM_64K 0x001e000
|
||||
#define OS_PM_256K 0x007e000
|
||||
#define OS_PM_1M 0x01fe000
|
||||
#define OS_PM_4M 0x07fe000
|
||||
#define OS_PM_16M 0x1ffe000
|
||||
|
||||
/*
|
||||
* Stack size for I/O device managers: PIM (PI Manager), VIM (VI Manager),
|
||||
* SIM (SI Manager)
|
||||
*
|
||||
*/
|
||||
#define OS_PIM_STACKSIZE 4096
|
||||
#define OS_VIM_STACKSIZE 4096
|
||||
#define OS_SIM_STACKSIZE 4096
|
||||
|
||||
#define OS_MIN_STACKSIZE 72
|
||||
|
||||
/*
|
||||
* Values for osTvType
|
||||
*/
|
||||
#define OS_TV_PAL 0
|
||||
#define OS_TV_NTSC 1
|
||||
#define OS_TV_MPAL 2
|
||||
|
||||
/*
|
||||
* Video Interface (VI) mode type
|
||||
*/
|
||||
#define OS_VI_NTSC_LPN1 0 /* NTSC */
|
||||
#define OS_VI_NTSC_LPF1 1
|
||||
#define OS_VI_NTSC_LAN1 2
|
||||
#define OS_VI_NTSC_LAF1 3
|
||||
#define OS_VI_NTSC_LPN2 4
|
||||
#define OS_VI_NTSC_LPF2 5
|
||||
#define OS_VI_NTSC_LAN2 6
|
||||
#define OS_VI_NTSC_LAF2 7
|
||||
#define OS_VI_NTSC_HPN1 8
|
||||
#define OS_VI_NTSC_HPF1 9
|
||||
#define OS_VI_NTSC_HAN1 10
|
||||
#define OS_VI_NTSC_HAF1 11
|
||||
#define OS_VI_NTSC_HPN2 12
|
||||
#define OS_VI_NTSC_HPF2 13
|
||||
|
||||
#define OS_VI_PAL_LPN1 14 /* PAL */
|
||||
#define OS_VI_PAL_LPF1 15
|
||||
#define OS_VI_PAL_LAN1 16
|
||||
#define OS_VI_PAL_LAF1 17
|
||||
#define OS_VI_PAL_LPN2 18
|
||||
#define OS_VI_PAL_LPF2 19
|
||||
#define OS_VI_PAL_LAN2 20
|
||||
#define OS_VI_PAL_LAF2 21
|
||||
#define OS_VI_PAL_HPN1 22
|
||||
#define OS_VI_PAL_HPF1 23
|
||||
#define OS_VI_PAL_HAN1 24
|
||||
#define OS_VI_PAL_HAF1 25
|
||||
#define OS_VI_PAL_HPN2 26
|
||||
#define OS_VI_PAL_HPF2 27
|
||||
|
||||
#define OS_VI_MPAL_LPN1 28 /* MPAL - mainly Brazil */
|
||||
#define OS_VI_MPAL_LPF1 29
|
||||
#define OS_VI_MPAL_LAN1 30
|
||||
#define OS_VI_MPAL_LAF1 31
|
||||
#define OS_VI_MPAL_LPN2 32
|
||||
#define OS_VI_MPAL_LPF2 33
|
||||
#define OS_VI_MPAL_LAN2 34
|
||||
#define OS_VI_MPAL_LAF2 35
|
||||
#define OS_VI_MPAL_HPN1 36
|
||||
#define OS_VI_MPAL_HPF1 37
|
||||
#define OS_VI_MPAL_HAN1 38
|
||||
#define OS_VI_MPAL_HAF1 39
|
||||
#define OS_VI_MPAL_HPN2 40
|
||||
#define OS_VI_MPAL_HPF2 41
|
||||
|
||||
/*
|
||||
* Video Interface (VI) special features
|
||||
*/
|
||||
#define OS_VI_GAMMA_ON 0x0001
|
||||
#define OS_VI_GAMMA_OFF 0x0002
|
||||
#define OS_VI_GAMMA_DITHER_ON 0x0004
|
||||
#define OS_VI_GAMMA_DITHER_OFF 0x0008
|
||||
#define OS_VI_DIVOT_ON 0x0010
|
||||
#define OS_VI_DIVOT_OFF 0x0020
|
||||
#define OS_VI_DITHER_FILTER_ON 0x0040
|
||||
#define OS_VI_DITHER_FILTER_OFF 0x0080
|
||||
|
||||
/*
|
||||
* Video Interface (VI) mode attribute bit
|
||||
*/
|
||||
#define OS_VI_BIT_NONINTERLACE 0x0001 /* lo-res */
|
||||
#define OS_VI_BIT_INTERLACE 0x0002 /* lo-res */
|
||||
#define OS_VI_BIT_NORMALINTERLACE 0x0004 /* hi-res */
|
||||
#define OS_VI_BIT_DEFLICKINTERLACE 0x0008 /* hi-res */
|
||||
#define OS_VI_BIT_ANTIALIAS 0x0010
|
||||
#define OS_VI_BIT_POINTSAMPLE 0x0020
|
||||
#define OS_VI_BIT_16PIXEL 0x0040
|
||||
#define OS_VI_BIT_32PIXEL 0x0080
|
||||
#define OS_VI_BIT_LORES 0x0100
|
||||
#define OS_VI_BIT_HIRES 0x0200
|
||||
#define OS_VI_BIT_NTSC 0x0400
|
||||
#define OS_VI_BIT_PAL 0x0800
|
||||
|
||||
/*
|
||||
* Leo Disk
|
||||
*/
|
||||
|
||||
/* transfer mode */
|
||||
|
||||
#define LEO_BLOCK_MODE 1
|
||||
#define LEO_TRACK_MODE 2
|
||||
#define LEO_SECTOR_MODE 3
|
||||
|
||||
/*
|
||||
* Controllers number
|
||||
*/
|
||||
|
||||
#ifndef _HW_VERSION_1
|
||||
#define MAXCONTROLLERS 4
|
||||
#else
|
||||
#define MAXCONTROLLERS 6
|
||||
#endif
|
||||
|
||||
/* controller errors */
|
||||
#define CONT_NO_RESPONSE_ERROR 0x8
|
||||
#define CONT_OVERRUN_ERROR 0x4
|
||||
#ifdef _HW_VERSION_1
|
||||
#define CONT_FRAME_ERROR 0x2
|
||||
#define CONT_COLLISION_ERROR 0x1
|
||||
#endif
|
||||
|
||||
/* Controller type */
|
||||
|
||||
#define CONT_ABSOLUTE 0x0001
|
||||
#define CONT_RELATIVE 0x0002
|
||||
#define CONT_JOYPORT 0x0004
|
||||
#define CONT_EEPROM 0x8000
|
||||
#define CONT_EEP16K 0x4000
|
||||
#define CONT_TYPE_MASK 0x1f07
|
||||
#define CONT_TYPE_NORMAL 0x0005
|
||||
#define CONT_TYPE_MOUSE 0x0002
|
||||
|
||||
/* Controller status */
|
||||
|
||||
#define CONT_CARD_ON 0x01
|
||||
#define CONT_CARD_PULL 0x02
|
||||
#define CONT_ADDR_CRC_ER 0x04
|
||||
#define CONT_EEPROM_BUSY 0x80
|
||||
|
||||
/* EEPROM TYPE */
|
||||
|
||||
#define EEPROM_TYPE_4K 0x01
|
||||
#define EEPROM_TYPE_16K 0x02
|
||||
|
||||
/* Buttons */
|
||||
|
||||
#define CONT_A 0x8000
|
||||
#define CONT_B 0x4000
|
||||
#define CONT_G 0x2000
|
||||
#define CONT_START 0x1000
|
||||
#define CONT_UP 0x0800
|
||||
#define CONT_DOWN 0x0400
|
||||
#define CONT_LEFT 0x0200
|
||||
#define CONT_RIGHT 0x0100
|
||||
#define CONT_L 0x0020
|
||||
#define CONT_R 0x0010
|
||||
#define CONT_E 0x0008
|
||||
#define CONT_D 0x0004
|
||||
#define CONT_C 0x0002
|
||||
#define CONT_F 0x0001
|
||||
|
||||
/* Nintendo's official button names */
|
||||
|
||||
#define A_BUTTON CONT_A
|
||||
#define B_BUTTON CONT_B
|
||||
#define L_TRIG CONT_L
|
||||
#define R_TRIG CONT_R
|
||||
#define Z_TRIG CONT_G
|
||||
#define START_BUTTON CONT_START
|
||||
#define U_JPAD CONT_UP
|
||||
#define L_JPAD CONT_LEFT
|
||||
#define R_JPAD CONT_RIGHT
|
||||
#define D_JPAD CONT_DOWN
|
||||
#define U_CBUTTONS CONT_E
|
||||
#define L_CBUTTONS CONT_C
|
||||
#define R_CBUTTONS CONT_F
|
||||
#define D_CBUTTONS CONT_D
|
||||
|
||||
/* File System size */
|
||||
#define OS_PFS_VERSION 0x0200
|
||||
#define OS_PFS_VERSION_HI (OS_PFS_VERSION >> 8)
|
||||
#define OS_PFS_VERSION_LO (OS_PFS_VERSION & 255)
|
||||
|
||||
#define PFS_FILE_NAME_LEN 16
|
||||
#define PFS_FILE_EXT_LEN 4
|
||||
#define BLOCKSIZE 32 /* bytes */
|
||||
#define PFS_ONE_PAGE 8 /* blocks */
|
||||
#define PFS_MAX_BANKS 62
|
||||
|
||||
/* File System flag */
|
||||
|
||||
#define PFS_READ 0
|
||||
#define PFS_WRITE 1
|
||||
#define PFS_CREATE 2
|
||||
|
||||
/* File System status */
|
||||
#define PFS_INITIALIZED 0x1
|
||||
#define PFS_CORRUPTED 0x2 /* File system was corrupted */
|
||||
|
||||
/* File System error number */
|
||||
|
||||
#define PFS_ERR_NOPACK 1 /* no memory card is plugged or */
|
||||
#define PFS_ERR_NEW_PACK 2 /* ram pack has been changed to a */
|
||||
/* different one */
|
||||
#define PFS_ERR_INCONSISTENT 3 /* need to run Pfschecker */
|
||||
#define PFS_ERR_CONTRFAIL CONT_OVERRUN_ERROR
|
||||
#define PFS_ERR_INVALID 5 /* invalid parameter or file not exist*/
|
||||
#define PFS_ERR_BAD_DATA 6 /* the data read from pack are bad*/
|
||||
#define PFS_DATA_FULL 7 /* no free pages on ram pack */
|
||||
#define PFS_DIR_FULL 8 /* no free directories on ram pack*/
|
||||
#define PFS_ERR_EXIST 9 /* file exists */
|
||||
#define PFS_ERR_ID_FATAL 10 /* dead ram pack */
|
||||
#define PFS_ERR_DEVICE 11 /* wrong device type*/
|
||||
|
||||
/* definition for EEPROM */
|
||||
|
||||
#define EEPROM_MAXBLOCKS 64
|
||||
#define EEP16K_MAXBLOCKS 256
|
||||
#define EEPROM_BLOCK_SIZE 8
|
||||
|
||||
/*
|
||||
* PI/EPI
|
||||
*/
|
||||
#define PI_DOMAIN1 0
|
||||
#define PI_DOMAIN2 1
|
||||
|
||||
/*
|
||||
* Profiler constants
|
||||
*/
|
||||
#define PROF_MIN_INTERVAL 50 /* microseconds */
|
||||
|
||||
/*
|
||||
* Boot addresses
|
||||
*/
|
||||
#define BOOT_ADDRESS_ULTRA 0x80000400
|
||||
#define BOOT_ADDRESS_COSIM 0x80002000
|
||||
#define BOOT_ADDRESS_EMU 0x20010000
|
||||
#define BOOT_ADDRESS_INDY 0x88100000
|
||||
|
||||
/*
|
||||
* Size of buffer the retains contents after NMI
|
||||
*/
|
||||
#define OS_APP_NMI_BUFSIZE 64
|
||||
|
||||
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Macro definitions
|
||||
*
|
||||
*/
|
||||
|
||||
/* PARTNER-N64 */
|
||||
#ifdef PTN64
|
||||
#define osReadHost osReadHost_pt
|
||||
#define osWriteHost osWriteHost_pt
|
||||
#endif
|
||||
|
||||
/* Get count of valid messages in queue */
|
||||
#define MQ_GET_COUNT(mq) ((mq)->validCount)
|
||||
|
||||
/* Figure out if message queue is empty or full */
|
||||
#define MQ_IS_EMPTY(mq) (MQ_GET_COUNT(mq) == 0)
|
||||
#define MQ_IS_FULL(mq) (MQ_GET_COUNT(mq) >= (mq)->msgCount)
|
||||
|
||||
/*
|
||||
* CPU counter increments at 3/4 of bus clock rate:
|
||||
*
|
||||
* Bus Clock Proc Clock Counter (1/2 Proc Clock)
|
||||
* --------- ---------- ------------------------
|
||||
* 62.5 Mhz 93.75 Mhz 46.875 Mhz
|
||||
*/
|
||||
extern u64 osClockRate;
|
||||
|
||||
#define OS_CLOCK_RATE 62500000LL
|
||||
#define OS_CPU_COUNTER (OS_CLOCK_RATE*3/4)
|
||||
#define OS_NSEC_TO_CYCLES(n) (((u64)(n)*(OS_CPU_COUNTER/15625000LL))/(1000000000LL/15625000LL))
|
||||
#define OS_USEC_TO_CYCLES(n) (((u64)(n)*(OS_CPU_COUNTER/15625LL))/(1000000LL/15625LL))
|
||||
#define OS_CYCLES_TO_NSEC(c) (((u64)(c)*(1000000000LL/15625000LL))/(OS_CPU_COUNTER/15625000LL))
|
||||
#define OS_CYCLES_TO_USEC(c) (((u64)(c)*(1000000LL/15625LL))/(OS_CPU_COUNTER/15625LL))
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Extern variables
|
||||
*
|
||||
*/
|
||||
extern OSViMode osViModeTable[]; /* Global VI mode table */
|
||||
|
||||
extern OSViMode osViModeNtscLpn1; /* Individual VI NTSC modes */
|
||||
extern OSViMode osViModeNtscLpf1;
|
||||
extern OSViMode osViModeNtscLan1;
|
||||
extern OSViMode osViModeNtscLaf1;
|
||||
extern OSViMode osViModeNtscLpn2;
|
||||
extern OSViMode osViModeNtscLpf2;
|
||||
extern OSViMode osViModeNtscLan2;
|
||||
extern OSViMode osViModeNtscLaf2;
|
||||
extern OSViMode osViModeNtscHpn1;
|
||||
extern OSViMode osViModeNtscHpf1;
|
||||
extern OSViMode osViModeNtscHan1;
|
||||
extern OSViMode osViModeNtscHaf1;
|
||||
extern OSViMode osViModeNtscHpn2;
|
||||
extern OSViMode osViModeNtscHpf2;
|
||||
|
||||
extern OSViMode osViModePalLpn1; /* Individual VI PAL modes */
|
||||
extern OSViMode osViModePalLpf1;
|
||||
extern OSViMode osViModePalLan1;
|
||||
extern OSViMode osViModePalLaf1;
|
||||
extern OSViMode osViModePalLpn2;
|
||||
extern OSViMode osViModePalLpf2;
|
||||
extern OSViMode osViModePalLan2;
|
||||
extern OSViMode osViModePalLaf2;
|
||||
extern OSViMode osViModePalHpn1;
|
||||
extern OSViMode osViModePalHpf1;
|
||||
extern OSViMode osViModePalHan1;
|
||||
extern OSViMode osViModePalHaf1;
|
||||
extern OSViMode osViModePalHpn2;
|
||||
extern OSViMode osViModePalHpf2;
|
||||
|
||||
extern OSViMode osViModeMpalLpn1; /* Individual VI MPAL modes */
|
||||
extern OSViMode osViModeMpalLpf1;
|
||||
extern OSViMode osViModeMpalLan1;
|
||||
extern OSViMode osViModeMpalLaf1;
|
||||
extern OSViMode osViModeMpalLpn2;
|
||||
extern OSViMode osViModeMpalLpf2;
|
||||
extern OSViMode osViModeMpalLan2;
|
||||
extern OSViMode osViModeMpalLaf2;
|
||||
extern OSViMode osViModeMpalHpn1;
|
||||
extern OSViMode osViModeMpalHpf1;
|
||||
extern OSViMode osViModeMpalHan1;
|
||||
extern OSViMode osViModeMpalHaf1;
|
||||
extern OSViMode osViModeMpalHpn2;
|
||||
extern OSViMode osViModeMpalHpf2;
|
||||
|
||||
extern s32 osRomType; /* Bulk or cartridge ROM. 0=cartridge 1=bulk */
|
||||
extern u32 osRomBase; /* Rom base address of the game image */
|
||||
extern u32 osTvType; /* 0 = PAL, 1 = NTSC, 2 = MPAL */
|
||||
extern u32 osResetType; /* 0 = cold reset, 1 = NMI */
|
||||
extern s32 osCicId;
|
||||
extern s32 osVersion;
|
||||
extern u32 osMemSize; /* Memory Size */
|
||||
extern s32 osAppNMIBuffer[];
|
||||
|
||||
extern OSIntMask __OSGlobalIntMask; /* global interrupt mask */
|
||||
extern OSPiHandle *__osPiTable; /* The head of OSPiHandle link list */
|
||||
extern OSPiHandle *__osDiskHandle; /* For exceptasm to get disk info*/
|
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Function prototypes
|
||||
*
|
||||
*/
|
||||
|
||||
/* Thread operations */
|
||||
|
||||
extern void osCreateThread(OSThread *, OSId, void (*)(void *),
|
||||
void *, void *, OSPri);
|
||||
extern void osDestroyThread(OSThread *);
|
||||
extern void osYieldThread(void);
|
||||
extern void osStartThread(OSThread *);
|
||||
extern void osStopThread(OSThread *);
|
||||
extern OSId osGetThreadId(OSThread *);
|
||||
extern void osSetThreadPri(OSThread *, OSPri);
|
||||
extern OSPri osGetThreadPri(OSThread *);
|
||||
|
||||
/* Message operations */
|
||||
|
||||
extern void osCreateMesgQueue(OSMesgQueue *, OSMesg *, s32);
|
||||
extern s32 osSendMesg(OSMesgQueue *, OSMesg, s32);
|
||||
extern s32 osJamMesg(OSMesgQueue *, OSMesg, s32);
|
||||
extern s32 osRecvMesg(OSMesgQueue *, OSMesg *, s32);
|
||||
|
||||
/* Event operations */
|
||||
|
||||
extern void osSetEventMesg(OSEvent, OSMesgQueue *, OSMesg);
|
||||
|
||||
/* Interrupt operations */
|
||||
|
||||
extern OSIntMask osGetIntMask(void);
|
||||
extern OSIntMask osSetIntMask(OSIntMask);
|
||||
|
||||
/* RDB port operations */
|
||||
|
||||
extern void osInitRdb(u8 *sendBuf, u32 sendSize);
|
||||
|
||||
/* Cache operations and macros */
|
||||
|
||||
extern void osInvalDCache(void *, size_t);
|
||||
extern void osInvalICache(void *, size_t);
|
||||
extern void osWritebackDCache(void *, size_t);
|
||||
extern void osWritebackDCacheAll(void);
|
||||
|
||||
#define OS_DCACHE_ROUNDUP_ADDR(x) (void *)(((((u32)(x)+0xf)/0x10)*0x10))
|
||||
#define OS_DCACHE_ROUNDUP_SIZE(x) (u32)(((((u32)(x)+0xf)/0x10)*0x10))
|
||||
|
||||
/* TLB management routines */
|
||||
|
||||
extern void osMapTLB(s32, OSPageMask, void *, u32, u32, s32);
|
||||
extern void osMapTLBRdb(void);
|
||||
extern void osUnmapTLB(s32);
|
||||
extern void osUnmapTLBAll(void);
|
||||
extern void osSetTLBASID(s32);
|
||||
|
||||
/* Address translation routines and macros */
|
||||
|
||||
extern u32 osVirtualToPhysical(void *);
|
||||
extern void * osPhysicalToVirtual(u32);
|
||||
|
||||
#define OS_K0_TO_PHYSICAL(x) (u32)(((char *)(x)-0x80000000))
|
||||
#define OS_K1_TO_PHYSICAL(x) (u32)(((char *)(x)-0xa0000000))
|
||||
|
||||
#define OS_PHYSICAL_TO_K0(x) (void *)(((u32)(x)+0x80000000))
|
||||
#define OS_PHYSICAL_TO_K1(x) (void *)(((u32)(x)+0xa0000000))
|
||||
|
||||
/* I/O operations */
|
||||
|
||||
/* Audio interface (Ai) */
|
||||
extern u32 osAiGetStatus(void);
|
||||
extern u32 osAiGetLength(void);
|
||||
extern s32 osAiSetFrequency(u32);
|
||||
extern s32 osAiSetNextBuffer(void *, u32);
|
||||
|
||||
/* Display processor interface (Dp) */
|
||||
extern u32 osDpGetStatus(void);
|
||||
extern void osDpSetStatus(u32);
|
||||
extern void osDpGetCounters(u32 *);
|
||||
extern s32 osDpSetNextBuffer(void *, u64);
|
||||
|
||||
/* Peripheral interface (Pi) */
|
||||
extern u32 osPiGetStatus(void);
|
||||
extern s32 osPiGetDeviceType(void);
|
||||
extern s32 osPiRawWriteIo(u32, u32);
|
||||
extern s32 osPiRawReadIo(u32, u32 *);
|
||||
extern s32 osPiRawStartDma(s32, u32, void *, u32);
|
||||
extern s32 osPiWriteIo(u32, u32);
|
||||
extern s32 osPiReadIo(u32, u32 *);
|
||||
extern s32 osPiStartDma(OSIoMesg *, s32, s32, u32, void *, u32,
|
||||
OSMesgQueue *);
|
||||
extern void osCreatePiManager(OSPri, OSMesgQueue *, OSMesg *, s32);
|
||||
|
||||
/* Video interface (Vi) */
|
||||
extern u32 osViGetStatus(void);
|
||||
extern u32 osViGetCurrentMode(void);
|
||||
extern u32 osViGetCurrentLine(void);
|
||||
extern u32 osViGetCurrentField(void);
|
||||
extern void *osViGetCurrentFramebuffer(void);
|
||||
extern void *osViGetNextFramebuffer(void);
|
||||
extern void osViSetXScale(f32);
|
||||
extern void osViSetYScale(f32);
|
||||
extern void osViSetSpecialFeatures(u32);
|
||||
extern void osViSetMode(OSViMode *);
|
||||
extern void osViSetEvent(OSMesgQueue *, OSMesg, u32);
|
||||
extern void osViSwapBuffer(void *);
|
||||
extern void osViBlack(u8);
|
||||
extern void osViFade(u8, u16);
|
||||
extern void osViRepeatLine(u8);
|
||||
extern void osCreateViManager(OSPri);
|
||||
|
||||
/* Timer interface */
|
||||
|
||||
extern OSTime osGetTime(void);
|
||||
extern void osSetTime(OSTime);
|
||||
extern u32 osSetTimer(OSTimer *, OSTime, OSTime,
|
||||
OSMesgQueue *, OSMesg);
|
||||
extern int osStopTimer(OSTimer *);
|
||||
|
||||
/* Controller interface */
|
||||
|
||||
extern s32 osContInit(OSMesgQueue *, u8 *, OSContStatus *);
|
||||
extern s32 osContReset(OSMesgQueue *, OSContStatus *);
|
||||
extern s32 osContStartQuery(OSMesgQueue *);
|
||||
extern s32 osContStartReadData(OSMesgQueue *);
|
||||
#ifndef _HW_VERSION_1
|
||||
extern s32 osContSetCh(u8);
|
||||
#endif
|
||||
extern void osContGetQuery(OSContStatus *);
|
||||
extern void osContGetReadData(OSContPad *);
|
||||
|
||||
/* file system interface */
|
||||
|
||||
extern s32 osPfsInitPak(OSMesgQueue *, OSPfs *, int);
|
||||
extern s32 osPfsRepairId(OSPfs *);
|
||||
extern s32 osPfsInit(OSMesgQueue *, OSPfs *, int);
|
||||
extern s32 osPfsReFormat(OSPfs *, OSMesgQueue *, int);
|
||||
extern s32 osPfsChecker(OSPfs *);
|
||||
extern s32 osPfsAllocateFile(OSPfs *, u16, u32, u8 *, u8 *, int, s32 *);
|
||||
extern s32 osPfsFindFile(OSPfs *, u16, u32, u8 *, u8 *, s32 *);
|
||||
extern s32 osPfsDeleteFile(OSPfs *, u16, u32, u8 *, u8 *);
|
||||
extern s32 osPfsReadWriteFile(OSPfs *, s32, u8, int, int, u8 *);
|
||||
extern s32 osPfsFileState(OSPfs *, s32, OSPfsState *);
|
||||
extern s32 osPfsGetLabel(OSPfs *, u8 *, int *);
|
||||
extern s32 osPfsSetLabel(OSPfs *, u8 *);
|
||||
extern s32 osPfsIsPlug(OSMesgQueue *, u8 *);
|
||||
extern s32 osPfsFreeBlocks(OSPfs *, s32 *);
|
||||
extern s32 osPfsNumFiles(OSPfs *, s32 *, s32 *);
|
||||
|
||||
/* EEPROM interface */
|
||||
|
||||
extern s32 osEepromProbe(OSMesgQueue *);
|
||||
extern s32 osEepromRead(OSMesgQueue *, u8, u8 *);
|
||||
extern s32 osEepromWrite(OSMesgQueue *, u8, u8 *);
|
||||
extern s32 osEepromLongRead(OSMesgQueue *, u8, u8 *, int);
|
||||
extern s32 osEepromLongWrite(OSMesgQueue *, u8, u8 *, int);
|
||||
|
||||
/* MOTOR interface */
|
||||
|
||||
extern s32 osMotorInit(OSMesgQueue *, OSPfs *, int);
|
||||
extern s32 osMotorStop(OSPfs *);
|
||||
extern s32 osMotorStart(OSPfs *);
|
||||
|
||||
/* Enhanced PI interface */
|
||||
|
||||
extern OSPiHandle *osCartRomInit(void);
|
||||
extern OSPiHandle *osLeoDiskInit(void);
|
||||
extern OSPiHandle *osDriveRomInit(void);
|
||||
|
||||
extern s32 osEPiDeviceType(OSPiHandle *, OSPiInfo *);
|
||||
extern s32 osEPiRawWriteIo(OSPiHandle *, u32 , u32);
|
||||
extern s32 osEPiRawReadIo(OSPiHandle *, u32 , u32 *);
|
||||
extern s32 osEPiRawStartDma(OSPiHandle *, s32 , u32 , void *, u32 );
|
||||
extern s32 osEPiWriteIo(OSPiHandle *, u32 , u32 );
|
||||
extern s32 osEPiReadIo(OSPiHandle *, u32 , u32 *);
|
||||
extern s32 osEPiStartDma(OSPiHandle *, OSIoMesg *, s32);
|
||||
extern s32 osEPiLinkHandle(OSPiHandle *);
|
||||
|
||||
/* Profiler Interface */
|
||||
|
||||
extern void osProfileInit(OSProf *, u32 profcnt);
|
||||
extern void osProfileStart(u32);
|
||||
extern void osProfileFlush(void);
|
||||
extern void osProfileStop(void);
|
||||
|
||||
/* Game <> Host data transfer functions */
|
||||
|
||||
extern s32 osTestHost(void);
|
||||
extern void osReadHost(void *, u32);
|
||||
extern void osWriteHost(void *, u32);
|
||||
extern void osAckRamromRead(void);
|
||||
extern void osAckRamromWrite(void);
|
||||
|
||||
|
||||
/* byte string operations */
|
||||
|
||||
extern void bcopy(const void *, void *, size_t);
|
||||
extern int bcmp(const void *, const void *, int);
|
||||
extern void bzero(void *, size_t);
|
||||
|
||||
/* Miscellaneous operations */
|
||||
|
||||
extern void osInitialize(void);
|
||||
extern u32 osGetCount(void);
|
||||
extern void osExit(void);
|
||||
extern u32 osGetMemSize(void);
|
||||
|
||||
/* Printf */
|
||||
|
||||
extern int sprintf(char *s, const char *fmt, ...);
|
||||
extern void osSyncPrintf(const char *fmt, ...);
|
||||
extern void osAsyncPrintf(const char *fmt, ...);
|
||||
extern int osSyncGetChars(char *buf);
|
||||
extern int osAsyncGetChars(char *buf);
|
||||
|
||||
#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */
|
||||
|
||||
#ifdef _LANGUAGE_C_PLUS_PLUS
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_OS_H */
|
||||
@@ -0,0 +1,92 @@
|
||||
|
||||
/*====================================================================
|
||||
* os_ai.h
|
||||
*
|
||||
* Copyright 1995, Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics,
|
||||
* Inc.; the contents of this file may not be disclosed to third
|
||||
* parties, copied or duplicated in any form, in whole or in part,
|
||||
* without the prior written permission of Silicon Graphics, Inc.
|
||||
*
|
||||
* RESTRICTED RIGHTS LEGEND:
|
||||
* Use, duplication or disclosure by the Government is subject to
|
||||
* restrictions as set forth in subdivision (c)(1)(ii) of the Rights
|
||||
* in Technical Data and Computer Software clause at DFARS
|
||||
* 252.227-7013, and/or in similar or successor clauses in the FAR,
|
||||
* DOD or NASA FAR Supplement. Unpublished - rights reserved under the
|
||||
* Copyright Laws of the United States.
|
||||
*====================================================================*/
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
Copyright (C) 1998 Nintendo. (Originated by SGI)
|
||||
|
||||
$RCSfile: os_ai.h,v $
|
||||
$Revision: 1.1 $
|
||||
$Date: 1998/10/09 08:01:04 $
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _OS_AI_H_
|
||||
#define _OS_AI_H_
|
||||
|
||||
#ifdef _LANGUAGE_C_PLUS_PLUS
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ultratypes.h"
|
||||
|
||||
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Type definitions
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Global definitions
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Macro definitions
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Extern variables
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Function prototypes
|
||||
*
|
||||
*/
|
||||
|
||||
/* Audio interface (Ai) */
|
||||
extern u32 osAiGetStatus(void);
|
||||
extern u32 osAiGetLength(void);
|
||||
extern s32 osAiSetFrequency(u32);
|
||||
extern s32 osAiSetNextBuffer(void *, u32);
|
||||
|
||||
|
||||
#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */
|
||||
|
||||
#ifdef _LANGUAGE_C_PLUS_PLUS
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_OS_AI_H_ */
|
||||
@@ -0,0 +1,96 @@
|
||||
|
||||
/*====================================================================
|
||||
* os_cache.h
|
||||
*
|
||||
* Copyright 1995, Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics,
|
||||
* Inc.; the contents of this file may not be disclosed to third
|
||||
* parties, copied or duplicated in any form, in whole or in part,
|
||||
* without the prior written permission of Silicon Graphics, Inc.
|
||||
*
|
||||
* RESTRICTED RIGHTS LEGEND:
|
||||
* Use, duplication or disclosure by the Government is subject to
|
||||
* restrictions as set forth in subdivision (c)(1)(ii) of the Rights
|
||||
* in Technical Data and Computer Software clause at DFARS
|
||||
* 252.227-7013, and/or in similar or successor clauses in the FAR,
|
||||
* DOD or NASA FAR Supplement. Unpublished - rights reserved under the
|
||||
* Copyright Laws of the United States.
|
||||
*====================================================================*/
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
Copyright (C) 1998 Nintendo. (Originated by SGI)
|
||||
|
||||
$RCSfile: os_cache.h,v $
|
||||
$Revision: 1.1 $
|
||||
$Date: 1998/10/09 08:01:04 $
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _OS_CACHE_H_
|
||||
#define _OS_CACHE_H_
|
||||
|
||||
#ifdef _LANGUAGE_C_PLUS_PLUS
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ultratypes.h"
|
||||
|
||||
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Type definitions
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Global definitions
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Macro definitions
|
||||
*
|
||||
*/
|
||||
|
||||
#define OS_DCACHE_ROUNDUP_ADDR(x) (void *)(((((u32)(x)+0xf)/0x10)*0x10))
|
||||
#define OS_DCACHE_ROUNDUP_SIZE(x) (u32)(((((u32)(x)+0xf)/0x10)*0x10))
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Extern variables
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Function prototypes
|
||||
*
|
||||
*/
|
||||
|
||||
/* Cache operations and macros */
|
||||
|
||||
extern void osInvalDCache(void *, size_t);
|
||||
extern void osInvalICache(void *, size_t);
|
||||
extern void osWritebackDCache(void *, size_t);
|
||||
extern void osWritebackDCacheAll(void);
|
||||
|
||||
|
||||
#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */
|
||||
|
||||
#ifdef _LANGUAGE_C_PLUS_PLUS
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_OS_CACHE_H_ */
|
||||
@@ -0,0 +1,107 @@
|
||||
|
||||
/*====================================================================
|
||||
* os_eeprom.h
|
||||
*
|
||||
* Copyright 1995, Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics,
|
||||
* Inc.; the contents of this file may not be disclosed to third
|
||||
* parties, copied or duplicated in any form, in whole or in part,
|
||||
* without the prior written permission of Silicon Graphics, Inc.
|
||||
*
|
||||
* RESTRICTED RIGHTS LEGEND:
|
||||
* Use, duplication or disclosure by the Government is subject to
|
||||
* restrictions as set forth in subdivision (c)(1)(ii) of the Rights
|
||||
* in Technical Data and Computer Software clause at DFARS
|
||||
* 252.227-7013, and/or in similar or successor clauses in the FAR,
|
||||
* DOD or NASA FAR Supplement. Unpublished - rights reserved under the
|
||||
* Copyright Laws of the United States.
|
||||
*====================================================================*/
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
Copyright (C) 1998 Nintendo. (Originated by SGI)
|
||||
|
||||
$RCSfile: os_eeprom.h,v $
|
||||
$Revision: 1.1 $
|
||||
$Date: 1998/10/09 08:01:06 $
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _OS_EEPROM_H_
|
||||
#define _OS_EEPROM_H_
|
||||
|
||||
#ifdef _LANGUAGE_C_PLUS_PLUS
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ultratypes.h"
|
||||
#include "os_message.h"
|
||||
|
||||
|
||||
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Type definitions
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Global definitions
|
||||
*
|
||||
*/
|
||||
|
||||
/* EEPROM TYPE */
|
||||
|
||||
#define EEPROM_TYPE_4K 0x01
|
||||
#define EEPROM_TYPE_16K 0x02
|
||||
|
||||
/* definition for EEPROM */
|
||||
|
||||
#define EEPROM_MAXBLOCKS 64
|
||||
#define EEP16K_MAXBLOCKS 256
|
||||
#define EEPROM_BLOCK_SIZE 8
|
||||
|
||||
|
||||
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Macro definitions
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Extern variables
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Function prototypes
|
||||
*
|
||||
*/
|
||||
|
||||
/* EEPROM interface */
|
||||
|
||||
extern s32 osEepromProbe(OSMesgQueue *);
|
||||
extern s32 osEepromRead(OSMesgQueue *, u8, u8 *);
|
||||
extern s32 osEepromWrite(OSMesgQueue *, u8, u8 *);
|
||||
extern s32 osEepromLongRead(OSMesgQueue *, u8, u8 *, int);
|
||||
extern s32 osEepromLongWrite(OSMesgQueue *, u8, u8 *, int);
|
||||
|
||||
|
||||
#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */
|
||||
|
||||
#ifdef _LANGUAGE_C_PLUS_PLUS
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_OS_EEPROM_H_ */
|
||||
@@ -0,0 +1,119 @@
|
||||
|
||||
/*====================================================================
|
||||
* os_exception.h
|
||||
*
|
||||
* Copyright 1995, Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics,
|
||||
* Inc.; the contents of this file may not be disclosed to third
|
||||
* parties, copied or duplicated in any form, in whole or in part,
|
||||
* without the prior written permission of Silicon Graphics, Inc.
|
||||
*
|
||||
* RESTRICTED RIGHTS LEGEND:
|
||||
* Use, duplication or disclosure by the Government is subject to
|
||||
* restrictions as set forth in subdivision (c)(1)(ii) of the Rights
|
||||
* in Technical Data and Computer Software clause at DFARS
|
||||
* 252.227-7013, and/or in similar or successor clauses in the FAR,
|
||||
* DOD or NASA FAR Supplement. Unpublished - rights reserved under the
|
||||
* Copyright Laws of the United States.
|
||||
*====================================================================*/
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
Copyright (C) 1998 Nintendo. (Originated by SGI)
|
||||
|
||||
$RCSfile: os_exception.h,v $
|
||||
$Revision: 1.1 $
|
||||
$Date: 1998/10/09 08:01:07 $
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _OS_EXCEPTION_H_
|
||||
#define _OS_EXCEPTION_H_
|
||||
|
||||
#ifdef _LANGUAGE_C_PLUS_PLUS
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ultratypes.h"
|
||||
|
||||
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Type definitions
|
||||
*
|
||||
*/
|
||||
|
||||
typedef u32 OSIntMask;
|
||||
typedef u32 OSHWIntr;
|
||||
|
||||
#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Global definitions
|
||||
*
|
||||
*/
|
||||
|
||||
/* Flags for debugging purpose */
|
||||
|
||||
#define OS_FLAG_CPU_BREAK 1 /* Break exception has occurred */
|
||||
#define OS_FLAG_FAULT 2 /* CPU fault has occurred */
|
||||
|
||||
/* Interrupt masks */
|
||||
|
||||
#define OS_IM_NONE 0x00000001
|
||||
#define OS_IM_SW1 0x00000501
|
||||
#define OS_IM_SW2 0x00000601
|
||||
#define OS_IM_CART 0x00000c01
|
||||
#define OS_IM_PRENMI 0x00001401
|
||||
#define OS_IM_RDBWRITE 0x00002401
|
||||
#define OS_IM_RDBREAD 0x00004401
|
||||
#define OS_IM_COUNTER 0x00008401
|
||||
#define OS_IM_CPU 0x0000ff01
|
||||
#define OS_IM_SP 0x00010401
|
||||
#define OS_IM_SI 0x00020401
|
||||
#define OS_IM_AI 0x00040401
|
||||
#define OS_IM_VI 0x00080401
|
||||
#define OS_IM_PI 0x00100401
|
||||
#define OS_IM_DP 0x00200401
|
||||
#define OS_IM_ALL 0x003fff01
|
||||
#define RCP_IMASK 0x003f0000
|
||||
#define RCP_IMASKSHIFT 16
|
||||
|
||||
|
||||
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Macro definitions
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Extern variables
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Function prototypes
|
||||
*
|
||||
*/
|
||||
|
||||
/* Interrupt operations */
|
||||
|
||||
extern OSIntMask osGetIntMask(void);
|
||||
extern OSIntMask osSetIntMask(OSIntMask);
|
||||
|
||||
|
||||
#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */
|
||||
|
||||
#ifdef _LANGUAGE_C_PLUS_PLUS
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_OS_EXCEPTION_H_ */
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef _ULTRA64_OS_INTERNAL_H_
|
||||
#define _ULTRA64_OS_INTERNAL_H_
|
||||
#include "os_message.h"
|
||||
|
||||
/* Internal functions used by the operating system */
|
||||
/* Do not include this header in application code */
|
||||
|
||||
/* Variables */
|
||||
|
||||
//extern u64 osClockRate;
|
||||
|
||||
/* Functions */
|
||||
|
||||
/*u32 __osProbeTLB(void *);
|
||||
u32 __osDisableInt(void);
|
||||
void __osRestoreInt(u32);*/
|
||||
OSThread *__osGetCurrFaultedThread(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef _OS_LIBC_H_
|
||||
#define _OS_LIBC_H_
|
||||
|
||||
#include "ultratypes.h"
|
||||
|
||||
// Old deprecated functions from strings.h, replaced by memcpy/memset.
|
||||
extern void bcopy(const void *, void *, size_t);
|
||||
extern void bzero(void *, size_t);
|
||||
|
||||
#endif /* !_OS_LIBC_H_ */
|
||||
@@ -0,0 +1,164 @@
|
||||
|
||||
/*====================================================================
|
||||
* os_message.h
|
||||
*
|
||||
* Copyright 1995, Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics,
|
||||
* Inc.; the contents of this file may not be disclosed to third
|
||||
* parties, copied or duplicated in any form, in whole or in part,
|
||||
* without the prior written permission of Silicon Graphics, Inc.
|
||||
*
|
||||
* RESTRICTED RIGHTS LEGEND:
|
||||
* Use, duplication or disclosure by the Government is subject to
|
||||
* restrictions as set forth in subdivision (c)(1)(ii) of the Rights
|
||||
* in Technical Data and Computer Software clause at DFARS
|
||||
* 252.227-7013, and/or in similar or successor clauses in the FAR,
|
||||
* DOD or NASA FAR Supplement. Unpublished - rights reserved under the
|
||||
* Copyright Laws of the United States.
|
||||
*====================================================================*/
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
Copyright (C) 1998 Nintendo. (Originated by SGI)
|
||||
|
||||
$RCSfile: os_message.h,v $
|
||||
$Revision: 1.1 $
|
||||
$Date: 1998/10/09 08:01:15 $
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _OS_MESSAGE_H_
|
||||
#define _OS_MESSAGE_H_
|
||||
|
||||
#ifdef _LANGUAGE_C_PLUS_PLUS
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ultratypes.h"
|
||||
#include "os_thread.h"
|
||||
|
||||
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Type definitions
|
||||
*
|
||||
*/
|
||||
|
||||
typedef u32 OSEvent;
|
||||
|
||||
/*
|
||||
* Structure for message
|
||||
*/
|
||||
typedef void * OSMesg;
|
||||
|
||||
/*
|
||||
* Structure for message queue
|
||||
*/
|
||||
typedef struct OSMesgQueue_s {
|
||||
OSThread *mtqueue; /* Queue to store threads blocked
|
||||
on empty mailboxes (receive) */
|
||||
OSThread *fullqueue; /* Queue to store threads blocked
|
||||
on full mailboxes (send) */
|
||||
s32 validCount; /* Contains number of valid message */
|
||||
s32 first; /* Points to first valid message */
|
||||
s32 msgCount; /* Contains total # of messages */
|
||||
OSMesg *msg; /* Points to message buffer array */
|
||||
} OSMesgQueue;
|
||||
|
||||
|
||||
#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Global definitions
|
||||
*
|
||||
*/
|
||||
|
||||
/* Events */
|
||||
#ifdef _FINALROM
|
||||
#define OS_NUM_EVENTS 15
|
||||
#else
|
||||
#define OS_NUM_EVENTS 23
|
||||
#endif
|
||||
|
||||
#define OS_EVENT_SW1 0 /* CPU SW1 interrupt */
|
||||
#define OS_EVENT_SW2 1 /* CPU SW2 interrupt */
|
||||
#define OS_EVENT_CART 2 /* Cartridge interrupt: used by rmon */
|
||||
#define OS_EVENT_COUNTER 3 /* Counter int: used by VI/Timer Mgr */
|
||||
#define OS_EVENT_SP 4 /* SP task done interrupt */
|
||||
#define OS_EVENT_SI 5 /* SI (controller) interrupt */
|
||||
#define OS_EVENT_AI 6 /* AI interrupt */
|
||||
#define OS_EVENT_VI 7 /* VI interrupt: used by VI/Timer Mgr */
|
||||
#define OS_EVENT_PI 8 /* PI interrupt: used by PI Manager */
|
||||
#define OS_EVENT_DP 9 /* DP full sync interrupt */
|
||||
#define OS_EVENT_CPU_BREAK 10 /* CPU breakpoint: used by rmon */
|
||||
#define OS_EVENT_SP_BREAK 11 /* SP breakpoint: used by rmon */
|
||||
#define OS_EVENT_FAULT 12 /* CPU fault event: used by rmon */
|
||||
#define OS_EVENT_THREADSTATUS 13 /* CPU thread status: used by rmon */
|
||||
#define OS_EVENT_PRENMI 14 /* Pre NMI interrupt */
|
||||
#ifndef _FINALROM
|
||||
#define OS_EVENT_RDB_READ_DONE 15 /* RDB read ok event: used by rmon */
|
||||
#define OS_EVENT_RDB_LOG_DONE 16 /* read of log data complete */
|
||||
#define OS_EVENT_RDB_DATA_DONE 17 /* read of hostio data complete */
|
||||
#define OS_EVENT_RDB_REQ_RAMROM 18 /* host needs ramrom access */
|
||||
#define OS_EVENT_RDB_FREE_RAMROM 19 /* host is done with ramrom access */
|
||||
#define OS_EVENT_RDB_DBG_DONE 20
|
||||
#define OS_EVENT_RDB_FLUSH_PROF 21
|
||||
#define OS_EVENT_RDB_ACK_PROF 22
|
||||
#endif
|
||||
|
||||
/* Flags to turn blocking on/off when sending/receiving message */
|
||||
|
||||
#define OS_MESG_NOBLOCK 0
|
||||
#define OS_MESG_BLOCK 1
|
||||
|
||||
|
||||
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Macro definitions
|
||||
*
|
||||
*/
|
||||
|
||||
/* Get count of valid messages in queue */
|
||||
#define MQ_GET_COUNT(mq) ((mq)->validCount)
|
||||
|
||||
/* Figure out if message queue is empty or full */
|
||||
#define MQ_IS_EMPTY(mq) (MQ_GET_COUNT(mq) == 0)
|
||||
#define MQ_IS_FULL(mq) (MQ_GET_COUNT(mq) >= (mq)->msgCount)
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Extern variables
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Function prototypes
|
||||
*
|
||||
*/
|
||||
|
||||
/* Message operations */
|
||||
|
||||
extern void osCreateMesgQueue(OSMesgQueue *, OSMesg *, s32);
|
||||
extern s32 osSendMesg(OSMesgQueue *, OSMesg, s32);
|
||||
extern s32 osJamMesg(OSMesgQueue *, OSMesg, s32);
|
||||
extern s32 osRecvMesg(OSMesgQueue *, OSMesg *, s32);
|
||||
|
||||
/* Event operations */
|
||||
|
||||
extern void osSetEventMesg(OSEvent, OSMesgQueue *, OSMesg);
|
||||
|
||||
|
||||
#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */
|
||||
|
||||
#ifdef _LANGUAGE_C_PLUS_PLUS
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_OS_MESSAGE_H_ */
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef _ULTRA64_OS_MISC_H_
|
||||
#define _ULTRA64_OS_MISC_H_
|
||||
#include "ultratypes.h"
|
||||
/* Miscellaneous OS functions */
|
||||
|
||||
void osInitialize(void);
|
||||
u32 osGetCount(void);
|
||||
|
||||
uintptr_t osVirtualToPhysical(void *);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,88 @@
|
||||
#ifndef _ULTRA64_PI_H_
|
||||
#define _ULTRA64_PI_H_
|
||||
#include <ultra64.h>
|
||||
|
||||
/* Ultra64 Parallel Interface */
|
||||
|
||||
/* Types */
|
||||
|
||||
typedef struct {
|
||||
#if !defined(VERSION_EU)
|
||||
u32 errStatus;
|
||||
#endif
|
||||
void *dramAddr;
|
||||
void *C2Addr;
|
||||
u32 sectorSize;
|
||||
u32 C1ErrNum;
|
||||
u32 C1ErrSector[4];
|
||||
} __OSBlockInfo;
|
||||
|
||||
typedef struct {
|
||||
u32 cmdType; // 0
|
||||
u16 transferMode; // 4
|
||||
u16 blockNum; // 6
|
||||
s32 sectorNum; // 8
|
||||
uintptr_t devAddr; // c
|
||||
#if defined(VERSION_EU)
|
||||
u32 errStatus; //error status added moved to blockinfo
|
||||
#endif
|
||||
u32 bmCtlShadow; // 10
|
||||
u32 seqCtlShadow; // 14
|
||||
__OSBlockInfo block[2]; // 18
|
||||
} __OSTranxInfo;
|
||||
|
||||
typedef struct OSPiHandle_s {
|
||||
struct OSPiHandle_s *next;
|
||||
u8 type;
|
||||
u8 latency;
|
||||
u8 pageSize;
|
||||
u8 relDuration;
|
||||
u8 pulse;
|
||||
u8 domain;
|
||||
u32 baseAddress;
|
||||
u32 speed;
|
||||
__OSTranxInfo transferInfo;
|
||||
} OSPiHandle;
|
||||
|
||||
typedef struct {
|
||||
u8 type;
|
||||
uintptr_t address;
|
||||
} OSPiInfo;
|
||||
|
||||
typedef struct {
|
||||
u16 type;
|
||||
u8 pri;
|
||||
u8 status;
|
||||
OSMesgQueue *retQueue;
|
||||
} OSIoMesgHdr;
|
||||
|
||||
typedef struct {
|
||||
/*0x00*/ OSIoMesgHdr hdr;
|
||||
/*0x08*/ void *dramAddr;
|
||||
/*0x0C*/ uintptr_t devAddr;
|
||||
/*0x10*/ size_t size;
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
OSPiHandle *piHandle; // from the official definition
|
||||
#endif
|
||||
} OSIoMesg;
|
||||
|
||||
/* Definitions */
|
||||
|
||||
#define OS_READ 0 // device -> RDRAM
|
||||
#define OS_WRITE 1 // device <- RDRAM
|
||||
|
||||
#define OS_MESG_PRI_NORMAL 0
|
||||
#define OS_MESG_PRI_HIGH 1
|
||||
|
||||
/* Functions */
|
||||
|
||||
s32 osPiStartDma(OSIoMesg *mb, s32 priority, s32 direction, uintptr_t devAddr, void *vAddr,
|
||||
size_t nbytes, OSMesgQueue *mq);
|
||||
void osCreatePiManager(OSPri pri, OSMesgQueue *cmdQ, OSMesg *cmdBuf, s32 cmdMsgCnt);
|
||||
OSMesgQueue *osPiGetCmdQueue(void);
|
||||
s32 osPiWriteIo(uintptr_t devAddr, u32 data);
|
||||
s32 osPiReadIo(uintptr_t devAddr, u32 *data);
|
||||
|
||||
s32 osPiRawStartDma(s32 dir, u32 cart_addr, void *dram_addr, size_t size);
|
||||
s32 osEPiRawStartDma(OSPiHandle *piHandle, s32 dir, u32 cart_addr, void *dram_addr, size_t size);
|
||||
#endif
|
||||
@@ -0,0 +1,92 @@
|
||||
|
||||
/*====================================================================
|
||||
* os_rdp.h
|
||||
*
|
||||
* Copyright 1995, Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics,
|
||||
* Inc.; the contents of this file may not be disclosed to third
|
||||
* parties, copied or duplicated in any form, in whole or in part,
|
||||
* without the prior written permission of Silicon Graphics, Inc.
|
||||
*
|
||||
* RESTRICTED RIGHTS LEGEND:
|
||||
* Use, duplication or disclosure by the Government is subject to
|
||||
* restrictions as set forth in subdivision (c)(1)(ii) of the Rights
|
||||
* in Technical Data and Computer Software clause at DFARS
|
||||
* 252.227-7013, and/or in similar or successor clauses in the FAR,
|
||||
* DOD or NASA FAR Supplement. Unpublished - rights reserved under the
|
||||
* Copyright Laws of the United States.
|
||||
*====================================================================*/
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
Copyright (C) 1998 Nintendo. (Originated by SGI)
|
||||
|
||||
$RCSfile: os_rdp.h,v $
|
||||
$Revision: 1.1 $
|
||||
$Date: 1998/10/09 08:01:16 $
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _OS_RDP_H_
|
||||
#define _OS_RDP_H_
|
||||
|
||||
#ifdef _LANGUAGE_C_PLUS_PLUS
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ultratypes.h"
|
||||
|
||||
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Type definitions
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Global definitions
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Macro definitions
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Extern variables
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Function prototypes
|
||||
*
|
||||
*/
|
||||
|
||||
/* Display processor interface (Dp) */
|
||||
extern u32 osDpGetStatus(void);
|
||||
extern void osDpSetStatus(u32);
|
||||
extern void osDpGetCounters(u32 *);
|
||||
extern s32 osDpSetNextBuffer(void *, u64);
|
||||
|
||||
|
||||
#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */
|
||||
|
||||
#ifdef _LANGUAGE_C_PLUS_PLUS
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_OS_RDP_H_ */
|
||||
@@ -0,0 +1,75 @@
|
||||
#ifndef _ULTRA64_THREAD_H_
|
||||
#define _ULTRA64_THREAD_H_
|
||||
#include "ultratypes.h"
|
||||
/* Recommended priorities for system threads */
|
||||
#define OS_PRIORITY_MAX 255
|
||||
#define OS_PRIORITY_VIMGR 254
|
||||
#define OS_PRIORITY_RMON 250
|
||||
#define OS_PRIORITY_RMONSPIN 200
|
||||
#define OS_PRIORITY_PIMGR 150
|
||||
#define OS_PRIORITY_SIMGR 140
|
||||
#define OS_PRIORITY_APPMAX 127
|
||||
#define OS_PRIORITY_IDLE 0
|
||||
|
||||
#define OS_STATE_STOPPED 1
|
||||
#define OS_STATE_RUNNABLE 2
|
||||
#define OS_STATE_RUNNING 4
|
||||
#define OS_STATE_WAITING 8
|
||||
|
||||
/* Types */
|
||||
|
||||
typedef s32 OSPri;
|
||||
typedef s32 OSId;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {f32 f_odd; f32 f_even;} f;
|
||||
} __OSfp;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* registers */
|
||||
/*0x20*/ u64 at, v0, v1, a0, a1, a2, a3;
|
||||
/*0x58*/ u64 t0, t1, t2, t3, t4, t5, t6, t7;
|
||||
/*0x98*/ u64 s0, s1, s2, s3, s4, s5, s6, s7;
|
||||
/*0xD8*/ u64 t8, t9, gp, sp, s8, ra;
|
||||
/*0x108*/ u64 lo, hi;
|
||||
/*0x118*/ u32 sr, pc, cause, badvaddr, rcp;
|
||||
/*0x12C*/ u32 fpcsr;
|
||||
__OSfp fp0, fp2, fp4, fp6, fp8, fp10, fp12, fp14;
|
||||
__OSfp fp16, fp18, fp20, fp22, fp24, fp26, fp28, fp30;
|
||||
} __OSThreadContext;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 flag;
|
||||
u32 count;
|
||||
u64 time;
|
||||
} __OSThreadprofile_s;
|
||||
|
||||
typedef struct OSThread_s
|
||||
{
|
||||
/*0x00*/ struct OSThread_s *next;
|
||||
/*0x04*/ OSPri priority;
|
||||
/*0x08*/ struct OSThread_s **queue;
|
||||
/*0x0C*/ struct OSThread_s *tlnext;
|
||||
/*0x10*/ u16 state;
|
||||
/*0x12*/ u16 flags;
|
||||
/*0x14*/ OSId id;
|
||||
/*0x18*/ int fp;
|
||||
/*0x1C*/ __OSThreadprofile_s *thprof;
|
||||
/*0x20*/ __OSThreadContext context;
|
||||
} OSThread;
|
||||
|
||||
|
||||
/* Functions */
|
||||
|
||||
void osCreateThread(OSThread *thread, OSId id, void (*entry)(void *),
|
||||
void *arg, void *sp, OSPri pri);
|
||||
OSId osGetThreadId(OSThread *thread);
|
||||
OSPri osGetThreadPri(OSThread *thread);
|
||||
void osSetThreadPri(OSThread *thread, OSPri pri);
|
||||
void osStartThread(OSThread *thread);
|
||||
void osStopThread(OSThread *thread);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef _ULTRA64_TIME_H_
|
||||
#define _ULTRA64_TIME_H_
|
||||
|
||||
#include "ultratypes.h"
|
||||
#include "os_message.h"
|
||||
|
||||
/* Types */
|
||||
|
||||
typedef struct OSTimer_str
|
||||
{
|
||||
struct OSTimer_str *next;
|
||||
struct OSTimer_str *prev;
|
||||
u64 interval;
|
||||
u64 remaining;
|
||||
OSMesgQueue *mq;
|
||||
OSMesg *msg;
|
||||
} OSTimer;
|
||||
|
||||
typedef u64 OSTime;
|
||||
|
||||
/* Functions */
|
||||
|
||||
OSTime osGetTime(void);
|
||||
void osSetTime(OSTime time);
|
||||
u32 osSetTimer(OSTimer *, OSTime, OSTime, OSMesgQueue *, OSMesg);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,107 @@
|
||||
|
||||
/*====================================================================
|
||||
* os_tlb.h
|
||||
*
|
||||
* Copyright 1995, Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics,
|
||||
* Inc.; the contents of this file may not be disclosed to third
|
||||
* parties, copied or duplicated in any form, in whole or in part,
|
||||
* without the prior written permission of Silicon Graphics, Inc.
|
||||
*
|
||||
* RESTRICTED RIGHTS LEGEND:
|
||||
* Use, duplication or disclosure by the Government is subject to
|
||||
* restrictions as set forth in subdivision (c)(1)(ii) of the Rights
|
||||
* in Technical Data and Computer Software clause at DFARS
|
||||
* 252.227-7013, and/or in similar or successor clauses in the FAR,
|
||||
* DOD or NASA FAR Supplement. Unpublished - rights reserved under the
|
||||
* Copyright Laws of the United States.
|
||||
*====================================================================*/
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
Copyright (C) 1998 Nintendo. (Originated by SGI)
|
||||
|
||||
$RCSfile: os_tlb.h,v $
|
||||
$Revision: 1.1 $
|
||||
$Date: 1998/10/09 08:01:20 $
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _OS_TLB_H_
|
||||
#define _OS_TLB_H_
|
||||
|
||||
#ifdef _LANGUAGE_C_PLUS_PLUS
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ultratypes.h"
|
||||
|
||||
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Type definitions
|
||||
*
|
||||
*/
|
||||
|
||||
typedef u32 OSPageMask;
|
||||
|
||||
|
||||
#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Global definitions
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Page size argument for TLB routines
|
||||
*/
|
||||
#define OS_PM_4K 0x0000000
|
||||
#define OS_PM_16K 0x0006000
|
||||
#define OS_PM_64K 0x001e000
|
||||
#define OS_PM_256K 0x007e000
|
||||
#define OS_PM_1M 0x01fe000
|
||||
#define OS_PM_4M 0x07fe000
|
||||
#define OS_PM_16M 0x1ffe000
|
||||
|
||||
|
||||
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Macro definitions
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Extern variables
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Function prototypes
|
||||
*
|
||||
*/
|
||||
|
||||
/* TLB management routines */
|
||||
|
||||
extern void osMapTLB(s32, OSPageMask, void *, u32, u32, s32);
|
||||
extern void osMapTLBRdb(void);
|
||||
extern void osUnmapTLB(s32);
|
||||
extern void osUnmapTLBAll(void);
|
||||
extern void osSetTLBASID(s32);
|
||||
|
||||
|
||||
#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */
|
||||
|
||||
#ifdef _LANGUAGE_C_PLUS_PLUS
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_OS_TLB_H_ */
|
||||
@@ -0,0 +1,117 @@
|
||||
#ifndef _ULTRA64_VI_H_
|
||||
#define _ULTRA64_VI_H_
|
||||
|
||||
#include "ultratypes.h"
|
||||
#include "os_message.h"
|
||||
|
||||
/* Ultra64 Video Interface */
|
||||
|
||||
|
||||
/* Special Features */
|
||||
#define OS_VI_GAMMA_ON 0x0001
|
||||
#define OS_VI_GAMMA_OFF 0x0002
|
||||
#define OS_VI_GAMMA_DITHER_ON 0x0004
|
||||
#define OS_VI_GAMMA_DITHER_OFF 0x0008
|
||||
#define OS_VI_DIVOT_ON 0x0010
|
||||
#define OS_VI_DIVOT_OFF 0x0020
|
||||
#define OS_VI_DITHER_FILTER_ON 0x0040
|
||||
#define OS_VI_DITHER_FILTER_OFF 0x0080
|
||||
|
||||
#define OS_VI_GAMMA 0x08
|
||||
#define OS_VI_GAMMA_DITHER 0x04
|
||||
#define OS_VI_DIVOT 0x10
|
||||
#define OS_VI_DITHER_FILTER 0x10000
|
||||
#define OS_VI_UNK200 0x200
|
||||
#define OS_VI_UNK100 0x100
|
||||
|
||||
|
||||
/* Types */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 ctrl;
|
||||
u32 width;
|
||||
u32 burst;
|
||||
u32 vSync;
|
||||
u32 hSync;
|
||||
u32 leap;
|
||||
u32 hStart;
|
||||
u32 xScale;
|
||||
u32 vCurrent;
|
||||
} OSViCommonRegs;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 origin;
|
||||
u32 yScale;
|
||||
u32 vStart;
|
||||
u32 vBurst;
|
||||
u32 vIntr;
|
||||
} OSViFieldRegs;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 type;
|
||||
OSViCommonRegs comRegs;
|
||||
OSViFieldRegs fldRegs[2];
|
||||
} OSViMode;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* 0x00 */ u16 unk00; //some kind of flags. swap buffer sets to 0x10
|
||||
/* 0x02 */ u16 retraceCount;
|
||||
/* 0x04 */ void* buffer;
|
||||
/* 0x08 */ OSViMode *modep;
|
||||
/* 0x0c */ u32 features;
|
||||
/* 0x10 */ OSMesgQueue *mq;
|
||||
/* 0x14 */ OSMesg *msg;
|
||||
/* 0x18 */ u32 unk18;
|
||||
/* 0x1c */ u32 unk1c;
|
||||
/* 0x20 */ u32 unk20;
|
||||
/* 0x24 */ f32 unk24;
|
||||
/* 0x28 */ u16 unk28;
|
||||
/* 0x2c */ u32 unk2c;
|
||||
} OSViContext;
|
||||
|
||||
void osCreateViManager(OSPri pri);
|
||||
void osViSetMode(OSViMode *mode);
|
||||
void osViSetEvent(OSMesgQueue *mq, OSMesg msg, u32 retraceCount);
|
||||
void osViBlack(u8 active);
|
||||
void osViSetSpecialFeatures(u32 func);
|
||||
void osViSwapBuffer(void *vaddr);
|
||||
|
||||
|
||||
#define OS_VI_NTSC_LPN1 0 /* NTSC */
|
||||
#define OS_VI_NTSC_LPF1 1
|
||||
#define OS_VI_NTSC_LAN1 2
|
||||
#define OS_VI_NTSC_LAF1 3
|
||||
#define OS_VI_NTSC_LPN2 4
|
||||
#define OS_VI_NTSC_LPF2 5
|
||||
#define OS_VI_NTSC_LAN2 6
|
||||
#define OS_VI_NTSC_LAF2 7
|
||||
#define OS_VI_NTSC_HPN1 8
|
||||
#define OS_VI_NTSC_HPF1 9
|
||||
#define OS_VI_NTSC_HAN1 10
|
||||
#define OS_VI_NTSC_HAF1 11
|
||||
#define OS_VI_NTSC_HPN2 12
|
||||
#define OS_VI_NTSC_HPF2 13
|
||||
|
||||
#define OS_VI_PAL_LPN1 14 /* PAL */
|
||||
#define OS_VI_PAL_LPF1 15
|
||||
#define OS_VI_PAL_LAN1 16
|
||||
#define OS_VI_PAL_LAF1 17
|
||||
#define OS_VI_PAL_LPN2 18
|
||||
#define OS_VI_PAL_LPF2 19
|
||||
#define OS_VI_PAL_LAN2 20
|
||||
#define OS_VI_PAL_LAF2 21
|
||||
#define OS_VI_PAL_HPN1 22
|
||||
#define OS_VI_PAL_HPF1 23
|
||||
#define OS_VI_PAL_HAN1 24
|
||||
#define OS_VI_PAL_HAF1 25
|
||||
#define OS_VI_PAL_HPN2 26
|
||||
#define OS_VI_PAL_HPF2 27
|
||||
|
||||
extern OSViMode osViModeTable[]; /* Global VI mode table */
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,116 @@
|
||||
#ifndef _ULTRA64_SPTASK_H_
|
||||
#define _ULTRA64_SPTASK_H_
|
||||
|
||||
/* Task Types */
|
||||
#define M_GFXTASK 1
|
||||
#define M_AUDTASK 2
|
||||
#define M_VIDTASK 3
|
||||
#define M_HVQTASK 6
|
||||
#define M_HVQMTASK 7
|
||||
|
||||
#if (defined(F3DEX_GBI) || defined(F3DLP_GBI) || defined(F3DEX_GBI_2))
|
||||
#define OS_YIELD_DATA_SIZE 0xc00
|
||||
#else
|
||||
#define OS_YIELD_DATA_SIZE 0x900
|
||||
#endif
|
||||
#define OS_YIELD_AUDIO_SIZE 0x400
|
||||
|
||||
/* Flags */
|
||||
#define M_TASK_FLAG0 1
|
||||
#define M_TASK_FLAG1 2
|
||||
#ifdef VERSION_SH
|
||||
#define M_TASK_FLAG2 4
|
||||
#endif
|
||||
|
||||
/* SpStatus */
|
||||
#define SPSTATUS_CLEAR_HALT 0x00000001
|
||||
#define SPSTATUS_SET_HALT 0x00000002
|
||||
#define SPSTATUS_CLEAR_BROKE 0x00000004
|
||||
#define SPSTATUS_CLEAR_INTR 0x00000008
|
||||
#define SPSTATUS_SET_INTR 0x00000010
|
||||
#define SPSTATUS_CLEAR_SSTEP 0x00000020
|
||||
#define SPSTATUS_SET_SSTEP 0x00000040
|
||||
#define SPSTATUS_CLEAR_INTR_ON_BREAK 0x00000080
|
||||
#define SPSTATUS_SET_INTR_ON_BREAK 0x00000100
|
||||
#define SPSTATUS_CLEAR_SIGNAL0 0x00000200
|
||||
#define SPSTATUS_SET_SIGNAL0 0x00000400
|
||||
#define SPSTATUS_CLEAR_SIGNAL1 0x00000800
|
||||
#define SPSTATUS_SET_SIGNAL1 0x00001000
|
||||
#define SPSTATUS_CLEAR_SIGNAL2 0x00002000
|
||||
#define SPSTATUS_SET_SIGNAL2 0x00004000
|
||||
#define SPSTATUS_CLEAR_SIGNAL3 0x00008000
|
||||
#define SPSTATUS_SET_SIGNAL3 0x00010000
|
||||
#define SPSTATUS_CLEAR_SIGNAL4 0x00020000
|
||||
#define SPSTATUS_SET_SIGNAL4 0x00040000
|
||||
#define SPSTATUS_CLEAR_SIGNAL5 0x00080000
|
||||
#define SPSTATUS_SET_SIGNAL5 0x00100000
|
||||
#define SPSTATUS_CLEAR_SIGNAL6 0x00200000
|
||||
#define SPSTATUS_SET_SIGNAL6 0x00800000
|
||||
#define SPSTATUS_CLEAR_SIGNAL7 0x01000000
|
||||
#define SPSTATUS_SET_SIGNAL7 0x02000000
|
||||
|
||||
#define SPSTATUS_HALT 0x0001
|
||||
#define SPSTATUS_BROKE 0x0002
|
||||
#define SPSTATUS_DMA_BUSY 0x0004
|
||||
#define SPSTATUS_DMA_FULL 0x0008
|
||||
#define SPSTATUS_IO_FULL 0x0010
|
||||
#define SPSTATUS_SINGLE_STEP 0x0020
|
||||
#define SPSTATUS_INTERRUPT_ON_BREAK 0x0040
|
||||
#define SPSTATUS_SIGNAL0_SET 0x0080
|
||||
#define SPSTATUS_SIGNAL1_SET 0x0100
|
||||
#define SPSTATUS_SIGNAL2_SET 0x0200
|
||||
#define SPSTATUS_SIGNAL3_SET 0x0400
|
||||
#define SPSTATUS_SIGNAL4_SET 0x0800
|
||||
#define SPSTATUS_SIGNAL5_SET 0x1000
|
||||
#define SPSTATUS_SIGNAL6_SET 0x2000
|
||||
#define SPSTATUS_SIGNAL7_SET 0x4000
|
||||
|
||||
/* Types */
|
||||
/* Types */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/*0x00*/ u32 type;
|
||||
/*0x04*/ u32 flags;
|
||||
|
||||
/*0x08*/ u64 *ucode_boot;
|
||||
/*0x0C*/ u32 ucode_boot_size;
|
||||
|
||||
/*0x10*/ u64 *ucode;
|
||||
/*0x14*/ u32 ucode_size;
|
||||
|
||||
/*0x18*/ u64 *ucode_data;
|
||||
/*0x1C*/ u32 ucode_data_size;
|
||||
|
||||
/*0x20*/ u64 *dram_stack;
|
||||
/*0x24*/ u32 dram_stack_size;
|
||||
|
||||
/*0x28*/ u64 *output_buff;
|
||||
/*0x2C*/ u64 *output_buff_size;
|
||||
|
||||
/*0x30*/ u64 *data_ptr;
|
||||
/*0x34*/ u32 data_size;
|
||||
|
||||
/*0x38*/ u64 *yield_data_ptr;
|
||||
/*0x3C*/ u32 yield_data_size;
|
||||
} OSTask_t; // size = 0x40
|
||||
|
||||
typedef union {
|
||||
OSTask_t t;
|
||||
long long int force_structure_alignment;
|
||||
} OSTask;
|
||||
|
||||
typedef u32 OSYieldResult;
|
||||
|
||||
/* Functions */
|
||||
|
||||
#define osSpTaskStart(p) \
|
||||
osSpTaskLoad(p); \
|
||||
osSpTaskStartGo(p);
|
||||
|
||||
void osSpTaskLoad(OSTask *task);
|
||||
void osSpTaskStartGo(OSTask *task);
|
||||
void osSpTaskYield(void);
|
||||
OSYieldResult osSpTaskYielded(OSTask *task);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef _ULTRA64_UCODE_H_
|
||||
#define _ULTRA64_UCODE_H_
|
||||
|
||||
#define SP_DRAM_STACK_SIZE8 0x400
|
||||
#define SP_UCODE_SIZE 0x1000
|
||||
#define SP_UCODE_DATA_SIZE 0x800
|
||||
|
||||
// standard boot ucode
|
||||
extern u64 rspF3DBootStart[], rspF3DBootEnd[];
|
||||
|
||||
// F3D ucode
|
||||
extern u64 rspF3DStart[], rspF3DEnd[];
|
||||
|
||||
// F3D ucode data
|
||||
extern u64 rspF3DDataStart[], rspF3DDataEnd[];
|
||||
|
||||
// aspMain (audio) ucode
|
||||
extern u64 rspAspMainStart[], rspAspMainEnd[];
|
||||
|
||||
// aspMain ucode data
|
||||
extern u64 rspAspMainDataStart[], rspAspMainDataEnd[];
|
||||
|
||||
#endif
|
||||
@@ -21,21 +21,56 @@
|
||||
#define SOUNDARGS_SHIFT_SOUNDID 16
|
||||
#define SOUNDARGS_SHIFT_PRIORITY 8
|
||||
|
||||
/* Sound banks */
|
||||
#define SOUND_BANK_ACTION 0
|
||||
#define SOUND_BANK_MOVING 1
|
||||
#define SOUND_BANK_VOICE 2
|
||||
#define SOUND_BANK_GENERAL 3
|
||||
#define SOUND_BANK_ENV 4
|
||||
#define SOUND_BANK_OBJ 5
|
||||
#define SOUND_BANK_AIR 6
|
||||
#define SOUND_BANK_MENU 7
|
||||
#define SOUND_BANK_GENERAL2 8
|
||||
#define SOUND_BANK_OBJ2 9
|
||||
#define SOUND_BANK_COUNT 10
|
||||
|
||||
#define SOUND_BANKS_ALL_BITS 0xffff
|
||||
#define SOUND_BANKS_ALL ((1 << SOUND_BANK_COUNT) - 1)
|
||||
#define SOUND_BANKS_FOREGROUND (\
|
||||
(1 << SOUND_BANK_ACTION) |\
|
||||
(1 << SOUND_BANK_VOICE) |\
|
||||
(1 << SOUND_BANK_MENU))
|
||||
#define SOUND_BANKS_BACKGROUND (SOUND_BANKS_ALL & ~SOUND_BANKS_FOREGROUND)
|
||||
#define SOUND_BANKS_DISABLED_DURING_INTRO_CUTSCENE (\
|
||||
(1 << SOUND_BANK_ENV) |\
|
||||
(1 << SOUND_BANK_OBJ) |\
|
||||
(1 << SOUND_BANK_GENERAL2) |\
|
||||
(1 << SOUND_BANK_OBJ2))
|
||||
#define SOUND_BANKS_DISABLED_AFTER_CREDITS (\
|
||||
(1 << SOUND_BANK_ACTION) |\
|
||||
(1 << SOUND_BANK_MOVING) |\
|
||||
(1 << SOUND_BANK_VOICE) |\
|
||||
(1 << SOUND_BANK_GENERAL))
|
||||
|
||||
/* Audio Status */
|
||||
#define SOUND_STATUS_STOPPED 0
|
||||
#define SOUND_STATUS_STARTING 1
|
||||
#define SOUND_STATUS_WAITING SOUND_STATUS_STARTING
|
||||
#define SOUND_STATUS_PLAYING 2
|
||||
|
||||
/* Audio lower bitflags. TODO: Figure out what these mean and use them below. */
|
||||
#define SOUND_LO_BITFLAG_UNK1 0x10 // fade in?
|
||||
#define SOUND_LOWER_BACKGROUND_MUSIC SOUND_LO_BITFLAG_UNK1
|
||||
#define SOUND_NO_ECHO 0x20 // not in JP
|
||||
#define SOUND_LO_BITFLAG_UNK8 0x80 // restart playing on each play_sound call?
|
||||
#define SOUND_DISCRETE SOUND_LO_BITFLAG_UNK8
|
||||
|
||||
/* Audio playback bitflags. */
|
||||
#define SOUND_NO_VOLUME_LOSS 0x1000000 // No volume loss with distance
|
||||
#define SOUND_VIBRATO 0x2000000 // Randomly alter frequency each audio frame
|
||||
#define SOUND_NO_PRIORITY_LOSS 0x4000000 // Do not prioritize closer sounds
|
||||
#define SOUND_NO_FREQUENCY_LOSS 0x8000000 // Frequency scale does not change with distance
|
||||
#define SOUND_CONSTANT_FREQUENCY SOUND_NO_FREQUENCY_LOSS
|
||||
|
||||
// silence
|
||||
#define NO_SOUND 0
|
||||
|
||||
@@ -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
|
||||
|
||||
+14
-14
@@ -4,7 +4,7 @@
|
||||
// This file contains various data types used in Super Mario 64 that don't yet
|
||||
// have an appropriate header.
|
||||
|
||||
// #include <ultra64.h>
|
||||
#include "ultra64.h"
|
||||
#include "macros.h"
|
||||
#include "PR/ultratypes.h"
|
||||
|
||||
@@ -62,19 +62,19 @@ enum SpTaskState {
|
||||
SPTASK_STATE_FINISHED_DP
|
||||
};
|
||||
|
||||
// struct SPTask
|
||||
// {
|
||||
// /*0x00*/ OSTask task;
|
||||
// /*0x40*/ OSMesgQueue *msgqueue;
|
||||
// /*0x44*/ OSMesg msg;
|
||||
// /*0x48*/ enum SpTaskState state;
|
||||
// }; // size = 0x4C, align = 0x8
|
||||
//
|
||||
// struct VblankHandler
|
||||
// {
|
||||
// OSMesgQueue *queue;
|
||||
// OSMesg msg;
|
||||
// };
|
||||
struct SPTask
|
||||
{
|
||||
/*0x00*/ OSTask task;
|
||||
/*0x40*/ OSMesgQueue *msgqueue;
|
||||
/*0x44*/ OSMesg msg;
|
||||
/*0x48*/ enum SpTaskState state;
|
||||
}; // size = 0x4C, align = 0x8
|
||||
|
||||
struct VblankHandler
|
||||
{
|
||||
OSMesgQueue *queue;
|
||||
OSMesg msg;
|
||||
};
|
||||
|
||||
#define ANIM_FLAG_NOLOOP (1 << 0) // 0x01
|
||||
#define ANIM_FLAG_FORWARD (1 << 1) // 0x02
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef _ULTRA64_H_
|
||||
#define _ULTRA64_H_
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#ifndef _LANGUAGE_C
|
||||
#define _LANGUAGE_C
|
||||
#endif
|
||||
|
||||
#include "PR/ultratypes.h"
|
||||
#include "PR/os_exception.h"
|
||||
#include "PR/os_misc.h"
|
||||
#include "PR/os_rdp.h"
|
||||
#include "PR/os_thread.h"
|
||||
#include "PR/os_time.h"
|
||||
#include "PR/os_message.h"
|
||||
#include "PR/os_cont.h"
|
||||
#include "PR/os_tlb.h"
|
||||
#include "PR/sptask.h"
|
||||
#include "PR/ucode.h"
|
||||
#include "PR/os_cache.h"
|
||||
#include "PR/os_vi.h"
|
||||
#include "PR/os_pi.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/os_eeprom.h"
|
||||
#include "PR/os_libc.h"
|
||||
#include "PR/os_ai.h"
|
||||
#include "PR/libaudio.h"
|
||||
#include "PR/libultra.h"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,93 @@
|
||||
#include "libultra_internal.h"
|
||||
#include "libaudio_internal.h"
|
||||
|
||||
#define PATCH(SRC, BASE, TYPE) //SRC = (TYPE)((uintptr_t) SRC + (uintptr_t) BASE)
|
||||
|
||||
void alSeqFileNew(ALSeqFile *f, u8 *base) {
|
||||
int i;
|
||||
for (i = 0; i < f->seqCount; i++) {
|
||||
PATCH(f->seqArray[i].offset, base, u8 *);
|
||||
}
|
||||
}
|
||||
|
||||
static void _bnkfPatchBank(ALInstrument *inst, ALBankFile *f, u8 *table) {
|
||||
int i;
|
||||
ALSound *sound;
|
||||
ALWaveTable *wavetable;
|
||||
u8 *table2;
|
||||
|
||||
if (inst->flags) {
|
||||
return;
|
||||
}
|
||||
|
||||
inst->flags = 1;
|
||||
|
||||
for (i = 0; i < inst->soundCount; i++) {
|
||||
PATCH(inst->soundArray[i], f, ALSound *);
|
||||
sound = inst->soundArray[i];
|
||||
if (sound->flags) {
|
||||
continue;
|
||||
}
|
||||
|
||||
table2 = table;
|
||||
|
||||
sound->flags = 1;
|
||||
PATCH(sound->envelope, f, ALEnvelope *);
|
||||
PATCH(sound->keyMap, f, ALKeyMap *);
|
||||
PATCH(sound->wavetable, f, ALWaveTable *);
|
||||
wavetable = sound->wavetable;
|
||||
if (wavetable->flags) {
|
||||
continue;
|
||||
}
|
||||
|
||||
wavetable->flags = 1;
|
||||
PATCH(wavetable->base, table2, u8 *);
|
||||
if (wavetable->type == 0) {
|
||||
PATCH(wavetable->waveInfo.adpcmWave.book, f, ALADPCMBook *);
|
||||
if (wavetable->waveInfo.adpcmWave.loop != NULL) {
|
||||
PATCH(wavetable->waveInfo.adpcmWave.loop, f, ALADPCMloop *);
|
||||
}
|
||||
} else if (wavetable->type == 1) {
|
||||
if (wavetable->waveInfo.rawWave.loop != NULL) {
|
||||
PATCH(wavetable->waveInfo.rawWave.loop, f, ALRawLoop *);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Force adding another jr $ra. Has to be called or it doesn't get put in the
|
||||
// right place.
|
||||
static void unused(void) {
|
||||
}
|
||||
|
||||
void alBnkfNew(ALBankFile *f, u8 *table) {
|
||||
ALBank *bank;
|
||||
int i;
|
||||
int j;
|
||||
unused();
|
||||
if (f->revision != AL_BANK_VERSION) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < f->bankCount; i++) {
|
||||
PATCH(f->bankArray[i], f, ALBank *);
|
||||
if (f->bankArray[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bank = f->bankArray[i];
|
||||
if (bank->flags == 0) {
|
||||
bank->flags = 1;
|
||||
if (bank->percussion != NULL) {
|
||||
PATCH(bank->percussion, f, ALInstrument *);
|
||||
_bnkfPatchBank(bank->percussion, f, table);
|
||||
}
|
||||
for (j = 0; j < bank->instCount; j++) {
|
||||
PATCH(bank->instArray[j], f, ALInstrument *);
|
||||
if (bank->instArray[j] != NULL) {
|
||||
_bnkfPatchBank(bank->instArray[j], f, table);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
#ifndef _LIBAUDIO_INTERNAL_H_
|
||||
#define _LIBAUDIO_INTERNAL_H_
|
||||
#include <ultra64.h>
|
||||
#define AL_BANK_VERSION 0x4231 /* 'B1' */
|
||||
|
||||
typedef u8 ALPan;
|
||||
typedef s32 ALMicroTime;
|
||||
|
||||
/* Possible wavetable types */
|
||||
enum
|
||||
{
|
||||
AL_ADPCM_WAVE = 0,
|
||||
AL_RAW16_WAVE
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 start;
|
||||
u32 end;
|
||||
u32 count;
|
||||
} ALRawLoop;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 start;
|
||||
u32 end;
|
||||
u32 count;
|
||||
ADPCM_STATE state;
|
||||
} ALADPCMloop;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
s32 order;
|
||||
s32 npredictors;
|
||||
s16 book[1]; // variable size, 8-byte aligned
|
||||
} ALADPCMBook;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ALMicroTime attackTime;
|
||||
ALMicroTime decayTime;
|
||||
ALMicroTime releaseTime;
|
||||
u8 attackVolume;
|
||||
u8 decayVolume;
|
||||
} ALEnvelope;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 velocityMin;
|
||||
u8 velocityMax;
|
||||
u8 keyMin;
|
||||
u8 keyMax;
|
||||
u8 keyBase;
|
||||
s8 detune;
|
||||
} ALKeyMap;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ALADPCMloop *loop;
|
||||
ALADPCMBook *book;
|
||||
} ALADPCMWaveInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ALRawLoop *loop;
|
||||
} ALRAWWaveInfo;
|
||||
|
||||
typedef struct ALWaveTable_s
|
||||
{
|
||||
u8 *base; /* ptr to start of wave data */
|
||||
s32 len; /* length of data in bytes */
|
||||
u8 type; /* compression type */
|
||||
u8 flags; /* offset/address flags */
|
||||
union {
|
||||
ALADPCMWaveInfo adpcmWave;
|
||||
ALRAWWaveInfo rawWave;
|
||||
} waveInfo;
|
||||
} ALWaveTable;
|
||||
|
||||
typedef struct ALSound_s
|
||||
{
|
||||
ALEnvelope *envelope;
|
||||
ALKeyMap *keyMap;
|
||||
ALWaveTable *wavetable; /* offset to wavetable struct */
|
||||
ALPan samplePan;
|
||||
u8 sampleVolume;
|
||||
u8 flags;
|
||||
} ALSound;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 volume; /* overall volume for this instrument */
|
||||
ALPan pan; /* 0 = hard left, 127 = hard right */
|
||||
u8 priority; /* voice priority for this instrument */
|
||||
u8 flags;
|
||||
u8 tremType; /* the type of tremelo osc. to use */
|
||||
u8 tremRate; /* the rate of the tremelo osc. */
|
||||
u8 tremDepth; /* the depth of the tremelo osc */
|
||||
u8 tremDelay; /* the delay for the tremelo osc */
|
||||
u8 vibType; /* the type of tremelo osc. to use */
|
||||
u8 vibRate; /* the rate of the tremelo osc. */
|
||||
u8 vibDepth; /* the depth of the tremelo osc */
|
||||
u8 vibDelay; /* the delay for the tremelo osc */
|
||||
s16 bendRange; /* pitch bend range in cents */
|
||||
s16 soundCount; /* number of sounds in this array */
|
||||
ALSound *soundArray[1];
|
||||
} ALInstrument;
|
||||
|
||||
typedef struct ALBank_s
|
||||
{
|
||||
s16 instCount; /* number of programs in this bank */
|
||||
u8 flags;
|
||||
u8 pad;
|
||||
s32 sampleRate; /* e.g. 44100, 22050, etc... */
|
||||
ALInstrument *percussion; /* default percussion for GM */
|
||||
ALInstrument *instArray[1]; /* ARRAY of instruments */
|
||||
} ALBank;
|
||||
|
||||
typedef struct
|
||||
{ /* Note: sizeof won't be correct */
|
||||
s16 revision; /* format revision of this file */
|
||||
s16 bankCount; /* number of banks */
|
||||
ALBank *bankArray[1]; /* ARRAY of bank offsets */
|
||||
} ALBankFile;
|
||||
|
||||
void alBnkfNew(ALBankFile *f, u8 *table);
|
||||
#endif
|
||||
@@ -0,0 +1,99 @@
|
||||
#ifndef _LIBULTRA_INTERNAL_H_
|
||||
#define _LIBULTRA_INTERNAL_H_
|
||||
#include <ultra64.h>
|
||||
|
||||
/*
|
||||
* This define is needed because the original definitions in __osDequeueThread.c are declared
|
||||
* seperately instead of part of a single struct, however some code alises over this memory
|
||||
* assuming a unified structure. To fix this, we declare the full type here and then alias the
|
||||
* symbol names to the correct members in AVOID_UB.
|
||||
*/
|
||||
#ifdef AVOID_UB
|
||||
typedef struct OSThread_ListHead_s
|
||||
{
|
||||
/*0x00*/ struct OSThread_s *next;
|
||||
/*0x04*/ OSPri priority;
|
||||
/*0x08*/ struct OSThread_s *queue;
|
||||
/*0x0C*/ struct OSThread_s *tlnext;
|
||||
/*0x10*/ struct OSThread_s *unk10;
|
||||
/*0x14*/ u32 unk14;
|
||||
} OSThread_ListHead;
|
||||
|
||||
// Now fix the symbols to the new one.
|
||||
extern OSThread_ListHead D_80334890_fix;
|
||||
|
||||
#define D_80334890 D_80334890_fix.next
|
||||
#define D_80334894 D_80334890_fix.priority
|
||||
#define D_80334898 D_80334890_fix.queue
|
||||
#define D_8033489C D_80334890_fix.tlnext
|
||||
#define D_803348A0 D_80334890_fix.unk10
|
||||
|
||||
// Fix for the EEPROM array.
|
||||
extern u32 D_80365E00[16];
|
||||
|
||||
// alias the last array element correctly
|
||||
#define D_80365E3C D_80365E00[15]
|
||||
#else
|
||||
// Original OSThread_ListHead definitions
|
||||
extern OSThread *D_80334890;
|
||||
extern u32 D_80334894;
|
||||
extern OSThread *D_80334898;
|
||||
extern OSThread *D_8033489C;
|
||||
extern OSThread *D_803348A0;
|
||||
|
||||
// Original EEPROM definitions
|
||||
extern u32 D_80365E00[15];
|
||||
extern u32 D_80365E3C;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
u32 initialized; // probably something like initialized?
|
||||
OSThread *mgrThread;
|
||||
OSMesgQueue *cmdQueue;
|
||||
OSMesgQueue *eventQueue;
|
||||
OSMesgQueue *accessQueue;
|
||||
s32 (*dma_func)(s32, u32, void *, size_t);
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
s32 (*edma_func)(OSPiHandle*, s32, u32, void *, size_t);
|
||||
#else
|
||||
u64 force_align;
|
||||
#endif
|
||||
} OSMgrArgs;
|
||||
|
||||
s32 __osDisableInt(void);
|
||||
void __osRestoreInt(s32);
|
||||
void __osEnqueueAndYield(OSThread **);
|
||||
void __osDequeueThread(OSThread **, OSThread *);
|
||||
void __osEnqueueThread(OSThread **, OSThread *);
|
||||
OSThread *__osPopThread(OSThread **);
|
||||
s32 __osSiRawStartDma(s32, void *);
|
||||
void __osSiCreateAccessQueue(void);
|
||||
void __osSiGetAccess(void);
|
||||
void __osSiRelAccess(void);
|
||||
u32 __osProbeTLB(void *);
|
||||
void __osPiCreateAccessQueue(void);
|
||||
void __osPiGetAccess(void);
|
||||
void __osSetSR(u32);
|
||||
u32 __osGetSR(void);
|
||||
void __osSetFpcCsr(u32);
|
||||
s32 __osSiRawReadIo(void *, u32 *);
|
||||
s32 __osSiRawWriteIo(void *, u32);
|
||||
s32 osPiRawReadIo(u32 a0, u32 *a1);
|
||||
void __osSpSetStatus(u32);
|
||||
u32 __osSpGetStatus(void);
|
||||
s32 __osSpSetPc(void *);
|
||||
s32 __osSpDeviceBusy(void);
|
||||
s32 __osSiDeviceBusy(void);
|
||||
s32 __osSpRawStartDma(u32 dir, void *sp_ptr, void *dram_ptr, size_t size);
|
||||
void __osViInit(void);
|
||||
OSViContext *__osViGetCurrentContext(void);
|
||||
OSViContext *__osViGetCurrentContext2(void);
|
||||
void __osViSwapContext(void);
|
||||
void __osSetTimerIntr(u64);
|
||||
u64 __osInsertTimer(OSTimer *);
|
||||
void __osSetCompare(u32);
|
||||
s32 __osAiDeviceBusy(void);
|
||||
void __osDispatchThread(void);
|
||||
u32 __osGetCause(void);
|
||||
s32 __osAtomicDec(u32 *);
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,117 @@
|
||||
#ifndef MIXER_H
|
||||
#define MIXER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <ultra64.h>
|
||||
|
||||
#ifdef VERSION_SH
|
||||
#define NEW_AUDIO_UCODE
|
||||
#endif
|
||||
|
||||
#undef aSegment
|
||||
#undef aClearBuffer
|
||||
#undef aSetBuffer
|
||||
#undef aLoadBuffer
|
||||
#undef aSaveBuffer
|
||||
#undef aDMEMMove
|
||||
#undef aMix
|
||||
#undef aEnvMixer
|
||||
#undef aResample
|
||||
#undef aInterleave
|
||||
#undef aSetVolume
|
||||
#undef aSetVolume32
|
||||
#undef aSetLoop
|
||||
#undef aLoadADPCM
|
||||
#undef aADPCMdec
|
||||
#undef aS8Dec
|
||||
#undef aAddMixer
|
||||
#undef aDuplicate
|
||||
#undef aDMEMMove2
|
||||
#undef aResampleZoh
|
||||
#undef aDownsampleHalf
|
||||
#undef aEnvSetup1
|
||||
#undef aEnvSetup2
|
||||
#undef aFilter
|
||||
#undef aHiLoGain
|
||||
#undef aUnknown25
|
||||
|
||||
void aClearBufferImpl(uint16_t addr, int nbytes);
|
||||
void aLoadADPCMImpl(int num_entries_times_16, const int16_t *book_source_addr);
|
||||
void aSetBufferImpl(uint8_t flags, uint16_t in, uint16_t out, uint16_t nbytes);
|
||||
void aDMEMMoveImpl(uint16_t in_addr, uint16_t out_addr, int nbytes);
|
||||
void aSetLoopImpl(ADPCM_STATE *adpcm_loop_state);
|
||||
void aADPCMdecImpl(uint8_t flags, ADPCM_STATE state);
|
||||
void aResampleImpl(uint8_t flags, uint16_t pitch, RESAMPLE_STATE state);
|
||||
|
||||
#ifndef NEW_AUDIO_UCODE
|
||||
void aSetVolumeImpl(uint8_t flags, int16_t v, int16_t t, int16_t r);
|
||||
void aLoadBufferImpl(const void *source_addr);
|
||||
void aSaveBufferImpl(int16_t *dest_addr);
|
||||
void aInterleaveImpl(uint16_t left, uint16_t right);
|
||||
void aMixImpl(int16_t gain, uint16_t in_addr, uint16_t out_addr);
|
||||
void aEnvMixerImpl(uint8_t flags, ENVMIX_STATE state);
|
||||
#else
|
||||
void aLoadBufferImpl(const void *source_addr, uint16_t dest_addr, uint16_t nbytes);
|
||||
void aSaveBufferImpl(uint16_t source_addr, int16_t *dest_addr, uint16_t nbytes);
|
||||
void aInterleaveImpl(uint16_t dest, uint16_t left, uint16_t right, uint16_t c);
|
||||
void aMixImpl(int16_t gain, uint16_t in_addr, uint16_t out_addr, uint16_t count);
|
||||
void aEnvSetup1Impl(uint8_t initial_vol_wet, uint16_t rate_wet, uint16_t rate_left, uint16_t rate_right);
|
||||
void aEnvSetup2Impl(uint16_t initial_vol_left, uint16_t initial_vol_right);
|
||||
void aEnvMixerImpl(uint16_t in_addr, uint16_t n_samples, bool swap_reverb,
|
||||
bool neg_left, bool neg_right,
|
||||
uint16_t dry_left_addr, uint16_t dry_right_addr,
|
||||
uint16_t wet_left_addr, uint16_t wet_right_addr);
|
||||
void aS8DecImpl(uint8_t flags, ADPCM_STATE state);
|
||||
void aAddMixerImpl(uint16_t in_addr, uint16_t out_addr, uint16_t count);
|
||||
void aDuplicateImpl(uint16_t in_addr, uint16_t out_addr, uint16_t count);
|
||||
void aDMEMMove2Impl(uint8_t t, uint16_t in_addr, uint16_t out_addr, uint16_t count);
|
||||
void aResampleZohImpl(uint16_t pitch, uint16_t start_fract);
|
||||
void aDownsampleHalfImpl(uint16_t n_samples, uint16_t in_addr, uint16_t out_addr);
|
||||
void aFilterImpl(uint8_t flags, uint16_t count_or_buf, int16_t state_or_filter[8]);
|
||||
void aHiLoGainImpl(uint8_t g, uint16_t count, uint16_t addr);
|
||||
void aUnknown25Impl(uint8_t f, uint16_t count, uint16_t out_addr, uint16_t in_addr);
|
||||
#endif
|
||||
|
||||
#define aSegment(pkt, s, b) do { } while(0)
|
||||
#define aClearBuffer(pkt, d, c) aClearBufferImpl(d, c)
|
||||
#define aLoadADPCM(pkt, c, d) aLoadADPCMImpl(c, d)
|
||||
#define aSetBuffer(pkt, f, i, o, c) aSetBufferImpl(f, i, o, c)
|
||||
#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)
|
||||
|
||||
#ifndef NEW_AUDIO_UCODE
|
||||
#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 aLoadBuffer(pkt, s) aLoadBufferImpl(s)
|
||||
#define aSaveBuffer(pkt, s) aSaveBufferImpl(s)
|
||||
#define aInterleave(pkt, l, r) aInterleaveImpl(l, r)
|
||||
#define aMix(pkt, f, g, i, o) aMixImpl(g, i, o)
|
||||
#define aEnvMixer(pkt, f, s) aEnvMixerImpl(f, s)
|
||||
#else
|
||||
#define aLoadBuffer(pkt, s, d, c) aLoadBufferImpl(s, d, c)
|
||||
#define aSaveBuffer(pkt, s, d, c) aSaveBufferImpl(s, d, c)
|
||||
#define aInterleave(pkt, o, l, r, c) aInterleaveImpl(o, l, r, c)
|
||||
#define aMix(pkt, g, i, o, c) aMixImpl(g, i, o, c)
|
||||
#define aEnvSetup1(pkt, initialVolReverb, rampReverb, rampLeft, rampRight) \
|
||||
aEnvSetup1Impl(initialVolReverb, rampReverb, rampLeft, rampRight)
|
||||
#define aEnvSetup2(pkt, initialVolLeft, initialVolRight) \
|
||||
aEnvSetup2Impl(initialVolLeft, initialVolRight)
|
||||
#define aEnvMixer(pkt, inBuf, nSamples, swapReverb, negLeft, negRight, \
|
||||
dryLeft, dryRight, wetLeft, wetRight) \
|
||||
aEnvMixerImpl(inBuf, nSamples, swapReverb, negLeft, negRight, \
|
||||
dryLeft, dryRight, wetLeft, wetRight)
|
||||
#define aS8Dec(pkt, f, s) aS8DecImpl(f, s)
|
||||
#define aAddMixer(pkt, s, d, c) aAddMixerImpl(s, d, c)
|
||||
#define aDuplicate(pkt, s, d, c) aDuplicateImpl(s, d, c)
|
||||
#define aDMEMMove2(pkt, t, i, o, c) aDMEMMove2Impl(t, i, o, c)
|
||||
#define aResampleZoh(pkt, pitch, startFract) aResampleZohImpl(pitch, startFract)
|
||||
#define aDownsampleHalf(pkt, nSamples, i, o) aDownsampleHalfImpl(nSamples, i, o)
|
||||
#define aFilter(pkt, f, countOrBuf, addr) aFilterImpl(f, countOrBuf, addr)
|
||||
#define aHiLoGain(pkt, g, buflen, i) aHiLoGainImpl(g, buflen, i)
|
||||
#define aUnknown25(pkt, f, c, o, i) aUnknown25Impl(f, c, o, i)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,216 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "libultra_internal.h"
|
||||
#include <macros.h>
|
||||
|
||||
#ifdef TARGET_WEB
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
extern OSMgrArgs piMgrArgs;
|
||||
|
||||
u64 osClockRate = 62500000;
|
||||
|
||||
s32 osPiStartDma(UNUSED OSIoMesg *mb, UNUSED s32 priority, UNUSED s32 direction,
|
||||
uintptr_t devAddr, void *vAddr, size_t nbytes,
|
||||
UNUSED OSMesgQueue *mq) {
|
||||
memcpy(vAddr, (const void *) devAddr, nbytes);
|
||||
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) {
|
||||
}
|
||||
s32 osJamMesg(UNUSED OSMesgQueue *mq, UNUSED OSMesg msg, UNUSED s32 flag) {
|
||||
return 0;
|
||||
}
|
||||
s32 osSendMesg(UNUSED OSMesgQueue *mq, UNUSED OSMesg msg, UNUSED s32 flag) {
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
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;
|
||||
}
|
||||
s32 osRecvMesg(UNUSED OSMesgQueue *mq, UNUSED OSMesg *msg, UNUSED s32 flag) {
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
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;
|
||||
}
|
||||
|
||||
uintptr_t osVirtualToPhysical(void *addr) {
|
||||
return (uintptr_t) addr;
|
||||
}
|
||||
|
||||
void osCreateViManager(UNUSED OSPri pri) {
|
||||
}
|
||||
void osViSetMode(UNUSED OSViMode *mode) {
|
||||
}
|
||||
void osViSetEvent(UNUSED OSMesgQueue *mq, UNUSED OSMesg msg, UNUSED u32 retraceCount) {
|
||||
}
|
||||
void osViBlack(UNUSED u8 active) {
|
||||
}
|
||||
void osViSetSpecialFeatures(UNUSED u32 func) {
|
||||
}
|
||||
void osViSwapBuffer(UNUSED void *vaddr) {
|
||||
}
|
||||
|
||||
OSTime osGetTime(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void osWritebackDCacheAll(void) {
|
||||
}
|
||||
|
||||
void osWritebackDCache(UNUSED void *a, UNUSED size_t b) {
|
||||
}
|
||||
|
||||
void osInvalDCache(UNUSED void *a, UNUSED size_t b) {
|
||||
}
|
||||
|
||||
u32 osGetCount(void) {
|
||||
static u32 counter;
|
||||
return counter++;
|
||||
}
|
||||
|
||||
s32 osAiSetFrequency(u32 freq) {
|
||||
u32 a1;
|
||||
s32 a2;
|
||||
u32 D_8033491C;
|
||||
|
||||
#ifdef VERSION_EU
|
||||
D_8033491C = 0x02E6025C;
|
||||
#else
|
||||
D_8033491C = 0x02E6D354;
|
||||
#endif
|
||||
|
||||
a1 = D_8033491C / (float) freq + .5f;
|
||||
|
||||
if (a1 < 0x84) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
a2 = (a1 / 66) & 0xff;
|
||||
if (a2 > 16) {
|
||||
a2 = 16;
|
||||
}
|
||||
|
||||
return D_8033491C / (s32) a1;
|
||||
}
|
||||
|
||||
s32 osEepromProbe(UNUSED OSMesgQueue *mq) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
s32 osEepromLongRead(UNUSED OSMesgQueue *mq, u8 address, u8 *buffer, int nbytes) {
|
||||
u8 content[512];
|
||||
s32 ret = -1;
|
||||
|
||||
#ifdef TARGET_WEB
|
||||
if (EM_ASM_INT({
|
||||
var s = localStorage.sm64_save_file;
|
||||
if (s && s.length === 684) {
|
||||
try {
|
||||
var binary = atob(s);
|
||||
if (binary.length === 512) {
|
||||
for (var i = 0; i < 512; i++) {
|
||||
HEAPU8[$0 + i] = binary.charCodeAt(i);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}, content)) {
|
||||
memcpy(buffer, content + address * 8, nbytes);
|
||||
ret = 0;
|
||||
}
|
||||
#else
|
||||
FILE *fp = fopen("sm64_save_file.bin", "rb");
|
||||
if (fp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (fread(content, 1, 512, fp) == 512) {
|
||||
memcpy(buffer, content + address * 8, nbytes);
|
||||
ret = 0;
|
||||
}
|
||||
fclose(fp);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 osEepromLongWrite(UNUSED OSMesgQueue *mq, u8 address, u8 *buffer, int nbytes) {
|
||||
u8 content[512] = {0};
|
||||
if (address != 0 || nbytes != 512) {
|
||||
osEepromLongRead(mq, 0, content, 512);
|
||||
}
|
||||
memcpy(content + address * 8, buffer, nbytes);
|
||||
|
||||
#ifdef TARGET_WEB
|
||||
EM_ASM({
|
||||
var str = "";
|
||||
for (var i = 0; i < 512; i++) {
|
||||
str += String.fromCharCode(HEAPU8[$0 + i]);
|
||||
}
|
||||
localStorage.sm64_save_file = btoa(str);
|
||||
}, content);
|
||||
s32 ret = 0;
|
||||
#else
|
||||
FILE* fp = fopen("sm64_save_file.bin", "wb");
|
||||
if (fp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
s32 ret = fwrite(content, 1, 512, fp) == 512 ? 0 : -1;
|
||||
fclose(fp);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 gNumVblanks;
|
||||
|
||||
s32 osMotorInit(UNUSED OSMesgQueue *mq, UNUSED void *pfs, UNUSED int channel) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 osMotorStart(UNUSED void *pfs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 osMotorStop(UNUSED void *pfs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
OSPiHandle *osCartRomInit(void) {
|
||||
static OSPiHandle handle;
|
||||
return &handle;
|
||||
}
|
||||
|
||||
OSPiHandle *osDriveRomInit(void) {
|
||||
static OSPiHandle handle;
|
||||
return &handle;
|
||||
}
|
||||
|
||||
s32 osEPiStartDma(UNUSED OSPiHandle *pihandle, OSIoMesg *mb, UNUSED s32 direction) {
|
||||
memcpy(mb->dramAddr, (const void *) mb->devAddr, mb->size);
|
||||
osSendMesg(mb->hdr.retQueue, mb, OS_MESG_NOBLOCK);
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define TYPE_CTL 1
|
||||
#define TYPE_TBL 2
|
||||
#define TYPE_SEQ 3
|
||||
|
||||
struct CLoop
|
||||
{
|
||||
unsigned int start;
|
||||
unsigned int end;
|
||||
int count;
|
||||
unsigned int pad;
|
||||
short state[1];
|
||||
};
|
||||
|
||||
|
||||
struct CBook
|
||||
{
|
||||
int order; // must be 2
|
||||
int npredictors; // must be 2
|
||||
short table[32]; // 8 * order * npredictors
|
||||
};
|
||||
|
||||
struct CSample{
|
||||
unsigned int zero;
|
||||
uintptr_t addr;
|
||||
struct CLoop* loop; // must not be null
|
||||
struct CBook* book; // must not be null
|
||||
unsigned int sample_size;
|
||||
};
|
||||
|
||||
struct CSound{
|
||||
struct CSample* sample_addr;
|
||||
float tuning;
|
||||
};
|
||||
|
||||
struct delay_arg{
|
||||
unsigned short delay;
|
||||
unsigned short arg;
|
||||
};
|
||||
|
||||
struct CEnvelope{
|
||||
struct delay_arg delay_args[1]; // array of [(delay,arg)]
|
||||
};
|
||||
|
||||
struct CDrum{
|
||||
unsigned char release_rate;
|
||||
unsigned char pan;
|
||||
unsigned char loaded;
|
||||
unsigned char pad;
|
||||
struct CSound snd;
|
||||
struct CEnvelope* env_addr;
|
||||
};
|
||||
|
||||
struct CInstrument{
|
||||
unsigned char loaded;
|
||||
unsigned char normal_range_lo;
|
||||
unsigned char normal_range_hi;
|
||||
unsigned char release_rate;
|
||||
struct CEnvelope* env_addr;
|
||||
struct CSound sound_lo;
|
||||
struct CSound sound_med;
|
||||
struct CSound sound_hi;
|
||||
};
|
||||
|
||||
struct TBL{
|
||||
unsigned char* data;
|
||||
};
|
||||
|
||||
struct SEQ{
|
||||
unsigned char* data;
|
||||
};
|
||||
|
||||
struct CTL
|
||||
{
|
||||
unsigned int numInstruments;
|
||||
unsigned int numDrums;
|
||||
unsigned int shared;
|
||||
unsigned int iso_date;
|
||||
struct CDrum** drum_pointers;
|
||||
struct CInstrument* instrument_pointers[1];
|
||||
};
|
||||
|
||||
struct seqObject{
|
||||
uintptr_t offset __attribute__((aligned (8)));
|
||||
unsigned int len __attribute__((aligned (8)));
|
||||
};
|
||||
|
||||
struct seqFile{
|
||||
unsigned short revision;
|
||||
unsigned short seqCount;
|
||||
unsigned int pad;
|
||||
struct seqObject seqArray[1];
|
||||
} __attribute__((aligned (16)));
|
||||
@@ -0,0 +1,374 @@
|
||||
#pragma once
|
||||
#include "convUtils.h"
|
||||
|
||||
#include "utils.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include "convUtils.h"
|
||||
#include "convTypes.h"
|
||||
|
||||
/**
|
||||
* This code is based on the only documentation that exists (that I know of) for the SM64 CTL/TBL format
|
||||
* as well as dylanpdx's audio extraction implementation.
|
||||
* https://github.com/n64decomp/sm64/blob/1372ae1bb7cbedc03df366393188f4f05dcfc422/tools/disassemble_sound.py
|
||||
* https://github.com/n64decomp/sm64/blob/1372ae1bb7cbedc03df366393188f4f05dcfc422/tools/assemble_sound.py
|
||||
* https://github.com/Retro64Mod/libsm64-retro64
|
||||
*/
|
||||
|
||||
#define ALIGN16(val) (((val) + 0xF) & ~0xF)
|
||||
|
||||
unsigned char* gCtlSeqs;
|
||||
|
||||
struct seqFile* parse_seqfile(unsigned char* seq){ /* Read SeqFile data */
|
||||
short revision = read_u16_be(seq);
|
||||
short bankCount = read_u16_be(seq + 2);
|
||||
|
||||
unsigned int size = sizeof(struct seqFile) + (bankCount-1) * sizeof(struct seqObject);
|
||||
|
||||
struct seqFile* seqFile = (struct seqFile*)calloc(size, 1);
|
||||
seqFile->revision = revision;
|
||||
seqFile->seqCount = bankCount;
|
||||
for (int i = 0; i < bankCount; i++){ // read bank offsets and sizes
|
||||
seqFile->seqArray[i].offset = (uintptr_t)read_u32_be(seq + 4 + i * 8);
|
||||
seqFile->seqArray[i].len = read_u32_be((seq + 4 + i * 8 + 4));
|
||||
}
|
||||
|
||||
if (revision == TYPE_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;
|
||||
for (int i = 0; i < bankCount; i++){
|
||||
uintptr_t start = pos;
|
||||
struct CTL* ptr = parse_ctl_data(seq+(seqFile->seqArray[i].offset), &pos);
|
||||
seqFile->seqArray[i].offset = ptr;
|
||||
seqFile->seqArray[i].len = (unsigned int)(pos - start);
|
||||
}
|
||||
}else if (revision == TYPE_TBL){
|
||||
// TBL file, contains raw audio data
|
||||
for (int i = 0; i < bankCount; i++){
|
||||
seqFile->seqArray[i].offset = seq+(seqFile->seqArray[i].offset);
|
||||
}
|
||||
}else if (revision == TYPE_SEQ){
|
||||
// SEQ file, contains music files (*.m64)
|
||||
for (int i = 0; i < bankCount; i++){
|
||||
seqFile->seqArray[i].offset = seq+(seqFile->seqArray[i].offset);
|
||||
}
|
||||
}
|
||||
|
||||
return seqFile;
|
||||
}
|
||||
|
||||
void ctl_free(){
|
||||
free(gCtlSeqs);
|
||||
}
|
||||
|
||||
void snd_ptrs_to_offsets(struct CSound* snd, uintptr_t ctlData){
|
||||
struct CSample* smp = snd->sample_addr;
|
||||
if((uintptr_t)(smp->loop) > ctlData)
|
||||
smp->loop = (struct CLoop*)((uintptr_t)(smp->loop) - ctlData);
|
||||
if((uintptr_t)(smp->book) > ctlData)
|
||||
smp->book = (struct CBook*)((uintptr_t)(smp->book) - ctlData);
|
||||
snd->sample_addr = (struct CSample*)((uintptr_t)(snd->sample_addr) - ctlData);
|
||||
}
|
||||
|
||||
void ptrs_to_offsets(struct seqFile* ctl){
|
||||
if (ctl->revision != TYPE_CTL){
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ctl->seqCount; i++){
|
||||
struct CTL* ptr = (struct CTL*)ctl->seqArray[i].offset;
|
||||
uintptr_t ctlData = (uintptr_t)ptr + 0x10;
|
||||
// find all samples in the CTL file
|
||||
for (int j = 0; j < ptr->numInstruments; j++){
|
||||
struct CInstrument* inst = ptr->instrument_pointers[j];
|
||||
if (inst==0x0)
|
||||
continue; // null instrument.
|
||||
inst->env_addr = (struct CEnvelope*)((uintptr_t)inst->env_addr - ctlData);
|
||||
if (inst->sound_hi.sample_addr!=0x0){
|
||||
snd_ptrs_to_offsets(&(inst->sound_hi), ctlData);
|
||||
}
|
||||
if (inst->sound_med.sample_addr!=0x0){
|
||||
snd_ptrs_to_offsets(&(inst->sound_med), ctlData);
|
||||
}
|
||||
if (inst->sound_lo.sample_addr!=0x0){
|
||||
snd_ptrs_to_offsets(&(inst->sound_lo), ctlData);
|
||||
}
|
||||
ptr->instrument_pointers[j] = (struct CInstrument*)((uintptr_t)(inst) - ctlData);
|
||||
}
|
||||
if(ptr->numDrums != 0){
|
||||
for (int j = 0; j < ptr->numDrums; j++){
|
||||
struct CDrum* drum = ptr->drum_pointers[j];
|
||||
if (drum==0x0)
|
||||
continue; // null drum.
|
||||
drum->env_addr = (struct CEnvelope*)((uintptr_t)drum->env_addr - ctlData);
|
||||
if (drum->snd.sample_addr!=0x0){
|
||||
snd_ptrs_to_offsets(&(drum->snd), ctlData);
|
||||
}
|
||||
ptr->drum_pointers[j] = (struct CDrum*)((uintptr_t)(drum) - ctlData);
|
||||
}
|
||||
ptr->drum_pointers = (struct CDrum**)((uintptr_t)(ptr->drum_pointers) - ctlData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct CLoop* parse_loop(unsigned char* loop, uintptr_t* pos){
|
||||
uint32_t count = read_u32_be(loop + 8); // variable is signed, but the data is being read as unsigned.
|
||||
unsigned int size = sizeof(struct CLoop) - 4;
|
||||
if(count != 0){
|
||||
size = sizeof(struct CLoop) - 4 + sizeof(short) * 16;
|
||||
}
|
||||
struct CLoop* loop_ptr = (struct CLoop*)(*pos);
|
||||
*pos += size;
|
||||
*pos = ALIGN16(*pos);
|
||||
|
||||
loop_ptr->start = read_u32_be(loop);
|
||||
loop_ptr->end = read_u32_be(loop + 4);
|
||||
loop_ptr->count = count;
|
||||
loop_ptr->pad = read_u32_be(loop + 12);
|
||||
|
||||
if (loop_ptr->count!=0){
|
||||
for (int i = 0;i<16;i++){
|
||||
loop_ptr->state[i]=read_u16_be(loop + 16 + i*2);
|
||||
}
|
||||
}
|
||||
|
||||
return loop_ptr;
|
||||
}
|
||||
|
||||
struct CBook* parse_book(unsigned char* book, uintptr_t* pos){
|
||||
struct CBook* book_ptr = (struct CBook*)(*pos);
|
||||
*pos += sizeof(struct CBook);
|
||||
*pos = ALIGN16(*pos);
|
||||
book_ptr->order = read_u32_be(book);
|
||||
book_ptr->npredictors = read_u32_be(book + 4); // both are signed
|
||||
unsigned char* table_data = book+8;
|
||||
for (int i = 0; i < 8 * book_ptr->order * book_ptr->npredictors; i ++){
|
||||
book_ptr->table[i] = read_u16_be(table_data + i * 2);
|
||||
}
|
||||
return book_ptr;
|
||||
}
|
||||
|
||||
struct CSample* parse_sample(unsigned char* sample,unsigned char* ctl, uintptr_t* pos){
|
||||
struct CSample* samp = (struct CSample*)(*pos);
|
||||
*pos += sizeof(struct CSample);
|
||||
*pos = ALIGN16(*pos);
|
||||
samp->zero=read_u32_be(sample);
|
||||
samp->addr=read_u32_be(sample+4);
|
||||
samp->loop=read_u32_be(sample+8);// loop address
|
||||
samp->book=read_u32_be(sample+12);// book address
|
||||
samp->sample_size=read_u32_be(sample+16);
|
||||
|
||||
samp->book=parse_book(ctl+((uintptr_t)samp->book), pos);
|
||||
samp->loop=parse_loop(ctl+((uintptr_t)samp->loop), pos);
|
||||
return samp;
|
||||
}
|
||||
|
||||
struct CSound* parse_sound(unsigned char* sound,unsigned char* ctl, uintptr_t* pos, uintptr_t sndPos, struct SampleList* samples){
|
||||
struct CSound* snd = (struct CSound*)(sndPos);
|
||||
snd->sample_addr=read_u32_be(sound);
|
||||
snd->tuning = (float)read_f32_be(sound+4);
|
||||
// if sample_addr is 0 then the sound is null
|
||||
if (snd->sample_addr!=0){
|
||||
int smpIndex = -1;
|
||||
for(int i = 0; i < samples->count; i++){
|
||||
if(samples->orig_addrs[i] == (uintptr_t)(snd->sample_addr)){
|
||||
smpIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(smpIndex < 0){
|
||||
samples->orig_addrs[samples->count] = (uintptr_t)(snd->sample_addr);
|
||||
snd->sample_addr = parse_sample(ctl+((uintptr_t)snd->sample_addr),ctl, pos);
|
||||
samples->addrs[samples->count] = snd->sample_addr;
|
||||
samples->count++;
|
||||
} else {
|
||||
snd->sample_addr = samples->addrs[smpIndex];
|
||||
}
|
||||
}
|
||||
return snd;
|
||||
}
|
||||
|
||||
struct CDrum* parse_drum(unsigned char* drum,unsigned char* ctl, uintptr_t* pos, struct SampleList* samples){ /* Read Drum data */
|
||||
struct CDrum* drumData = malloc(sizeof(struct CDrum));
|
||||
drumData->release_rate = drum[0];
|
||||
drumData->pan = drum[1];
|
||||
drumData->loaded = drum[2];
|
||||
drumData->pad = drum[3];
|
||||
drumData->snd=*parse_sound(drum+4,ctl, pos, &drumData->snd, samples);
|
||||
drumData->env_addr=read_u32_be(drum+12);
|
||||
return drumData;
|
||||
}
|
||||
|
||||
struct CEnvelope* parse_envelope(unsigned char* env, uintptr_t* pos, int* size){
|
||||
int count = 0;
|
||||
while(1){
|
||||
unsigned short delay = read_u16_le(env + count * 4);
|
||||
unsigned short arg = read_u16_le(env + count * 4 + 2);
|
||||
unsigned short delayC = (-delay);
|
||||
count++;
|
||||
if ((1 <= delayC && delayC <= 3) || delay == 0)
|
||||
break;
|
||||
}
|
||||
*size = sizeof(struct CEnvelope) + sizeof(struct delay_arg) * (count-1);
|
||||
struct CEnvelope* envData = malloc(*size);
|
||||
for (int i = 0; i < count; i++){
|
||||
envData->delay_args[i].delay = read_u16_le(env + i * 4);
|
||||
envData->delay_args[i].arg = read_u16_le(env + i * 4 + 2);
|
||||
}
|
||||
return envData;
|
||||
}
|
||||
|
||||
struct CInstrument* parse_instrument(unsigned char* instrument,unsigned char* ctl, uintptr_t* pos, struct SampleList* samples){
|
||||
struct CInstrument* inst = malloc(sizeof(struct CInstrument));
|
||||
inst->loaded = instrument[0];
|
||||
inst->normal_range_lo = instrument[1];
|
||||
inst->normal_range_hi = instrument[2];
|
||||
inst->release_rate = instrument[3];
|
||||
inst->env_addr=read_u32_be(instrument+4);
|
||||
inst->sound_lo=*parse_sound(instrument+8,ctl, pos, &(inst->sound_lo), samples);
|
||||
inst->sound_med=*parse_sound(instrument+16,ctl, pos, &(inst->sound_med), samples);
|
||||
inst->sound_hi=*parse_sound(instrument+24,ctl, pos, &(inst->sound_hi), samples);
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
struct TBL* parse_tbl_data(unsigned char* tbl){
|
||||
struct TBL* tblData = malloc(sizeof(struct TBL));
|
||||
tblData->data = tbl;
|
||||
return tblData;
|
||||
}
|
||||
|
||||
struct SEQ* parse_seq_data(unsigned char* seq){
|
||||
struct SEQ* seqData = malloc(sizeof(struct SEQ));
|
||||
seqData->data = seq;
|
||||
return seqData;
|
||||
}
|
||||
|
||||
struct CTL* parse_ctl_data(unsigned char* ctlData, uintptr_t* pos){
|
||||
int instruments=read_u32_be(ctlData);
|
||||
unsigned int size = sizeof(struct CTL) + sizeof(struct CInstrument*) * (instruments-1);
|
||||
struct CTL* ctl = (struct CTL*)(*pos);
|
||||
*pos += size;
|
||||
*pos = ALIGN16(*pos);
|
||||
#pragma region Parse CTL header
|
||||
ctl->numInstruments = read_u32_be(ctlData);
|
||||
ctl->numDrums = read_u32_be(ctlData + 4);
|
||||
ctl->shared = read_u32_be(ctlData + 8);
|
||||
ctl->iso_date = read_u32_be(ctlData + 12);
|
||||
#pragma endregion
|
||||
struct SampleList samples = {0};
|
||||
struct EnvelopeMeta envData[128] = {0};
|
||||
int envCount = 0;
|
||||
samples.count = 0;
|
||||
// header parsed, now read data
|
||||
if(ctl->numDrums != 0) {
|
||||
ctl->drum_pointers= (struct CDrum**)(*pos);
|
||||
size = sizeof(struct CDrum*) * ctl->numDrums;
|
||||
*pos += size;
|
||||
*pos = ALIGN16(*pos);
|
||||
int drumTablePtr = read_u32_be(ctlData + 16);
|
||||
for (int i = 0; i < ctl->numDrums; i++){
|
||||
uint32_t data = read_u32_be(ctlData + drumTablePtr+16 + i * 4);
|
||||
|
||||
struct CDrum* d = parse_drum(ctlData+data+16,ctlData+16, pos, &samples);
|
||||
bool used = 0;
|
||||
for(int j = 0; j < envCount; j++){
|
||||
if(envData[j].orig == (uintptr_t)d->env_addr){
|
||||
used = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(used == 0){
|
||||
int size = 0;
|
||||
unsigned char* addr = ctlData+((uintptr_t)d->env_addr)+16;
|
||||
envData[envCount].orig = (uintptr_t)(d->env_addr);
|
||||
envData[envCount].addr = parse_envelope(addr, pos, &size);
|
||||
envData[envCount].size = size;
|
||||
envCount++;
|
||||
}
|
||||
ctl->drum_pointers[i] = d;
|
||||
}
|
||||
*pos = ALIGN16(*pos);
|
||||
} else {
|
||||
ctl->drum_pointers= NULL;
|
||||
}
|
||||
// parse instrument data
|
||||
int instTablePtr = 4;
|
||||
for (int i = 0; i < ctl->numInstruments; i++){
|
||||
uint32_t data = read_u32_be(ctlData + 16 + instTablePtr + i * 4);
|
||||
if (data == 0)
|
||||
continue;
|
||||
struct CInstrument* inst = parse_instrument(ctlData+16+data,ctlData+16, pos, &samples);
|
||||
bool used = 0;
|
||||
for(int j = 0; j < envCount; j++){
|
||||
if(envData[j].orig == (uintptr_t)inst->env_addr){
|
||||
used = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(used == 0){
|
||||
int size = 0;
|
||||
unsigned char* addr = ctlData+((uintptr_t)inst->env_addr)+16;
|
||||
envData[envCount].orig = (uintptr_t)(inst->env_addr);
|
||||
envData[envCount].addr = parse_envelope(addr, pos, &size);
|
||||
envData[envCount].size = size;
|
||||
envCount++;
|
||||
}
|
||||
ctl->instrument_pointers[i] = inst;
|
||||
}
|
||||
*pos = ALIGN16(*pos);
|
||||
|
||||
// Copy envelopes to ctl
|
||||
for (int i = 0; i < envCount; i++){
|
||||
struct CEnvelope* env = envData[i].addr;
|
||||
memcpy((uint8_t*)(*pos), env, envData[i].size);
|
||||
for (int j = 0; j < ctl->numInstruments; j++){
|
||||
struct CInstrument* inst = ctl->instrument_pointers[j];
|
||||
if (inst == 0x0)
|
||||
continue;
|
||||
if((uintptr_t)(inst->env_addr) == envData[i].orig){
|
||||
inst->env_addr = (struct CEnvelope*)(*pos);
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < ctl->numDrums; j++){
|
||||
struct CDrum* drum = ctl->drum_pointers[j];
|
||||
if (drum == 0x0)
|
||||
continue;
|
||||
if((uintptr_t)(drum->env_addr) == envData[i].orig){
|
||||
drum->env_addr = (struct CEnvelope*)(*pos);
|
||||
}
|
||||
}
|
||||
free(env);
|
||||
*pos += envData[i].size;
|
||||
}
|
||||
*pos = ALIGN16(*pos);
|
||||
|
||||
// Copy instruments to ctl
|
||||
for (int i = 0; i < ctl->numInstruments; i++){
|
||||
struct CInstrument* inst = ctl->instrument_pointers[i];
|
||||
if (inst == 0x0)
|
||||
continue;
|
||||
memcpy((uint8_t*)(*pos), inst, sizeof(struct CInstrument));
|
||||
free(inst);
|
||||
ctl->instrument_pointers[i] = (struct CInstrument*)(*pos);
|
||||
*pos += sizeof(struct CInstrument);
|
||||
}
|
||||
*pos = ALIGN16(*pos);
|
||||
|
||||
// Copy drums to ctl
|
||||
for (int i = 0; i < ctl->numDrums; i++){
|
||||
struct CDrum* drum = ctl->drum_pointers[i];
|
||||
if (drum == 0x0)
|
||||
continue;
|
||||
memcpy((uint8_t*)(*pos), drum, sizeof(struct CDrum));
|
||||
free(drum);
|
||||
ctl->drum_pointers[i] = (struct CDrum*)(*pos);
|
||||
*pos += sizeof(struct CDrum);
|
||||
}
|
||||
*pos = ALIGN16(*pos);
|
||||
//
|
||||
|
||||
return ctl;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../pc/libaudio_internal.h"
|
||||
|
||||
#define read_u16_le(p) ((uint8_t*)p)[1] * 0x100u + ((uint8_t*)p)[0]
|
||||
|
||||
struct EnvelopeMeta {
|
||||
uintptr_t orig;
|
||||
struct CEnvelope* addr;
|
||||
int size;
|
||||
};
|
||||
|
||||
struct SampleList {
|
||||
int count;
|
||||
uintptr_t orig_addrs[256];
|
||||
struct CSample* addrs[256];
|
||||
};
|
||||
|
||||
struct seqFile* parse_seqfile(unsigned char* seq);
|
||||
struct CTL* parse_ctl_data(unsigned char* ctlData, uintptr_t* pos);
|
||||
struct TBL* parse_tbl_data(unsigned char* tbl);
|
||||
struct SEQ* parse_seq_data(unsigned char* seq);
|
||||
void ptrs_to_offsets(struct seqFile* ctl);
|
||||
void ctl_free();
|
||||
#define INITIAL_GFX_ALLOC 10
|
||||
#define INITIAL_GEO_ALLOC 10
|
||||
@@ -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"
|
||||
@@ -29,6 +30,7 @@
|
||||
#include "load_surfaces.h"
|
||||
#include "gfx_adapter.h"
|
||||
#include "load_anim_data.h"
|
||||
#include "load_audio_data.h"
|
||||
#include "load_tex_data.h"
|
||||
#include "obj_pool.h"
|
||||
|
||||
@@ -134,6 +136,30 @@ SM64_LIB_FN void sm64_global_terminate( void )
|
||||
memory_terminate();
|
||||
}
|
||||
|
||||
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 ) {
|
||||
if ( !is_audio_initialized ) {
|
||||
DEBUG_PRINT("Attempted to tick audio, but sm64_audio_init() has not been called yet.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
update_game_sound();
|
||||
|
||||
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 )
|
||||
{
|
||||
surfaces_load_static( surfaceArray, numSurfaces );
|
||||
|
||||
@@ -133,6 +133,9 @@ 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 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 );
|
||||
|
||||
extern SM64_LIB_FN int32_t sm64_mario_create( float x, float y, float z );
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "load_audio_data.h"
|
||||
|
||||
#include "decomp/tools/convUtils.h"
|
||||
#include "decomp/audio/load.h"
|
||||
#include "decomp/audio/load_dat.h"
|
||||
|
||||
bool is_audio_initialized = false;
|
||||
|
||||
extern void load_audio_banks( uint8_t *rom ) {
|
||||
uint8_t *rom2 = malloc( 0x800000 );
|
||||
|
||||
memcpy( rom2, rom, 0x800000 );
|
||||
rom = rom2;
|
||||
gSoundDataADSR = parse_seqfile( rom+0x57B720 ); //ctl
|
||||
gSoundDataRaw = parse_seqfile( rom+0x593560 ); //tbl
|
||||
gMusicData = parse_seqfile( rom+0x7B0860 );
|
||||
gBankSetsData = rom+0x7CC621;
|
||||
memmove( gBankSetsData+0x45,gBankSetsData+0x45-1,0x5B );
|
||||
gBankSetsData[0x45]=0x00;
|
||||
ptrs_to_offsets( gSoundDataADSR );
|
||||
|
||||
audio_init();
|
||||
sound_init();
|
||||
sound_reset( 0 );
|
||||
|
||||
is_audio_initialized = true;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern bool is_audio_initialized;
|
||||
|
||||
extern void load_audio_banks( uint8_t *rom );
|
||||
@@ -1,8 +1,19 @@
|
||||
#include "play_sound.h"
|
||||
|
||||
#include "decomp/audio/external.h"
|
||||
#include "debug_print.h"
|
||||
#include "load_audio_data.h"
|
||||
|
||||
SM64PlaySoundFunctionPtr g_play_sound_func = NULL;
|
||||
|
||||
extern void play_sound( uint32_t soundBits, f32 *pos ) {
|
||||
if ( is_audio_initialized ) {
|
||||
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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user