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