Introduced the ability to parse audio tables from the ROM!
This commit is contained in:
@@ -99,9 +99,9 @@ s8 gAudioUpdatesPerFrame;
|
||||
extern u64 gAudioGlobalsStartMarker;
|
||||
extern u64 gAudioGlobalsEndMarker;
|
||||
|
||||
extern u8* gSoundDataADSR; // sound_data.ctl
|
||||
extern u8* gSoundDataRaw; // sound_data.tbl
|
||||
extern u8* gMusicData; // sequences.s
|
||||
extern struct seqFile *gSoundDataADSR; // sound_data.ctl
|
||||
extern struct seqFile *gSoundDataRaw; // sound_data.tbl
|
||||
extern struct seqFile *gMusicData; // sequences.s
|
||||
extern u8* gBankSetsData; // bank_sets.s
|
||||
|
||||
ALSeqFile *get_audio_file_header(s32 arg0);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#include "load_dat.h"
|
||||
|
||||
unsigned char* gSoundDataADSR;
|
||||
struct seqFile *gSoundDataADSR;
|
||||
|
||||
unsigned char* gSoundDataRaw;
|
||||
struct seqFile *gSoundDataRaw;
|
||||
|
||||
unsigned char* gMusicData;
|
||||
struct seqFile *gMusicData;
|
||||
|
||||
#ifndef VERSION_SH
|
||||
unsigned char* gBankSetsData;
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
extern unsigned char* gSoundDataADSR;
|
||||
#include "../tools/convTypes.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
extern unsigned char* gSoundDataRaw;
|
||||
extern struct seqFile *gSoundDataADSR;
|
||||
|
||||
extern unsigned char* gMusicData;
|
||||
extern struct seqFile *gSoundDataRaw;
|
||||
|
||||
extern struct seqFile *gMusicData;
|
||||
|
||||
#ifndef VERSION_SH
|
||||
extern unsigned char *gBankSetsData;
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
#pragma once
|
||||
|
||||
#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,394 @@
|
||||
#pragma once
|
||||
#include "convUtils.h"
|
||||
|
||||
#include "utils.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "convUtils.h"
|
||||
#include "convTypes.h"
|
||||
#include "../../debug_print.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 */
|
||||
DEBUG_PRINT("parse_seqfile()");
|
||||
|
||||
short revision = read_u16_be(seq);
|
||||
short bankCount = read_u16_be(seq + 2);
|
||||
DEBUG_PRINT("- bankCount: %d", bankCount);
|
||||
|
||||
unsigned int size = sizeof(struct seqFile) + (bankCount-1) * sizeof(struct seqObject);
|
||||
DEBUG_PRINT("- seqFile size: %d", sizeof(struct seqFile));
|
||||
DEBUG_PRINT("- actual size: %d", size);
|
||||
|
||||
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){
|
||||
DEBUG_PRINT("- found 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){
|
||||
DEBUG_PRINT("- found 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){
|
||||
DEBUG_PRINT("- found seq!");
|
||||
// SEQ file, contains music files (*.m64)
|
||||
for (int i = 0; i < bankCount; i++){
|
||||
seqFile->seqArray[i].offset = seq+(seqFile->seqArray[i].offset);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_PRINT("- returning seq: %p", seqFile);
|
||||
|
||||
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){
|
||||
DEBUG_PRINT("ptrs_to_offsets()");
|
||||
|
||||
DEBUG_PRINT("- checking if type is not ctl...");
|
||||
DEBUG_PRINT("%p", ctl);
|
||||
if (ctl->revision != TYPE_CTL){
|
||||
DEBUG_PRINT("Sequence file is not a CTL file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_PRINT("- looping through ctl");
|
||||
DEBUG_PRINT("seq count: %d", ctl->seqCount);
|
||||
for (int i = 0; i < ctl->seqCount; i++){
|
||||
DEBUG_PRINT("- for seq");
|
||||
struct CTL* ptr = (struct CTL*)ctl->seqArray[i].offset;
|
||||
uintptr_t ctlData = (uintptr_t)ptr + 0x10;
|
||||
// find all samples in the CTL file
|
||||
DEBUG_PRINT("- finding samples");
|
||||
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);
|
||||
}
|
||||
DEBUG_PRINT("- finding drums");
|
||||
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,25 @@
|
||||
#pragma once
|
||||
#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
|
||||
+2
-2
@@ -135,8 +135,8 @@ SM64_LIB_FN void sm64_global_terminate( void )
|
||||
memory_terminate();
|
||||
}
|
||||
|
||||
SM64_LIB_FN struct AudioBanks sm64_asset_load_audio_banks( void ) {
|
||||
return load_audio_banks();
|
||||
SM64_LIB_FN struct AudioBanks sm64_asset_load_audio_banks( uint8_t *rom ) {
|
||||
return load_audio_banks( rom );
|
||||
}
|
||||
|
||||
SM64_LIB_FN void sm64_static_surfaces_load( const struct SM64Surface *surfaceArray, uint32_t numSurfaces )
|
||||
|
||||
+1
-1
@@ -80,7 +80,7 @@ extern SM64_LIB_FN void sm64_register_play_sound_function( SM64PlaySoundFunction
|
||||
extern SM64_LIB_FN void sm64_global_init( uint8_t *rom, uint8_t *outTexture );
|
||||
extern SM64_LIB_FN void sm64_global_terminate( void );
|
||||
|
||||
extern SM64_LIB_FN struct AudioBanks sm64_asset_load_audio_banks( void );
|
||||
extern SM64_LIB_FN struct AudioBanks sm64_asset_load_audio_banks( uint8_t *rom );
|
||||
|
||||
extern SM64_LIB_FN void sm64_static_surfaces_load( const struct SM64Surface *surfaceArray, uint32_t numSurfaces );
|
||||
|
||||
|
||||
+17
-1
@@ -1,8 +1,24 @@
|
||||
#include "load_audio_data.h"
|
||||
|
||||
#include "decomp/tools/convUtils.h"
|
||||
#include "decomp/audio/load.h"
|
||||
#include "decomp/audio/load_dat.h"
|
||||
|
||||
extern struct AudioBanks load_audio_banks( uint8_t *rom ) {
|
||||
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();
|
||||
|
||||
extern struct AudioBanks load_audio_banks() {
|
||||
int numBanks = 10;
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
bank_load_immediate(i, 2);
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct AudioBanks {
|
||||
int numCtlEntries;
|
||||
struct CtlEntry * ctlEntries;
|
||||
};
|
||||
|
||||
extern struct AudioBanks load_audio_banks();
|
||||
extern struct AudioBanks load_audio_banks( uint8_t *rom );
|
||||
Reference in New Issue
Block a user