diff --git a/configure.py b/configure.py index 7e3b0e90..9abe9527 100755 --- a/configure.py +++ b/configure.py @@ -930,11 +930,11 @@ LIBS = [ ["musyx/runtime/seq_api", True], ["musyx/runtime/snd_synthapi", True, {"add_to_all": False}], ["musyx/runtime/stream", False], - "musyx/runtime/synthdata", + ["musyx/runtime/synthdata", False], "musyx/runtime/synthmacros", ["musyx/runtime/synthvoice", False], ["musyx/runtime/synth_ac", True], - "musyx/runtime/synth_adsr", + ["musyx/runtime/synth_adsr", False], ["musyx/runtime/synth_vsamples", False], ["musyx/runtime/synth_dbtab", True], ["musyx/runtime/s_data", True], diff --git a/include/musyx/musyx_priv.h b/include/musyx/musyx_priv.h index dab2ee2a..514d072d 100644 --- a/include/musyx/musyx_priv.h +++ b/include/musyx/musyx_priv.h @@ -250,6 +250,43 @@ typedef struct SDIR_DATA { unsigned long extraData; // offset 0x1C, size 0x4 } SDIR_DATA; +typedef struct SDIR_TAB { + // total size: 0xC + struct SDIR_DATA* data; // offset 0x0, size 0x4 + void* base; // offset 0x4, size 0x4 + unsigned short numSmp; // offset 0x8, size 0x2 + unsigned short res; // offset 0xA, size 0x2 +} SDIR_TAB; + +typedef struct DATA_TAB { + // total size: 0x8 + void* data; // offset 0x0, size 0x4 + unsigned short id; // offset 0x4, size 0x2 + unsigned short refCount; // offset 0x6, size 0x2 +} DATA_TAB; + +typedef struct LAYER_TAB { + // total size: 0xC + void* data; // offset 0x0, size 0x4 + unsigned short id; // offset 0x4, size 0x2 + unsigned short num; // offset 0x6, size 0x2 + unsigned short refCount; // offset 0x8, size 0x2 + unsigned short reserved; // offset 0xA, size 0x2 +} LAYER_TAB; + +typedef struct MAC_MAINTAB { + // total size: 0x4 + unsigned short num; // offset 0x0, size 0x2 + unsigned short subTabIndex; // offset 0x2, size 0x2 +} MAC_MAINTAB; + +typedef struct MAC_SUBTAB { + // total size: 0x8 + void* data; // offset 0x0, size 0x4 + unsigned short id; // offset 0x4, size 0x2 + unsigned short refCount; // offset 0x6, size 0x2 +} MAC_SUBTAB; + typedef struct GSTACK { // total size: 0xC struct GROUP_DATA* gAddr; // offset 0x0, size 0x4 @@ -732,7 +769,7 @@ extern DSPstudioinfo dspStudio[8]; extern SYNTH_VOICE* synthVoice; extern DSPvoice* dspVoice; -typedef s32 (*SND_COMPARE)(u16*, u8*); +typedef s32 (*SND_COMPARE)(void*, void*); typedef struct FX_TAB { // total size: 0xA @@ -753,6 +790,13 @@ typedef struct FX_DATA { struct FX_TAB fx[1]; // offset 0x4, size 0xA } FX_DATA; +typedef struct FX_GROUP { + // total size: 0x8 + unsigned short gid; // offset 0x0, size 0x2 + unsigned short fxNum; // offset 0x2, size 0x2 + struct FX_TAB * fxTab; // offset 0x4, size 0x4 +} FX_GROUP; + typedef struct PAGE { // total size: 0x6 unsigned short macro; // offset 0x0, size 0x2 @@ -778,7 +822,7 @@ typedef struct MIDISETUP { MIDI_CHANNEL_SETUP channel[16]; // offset 0x4, size 0x50 } MIDISETUP; -void dataInit(u32, s32); /* extern */ +void dataInit(u32, u32); /* extern */ void dataInitStack(); /* extern */ u32 dataInsertSDir(SDIR_DATA* sdir, void* smp_data); u32 dataRemoveSDir(SDIR_DATA* sdir); @@ -821,7 +865,7 @@ void synthKillVoicesByMacroReferences(u16* ref); void synthExit(); u16 sndRand(void); s16 sndSin(u16 angle); -u8* sndBSearch(u16* key, u8* subTab, s32 mainTab, s32 len, SND_COMPARE cmp); +void* sndBSearch(void* key, void* base, s32 num, s32 len, SND_COMPARE cmp); void sndConvertMs(u32* time); void sndConvertTicks(u32* out, SYNTH_VOICE* svoice); u32 sndConvert2Ms(u32 time); @@ -864,7 +908,6 @@ void salFree(void* addr); #define SAL_MAX_STUDIONUM 8 extern u8 salMaxStudioNum; extern u8 salNumVoices; -extern float dspDLSVolTab[128]; /* Stream */ typedef s32 (*SND_STREAM_UPDATE_CALLBACK)(void* buffer1, u32 len1, void* buffer2, u32 len2, diff --git a/src/musyx/runtime/snd_service.c b/src/musyx/runtime/snd_service.c index f3a0653a..5131a6af 100644 --- a/src/musyx/runtime/snd_service.c +++ b/src/musyx/runtime/snd_service.c @@ -94,19 +94,19 @@ s16 sndSin(u16 angle) { return -sndSintab[SINTAB_ELEMENT_COUNT - (angle & SINTAB_ELEMENT_COUNT)]; } -u8* sndBSearch(u16* key, u8* subTab, s32 mainTab, s32 len, SND_COMPARE cmp) { +void* sndBSearch(void* key, void* base, s32 num, s32 len, SND_COMPARE cmp) { s32 left; s32 right; s32 mid; s32 found; u8* test; - if (mainTab != 0) { + if (num != 0) { left = 1; - right = mainTab; + right = num; do { mid = ((left + right) >> 1); - test = subTab + (len * (mid - 1)); + test = (u8*)(u32)base + (len * (mid - 1)); found = (*cmp)(key, test); if (found == 0) { return test; diff --git a/src/musyx/runtime/synth_adsr.c b/src/musyx/runtime/synth_adsr.c new file mode 100644 index 00000000..98bb4353 --- /dev/null +++ b/src/musyx/runtime/synth_adsr.c @@ -0,0 +1,58 @@ +#include "musyx/assert.h" +#include "musyx/musyx_priv.h" +#include "musyx/synth_dbtab.h" + +#include + +extern float powf(float, float); + +static u32 adsrGetIndex(ADSR_VARS* adsr) { + long i = 193 - ((adsr->currentIndex + 0x8000) >> 16); + return i < 0 ? 0 : i; +} + +u32 adsrConvertTimeCents(long tc) { return 1000.f * powf(2.f, 1.2715658e-08f * tc); } + +u32 salChangeADSRState(ADSR_VARS* adsr) { + u32 VoiceDone; // r30 +} + +u32 adsrSetup(ADSR_VARS* adsr) { + adsr->state = 0; + salChangeADSRState(adsr); +} + +u32 adsrStartRelease(ADSR_VARS* adsr, u32 rtime) { + switch (adsr->mode) { + case 0: + adsr->state = 4; + adsr->cnt = rtime; + if (rtime == 0) { + adsr->cnt = 1; + adsr->currentDelta = 0; + return 1; + } + adsr->currentDelta = -(adsr->currentVolume / rtime); + break; + case 1: + if (adsr->data.dls.aMode == 0 && adsr->state == 1) { + adsr->currentIndex = (193 - dspScale2IndexTab[adsr->currentVolume >> 21]) * 0x10000; + } + + adsr->cnt = (u32)(3.238342E-4f * (float)adsr->currentIndex * (float)rtime) >> 12; + adsr->state = 4; + if (adsr->cnt == 0) { + adsr->cnt = 1; + adsr->currentDelta = adsr->currentIndex = adsr->currentVolume = 0; + return 1; + } + + adsr->currentDelta = -(adsr->currentIndex / adsr->cnt); + break; + } + + return 0; +} + +u32 adsrRelease(ADSR_VARS* adsr) { +} diff --git a/src/musyx/runtime/synthdata.c b/src/musyx/runtime/synthdata.c new file mode 100644 index 00000000..8a881f60 --- /dev/null +++ b/src/musyx/runtime/synthdata.c @@ -0,0 +1,217 @@ +#include "musyx/assert.h" +#include "musyx/musyx_priv.h" + +static u16 dataSmpSDirNum = 0; +static SDIR_TAB dataSmpSDirs[128]; +static u16 dataCurveNum = 0; +static DATA_TAB dataCurveTab[2048]; +static u16 dataKeymapNum = 0; +static DATA_TAB dataKeymapTab[256]; +static u16 dataLayerNum = 0; +static LAYER_TAB dataLayerTab[256]; +static u16 dataMacTotal = 0; +static MAC_MAINTAB dataMacMainTab[512]; +static MAC_SUBTAB dataMacSubTabmem[2048]; +static u16 dataFXGroupNum = 0; +static FX_GROUP dataFXGroups[128]; + +u32 dataInsertKeymap(u16 cid, void* keymapdata) { + long i; // r31 + long j; // r29 +} + +unsigned long dataRemoveKeymap(unsigned short sid) { + long i; // r31 + long j; // r30 +} +unsigned long dataInsertLayer(unsigned short cid, void* layerdata, unsigned short size) { + long i; // r31 + long j; // r29 +} +unsigned long dataRemoveLayer(unsigned short sid) { + long i; // r31 + long j; // r30 +} +unsigned long dataInsertCurve(unsigned short cid, void* curvedata) { + long i; // r31 + long j; // r29 +} +unsigned long dataRemoveCurve(unsigned short sid) { + long i; // r31 + long j; // r30 +} +unsigned long dataInsertSDir(struct SDIR_DATA* sdir, void* smp_data) { + long i; // r31 + struct SDIR_DATA* s; // r25 + unsigned short n; // r27 + unsigned short j; // r29 + unsigned short k; // r26 +} +unsigned long dataRemoveSDir(struct SDIR_DATA* sdir) { + long i; // r28 + long j; // r30 + long index; // r27 + struct SDIR_DATA* data; // r31 +} +unsigned long dataAddSampleReference(unsigned short sid) { + unsigned long i; // r29 + struct SAMPLE_HEADER* header; // r1+0xC + struct SDIR_DATA* data; // r30 + struct SDIR_DATA* sdir; // r31 +} +unsigned long dataRemoveSampleReference(unsigned short sid) { + unsigned long i; // r30 + struct SDIR_DATA* sdir; // r31 +} +unsigned long dataInsertFX(unsigned short gid, struct FX_TAB* fx, unsigned short fxNum) { + long i; // r31 +} +unsigned long dataRemoveFX(unsigned short gid) { + long i; // r31 + long j; // r30 +} +unsigned long dataInsertMacro(unsigned short mid, void* macroaddr) { + long main; // r28 + long pos; // r29 + long base; // r27 + long i; // r31 +} +unsigned long dataRemoveMacro(unsigned short mid) { + long main; // r29 + long base; // r28 + long i; // r31 +} +long maccmp(void* p1, void* p2) { return ((MAC_SUBTAB*)p1)->id - ((MAC_SUBTAB*)p2)->id; } + +struct MSTEP* dataGetMacro(unsigned short mid) { + static s32 base; + static s32 main; + static MAC_SUBTAB key; + static MAC_SUBTAB* result; + + main = (mid >> 6) & 0x3fff; + + if (dataMacMainTab[main].num != 0) { + base = dataMacMainTab[main].subTabIndex; + key.id = mid; + if ((result = (MAC_SUBTAB*)sndBSearch(&key, &dataMacSubTabmem[base], dataMacMainTab[main].num, + 8, maccmp)) != NULL) { + return result->data; + } + } + + return NULL; +} + +long smpcmp(void* p1, void* p2) { return ((SDIR_DATA*)p1)->id - ((SDIR_DATA*)p2)->id; } + +long dataGetSample(unsigned short sid, SAMPLE_INFO* newsmp) { + static s32 base; + static s32 main; + static SDIR_DATA key; + static SDIR_DATA* result; + static SAMPLE_HEADER* sheader; + long i; // r30 + + key.id = sid; + + for (i = 0; i < dataSmpSDirNum; ++i) { + if ((result = sndBSearch(&key, dataSmpSDirs[i].data, dataSmpSDirs[i].numSmp, sizeof(SDIR_DATA), + smpcmp)) != NULL) { + if (result->ref_cnt != 0xFFFF) { + sheader = &result->header; + newsmp->info = sheader->info; + newsmp->addr = result->addr; + newsmp->offset = 0; + newsmp->loop = sheader->loopOffset; + newsmp->length = sheader->length & 0xffffff; + newsmp->loopLength = sheader->loopLength; + newsmp->compType = sheader->length >> 24; + + if (result->extraData) { + newsmp->extraData = (void*)((u32) & (dataSmpSDirs[i].data)->id + result->extraData); + } + return 0; + } + } + } + + return -1; +} + +long curvecmp(void* p1, void* p2) { return ((DATA_TAB*)p1)->id - ((DATA_TAB*)p2)->id; } + +void* dataGetCurve(unsigned short cid) { + static DATA_TAB key; + static DATA_TAB* result; + + key.id = cid; + if (result = + (DATA_TAB*)sndBSearcH(&key, dataCurveTab, dataCurveNum, sizeof(DATA_TAB), curvecmp)) { + return result->data; + } + return NULL; +} + +void* dataGetKeymap(unsigned short cid) { + static DATA_TAB key; + static DATA_TAB* result; + + key.id = cid; + if (result = + (DATA_TAB*)sndBSearcH(&key, dataCurveTab, dataCurveNum, sizeof(DATA_TAB), curvecmp)) { + return result->data; + } + return NULL; +} + +long layercmp(void* p1, void* p2) { return ((LAYER_TAB*)p1)->id - ((LAYER_TAB*)p2)->id; } + +void* dataGetLayer(unsigned short cid, unsigned short* n) { + static LAYER_TAB key; + static LAYER_TAB* result; + + key.id = cid; + if (result = + (LAYER_TAB*)sndBSearcH(&key, dataLayerTab, dataLayerNum, sizeof(LAYER_TAB), layercmp)) { + *n = result->num; + return result->data; + } + return NULL; +} + +long fxcmp(void* p1, void* p2) { return ((FX_TAB*)p1)->id - ((FX_TAB*)p2)->id; } + +struct FX_TAB* dataGetFX(unsigned short fid) { + static FX_TAB key; + FX_TAB* ret; // r29 + long i; // r31 + + key.id = fid; + for (i = 0; i < dataFXGroupNum; ++i) { + if ((ret = (FX_TAB*)sndBSearch(&key, dataFXGroups[i].fxTab, dataFXGroups[i].fxNum, + sizeof(FX_TAB), fxcmp))) { + return ret; + } + } + + return NULL; +} + +void dataInit(u32 smpBase, u32 smpLength) { + long i; // r31 + + dataSmpSDirNum = 0; + dataCurveNum = 0; + dataKeymapNum = 0; + dataLayerNum = 0; + dataFXGroupNum = 0; + dataMacTotal = 0; + for (i = 0; i < 512; ++i) { + dataMacMainTab[i].num = 0; + dataMacMainTab[i].subTabIndex = 0; + } + hwInitSampleMem(smpBase, smpLength); +} + +void dataExit() { hwExitSampleMem(); }