mirror of
https://github.com/HarbourMasters/Starship.git
synced 2025-02-02 16:23:57 +03:00
We are so fucking close omg
This commit is contained in:
parent
2354ee76a3
commit
52d3eca421
@ -29,7 +29,7 @@ typedef void (*AudioCustomUpdateFunction)(void);
|
||||
// Also known as "Pulses Per Quarter Note" or "Tatums Per Beat"
|
||||
#define SEQTICKS_PER_BEAT 48
|
||||
|
||||
#define IS_SEQUENCE_CHANNEL_VALID(ptr) ((u32) (ptr) != (u32) &gSeqChannelNone)
|
||||
#define IS_SEQUENCE_CHANNEL_VALID(ptr) ((uintptr_t) (ptr) != (uintptr_t) &gSeqChannelNone)
|
||||
#define SEQ_NUM_CHANNELS 16
|
||||
#define SEQ_IO_VAL_NONE -1
|
||||
|
||||
@ -215,19 +215,21 @@ typedef struct {
|
||||
/* 0x00 */ u32 start;
|
||||
/* 0x04 */ u32 end;
|
||||
/* 0x08 */ u32 count;
|
||||
/* 0x10 */ u64 predictorState[4]; // only exists if count != 0. 8-byte aligned
|
||||
/* 0x10 */ s16 predictorState[16]; // only exists if count != 0. 8-byte aligned
|
||||
} AdpcmLoop; // size = 0x30 or 0x10, 0x8 aligned
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ s32 order;
|
||||
/* 0x04 */ s32 numPredictors;
|
||||
#ifdef AVOID_UB
|
||||
/* 0x08 */ u64 book[]; // size 8 * order * numPredictors.
|
||||
#else
|
||||
/* 0x08 */ u64 book[1]; // size 8 * order * numPredictors.
|
||||
#endif
|
||||
/* 0x08 */ s16* book; // size 8 * order * numPredictors.
|
||||
} AdpcmBook; // size >= 8, 0x8 aligned
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ s32 order;
|
||||
/* 0x04 */ s32 numPredictors;
|
||||
/* 0x08 */ u32 book; // size 8 * order * numPredictors.
|
||||
} AdpcmBook32Bit; // size >= 8, 0x8 aligned
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ u32 codec : 4; // The state of compression or decompression
|
||||
/* 0x00 */ u32 medium : 2; // Medium where sample is currently stored
|
||||
@ -242,10 +244,27 @@ typedef struct {
|
||||
book; // Adpcm book parameters used by the sample. Offset from the start of the sound font / pointer to ram
|
||||
} Sample; // size = 0x10
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ u32 codec : 4; // The state of compression or decompression
|
||||
/* 0x00 */ u32 medium : 2; // Medium where sample is currently stored
|
||||
/* 0x00 */ u32 unk_bit26 : 1;
|
||||
/* 0x00 */ u32 isRelocated : 1; // Has the sample header been relocated (offsets to pointers)
|
||||
/* 0x01 */ u32 size : 24; // Size of the sample
|
||||
/* 0x04 */ u32 sampleAddr; // Raw sample data. Offset from the start of the sample bank or absolute address to
|
||||
// either rom or ram
|
||||
/* 0x08 */ u32 loop; // Adpcm loop parameters used by the sample. Offset from the start of the sound font / pointer to ram
|
||||
/* 0x0C */ u32 book; // Adpcm book parameters used by the sample. Offset from the start of the sound font / pointer to ram
|
||||
} Sample32Bit; // size = 0x10
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ Sample* sample;
|
||||
/* 0x04 */ f32 tuning; // frequency modulation factor
|
||||
} TunedSample; // size = 0x8
|
||||
} TunedSample;// size = 0x8
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ u32 sample;
|
||||
/* 0x04 */ f32 tuning; // frequency modulation factor
|
||||
} TunedSample32Bit;
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ u8 isRelocated; // have the envelope and all samples been relocated (offsets to pointers)
|
||||
@ -258,6 +277,17 @@ typedef struct {
|
||||
/* 0x18 */ TunedSample highPitchTunedSample;
|
||||
} Instrument; // size = 0x20
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ u8 isRelocated; // have the envelope and all samples been relocated (offsets to pointers)
|
||||
/* 0x01 */ u8 normalRangeLo;
|
||||
/* 0x02 */ u8 normalRangeHi;
|
||||
/* 0x03 */ u8 adsrDecayIndex; // index used to obtain adsr decay rate from adsrDecayTable
|
||||
/* 0x04 */ u32 envelope;
|
||||
/* 0x08 */ TunedSample32Bit lowPitchTunedSample;
|
||||
/* 0x10 */ TunedSample32Bit normalPitchTunedSample;
|
||||
/* 0x18 */ TunedSample32Bit highPitchTunedSample;
|
||||
} Instrument32Bit; // size = 0x20
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ u8 adsrDecayIndex; // index used to obtain adsr decay rate from adsrDecayTable
|
||||
/* 0x01 */ u8 pan;
|
||||
@ -266,6 +296,14 @@ typedef struct {
|
||||
/* 0x0C */ EnvelopePoint* envelope;
|
||||
} Drum; // size = 0x10
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ u8 adsrDecayIndex; // index used to obtain adsr decay rate from adsrDecayTable
|
||||
/* 0x01 */ u8 pan;
|
||||
/* 0x02 */ u8 isRelocated; // have tunedSample.sample and envelope been relocated (offsets to pointers)
|
||||
/* 0x04 */ TunedSample tunedSample;
|
||||
/* 0x0C */ EnvelopePoint* envelope;
|
||||
} Drum32Bit; // size = 0x10
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ TunedSample tunedSample;
|
||||
} SoundEffect; // size = 0x08
|
||||
@ -766,13 +804,13 @@ typedef struct {
|
||||
/* 0x0 */ union {
|
||||
u32 opArgs;
|
||||
struct {
|
||||
u8 op;
|
||||
u8 arg0;
|
||||
u8 arg1;
|
||||
u8 arg2;
|
||||
u8 arg1;
|
||||
u8 arg0;
|
||||
u8 op;
|
||||
};
|
||||
};
|
||||
/* 0x4 */ union {
|
||||
union {
|
||||
void* data;
|
||||
f32 asFloat;
|
||||
s32 asInt;
|
||||
|
@ -233,9 +233,9 @@ AudioSpec gAudioSpecs[] = {
|
||||
};
|
||||
s32 D_800C7C28 = 0x20000000; // unused?
|
||||
s16 gSeqTicksPerBeat = 0x30;
|
||||
s32 gAudioHeapSize = 0xAFE00;
|
||||
s32 gInitPoolSize = 0x26000;
|
||||
u32 gPermanentPoolSize = 0x21000;
|
||||
s32 gAudioHeapSize = 0xAFE00 * 2;
|
||||
s32 gInitPoolSize = 0x26000 * 2;
|
||||
u32 gPermanentPoolSize = 0x21000 * 2;
|
||||
u16 gSequenceMedium = 0;
|
||||
u16 gSoundFontMedium = 0;
|
||||
u16 gSampleBankMedium = 0;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "sys.h"
|
||||
#include "sf64audio_provisional.h"
|
||||
#include "endianness.h"
|
||||
|
||||
static const char devstr[] = "Audio:Envp: overflow %f\n";
|
||||
|
||||
@ -199,7 +200,7 @@ f32 func_80013B90(AdsrState* adsr) {
|
||||
adsr->state = ADSR_STATE_LOOP;
|
||||
case_ADSR_STATE_LOOP:
|
||||
case ADSR_STATE_LOOP:
|
||||
adsr->delay = adsr->envelope[adsr->envIndex].delay;
|
||||
adsr->delay = BSWAP16(adsr->envelope[adsr->envIndex].delay);
|
||||
switch (adsr->delay) {
|
||||
case ADSR_DISABLE:
|
||||
adsr->state = ADSR_STATE_DISABLED;
|
||||
@ -208,7 +209,7 @@ f32 func_80013B90(AdsrState* adsr) {
|
||||
adsr->state = ADSR_STATE_HANG;
|
||||
break;
|
||||
case ADSR_GOTO:
|
||||
adsr->envIndex = adsr->envelope[adsr->envIndex].arg;
|
||||
adsr->envIndex = BSWAP16(adsr->envelope[adsr->envIndex].arg);
|
||||
goto case_ADSR_STATE_LOOP;
|
||||
case ADSR_RESTART:
|
||||
adsr->state = ADSR_STATE_INITIAL;
|
||||
@ -221,7 +222,7 @@ f32 func_80013B90(AdsrState* adsr) {
|
||||
adsr->delay = 1;
|
||||
}
|
||||
|
||||
adsr->target = adsr->envelope[adsr->envIndex].arg / 32767.0f;
|
||||
adsr->target = (s16)BE16SWAP(adsr->envelope[adsr->envIndex].arg) / 32767.0f;
|
||||
adsr->target = SQ(adsr->target);
|
||||
adsr->velocity = (adsr->target - adsr->current) / adsr->delay;
|
||||
adsr->state = ADSR_STATE_FADE;
|
||||
|
@ -637,7 +637,7 @@ void Audio_ResetSfxChannelState(void) {
|
||||
}
|
||||
|
||||
void Audio_StartSequence(u8 seqPlayId, u8 seqId, u8 seqArgs, u16 fadeInTime) {
|
||||
u8 i;
|
||||
u8 i = 0;
|
||||
s32 pad;
|
||||
|
||||
if (!sStartSeqDisabled || (seqPlayId == SEQ_PLAYER_SFX)) {
|
||||
@ -2644,8 +2644,7 @@ void Audio_RestoreVolumeSettings(u8 audioType) {
|
||||
}
|
||||
}
|
||||
|
||||
void Audio_SetVolume(u8 audioType, u8 volume) {
|
||||
return;
|
||||
void Audio_SetVolume(u8 audioType, u8 volume) {
|
||||
if (volume > 99) {
|
||||
volume = 99;
|
||||
}
|
||||
|
@ -148,6 +148,7 @@ void* AudioHeap_Alloc(AudioAllocPool* pool, u32 size) {
|
||||
|
||||
void AudioHeap_InitPool(AudioAllocPool* pool, void* ramAddr, u32 size) {
|
||||
pool->curRamAddr = pool->startRamAddr = (u8*) ramAddr;
|
||||
size *= 4;
|
||||
pool->size = size - ((uintptr_t) ramAddr & 0xF);
|
||||
pool->numEntries = 0;
|
||||
}
|
||||
|
@ -1,8 +1,12 @@
|
||||
#include <stdlib.h>
|
||||
#include "sys.h"
|
||||
#include "sf64dma.h"
|
||||
#include "sf64audio_provisional.h"
|
||||
#include "assets/ast_audio.h"
|
||||
#include "port/Engine.h"
|
||||
#include "endianness.h"
|
||||
#include "port/Engine.h"
|
||||
#include "port/resource/loaders/AudioLoader.h"
|
||||
|
||||
s32 D_80146D80;
|
||||
s32 PAD_80146D88[2];
|
||||
@ -33,8 +37,8 @@ void AudioLoad_ProcessAsyncLoads(s32 resetStatus);
|
||||
void AudioLoad_ProcessAsyncLoad(AudioAsyncLoad* asyncLoad, s32 resetStatus);
|
||||
void AudioLoad_AsyncDma(AudioAsyncLoad* asyncLoad, u32 size);
|
||||
void AudioLoad_AsyncDmaUnkMedium(uintptr_t devAddr, u8* ramAddr, u32 size, s32 unkMediumParam);
|
||||
void AudioLoad_RelocateSample(TunedSample* tSample, u32 fontDataAddr, SampleBankRelocInfo* relocInfo);
|
||||
s32 AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, u32 fontDataAddr, SampleBankRelocInfo* relocData, s32 isAsync);
|
||||
void AudioLoad_RelocateSample(TunedSample* sample, TunedSample32Bit* tSample, uintptr_t fontDataAddr, SampleBankRelocInfo* relocInfo);
|
||||
s32 AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, uintptr_t fontDataAddr, SampleBankRelocInfo* relocData, s32 isAsync);
|
||||
s32 AudioLoad_ProcessSamplePreloads(s32 resetStatus);
|
||||
|
||||
void AudioLoad_DecreaseSampleDmaTtls(void) {
|
||||
@ -386,13 +390,12 @@ void AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) {
|
||||
|
||||
func_800144E4(&gSeqPlayers[playerIdx]);
|
||||
|
||||
index = *((u16*) gSeqFontTable + seqId);
|
||||
numFonts = gSeqFontTable[index++];
|
||||
index = BSWAP16(*((u16*) gSeqFontTable + seqId));
|
||||
fontId = 0xFF;
|
||||
|
||||
for (numFonts; numFonts > 0; numFonts--) {
|
||||
for (numFonts = gSeqFontTable[index++]; numFonts > 0; numFonts--) {
|
||||
fontId = gSeqFontTable[index++];
|
||||
AudioLoad_SyncLoadFont(fontId);
|
||||
// AudioLoad_SyncLoadFont(fontId);
|
||||
}
|
||||
|
||||
seqData = AudioLoad_SyncLoadSeq(seqId);
|
||||
@ -401,23 +404,17 @@ void AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) {
|
||||
|
||||
gSeqPlayers[playerIdx].seqId = seqId;
|
||||
gSeqPlayers[playerIdx].defaultFont = fontId;
|
||||
gSeqPlayers[playerIdx].enabled = true;
|
||||
gSeqPlayers[playerIdx].enabled = 1;
|
||||
gSeqPlayers[playerIdx].seqData = seqData;
|
||||
gSeqPlayers[playerIdx].scriptState.pc = seqData;
|
||||
gSeqPlayers[playerIdx].scriptState.depth = 0;
|
||||
gSeqPlayers[playerIdx].delay = 0;
|
||||
gSeqPlayers[playerIdx].finished = false;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
;
|
||||
}
|
||||
gSeqPlayers[playerIdx].finished = 0;
|
||||
}
|
||||
|
||||
void* AudioLoad_SyncLoadSeq(s32 seqId) {
|
||||
s32 seqIdx = AudioLoad_GetLoadTableIndex(SEQUENCE_TABLE, seqId);
|
||||
s32 didAllocate;
|
||||
|
||||
return AudioLoad_SyncLoad(0, seqIdx, &didAllocate);
|
||||
AudioTable* table = AudioLoad_GetLoadTable(SEQUENCE_TABLE);
|
||||
return Audio_LoadBlob(gAudioTable, table->entries[seqId].romAddr);
|
||||
}
|
||||
|
||||
void* AudioLoad_SyncLoadSampleBank(u32 sampleBankId, s32* outMedium) {
|
||||
@ -498,7 +495,7 @@ void* AudioLoad_SyncLoad(u32 tableType, u32 id, s32* didAllocate) {
|
||||
u8* ramAddr;
|
||||
u32 medium;
|
||||
s32 loadStatus;
|
||||
u32 romAddr;
|
||||
uintptr_t romAddr;
|
||||
s32 pad;
|
||||
s32 cachePolicy;
|
||||
|
||||
@ -621,12 +618,10 @@ AudioTable* AudioLoad_GetLoadTable(s32 tableType) {
|
||||
return table;
|
||||
}
|
||||
|
||||
void AudioLoad_RelocateFont(s32 fontId, u32 fontBaseAddr, void* relocData) {
|
||||
u32* fontDataPtrs = fontBaseAddr;
|
||||
u32** drumDataPtrs = fontBaseAddr;
|
||||
void AudioLoad_RelocateFont(s32 fontId, uintptr_t fontBaseAddr, SampleBankRelocInfo* relocData) {
|
||||
uint32_t* fontDataPtrs = fontBaseAddr;
|
||||
uint32_t** drumDataPtrs = fontBaseAddr;
|
||||
s32 numDrums;
|
||||
Drum* drum;
|
||||
Instrument* instrument;
|
||||
u32 offset;
|
||||
s32 i;
|
||||
s32 numInstruments;
|
||||
@ -634,53 +629,41 @@ void AudioLoad_RelocateFont(s32 fontId, u32 fontBaseAddr, void* relocData) {
|
||||
numDrums = gSoundFontList[fontId].numDrums;
|
||||
numInstruments = gSoundFontList[fontId].numInstruments;
|
||||
|
||||
if ((fontDataPtrs[0] != 0) && (numDrums != 0)) {
|
||||
fontDataPtrs[0] += fontBaseAddr;
|
||||
Drum** relocatedDrums = memalloc(numDrums * sizeof(Drum*));
|
||||
Instrument** relocatedInstruments = memalloc((numInstruments + 1) * sizeof(Instrument*));
|
||||
|
||||
if ((fontDataPtrs[0] != 0) && (numDrums != 0)) {
|
||||
for (i = 0; i < numDrums; i++) {
|
||||
offset = *(*drumDataPtrs + i);
|
||||
if (offset != 0) {
|
||||
drum = offset += fontBaseAddr;
|
||||
*(*drumDataPtrs + i) = drum;
|
||||
|
||||
if (!drum->isRelocated) {
|
||||
AudioLoad_RelocateSample(&drum->tunedSample, fontBaseAddr, relocData);
|
||||
offset = (u32) drum->envelope;
|
||||
drum->envelope = offset + fontBaseAddr;
|
||||
drum->isRelocated = true;
|
||||
}
|
||||
relocatedDrums[i] = Audio_LoadDrum(BSWAP32(offset) + fontBaseAddr, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 1; i <= numInstruments; i++) {
|
||||
if (fontDataPtrs[i] != 0) {
|
||||
Instrument* instrument = Audio_LoadInstrument(BSWAP32(fontDataPtrs[i]) + fontBaseAddr, 0);
|
||||
Instrument32Bit* base = fontBaseAddr + BSWAP32(fontDataPtrs[i]);
|
||||
|
||||
fontDataPtrs[i] += fontBaseAddr;
|
||||
|
||||
instrument = fontDataPtrs[i];
|
||||
if (!instrument->isRelocated) {
|
||||
if (instrument->normalRangeLo != 0) {
|
||||
AudioLoad_RelocateSample(&instrument->lowPitchTunedSample, fontBaseAddr, relocData);
|
||||
}
|
||||
AudioLoad_RelocateSample(&instrument->normalPitchTunedSample, fontBaseAddr, relocData);
|
||||
if (instrument->normalRangeHi != 0x7F) {
|
||||
AudioLoad_RelocateSample(&instrument->highPitchTunedSample, fontBaseAddr, relocData);
|
||||
}
|
||||
offset = (u32) instrument->envelope;
|
||||
instrument->envelope = offset + fontBaseAddr;
|
||||
instrument->isRelocated = true;
|
||||
if (instrument->normalRangeLo != 0) {
|
||||
AudioLoad_RelocateSample(&instrument->lowPitchTunedSample, &base->lowPitchTunedSample, fontBaseAddr, relocData);
|
||||
}
|
||||
AudioLoad_RelocateSample(&instrument->normalPitchTunedSample, &base->normalPitchTunedSample, fontBaseAddr, relocData);
|
||||
if (instrument->normalRangeHi != 0x7F) {
|
||||
AudioLoad_RelocateSample(&instrument->highPitchTunedSample, &base->highPitchTunedSample, fontBaseAddr, relocData);
|
||||
}
|
||||
|
||||
relocatedInstruments[i] = instrument;
|
||||
}
|
||||
}
|
||||
|
||||
gSoundFontList[fontId].drums = fontDataPtrs[0];
|
||||
gSoundFontList[fontId].instruments = (u32) &fontDataPtrs[1];
|
||||
gSoundFontList[fontId].drums = relocatedDrums;
|
||||
gSoundFontList[fontId].instruments = relocatedInstruments;
|
||||
}
|
||||
|
||||
void AudioLoad_SyncDma(uintptr_t devAddr, u8* ramAddr, u32 size, s32 medium) {
|
||||
size = ALIGN16(size);
|
||||
|
||||
osInvalDCache(ramAddr, size);
|
||||
|
||||
while (true) {
|
||||
@ -738,7 +721,7 @@ s32 AudioLoad_Dma(OSIoMesg* mesg, u32 priority, s32 direction, uintptr_t devAddr
|
||||
mesg->devAddr = devAddr;
|
||||
mesg->size = size;
|
||||
|
||||
handle->transferInfo.cmdType = 2;
|
||||
// handle->transferInfo.cmdType = 2;
|
||||
// osEPiStartDma(handle, mesg, direction);
|
||||
memcpy(ramAddr, (void*) devAddr, size);
|
||||
|
||||
@ -941,19 +924,17 @@ void AudioLoad_Init(void) {
|
||||
gSeqFontTable = gSeqFontTableInit;
|
||||
gNumSequences = gSequenceTable->base.numEntries;
|
||||
|
||||
AudioLoad_InitTable(gSequenceTable, LOAD_ASSET(gAudioSeq), gSequenceMedium);
|
||||
AudioLoad_InitTable(gSoundFontTable, LOAD_ASSET(gAudioBank), gSoundFontMedium);
|
||||
AudioLoad_InitTable(gSampleBankTable, LOAD_ASSET(gAudioTable), gSampleBankMedium);
|
||||
// AudioLoad_InitTable(gSequenceTable, LOAD_ASSET(gAudioSeq), gSequenceMedium);
|
||||
// AudioLoad_InitTable(gSoundFontTable, LOAD_ASSET(gAudioBank), gSoundFontMedium);
|
||||
// AudioLoad_InitTable(gSampleBankTable, LOAD_ASSET(gAudioTable), gSampleBankMedium);
|
||||
|
||||
numFonts = gSoundFontTable->base.numEntries;
|
||||
|
||||
gSoundFontList = AudioHeap_Alloc(&gInitPool, numFonts * sizeof(SoundFont));
|
||||
|
||||
for (i = 0; i < numFonts; i++) {
|
||||
gSoundFontList[i].sampleBankId1 = (gSoundFontTable->entries[i].shortData1 >> 8) & 0xFF;
|
||||
gSoundFontList[i].sampleBankId2 = gSoundFontTable->entries[i].shortData1 & 0xFF;
|
||||
gSoundFontList[i].numInstruments = (gSoundFontTable->entries[i].shortData2 >> 8) & 0xFF;
|
||||
gSoundFontList[i].numDrums = gSoundFontTable->entries[i].shortData2 & 0xFF;
|
||||
gSoundFontList[i] = Audio_LoadFont(gSoundFontTable->entries[i]);
|
||||
gFontLoadStatus[i] = 2;
|
||||
}
|
||||
|
||||
ramAddr = AudioHeap_Alloc(&gInitPool, gPermanentPoolSize);
|
||||
@ -1277,35 +1258,40 @@ void AudioLoad_AsyncDmaUnkMedium(uintptr_t devAddr, u8* ramAddr, u32 size, s32 u
|
||||
static const char devstr50[] = "Error: Already wavetable is touched %x.\n";
|
||||
static const char devstr51[] = "Touch Warning: Length zero %x\n";
|
||||
|
||||
void AudioLoad_RelocateSample(TunedSample* tSample, u32 fontDataAddr, SampleBankRelocInfo* relocInfo) {
|
||||
void* reloc;
|
||||
Sample* sample;
|
||||
void AudioLoad_RelocateSample(TunedSample* tunedSample, TunedSample32Bit* tSample, uintptr_t fontDataAddr, SampleBankRelocInfo* relocInfo) {
|
||||
Sample32Bit* baseSample = fontDataAddr + BSWAP32(tSample->sample);
|
||||
|
||||
// "Error: Already wavetable is touched %x.\n";
|
||||
if ((u32) tSample->sample <= AUDIO_RELOCATED_ADDRESS_START) {
|
||||
sample = tSample->sample = reloc = (u32) tSample->sample + fontDataAddr;
|
||||
// "Touch Warning: Length zero %x\n";
|
||||
if ((sample->size != 0) && (sample->isRelocated != 1)) {
|
||||
sample->loop = reloc = (u32) sample->loop + fontDataAddr;
|
||||
sample->book = reloc = (u32) sample->book + fontDataAddr;
|
||||
switch (sample->medium) {
|
||||
case MEDIUM_RAM:
|
||||
sample->sampleAddr = reloc = sample->sampleAddr + relocInfo->baseAddr1;
|
||||
sample->medium = relocInfo->medium1;
|
||||
break;
|
||||
case MEDIUM_UNK:
|
||||
sample->sampleAddr = reloc = sample->sampleAddr + relocInfo->baseAddr2;
|
||||
sample->medium = relocInfo->medium2;
|
||||
break;
|
||||
case MEDIUM_CART:
|
||||
case MEDIUM_DISK_DRIVE:
|
||||
break;
|
||||
}
|
||||
// "Touch Warning: Length zero %x\n";
|
||||
if ((baseSample->size != 0) && (baseSample->isRelocated != 1)) {
|
||||
Sample* output = memalloc(sizeof(Sample));
|
||||
|
||||
sample->isRelocated = true;
|
||||
if (sample->unk_bit26 && (sample->medium != 0)) {
|
||||
gUsedSamples[gNumUsedSamples++] = sample;
|
||||
}
|
||||
output->loop = Audio_LoadLoop(fontDataAddr + BSWAP32(baseSample->loop));
|
||||
output->book = Audio_LoadBook(fontDataAddr + BSWAP32(baseSample->book));
|
||||
output->codec = baseSample->codec;
|
||||
output->medium = baseSample->medium;
|
||||
output->unk_bit26 = baseSample->unk_bit26;
|
||||
output->isRelocated = baseSample->isRelocated;
|
||||
output->size = baseSample->size;
|
||||
|
||||
output->isRelocated = 1;
|
||||
switch (baseSample->medium) {
|
||||
case MEDIUM_RAM:
|
||||
// baseSample->sampleAddr = Audio_LoadCopy(relocInfo->baseAddr1 + BSWAP32(baseSample->sampleAddr), BSWAP32(baseSample->size));
|
||||
baseSample->medium = relocInfo->medium1;
|
||||
break;
|
||||
case MEDIUM_UNK:
|
||||
// baseSample->sampleAddr = Audio_LoadCopy(relocInfo->baseAddr2 + BSWAP32(baseSample->sampleAddr), BSWAP32(baseSample->size));
|
||||
baseSample->medium = relocInfo->medium2;
|
||||
break;
|
||||
case MEDIUM_CART:
|
||||
case MEDIUM_DISK_DRIVE:
|
||||
output->sampleAddr = fontDataAddr + BSWAP32(baseSample->sampleAddr);
|
||||
break;
|
||||
}
|
||||
|
||||
baseSample->isRelocated = true;
|
||||
if (baseSample->unk_bit26 && (baseSample->medium != 0)) {
|
||||
gUsedSamples[gNumUsedSamples++] = output;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1316,7 +1302,7 @@ static const char devstr54[] = "Warning: Length zero %x\n";
|
||||
static const char devstr55[] = "Wave Load %d \n";
|
||||
static const char devstr56[] = "Total Bg Wave Load %d \n";
|
||||
|
||||
s32 AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, u32 fontDataAddr, SampleBankRelocInfo* relocData, s32 isAsync) {
|
||||
s32 AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, uintptr_t fontDataAddr, SampleBankRelocInfo* relocData, s32 isAsync) {
|
||||
s32 i;
|
||||
Sample* sample;
|
||||
u8* sampleRamAddr;
|
||||
@ -1534,4 +1520,4 @@ s32 AudioLoad_GetSamplesForFont(s32 fontId, Sample** sampleSet) {
|
||||
}
|
||||
|
||||
return numLoaded;
|
||||
}
|
||||
}
|
@ -248,10 +248,6 @@ void func_80011FA8(void) {
|
||||
|
||||
playbackState = ¬e->playbackState;
|
||||
if ((playbackState->parentLayer != NO_LAYER)) {
|
||||
if ((u32) playbackState->parentLayer < 0x7FFFFFFF) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((note != playbackState->parentLayer->note) && (playbackState->unk_04 == 0)) {
|
||||
playbackState->adsr.action.asByte |= 0x10;
|
||||
playbackState->adsr.fadeOutVel = gAudioBufferParams.ticksPerUpdateInv;
|
||||
@ -284,7 +280,6 @@ void func_80011FA8(void) {
|
||||
block_21:
|
||||
|
||||
if (playbackState->priority != 0) {
|
||||
if (1) {}
|
||||
noteSub = ¬e->noteSubEu;
|
||||
if ((playbackState->unk_04 > 0) || noteSub->bitField0.finished) {
|
||||
if ((playbackState->adsr.state == 0) || noteSub->bitField0.finished) {
|
||||
|
@ -268,7 +268,7 @@ void* func_800145FC(AudioListItem* list) {
|
||||
list->prev = item->prev;
|
||||
item->prev = NULL;
|
||||
list->u.count--;
|
||||
return (void*) item->u.count;
|
||||
return (void*) item->u.value;
|
||||
}
|
||||
|
||||
void func_8001463C(void) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "sys.h"
|
||||
#include "sf64audio_provisional.h"
|
||||
#include "audio/mixer.h"
|
||||
#include "endianness.h"
|
||||
|
||||
s32 D_80145D40; // unused
|
||||
|
||||
@ -745,8 +746,8 @@ Acmd* func_8000A25C(s16* aiBuf, s32 aiBufLen, Acmd* aList, s32 updateIndex) {
|
||||
u8 sp84[0x3C];
|
||||
NoteSubEu* temp_v0;
|
||||
s16 var_s2;
|
||||
s16 i;
|
||||
s32 j;
|
||||
s16 i = 0;
|
||||
s32 j = 0;
|
||||
|
||||
var_s2 = 0;
|
||||
if (gNumSynthReverbs == 0) {
|
||||
@ -832,7 +833,7 @@ Acmd* func_8000A700(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisState* synth
|
||||
s32 padD8;
|
||||
s32 padD4;
|
||||
s32 padD0;
|
||||
u32 sampleAddr; // spCC
|
||||
uintptr_t sampleAddr; // spCC
|
||||
s32 padC8;
|
||||
s32 samplesLenAdjusted; // spC4
|
||||
s32 nAdpcmSamplesProcessed; // spC0
|
||||
@ -1011,7 +1012,7 @@ Acmd* func_8000A700(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisState* synth
|
||||
flags, &synthState->sampleDmaIndex, bookSample->medium);
|
||||
}
|
||||
// if (1){}
|
||||
sampleDataStartPad = (u32) sampleData & 0xF;
|
||||
sampleDataStartPad = (uintptr_t) sampleData & 0xF;
|
||||
aLoadBuffer(aList++, OS_K0_TO_PHYSICAL(sampleData - sampleDataStartPad), addr, aligned);
|
||||
} else {
|
||||
nSamplesToDecode = 0;
|
||||
|
@ -42,68 +42,58 @@ static const char devstr14[] = "Error : Queue is not empty ( %x ) \n";
|
||||
void AudioThread_CreateNextAudioBuffer(s16 *samples, u32 num_samples) {
|
||||
static s32 gMaxAbiCmdCnt = 128;
|
||||
static SPTask* gWaitingAudioTask = NULL;
|
||||
u32 sp54;
|
||||
s32 sp50;
|
||||
s32 sp4C;
|
||||
s32 pad48;
|
||||
OSTask_t* task;
|
||||
u16* sp40;
|
||||
s32 pad3C;
|
||||
OSMesg sp38;
|
||||
OSMesg sp34;
|
||||
s32 pad30;
|
||||
s32 abiCmdCount;
|
||||
u32 specId;
|
||||
OSMesg msg;
|
||||
|
||||
gAudioTaskCountQ++;
|
||||
if ((gAudioTaskCountQ % gAudioBufferParams.count) != 0) {
|
||||
return;
|
||||
return gWaitingAudioTask;
|
||||
}
|
||||
osSendMesg(gAudioTaskStartQueue, OS_MESG_32(gAudioTaskCountQ), 0);
|
||||
osSendMesg(gAudioTaskStartQueue, OS_MESG_32(gAudioTaskCountQ), OS_MESG_NOBLOCK);
|
||||
gAudioTaskIndexQ ^= 1;
|
||||
gCurAiBuffIndex++;
|
||||
gCurAiBuffIndex %= 3;
|
||||
sp4C = (gCurAiBuffIndex + 1) % 3;
|
||||
sp54 = osAiGetLength() >> 2;
|
||||
if ((gAudioResetTimer < 16) && (gAiBuffLengths[sp4C] != 0)) {
|
||||
osAiSetNextBuffer(gAiBuffers[sp4C], gAiBuffLengths[sp4C] * 4);
|
||||
}
|
||||
if (gCurAudioFrameDmaCount && gCurAudioFrameDmaCount) {}
|
||||
|
||||
gCurAudioFrameDmaCount = 0;
|
||||
AudioLoad_DecreaseSampleDmaTtls();
|
||||
AudioLoad_ProcessLoads(gAudioResetStep);
|
||||
if (osRecvMesg(&gAudioTaskMesgQueue, &sp38, 0) != -1) {
|
||||
// AudioLoad_ProcessLoads(gAudioResetStep);
|
||||
|
||||
if (MQ_GET_MESG(gAudioSpecQueue, &specId)) {
|
||||
if (gAudioResetStep == 0) {
|
||||
gAudioResetStep = 5;
|
||||
}
|
||||
gAudioSpecId = sp38.data32;
|
||||
gAudioSpecId = specId;
|
||||
}
|
||||
|
||||
if ((gAudioResetStep != 0) && (AudioHeap_ResetStep() == 0)) {
|
||||
if (gAudioResetStep == 0) {
|
||||
osSendMesg(gAudioResetQueue, OS_MESG_32((s32) gAudioSpecId), 0);
|
||||
osSendMesg(gAudioResetQueue, OS_MESG_32((s32) gAudioSpecId), OS_MESG_NOBLOCK);
|
||||
}
|
||||
gWaitingAudioTask = NULL;
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (gAudioResetTimer > 16) {
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
if (gAudioResetTimer != 0) {
|
||||
gAudioResetTimer++;
|
||||
}
|
||||
|
||||
gAudioCurTask = &gAudioRspTasks[gAudioTaskIndexQ];
|
||||
gCurAbiCmdBuffer = gAbiCmdBuffs[gAudioTaskIndexQ];
|
||||
sp4C = gCurAiBuffIndex;
|
||||
sp40 = gAiBuffers[sp4C];
|
||||
gAiBuffLengths[sp4C] = num_samples;
|
||||
if (gAiBuffLengths[sp4C] < gAudioBufferParams.minAiBufferLength) {
|
||||
gAiBuffLengths[sp4C] = gAudioBufferParams.minAiBufferLength;
|
||||
|
||||
while (MQ_GET_MESG(gThreadCmdProcQueue, &msg)) {
|
||||
AudioThread_ProcessCmds(msg.data32);
|
||||
}
|
||||
if (gAiBuffLengths[sp4C] > gAudioBufferParams.maxAiBufferLength) {
|
||||
gAiBuffLengths[sp4C] = gAudioBufferParams.maxAiBufferLength;
|
||||
}
|
||||
while (osRecvMesg(gThreadCmdProcQueue, &sp34, 0) != -1) {
|
||||
AudioThread_ProcessCmds(sp34.data32);
|
||||
}
|
||||
gCurAbiCmdBuffer = func_80009B64(gCurAbiCmdBuffer, &sp50, samples, num_samples);
|
||||
|
||||
gCurAbiCmdBuffer = func_80009B64(gCurAbiCmdBuffer, &abiCmdCount, samples, num_samples);
|
||||
gAudioRandom = osGetCount() * (gAudioRandom + gAudioTaskCountQ);
|
||||
|
||||
gAudioCurTask->msg = OS_MESG_PTR(NULL);
|
||||
|
||||
if (gMaxAbiCmdCnt < abiCmdCount) {
|
||||
gMaxAbiCmdCnt = abiCmdCount;
|
||||
}
|
||||
}
|
||||
|
||||
SPTask* AudioThread_CreateTask() {
|
||||
@ -233,7 +223,7 @@ void AudioThread_ProcessGlobalCmd(AudioCmd* cmd) {
|
||||
case AUDIOCMD_OP_GLOBAL_INIT_SEQPLAYER:
|
||||
case AUDIOCMD_OP_GLOBAL_INIT_SEQPLAYER_ALT:
|
||||
AudioLoad_SyncInitSeqPlayer(cmd->arg0, cmd->arg1, cmd->arg2);
|
||||
AudioThread_SetFadeInTimer(cmd->arg0, (s32) cmd->data);
|
||||
AudioThread_SetFadeInTimer(cmd->arg0, (uintptr_t) cmd->data);
|
||||
break;
|
||||
case AUDIOCMD_OP_GLOBAL_DISABLE_SEQPLAYER:
|
||||
if (gSeqPlayers[cmd->arg0].enabled) {
|
||||
@ -355,7 +345,7 @@ void AudioThread_ScheduleProcessCmds(void) {
|
||||
D_800C7C70 = (u8) (gThreadCmdWritePos - gThreadCmdReadPos + 0x100);
|
||||
}
|
||||
msg = (((gThreadCmdReadPos & 0xFF) << 8) | (gThreadCmdWritePos & 0xFF));
|
||||
osSendMesg(gThreadCmdProcQueue, OS_MESG_32(msg), OS_MESG_NOBLOCK);
|
||||
osSendMesg32(gThreadCmdProcQueue, msg, OS_MESG_NOBLOCK);
|
||||
gThreadCmdReadPos = gThreadCmdWritePos;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "sys.h"
|
||||
#include "endianness.h"
|
||||
#include "sf64audio_provisional.h"
|
||||
|
||||
f32 gBendPitchOneOctaveFrequencies[] = {
|
||||
@ -197,6 +198,7 @@ u8 gDefaultShortNoteVelocityTable[] = {
|
||||
u8 gDefaultShortNoteGateTimeTable[] = {
|
||||
229, 203, 177, 151, 139, 126, 113, 100, 87, 74, 61, 48, 36, 23, 10, 0,
|
||||
};
|
||||
|
||||
EnvelopePoint gDefaultEnvelope[] = {
|
||||
{ 4, 32000 },
|
||||
{ 1000, 32000 },
|
||||
|
@ -41,13 +41,19 @@ void AudioThread_CreateNextAudioBuffer(int16_t *samples, uint32_t num_samples);
|
||||
}
|
||||
|
||||
GameEngine* GameEngine::Instance;
|
||||
static GamePool MemoryPool = {
|
||||
.chunk = 2048,
|
||||
.cursor = 0,
|
||||
.length = 0,
|
||||
.memory = nullptr
|
||||
};
|
||||
|
||||
GameEngine::GameEngine() {
|
||||
std::vector<std::string> OTRFiles;
|
||||
if (const std::string cube_path = Ship::Context::GetPathRelativeToAppDirectory("starship.otr"); std::filesystem::exists(cube_path)) {
|
||||
OTRFiles.push_back(cube_path);
|
||||
}
|
||||
if (const std::string sm64_otr_path = Ship::Context::GetPathRelativeToAppBundle("sf64.otr"); std::filesystem::exists(sm64_otr_path)) {
|
||||
if (const std::string sm64_otr_path = Ship::Context::GetPathRelativeToAppDirectory("sf64.otr"); std::filesystem::exists(sm64_otr_path)) {
|
||||
OTRFiles.push_back(sm64_otr_path);
|
||||
}
|
||||
if (const std::string patches_path = Ship::Context::GetPathRelativeToAppDirectory("mods"); !patches_path.empty() && std::filesystem::exists(patches_path)) {
|
||||
@ -60,7 +66,7 @@ GameEngine::GameEngine() {
|
||||
}
|
||||
}
|
||||
|
||||
this->context = Ship::Context::CreateInstance("Starship", "ship", "starship.cfg.json", OTRFiles, {}, 3);
|
||||
this->context = Ship::Context::CreateInstance("Starship", "ship", "starship.cfg.json", OTRFiles, {}, 3, { 32000, 1024, 2480 });
|
||||
|
||||
auto loader = context->GetResourceManager()->GetResourceLoader();
|
||||
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryAnimV0>(), RESOURCE_FORMAT_BINARY, "Animation", static_cast<uint32_t>(SF64::ResourceType::AnimData), 0);
|
||||
@ -95,7 +101,7 @@ void GameEngine::Create(){
|
||||
}
|
||||
|
||||
void GameEngine::Destroy(){
|
||||
|
||||
free(MemoryPool.memory);
|
||||
}
|
||||
|
||||
bool ShouldClearTextureCacheAtEndOfFrame = false;
|
||||
@ -133,7 +139,7 @@ void GameEngine::HandleAudioThread(){
|
||||
u32 num_audio_samples = samples_left < AudioPlayerGetDesiredBuffered() ? SAMPLES_HIGH : SAMPLES_LOW;
|
||||
s16 audio_buffer[SAMPLES_PER_FRAME];
|
||||
for (int i = 0; i < NUM_AUDIO_CHANNELS; i++) {
|
||||
AudioThread_CreateNextAudioBuffer(audio_buffer + i * (num_audio_samples * 2), num_audio_samples);
|
||||
AudioThread_CreateNextAudioBuffer(audio_buffer + i * (num_audio_samples * 2), num_audio_samples * 2);
|
||||
}
|
||||
AudioPlayerPlayFrame((u8 *) audio_buffer, 2 * num_audio_samples * 4);
|
||||
audio.processing = false;
|
||||
@ -427,4 +433,28 @@ extern "C" int32_t OTRConvertHUDXToScreenX(int32_t v) {
|
||||
float screenScaledCoord = gameCoord * gameScreenRatio;
|
||||
int32_t screenScaledCoordInt = screenScaledCoord;
|
||||
return screenScaledCoordInt;
|
||||
}
|
||||
|
||||
extern "C" void* GameEngine_Malloc(size_t size) {
|
||||
// This is really wrong
|
||||
return malloc(size);
|
||||
|
||||
const auto chunk = MemoryPool.chunk;
|
||||
|
||||
if(size == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(MemoryPool.cursor + size < MemoryPool.length) {
|
||||
const auto res = static_cast<uint8_t*>(MemoryPool.memory) + MemoryPool.cursor;
|
||||
MemoryPool.cursor += size;
|
||||
SPDLOG_INFO("Allocating {} into memory pool", size);
|
||||
return res;
|
||||
}
|
||||
|
||||
MemoryPool.length += chunk;
|
||||
MemoryPool.memory = MemoryPool.memory == nullptr ? malloc(MemoryPool.length) : realloc(MemoryPool.memory, MemoryPool.length);
|
||||
memset(static_cast<uint8_t*>(MemoryPool.memory) + MemoryPool.length, 0, MemoryPool.length - chunk);
|
||||
SPDLOG_INFO("Memory pool resized from {} to {}", MemoryPool.length - chunk, MemoryPool.length);
|
||||
return GameEngine_Malloc(size);
|
||||
}
|
@ -3,6 +3,13 @@
|
||||
#define LOAD_ASSET(path) (path == NULL ? NULL : (GameEngine_OTRSigCheck((const char*) path) ? ResourceGetDataByName((const char*) path) : path))
|
||||
#define LOAD_ASSET_RAW(path) ResourceGetDataByName((const char*) path)
|
||||
|
||||
struct GamePool {
|
||||
unsigned long chunk;
|
||||
unsigned long cursor;
|
||||
unsigned long length;
|
||||
void* memory;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <vector>
|
||||
#include <Fast3D/gfx_pc.h>
|
||||
@ -34,7 +41,16 @@ class GameEngine {
|
||||
static void ProcessGfxCommands(Gfx* commands);
|
||||
static uint32_t GetInterpolationFPS();
|
||||
};
|
||||
|
||||
extern "C" void* GameEngine_Malloc(size_t size);
|
||||
|
||||
|
||||
#define memallocn(type, n) (type*) GameEngine_Malloc(sizeof(type) * n)
|
||||
#define memalloc(type) memallocn(type, 1)
|
||||
|
||||
#else
|
||||
#include <stdint.h>
|
||||
|
||||
void GameEngine_ProcessGfxCommands(Gfx* commands);
|
||||
float GameEngine_GetAspectRatio();
|
||||
uint8_t GameEngine_OTRSigCheck(char* imgData);
|
||||
@ -48,4 +64,6 @@ int16_t OTRGetRectDimensionFromLeftEdge(float v);
|
||||
int16_t OTRGetRectDimensionFromRightEdge(float v);
|
||||
uint32_t OTRGetGameRenderWidth();
|
||||
uint32_t OTRGetGameRenderHeight();
|
||||
void* GameEngine_Malloc(size_t size);
|
||||
#define memalloc(size) GameEngine_Malloc(size)
|
||||
#endif
|
@ -21,9 +21,9 @@ void Graphics_PushFrame(Gfx* data) {
|
||||
extern "C" void Timer_Update();
|
||||
|
||||
void push_frame() {
|
||||
Graphics_ThreadUpdate();
|
||||
GameEngine::StartAudioFrame();
|
||||
GameEngine::Instance->StartFrame();
|
||||
Graphics_ThreadUpdate();
|
||||
Timer_Update();
|
||||
// thread5_iteration();
|
||||
GameEngine::EndAudioFrame();
|
||||
|
192
src/port/resource/loaders/AudioLoader.cpp
Normal file
192
src/port/resource/loaders/AudioLoader.cpp
Normal file
@ -0,0 +1,192 @@
|
||||
#include "AudioLoader.h"
|
||||
#include "utils/binarytools/BinaryReader.h"
|
||||
#include "assets/ast_audio.h"
|
||||
#include "BitConverter.h"
|
||||
#include "port/Engine.h"
|
||||
#include <vector>
|
||||
|
||||
Ship::BinaryReader Audio_MakeReader(const char* resource, u32 offset = 0){
|
||||
auto data = (char*)ResourceGetDataByName(resource);
|
||||
auto size = ResourceGetSizeByName(resource);
|
||||
|
||||
Ship::BinaryReader reader(data, size);
|
||||
reader.SetEndianness(Ship::Endianness::Big);
|
||||
reader.Seek(offset, Ship::SeekOffsetType::Start);
|
||||
|
||||
return reader;
|
||||
}
|
||||
|
||||
char* Audio_LoadBlob(const char* resource, u32 offset){
|
||||
auto data = (char*)ResourceGetDataByName(resource);
|
||||
|
||||
return data + offset;
|
||||
}
|
||||
|
||||
EnvelopePoint* Audio_LoadEnvelope(uint32_t addr) {
|
||||
auto reader = Audio_MakeReader(gAudioBank, addr);
|
||||
|
||||
std::vector<EnvelopePoint> temp;
|
||||
while(true) {
|
||||
int16_t delay = reader.ReadInt16();
|
||||
int16_t arg = reader.ReadInt16();
|
||||
|
||||
temp.push_back({delay, arg});
|
||||
|
||||
if (delay < 0){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EnvelopePoint* envelopes = memallocn(EnvelopePoint, temp.size());
|
||||
memcpy(envelopes, temp.data(), sizeof(EnvelopePoint) * temp.size());
|
||||
|
||||
return envelopes;
|
||||
}
|
||||
|
||||
extern "C" SoundFont Audio_LoadFont(AudioTableEntry entry) {
|
||||
auto reader = Audio_MakeReader(gAudioBank, entry.romAddr);
|
||||
|
||||
SoundFont font = {
|
||||
.numInstruments = (entry.shortData2 >> 8) & 0xFF,
|
||||
.numDrums = entry.shortData2 & 0xFF,
|
||||
.sampleBankId1 = (entry.shortData1 >> 8) & 0xFF,
|
||||
.sampleBankId2 = entry.shortData1 & 0xFF,
|
||||
};
|
||||
|
||||
font.instruments = memallocn(Instrument*, font.numInstruments);
|
||||
font.drums = memallocn(Drum*, font.numDrums);
|
||||
|
||||
uint32_t drumBaseAddr = entry.romAddr + reader.ReadUInt32();
|
||||
uint32_t instBaseAddr = 4;
|
||||
|
||||
if(font.drums != nullptr && drumBaseAddr != 0){
|
||||
reader.Seek(drumBaseAddr, Ship::SeekOffsetType::Start);
|
||||
for(size_t i = 0; i < font.numDrums; i++){
|
||||
font.drums[i] = Audio_LoadDrum(entry.romAddr + reader.ReadUInt32(), entry.romAddr, font.sampleBankId1);
|
||||
}
|
||||
}
|
||||
|
||||
if(font.instruments != nullptr){
|
||||
reader.Seek(instBaseAddr, Ship::SeekOffsetType::Start);
|
||||
for(size_t i = 1; i < font.numInstruments; i++){
|
||||
font.instruments[i] = Audio_LoadInstrument(reader.ReadUInt32(), font.sampleBankId1);
|
||||
}
|
||||
}
|
||||
|
||||
gSampleFontLoadStatus[font.sampleBankId1] = 2;
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
extern "C" AdpcmLoop* Audio_LoadLoop(uint32_t addr) {
|
||||
auto reader = Audio_MakeReader(gAudioBank, addr);
|
||||
AdpcmLoop* loop = memalloc(AdpcmLoop);
|
||||
|
||||
loop->start = reader.ReadInt32();
|
||||
loop->end = reader.ReadUInt32();
|
||||
loop->count = reader.ReadUInt32();
|
||||
|
||||
if(loop->count != 0){
|
||||
for(size_t i = 0; i < 16; i++){
|
||||
loop->predictorState[i] = reader.ReadInt16();
|
||||
}
|
||||
}
|
||||
|
||||
return loop;
|
||||
}
|
||||
|
||||
extern "C" AdpcmBook* Audio_LoadBook(uint32_t addr) {
|
||||
auto reader = Audio_MakeReader(gAudioBank, addr);
|
||||
|
||||
AdpcmBook* book = memalloc(AdpcmBook);
|
||||
book->order = reader.ReadInt32();
|
||||
book->numPredictors = reader.ReadInt32();
|
||||
|
||||
size_t length = 8 * book->order * book->numPredictors;
|
||||
book->book = memallocn(int16_t, length);
|
||||
|
||||
if(length > 16){
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < length; i++){
|
||||
book->book[i] = reader.ReadInt16();
|
||||
}
|
||||
|
||||
return book;
|
||||
}
|
||||
|
||||
Sample* Audio_LoadSample(uint32_t sampleAddr, uint32_t baseAddr = 0, uint32_t sampleBankID = 0) {
|
||||
auto reader = Audio_MakeReader(gAudioBank, sampleAddr);
|
||||
|
||||
Sample* sample = memalloc(Sample);
|
||||
sample->size = reader.ReadUInt32();
|
||||
uint32_t addr = reader.ReadUInt32();
|
||||
sample->loop = Audio_LoadLoop(baseAddr + reader.ReadUInt32());
|
||||
sample->book = Audio_LoadBook(baseAddr + reader.ReadUInt32());
|
||||
|
||||
sample->isRelocated = 1;
|
||||
sample->sampleAddr = (uint8_t*) Audio_LoadBlob(gAudioTable, gSeqTableInit.entries[sampleBankID].romAddr) + addr;
|
||||
|
||||
return sample;
|
||||
}
|
||||
|
||||
TunedSample Audio_LoadTunedSample(uint32_t addr, uint32_t baseAddr = 0, uint32_t sampleBankID = 0) {
|
||||
auto reader = Audio_MakeReader(gAudioBank, addr);
|
||||
auto sampleAddr = reader.ReadUInt32();
|
||||
auto tuning = reader.ReadFloat();
|
||||
|
||||
if(sampleAddr == 0){
|
||||
assert(tuning == 0.0f);
|
||||
return { nullptr, 0.0f };
|
||||
}
|
||||
|
||||
return {
|
||||
.sample = Audio_LoadSample(baseAddr + sampleAddr, baseAddr, sampleBankID),
|
||||
.tuning = tuning
|
||||
};
|
||||
}
|
||||
|
||||
extern "C" Instrument* Audio_LoadInstrument(uint32_t addr, uint32_t sampleBankID) {
|
||||
if (addr == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto reader = Audio_MakeReader(gAudioBank, addr);
|
||||
|
||||
Instrument* instrument = memalloc(Instrument);
|
||||
instrument->isRelocated = reader.ReadUByte();
|
||||
instrument->normalRangeLo = reader.ReadUByte();
|
||||
instrument->normalRangeHi = reader.ReadUByte();
|
||||
instrument->adsrDecayIndex = reader.ReadUByte();
|
||||
instrument->envelope = Audio_LoadEnvelope(reader.ReadUInt32());
|
||||
instrument->lowPitchTunedSample = Audio_LoadTunedSample(addr + 8, 0, sampleBankID);
|
||||
instrument->normalPitchTunedSample = Audio_LoadTunedSample(addr + 16, 0, sampleBankID);
|
||||
instrument->highPitchTunedSample = Audio_LoadTunedSample(addr + 24, 0, sampleBankID);
|
||||
instrument->isRelocated = 1;
|
||||
|
||||
return instrument;
|
||||
}
|
||||
|
||||
extern "C" Drum* Audio_LoadDrum(uint32_t addr, uint32_t baseAddr, uint32_t sampleBankID) {
|
||||
|
||||
if(baseAddr != 0 && addr >= baseAddr){
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto reader = Audio_MakeReader(gAudioBank, addr);
|
||||
Drum* drum = memalloc(Drum);
|
||||
|
||||
drum->adsrDecayIndex = reader.ReadInt8();
|
||||
drum->pan = reader.ReadInt8();
|
||||
drum->isRelocated = reader.ReadUByte();
|
||||
reader.ReadUByte();
|
||||
drum->isRelocated = 1;
|
||||
|
||||
|
||||
drum->tunedSample = Audio_LoadTunedSample(addr + 4, baseAddr, sampleBankID);
|
||||
reader.Seek(0x8, Ship::SeekOffsetType::Current);
|
||||
drum->envelope = Audio_LoadEnvelope(reader.ReadUInt32());
|
||||
|
||||
return drum;
|
||||
}
|
20
src/port/resource/loaders/AudioLoader.h
Normal file
20
src/port/resource/loaders/AudioLoader.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "sf64audio_provisional.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
char* Audio_LoadBlob(const char* resource, u32 offset);
|
||||
AdpcmBook* Audio_LoadBook(uint32_t addr);
|
||||
AdpcmLoop* Audio_LoadLoop(uint32_t addr);
|
||||
Instrument* Audio_LoadInstrument(uint32_t addr, uint32_t sampleBankID);
|
||||
Drum* Audio_LoadDrum(uint32_t addr, uint32_t baseAddr, uint32_t sampleBankID);
|
||||
Sample* Audio_LoadSample(uint32_t addr, uint32_t sampleBankID);
|
||||
SoundFont Audio_LoadFont(AudioTableEntry entry);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -103,31 +103,10 @@ void Main_Initialize(void) {
|
||||
}
|
||||
|
||||
void Audio_ThreadEntry(void* arg0) {
|
||||
// SPTask* task;
|
||||
SPTask* task;
|
||||
|
||||
AudioLoad_Init();
|
||||
Audio_InitSounds();
|
||||
|
||||
// task = AudioThread_CreateTask();
|
||||
// if (task != NULL) {
|
||||
// task->msgQueue = &gAudioTaskMsgQueue;
|
||||
// task->msg = OS_MESG_32(TASK_MESG_1);
|
||||
// osWritebackDCacheAll();
|
||||
// osSendMesg(&gTaskMsgQueue, OS_MESG_PTR(task), OS_MESG_PRI_NORMAL);
|
||||
// }
|
||||
// while (true) {
|
||||
// task = AudioThread_CreateTask();
|
||||
// if (task != NULL) {
|
||||
// task->msgQueue = &gAudioTaskMsgQueue;
|
||||
// task->msg = OS_MESG_32(TASK_MESG_1);
|
||||
// osWritebackDCacheAll();
|
||||
// }
|
||||
// MQ_GET_MESG(&gAudioTaskMesgQueue, NULL);
|
||||
// if (task != NULL) {
|
||||
// osSendMesg(&gTaskMsgQueue, OS_MESG_PTR(task), OS_MESG_PRI_NORMAL);
|
||||
// }
|
||||
// MQ_WAIT_FOR_MESG(&gAudioVImesgQueue, NULL);
|
||||
// }
|
||||
}
|
||||
|
||||
void Graphics_SetTask(void) {
|
||||
@ -299,7 +278,8 @@ void Graphics_ThreadUpdate() {
|
||||
// }
|
||||
|
||||
// LTODO: There is no audio for now :P
|
||||
// Audio_Update();
|
||||
osSendMesg(&gTaskMesgQueue, OS_MESG_PTR(NULL), OS_MESG_NOBLOCK);
|
||||
Audio_Update();
|
||||
}
|
||||
|
||||
void Main_InitMesgQueues(void) {
|
||||
@ -388,6 +368,8 @@ void Main_ThreadEntry(void* arg0) {
|
||||
Graphics_ThreadEntry(NULL);
|
||||
Controller_Init();
|
||||
|
||||
Main_InitMesgQueues();
|
||||
|
||||
// LTODO: Implement timers
|
||||
// Timer_ThreadEntry(NULL);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user