From a42f503dbfb58d4fec397fd455b375ae91d13d01 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Fri, 24 Feb 2023 18:11:03 -0800 Subject: [PATCH] Match and link s_data --- asm/musyx/runtime/s_data.s | 50 +++--- asm/musyx/runtime/seq.s | 2 +- configure.py | 4 +- include/musyx/musyx.h | 63 ++++++- include/musyx/musyx_priv.h | 142 ++++++++++++++- src/musyx/runtime/hardware.c | 68 ++++++-- src/musyx/runtime/profile.c | 94 ++++++++++ src/musyx/runtime/s_data.c | 326 +++++++++++++++++++++++++++++++++++ 8 files changed, 697 insertions(+), 52 deletions(-) create mode 100644 src/musyx/runtime/profile.c create mode 100644 src/musyx/runtime/s_data.c diff --git a/asm/musyx/runtime/s_data.s b/asm/musyx/runtime/s_data.s index 11f97cba..5ca40c5a 100644 --- a/asm/musyx/runtime/s_data.s +++ b/asm/musyx/runtime/s_data.s @@ -21,8 +21,8 @@ dataInitStack: /* 803AA188 003A70E8 B0 0D AF 18 */ sth r0, sp@sda21(r13) /* 803AA18C 003A70EC 4E 80 00 20 */ blr -.global ScanIDList -ScanIDList: +.global InsertData +InsertData: /* 803AA190 003A70F0 94 21 FF F0 */ stwu r1, -0x10(r1) /* 803AA194 003A70F4 7C 08 02 A6 */ mflr r0 /* 803AA198 003A70F8 90 01 00 14 */ stw r0, 0x14(r1) @@ -281,7 +281,7 @@ lbl_803AA4D4: /* 803AA4D8 003A7438 7F A4 EB 78 */ mr r4, r29 /* 803AA4DC 003A743C 38 A0 00 01 */ li r5, 1 /* 803AA4E0 003A7440 38 C0 00 00 */ li r6, 0 -/* 803AA4E4 003A7444 4B FF FC AD */ bl ScanIDList +/* 803AA4E4 003A7444 4B FF FC AD */ bl InsertData /* 803AA4E8 003A7448 3B 5A 00 01 */ addi r26, r26, 1 lbl_803AA4EC: /* 803AA4EC 003A744C A0 19 00 02 */ lhz r0, 2(r25) @@ -296,7 +296,7 @@ lbl_803AA504: /* 803AA50C 003A746C 38 A0 00 01 */ li r5, 1 /* 803AA510 003A7470 38 C0 00 00 */ li r6, 0 /* 803AA514 003A7474 3B 39 00 02 */ addi r25, r25, 2 -/* 803AA518 003A7478 4B FF FC 79 */ bl ScanIDList +/* 803AA518 003A7478 4B FF FC 79 */ bl InsertData lbl_803AA51C: /* 803AA51C 003A747C A0 79 00 00 */ lhz r3, 0(r25) /* 803AA520 003A7480 28 03 FF FF */ cmplwi r3, 0xffff @@ -315,7 +315,7 @@ lbl_803AA544: /* 803AA548 003A74A8 7F C4 F3 78 */ mr r4, r30 /* 803AA54C 003A74AC 38 A0 00 00 */ li r5, 0 /* 803AA550 003A74B0 38 C0 00 00 */ li r6, 0 -/* 803AA554 003A74B4 4B FF FC 3D */ bl ScanIDList +/* 803AA554 003A74B4 4B FF FC 3D */ bl InsertData /* 803AA558 003A74B8 3B 39 00 01 */ addi r25, r25, 1 lbl_803AA55C: /* 803AA55C 003A74BC A0 1A 00 02 */ lhz r0, 2(r26) @@ -330,7 +330,7 @@ lbl_803AA574: /* 803AA57C 003A74DC 38 A0 00 00 */ li r5, 0 /* 803AA580 003A74E0 38 C0 00 00 */ li r6, 0 /* 803AA584 003A74E4 3B 5A 00 02 */ addi r26, r26, 2 -/* 803AA588 003A74E8 4B FF FC 09 */ bl ScanIDList +/* 803AA588 003A74E8 4B FF FC 09 */ bl InsertData lbl_803AA58C: /* 803AA58C 003A74EC A0 7A 00 00 */ lhz r3, 0(r26) /* 803AA590 003A74F0 28 03 FF FF */ cmplwi r3, 0xffff @@ -348,7 +348,7 @@ lbl_803AA5B4: /* 803AA5B8 003A7518 7F C4 F3 78 */ mr r4, r30 /* 803AA5BC 003A751C 38 A0 00 04 */ li r5, 4 /* 803AA5C0 003A7520 38 C0 00 00 */ li r6, 0 -/* 803AA5C4 003A7524 4B FF FB CD */ bl ScanIDList +/* 803AA5C4 003A7524 4B FF FB CD */ bl InsertData /* 803AA5C8 003A7528 3B 39 00 01 */ addi r25, r25, 1 lbl_803AA5CC: /* 803AA5CC 003A752C A0 1A 00 02 */ lhz r0, 2(r26) @@ -363,7 +363,7 @@ lbl_803AA5E4: /* 803AA5EC 003A754C 38 A0 00 04 */ li r5, 4 /* 803AA5F0 003A7550 38 C0 00 00 */ li r6, 0 /* 803AA5F4 003A7554 3B 5A 00 02 */ addi r26, r26, 2 -/* 803AA5F8 003A7558 4B FF FB 99 */ bl ScanIDList +/* 803AA5F8 003A7558 4B FF FB 99 */ bl InsertData lbl_803AA5FC: /* 803AA5FC 003A755C A0 7A 00 00 */ lhz r3, 0(r26) /* 803AA600 003A7560 28 03 FF FF */ cmplwi r3, 0xffff @@ -381,7 +381,7 @@ lbl_803AA624: /* 803AA628 003A7588 7F C4 F3 78 */ mr r4, r30 /* 803AA62C 003A758C 38 A0 00 02 */ li r5, 2 /* 803AA630 003A7590 38 C0 00 00 */ li r6, 0 -/* 803AA634 003A7594 4B FF FB 5D */ bl ScanIDList +/* 803AA634 003A7594 4B FF FB 5D */ bl InsertData /* 803AA638 003A7598 3B 39 00 01 */ addi r25, r25, 1 lbl_803AA63C: /* 803AA63C 003A759C A0 1A 00 02 */ lhz r0, 2(r26) @@ -396,7 +396,7 @@ lbl_803AA654: /* 803AA65C 003A75BC 38 A0 00 02 */ li r5, 2 /* 803AA660 003A75C0 38 C0 00 00 */ li r6, 0 /* 803AA664 003A75C4 3B 5A 00 02 */ addi r26, r26, 2 -/* 803AA668 003A75C8 4B FF FB 29 */ bl ScanIDList +/* 803AA668 003A75C8 4B FF FB 29 */ bl InsertData lbl_803AA66C: /* 803AA66C 003A75CC A0 7A 00 00 */ lhz r3, 0(r26) /* 803AA670 003A75D0 28 03 FF FF */ cmplwi r3, 0xffff @@ -414,7 +414,7 @@ lbl_803AA694: /* 803AA698 003A75F8 7F C4 F3 78 */ mr r4, r30 /* 803AA69C 003A75FC 38 A0 00 03 */ li r5, 3 /* 803AA6A0 003A7600 38 C0 00 00 */ li r6, 0 -/* 803AA6A4 003A7604 4B FF FA ED */ bl ScanIDList +/* 803AA6A4 003A7604 4B FF FA ED */ bl InsertData /* 803AA6A8 003A7608 3B 39 00 01 */ addi r25, r25, 1 lbl_803AA6AC: /* 803AA6AC 003A760C A0 1A 00 02 */ lhz r0, 2(r26) @@ -429,7 +429,7 @@ lbl_803AA6C4: /* 803AA6CC 003A762C 38 A0 00 03 */ li r5, 3 /* 803AA6D0 003A7630 38 C0 00 00 */ li r6, 0 /* 803AA6D4 003A7634 3B 5A 00 02 */ addi r26, r26, 2 -/* 803AA6D8 003A7638 4B FF FA B9 */ bl ScanIDList +/* 803AA6D8 003A7638 4B FF FA B9 */ bl InsertData lbl_803AA6DC: /* 803AA6DC 003A763C A0 7A 00 00 */ lhz r3, 0(r26) /* 803AA6E0 003A7640 28 03 FF FF */ cmplwi r3, 0xffff @@ -533,7 +533,7 @@ lbl_803AA82C: /* 803AA830 003A7790 38 80 00 00 */ li r4, 0 /* 803AA834 003A7794 38 A0 00 01 */ li r5, 1 /* 803AA838 003A7798 38 C0 00 01 */ li r6, 1 -/* 803AA83C 003A779C 4B FF F9 55 */ bl ScanIDList +/* 803AA83C 003A779C 4B FF F9 55 */ bl InsertData /* 803AA840 003A77A0 3B 7B FF FF */ addi r27, r27, -1 lbl_803AA844: /* 803AA844 003A77A4 A0 1C FF FE */ lhz r0, -2(r28) @@ -548,7 +548,7 @@ lbl_803AA860: /* 803AA864 003A77C4 38 80 00 00 */ li r4, 0 /* 803AA868 003A77C8 38 A0 00 01 */ li r5, 1 /* 803AA86C 003A77CC 38 C0 00 01 */ li r6, 1 -/* 803AA870 003A77D0 4B FF F9 21 */ bl ScanIDList +/* 803AA870 003A77D0 4B FF F9 21 */ bl InsertData /* 803AA874 003A77D4 3B 9C FF FE */ addi r28, r28, -2 /* 803AA878 003A77D8 48 00 00 1C */ b lbl_803AA894 lbl_803AA87C: @@ -556,7 +556,7 @@ lbl_803AA87C: /* 803AA880 003A77E0 38 80 00 00 */ li r4, 0 /* 803AA884 003A77E4 38 A0 00 01 */ li r5, 1 /* 803AA888 003A77E8 38 C0 00 01 */ li r6, 1 -/* 803AA88C 003A77EC 4B FF F9 05 */ bl ScanIDList +/* 803AA88C 003A77EC 4B FF F9 05 */ bl InsertData /* 803AA890 003A77F0 3B 9C FF FE */ addi r28, r28, -2 lbl_803AA894: /* 803AA894 003A77F4 7C 1C E8 40 */ cmplw r28, r29 @@ -577,7 +577,7 @@ lbl_803AA8C0: /* 803AA8C4 003A7824 38 80 00 00 */ li r4, 0 /* 803AA8C8 003A7828 38 A0 00 00 */ li r5, 0 /* 803AA8CC 003A782C 38 C0 00 01 */ li r6, 1 -/* 803AA8D0 003A7830 4B FF F8 C1 */ bl ScanIDList +/* 803AA8D0 003A7830 4B FF F8 C1 */ bl InsertData /* 803AA8D4 003A7834 3B 7B 00 01 */ addi r27, r27, 1 lbl_803AA8D8: /* 803AA8D8 003A7838 A0 1C 00 02 */ lhz r0, 2(r28) @@ -592,7 +592,7 @@ lbl_803AA8F0: /* 803AA8F8 003A7858 38 A0 00 00 */ li r5, 0 /* 803AA8FC 003A785C 38 C0 00 01 */ li r6, 1 /* 803AA900 003A7860 3B 9C 00 02 */ addi r28, r28, 2 -/* 803AA904 003A7864 4B FF F8 8D */ bl ScanIDList +/* 803AA904 003A7864 4B FF F8 8D */ bl InsertData lbl_803AA908: /* 803AA908 003A7868 A0 7C 00 00 */ lhz r3, 0(r28) /* 803AA90C 003A786C 28 03 FF FF */ cmplwi r3, 0xffff @@ -610,7 +610,7 @@ lbl_803AA930: /* 803AA934 003A7894 38 80 00 00 */ li r4, 0 /* 803AA938 003A7898 38 A0 00 04 */ li r5, 4 /* 803AA93C 003A789C 38 C0 00 01 */ li r6, 1 -/* 803AA940 003A78A0 4B FF F8 51 */ bl ScanIDList +/* 803AA940 003A78A0 4B FF F8 51 */ bl InsertData /* 803AA944 003A78A4 3B 7B 00 01 */ addi r27, r27, 1 lbl_803AA948: /* 803AA948 003A78A8 A0 1C 00 02 */ lhz r0, 2(r28) @@ -625,7 +625,7 @@ lbl_803AA960: /* 803AA968 003A78C8 38 A0 00 04 */ li r5, 4 /* 803AA96C 003A78CC 38 C0 00 01 */ li r6, 1 /* 803AA970 003A78D0 3B 9C 00 02 */ addi r28, r28, 2 -/* 803AA974 003A78D4 4B FF F8 1D */ bl ScanIDList +/* 803AA974 003A78D4 4B FF F8 1D */ bl InsertData lbl_803AA978: /* 803AA978 003A78D8 A0 7C 00 00 */ lhz r3, 0(r28) /* 803AA97C 003A78DC 28 03 FF FF */ cmplwi r3, 0xffff @@ -643,7 +643,7 @@ lbl_803AA9A0: /* 803AA9A4 003A7904 38 80 00 00 */ li r4, 0 /* 803AA9A8 003A7908 38 A0 00 02 */ li r5, 2 /* 803AA9AC 003A790C 38 C0 00 01 */ li r6, 1 -/* 803AA9B0 003A7910 4B FF F7 E1 */ bl ScanIDList +/* 803AA9B0 003A7910 4B FF F7 E1 */ bl InsertData /* 803AA9B4 003A7914 3B 7B 00 01 */ addi r27, r27, 1 lbl_803AA9B8: /* 803AA9B8 003A7918 A0 1C 00 02 */ lhz r0, 2(r28) @@ -658,7 +658,7 @@ lbl_803AA9D0: /* 803AA9D8 003A7938 38 A0 00 02 */ li r5, 2 /* 803AA9DC 003A793C 38 C0 00 01 */ li r6, 1 /* 803AA9E0 003A7940 3B 9C 00 02 */ addi r28, r28, 2 -/* 803AA9E4 003A7944 4B FF F7 AD */ bl ScanIDList +/* 803AA9E4 003A7944 4B FF F7 AD */ bl InsertData lbl_803AA9E8: /* 803AA9E8 003A7948 A0 7C 00 00 */ lhz r3, 0(r28) /* 803AA9EC 003A794C 28 03 FF FF */ cmplwi r3, 0xffff @@ -676,7 +676,7 @@ lbl_803AAA10: /* 803AAA14 003A7974 38 80 00 00 */ li r4, 0 /* 803AAA18 003A7978 38 A0 00 03 */ li r5, 3 /* 803AAA1C 003A797C 38 C0 00 01 */ li r6, 1 -/* 803AAA20 003A7980 4B FF F7 71 */ bl ScanIDList +/* 803AAA20 003A7980 4B FF F7 71 */ bl InsertData /* 803AAA24 003A7984 3B 7B 00 01 */ addi r27, r27, 1 lbl_803AAA28: /* 803AAA28 003A7988 A0 1C 00 02 */ lhz r0, 2(r28) @@ -691,7 +691,7 @@ lbl_803AAA40: /* 803AAA48 003A79A8 38 A0 00 03 */ li r5, 3 /* 803AAA4C 003A79AC 38 C0 00 01 */ li r6, 1 /* 803AAA50 003A79B0 3B 9C 00 02 */ addi r28, r28, 2 -/* 803AAA54 003A79B4 4B FF F7 3D */ bl ScanIDList +/* 803AAA54 003A79B4 4B FF F7 3D */ bl InsertData lbl_803AAA58: /* 803AAA58 003A79B8 A0 7C 00 00 */ lhz r3, 0(r28) /* 803AAA5C 003A79BC 28 03 FF FF */ cmplwi r3, 0xffff @@ -710,8 +710,8 @@ lbl_803AAA78: /* 803AAA8C 003A79EC 38 21 00 20 */ addi r1, r1, 0x20 /* 803AAA90 003A79F0 4E 80 00 20 */ blr -.global sndSeqPlaySong -sndSeqPlaySong: +.global seqPlaySong +seqPlaySong: /* 803AAA94 003A79F4 94 21 FF D0 */ stwu r1, -0x30(r1) /* 803AAA98 003A79F8 7C 08 02 A6 */ mflr r0 /* 803AAA9C 003A79FC 90 01 00 34 */ stw r0, 0x34(r1) diff --git a/asm/musyx/runtime/seq.s b/asm/musyx/runtime/seq.s index 0e2aa73e..e5e1188c 100644 --- a/asm/musyx/runtime/seq.s +++ b/asm/musyx/runtime/seq.s @@ -2446,7 +2446,7 @@ lbl_80396CCC: /* 80396CF8 00393C58 38 E0 00 01 */ li r7, 1 /* 80396CFC 00393C5C 80 BF 00 10 */ lwz r5, 0x10(r31) /* 80396D00 00393C60 89 1F 00 19 */ lbz r8, 0x19(r31) -/* 80396D04 00393C64 48 01 3D 91 */ bl sndSeqPlaySong +/* 80396D04 00393C64 48 01 3D 91 */ bl seqPlaySong /* 80396D08 00393C68 3C 03 00 01 */ addis r0, r3, 1 /* 80396D0C 00393C6C 90 7D 00 00 */ stw r3, 0(r29) /* 80396D10 00393C70 28 00 FF FF */ cmplwi r0, 0xffff diff --git a/configure.py b/configure.py index 2309f976..3da0b0f0 100755 --- a/configure.py +++ b/configure.py @@ -920,7 +920,7 @@ LIBS = [ { "lib": "musyx", #"mw_version": "1.2.5", - #"cflags": "-proc gecko -fp hard -nodefaults -nosyspath -i include -i libc -g -sym on -D_DEBUG=1 -enum int -use_lmw_stmw on", + #"cflags": "-proc gecko -fp hard -nodefaults -nosyspath -i include -i libc -g -sym on -D_DEBUG=1 -enum int ", "mw_version": "1.3.2", "cflags": "$cflags_musyx", "host": False, @@ -937,7 +937,7 @@ LIBS = [ "musyx/runtime/synth_adsr", ["musyx/runtime/synth_vsamples", False], ["musyx/runtime/synth_dbtab", True], - "musyx/runtime/s_data", + ["musyx/runtime/s_data", True], ["musyx/runtime/hw_dspctrl", False], ["musyx/runtime/hw_volconv", False], ["musyx/runtime/snd3d", False], diff --git a/include/musyx/musyx.h b/include/musyx/musyx.h index 504acd43..486adf79 100644 --- a/include/musyx/musyx.h +++ b/include/musyx/musyx.h @@ -1,6 +1,8 @@ #ifndef _MUSYX_MUSYX #define _MUSYX_MUSYX +#include + #ifdef __cplusplus extern "C" { #endif @@ -61,6 +63,20 @@ typedef struct SND_SEQVOLDEF { u8 volGroup; } SND_SEQVOLDEF; +typedef struct SND_PLAYPARA { + u32 flags; + u32 trackMute[2]; + u16 speed; + struct { + u16 time; + u8 target; + } volume; + u8 numSeqVolDef; + SND_SEQVOLDEF* seqVolDef; + u8 numFaded; + u8* faded; +} SND_PLAYPARA; + typedef struct SND_HOOKS { void* (*malloc)(u32 len); void (*free)(void* addr); @@ -109,8 +125,8 @@ void sndSilence(); typedef enum { SND_STUDIO_TYPE_STD = 0, - SND_STUDIO_TYPE_RESERVED0 = 1, - SND_STUDIO_TYPE_RESERVED1 = 2, + SND_STUDIO_TYPE_RESERVED0 = 1, + SND_STUDIO_TYPE_RESERVED1 = 2, SND_STUDIO_TYPE_RESERVED2 = 3, } SND_STUDIO_TYPE; @@ -291,6 +307,49 @@ void sndAuxCallbackChorus(u8 reason, SND_AUX_INFO* info, void* user); bool sndAuxCallbackPrepareChorus(SND_AUX_CHORUS* ch); bool sndAuxCallbackShutdownChorus(SND_AUX_CHORUS* ch); bool sndAuxCallbackUpdateSettingsChorus(SND_AUX_CHORUS* ch); + +typedef struct SND_PROFILE_DATA { + unsigned long loadStores; + unsigned long missCycles; + unsigned long cycles; + unsigned long instructions; + unsigned long lastLoadStores; + unsigned long lastMissCycles; + unsigned long lastCycles; + unsigned long lastInstructions; + unsigned long peekLoadStores; + unsigned long peekMissCycles; + unsigned long peekCycles; + unsigned long peekInstructions; + unsigned long _loadStores; + unsigned long _missCycles; + unsigned long _cycles; + unsigned long _instructions; + float avgLoadStores; + float avgMissCycles; + float avgCycles; + float avgInstructions; + float sumLoadStores; + float sumMissCycles; + float sumCycles; + float sumInstructions; + unsigned long cnt; + unsigned long paused; +} SND_PROFILE_DATA; + +typedef struct SND_PROFILE_INFO { + SND_PROFILE_DATA dspCtrl; + SND_PROFILE_DATA auxProcessing; + SND_PROFILE_DATA sequencer; + SND_PROFILE_DATA synthesizer; + SND_PROFILE_DATA emitters; + SND_PROFILE_DATA streaming; + unsigned char numMusicVoices; + unsigned char numSFXVoices; +} SND_PROFILE_INFO; + +typedef void (*SND_PROF_USERCALLBACK)(struct SND_PROFILE_INFO*); +extern SND_PROF_USERCALLBACK sndProfUserCallback; #ifdef __cplusplus } #endif diff --git a/include/musyx/musyx_priv.h b/include/musyx/musyx_priv.h index d8931189..dab2ee2a 100644 --- a/include/musyx/musyx_priv.h +++ b/include/musyx/musyx_priv.h @@ -208,6 +208,55 @@ typedef struct SAMPLE_INFO { u8 compType; // offset 0x1C, size 0x1 } SAMPLE_INFO; +typedef struct GROUP_DATA { + // total size: 0x28 + unsigned long nextOff; // offset 0x0, size 0x4 + unsigned short id; // offset 0x4, size 0x2 + unsigned short type; // offset 0x6, size 0x2 + unsigned long macroOff; // offset 0x8, size 0x4 + unsigned long sampleOff; // offset 0xC, size 0x4 + unsigned long curveOff; // offset 0x10, size 0x4 + unsigned long keymapOff; // offset 0x14, size 0x4 + unsigned long layerOff; // offset 0x18, size 0x4 + union { + struct fx { + // total size: 0x4 + unsigned long tableOff; // offset 0x0, size 0x4 + } fx; + struct song { + // total size: 0xC + unsigned long normpageOff; // offset 0x0, size 0x4 + unsigned long drumpageOff; // offset 0x4, size 0x4 + unsigned long midiSetupOff; // offset 0x8, size 0x4 + } song; + } data; // offset 0x1C, size 0xC +} GROUP_DATA; + +typedef struct SAMPLE_HEADER { + // total size: 0x10 + unsigned long info; // offset 0x0, size 0x4 + unsigned long length; // offset 0x4, size 0x4 + unsigned long loopOffset; // offset 0x8, size 0x4 + unsigned long loopLength; // offset 0xC, size 0x4 +} SAMPLE_HEADER; + +typedef struct SDIR_DATA { + // total size: 0x20 + unsigned short id; // offset 0x0, size 0x2 + unsigned short ref_cnt; // offset 0x2, size 0x2 + unsigned long offset; // offset 0x4, size 0x4 + void* addr; // offset 0x8, size 0x4 + struct SAMPLE_HEADER header; // offset 0xC, size 0x10 + unsigned long extraData; // offset 0x1C, size 0x4 +} SDIR_DATA; + +typedef struct GSTACK { + // total size: 0xC + struct GROUP_DATA* gAddr; // offset 0x0, size 0x4 + struct SDIR_DATA* sdirAddr; // offset 0x4, size 0x4 + void* prjAddr; // offset 0x8, size 0x4 +} GSTACK; + typedef struct VSampleInfo { // total size: 0xC void* loopBufferAddr; // offset 0x0, size 0x4 @@ -551,6 +600,31 @@ typedef struct KEYMAP { unsigned char reserved[2]; // offset 0x6, size 0x2 } KEYMAP; +typedef struct MEM_DATA { + // total size: 0x408 + unsigned long nextOff; // offset 0x0, size 0x4 + unsigned short id; // offset 0x4, size 0x2 + unsigned short reserved; // offset 0x6, size 0x2 + union { + struct { + // total size: 0x10 + unsigned long num; // offset 0x0, size 0x4 + LAYER entry[1]; // offset 0x4, size 0xC + } layer; + KEYMAP map[128]; + unsigned char tab[1]; + MSTEP cmd[1][2]; + } data; // offset 0x8, size 0x400 +} MEM_DATA; + +typedef struct POOL_DATA { + // total size: 0x10 + u32 macroOff; // offset 0x0, size 0x4 + u32 curveOff; // offset 0x4, size 0x4 + u32 keymapOff; // offset 0x8, size 0x4 + u32 layerOff; // offset 0xC, size 0x4 +} POOL_DATA; + typedef struct SAL_VOLINFO { // total size: 0x24 float volL; // offset 0x0, size 0x4 @@ -671,6 +745,7 @@ typedef struct FX_TAB { unsigned char key; // offset 0x8, size 0x1 unsigned char vGroup; // offset 0x9, size 0x1 } FX_TAB; + typedef struct FX_DATA { // total size: 0xE unsigned short num; // offset 0x0, size 0x2 @@ -678,22 +753,72 @@ typedef struct FX_DATA { struct FX_TAB fx[1]; // offset 0x4, size 0xA } FX_DATA; +typedef struct PAGE { + // total size: 0x6 + unsigned short macro; // offset 0x0, size 0x2 + unsigned char prio; // offset 0x2, size 0x1 + unsigned char maxVoices; // offset 0x3, size 0x1 + unsigned char index; // offset 0x4, size 0x1 + unsigned char reserved; // offset 0x5, size 0x1 +} PAGE; + +typedef struct MIDI_CHANNEL_SETUP { + // total size: 0x5 + unsigned char program; // offset 0x0, size 0x1 + unsigned char volume; // offset 0x1, size 0x1 + unsigned char panning; // offset 0x2, size 0x1 + unsigned char reverb; // offset 0x3, size 0x1 + unsigned char chorus; // offset 0x4, size 0x1 +} MIDI_CHANNEL_SETUP; + +typedef struct MIDISETUP { + // total size: 0x54 + u16 songId; // offset 0x0, size 0x2 + u16 reserved; // offset 0x2, size 0x2 + MIDI_CHANNEL_SETUP channel[16]; // offset 0x4, size 0x50 +} MIDISETUP; + void dataInit(u32, s32); /* extern */ void dataInitStack(); /* extern */ +u32 dataInsertSDir(SDIR_DATA* sdir, void* smp_data); +u32 dataRemoveSDir(SDIR_DATA* sdir); +u32 dataInsertMacro(u16 mid, void* macroaddr); +u32 dataRemoveMacro(u16 mid); +u32 dataInsertCurve(u16 cid, void* curvedata); +u32 dataRemoveCurve(u16 sid); +u32 dataAddSampleReference(u16 sid); +u32 dataRemoveSampleReference(u16 sid); +u32 dataInsertKeymap(u16 cid, void* keymapdata); +u32 dataRemoveKeymap(u16 sid); +u32 dataInsertLayer(u16 cid, void* layerdata, u16 size); +u32 dataRemoveLayer(u16 sid); +u32 dataInsertFX(u16 gid, FX_TAB* fx, u16 fxNum); FX_TAB* dataGetFX(u16 fid); s32 hwInit(u32* frq, u16 numVoices, u16 numStudios, u32 flags); /* extern */ void hwEnableIrq(); void hwDisableIrq(); -void s3dInit(s32); /* extern */ -void seqInit(); /* extern */ -void streamInit(); /* extern */ -void synthInit(u32, u8); /* extern */ -void vsInit(); /* extern */ +void* hwTransAddr(void* samples); + +void seqInit(); /* extern */ +unsigned long seqStartPlay(PAGE* norm, PAGE* drum, MIDISETUP* midiSetup, u32* song, + SND_PLAYPARA* para, u8 studio, u16 sgid); +void streamInit(); /* extern */ +void vsInit(); /* extern */ void hwExit(); void dataExit(); +void s3dInit(s32); /* extern */ +void s3dKillEmitterByFXID(FX_TAB* fxTab, unsigned long num); void s3dExit(); -void synthExit(); +void synthInit(u32, u8); /* extern */ +extern u16 voicePrioSortRootListRoot; +extern u8 voiceMusicRunning; +extern u8 voiceFxRunning; +extern u8 voiceListInsert; +extern u8 voiceListRoot; + u32 synthGetTicksPerSecond(SYNTH_VOICE* svoice); +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); @@ -785,6 +910,11 @@ void* aramStoreData(void* src, unsigned long len); void aramRemoveData(void* aram, unsigned long len); void macMakeInactive(SYNTH_VOICE* svoice, MAC_STATE); + +void sndProfUpdateMisc(SND_PROFILE_INFO* info); +void sndProfResetPMC(SND_PROFILE_DATA* info); +void sndProfStartPMC(SND_PROFILE_DATA* info); + #ifdef __cplusplus } #endif diff --git a/src/musyx/runtime/hardware.c b/src/musyx/runtime/hardware.c index cfc78fdd..47ba8b75 100644 --- a/src/musyx/runtime/hardware.c +++ b/src/musyx/runtime/hardware.c @@ -14,6 +14,8 @@ static volatile const u16 itdOffTab[128] = { 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, }; +SND_PROFILE_INFO prof; + u8 salFrame; u8 salAuxFrame; u8 salNumVoices; @@ -23,49 +25,72 @@ u8 salTimeOffset; void hwSetTimeOffset(u8 offset); void snd_handle_irq() { - u8 i; - u8 j; + u8 r; // r31 + u8 i; // r30 + u8 v; // r29 if (sndActive == 0) { return; } streamCorrectLoops(); hwIRQEnterCritical(); + // sndProfStartPCM(&prof.dspCtrl); salCtrlDsp(salAiGetDest()); + // sndProfStopPMC(&prof.dspCtrl); hwIRQLeaveCritical(); hwIRQEnterCritical(); + // sndProfStartPCM(&prof.auxProcessing); salHandleAuxProcessing(); + // sndProfStopPMC(&prof.auxProcessing); hwIRQLeaveCritical(); hwIRQEnterCritical(); salFrame ^= 1; salAuxFrame = (salAuxFrame + 1) % 3; - for (i = 0; i < salNumVoices; ++i) { - for (j = 0; j < 5; ++j) { - dspVoice[i].changed[j] = 0; + for (v = 0; v < salNumVoices; ++v) { + for (i = 0; i < 5; ++i) { + dspVoice[v].changed[i] = 0; } } + // sndProfStartPMC(&prof.sequencer); + // sndProfPausePMC(&prof.sequencer); + // sndProfStartPMC(&prof.synthesizer); + // sndProfPausePMC(&prof.synthesizer); hwIRQLeaveCritical(); - - for (i = 0; i < 5; ++i) { + for (r = 0; r < 5; ++r) { hwIRQEnterCritical(); - hwSetTimeOffset(i); + hwSetTimeOffset(r); + // sndProfStartPMC(&prof.sequencer); seqHandle(256); + // sndProfPausePMC(&prof.sequencer); + // sndProfStartPMC(&prof.synthesizer); synthHandle(256); + // sndProfPausePMC(&prof.synthesizer); hwIRQLeaveCritical(); } + // sndProfStopPMC(&prof.sequencer); + // sndProfStopPMC(&prof.synthesizer); hwIRQEnterCritical(); hwSetTimeOffset(0); + // sndProfStartPMC(&prof.emitters); s3dHandle(); + // sndProfStopPMC(&prof.emitters); hwIRQLeaveCritical(); hwIRQEnterCritical(); + // sndProfStartPMC(&prof.streaming); streamHandle(); + // sndProfStopPMC(&prof.streaming); hwIRQLeaveCritical(); hwIRQEnterCritical(); vsSampleUpdates(); hwIRQLeaveCritical(); + // sndProfUpdateMisc(&prof); + + // if (sndProfUserCallback) { + // sndProfUserCallback(&prof); + // } } s32 hwInit(u32* frq, u16 numVoices, u16 numStudios, u32 flags) { @@ -278,11 +303,9 @@ void hwSetPolyPhaseFilter(unsigned long v, unsigned char salCoefSel) { dsp_vptr->changed[0] |= 0x80; } -inline void SetupITD(DSPvoice* dsp_vptr, u8 pan) { - u16 panA = itdOffTab[pan]; - u16 panB = itdOffTab[pan]; - dsp_vptr->itdShiftL = panA; - dsp_vptr->itdShiftR = 32 - panB; +void SetupITD(DSPvoice* dsp_vptr, u8 pan) { + dsp_vptr->itdShiftL = itdOffTab[pan]; + dsp_vptr->itdShiftR = 32 - itdOffTab[pan]; dsp_vptr->changed[0] |= 0x200; } @@ -296,8 +319,7 @@ void hwSetITDMode(u32 v, u8 mode) { dspVoice[v].flags &= ~0x80000000; } - -#define hwGetITDMode(dsp_vptr) (dsp_vptr->flags & 0x80000000) +#define hwGetITDMode(dsp_vptr) (dsp_vptr->flags & 0x80000000) void hwSetVolume(unsigned long v, unsigned char table, float vol, unsigned long pan, unsigned long span, float auxa, float auxb) { @@ -487,6 +509,9 @@ asm void hwFlushStream(void* base, unsigned long offset, unsigned long bytes, #pragma pop /* clang-format on */ #endif + +void hwPrepareStreamBuffer() { +} u32 hwInitStream(u32 len) { return aramAllocateStreamBuffer(len); } void hwExitStream(u8 id) { aramFreeStreamBuffer(id); } @@ -532,7 +557,11 @@ void hwSetSaveSampleCallback(ARAMUploadCallback callback, unsigned long chunckSi } void hwRemoveSample(void* header, void* data) { - aramRemoveData(data, convert_length(((u32*)header)[1] & 0xFFFFFF, ((u32*)header)[1] >> 0x18)); + u32 len; // r31 + u8 type; // r30 + type = ((u32*)header)[1] >> 0x18; + len = convert_length(((u32*)header)[1] & 0xFFFFFF, type); + aramRemoveData(data, len); } void hwSyncSampleMem() { aramSyncTransferQueue(); } @@ -541,6 +570,13 @@ void hwFrameDone() {} void sndSetHooks(SND_HOOKS* hooks) { salHooks = *hooks; } +void hwEnableHRTF() { + if (dspHRTFOn != FALSE) { + return; + } + dspHRTFOn = TRUE; + salInitHRTFBuffer(); +} void hwDisableHRTF() { dspHRTFOn = FALSE; } u32 hwGetVirtualSampleID(u32 v) { diff --git a/src/musyx/runtime/profile.c b/src/musyx/runtime/profile.c new file mode 100644 index 00000000..53000f0e --- /dev/null +++ b/src/musyx/runtime/profile.c @@ -0,0 +1,94 @@ +#include "dolphin/PPCArch.h" +#include "musyx/musyx_priv.h" + +SND_PROF_USERCALLBACK sndProfUserCallback = NULL; + +void sndProfSetCallback(SND_PROF_USERCALLBACK callback) { sndProfUserCallback = callback; } + +void sndProfUpdateMisc(SND_PROFILE_INFO* info) { + info->numMusicVoices = voiceMusicRunning; + info->numSFXVoices = voiceFxRunning; +} + +void sndProfResetPMC(SND_PROFILE_DATA* info) { + PPCMtpmc1(0); + PPCMtpmc2(0); + PPCMtpmc3(0); + PPCMtpmc4(0); + info->sumLoadStores = info->loadStores = 0; + info->sumMissCycles = info->missCycles = 0; + info->sumCycles = info->cycles = 0; + info->sumInstructions = info->instructions = 0; + info->peekLoadStores = 0; + info->peekMissCycles = 0; + info->peekCycles = 0; + info->peekInstructions = 0; + info->cnt = 0; + info->paused = 1; +} +void sndProfStartPMC(SND_PROFILE_DATA* info) { + PPCMtmmcr0(0); + PPCMtmmcr1(0); + info->paused = 0; + info->_loadStores = PPCMfpmc2(); + info->_missCycles = PPCMfpmc3(); + info->_cycles = PPCMfpmc4(); + info->_instructions = PPCMfpmc1(); + PPCMtmmcr1(0x78400000); + PPCMtmmcr0(0xc08b); +} + +void sndProfPausePMC(SND_PROFILE_DATA* info) { + PPCMtmmcr0(0); + PPCMtmmcr1(0); + info->loadStores += PPCMfpmc2() - info->_loadStores; + info->missCycles += PPCMfpmc3() - info->_missCycles; + info->cycles += PPCMfpmc4() - info->_cycles; + info->instructions += PPCMfpmc1() - info->_instructions; + info->paused = 1; + PPCMtmmcr1(0x78400000); + PPCMtmmcr0(0xc08b); +} +void sndProfStopPMC(SND_PROFILE_DATA* info) { + PPCMtmmcr0(0); + PPCMtmmcr1(0); + if (info->paused == 0) { + info->loadStores = info->loadStores + (PPCMfpmc2() - info->_loadStores); + info->missCycles = info->missCycles + (PPCMfpmc3() - info->_missCycles); + info->cycles = info->cycles + (PPCMfpmc4() - info->_cycles); + info->instructions = info->instructions + (PPCMfpmc1() - info->_instructions); + info->paused = 1; + } + info->cnt = info->cnt + 1; + info->sumLoadStores += info->loadStores; + info->sumMissCycles += info->missCycles; + + info->sumCycles += info->cycles; + info->sumInstructions += info->instructions; + info->avgLoadStores = info->sumLoadStores / info->cnt; + info->avgMissCycles = info->sumMissCycles / info->cnt; + info->avgCycles = info->sumCycles / info->cnt; + info->avgInstructions = info->sumInstructions / info->cnt; + info->lastLoadStores = info->loadStores; + info->lastMissCycles = info->missCycles; + info->lastCycles = info->cycles; + info->lastInstructions = info->instructions; + if (info->loadStores > info->peekLoadStores) { + info->peekLoadStores = info->loadStores; + } + if (info->missCycles > info->peekMissCycles) { + info->peekMissCycles = info->missCycles; + } + if (info->cycles > info->peekCycles) { + info->peekCycles = info->cycles; + } + if (info->instructions > info->peekInstructions) { + info->peekInstructions = info->instructions; + } + info->loadStores = 0; + info->missCycles = 0; + info->cycles = 0; + info->instructions = 0; + PPCMtmmcr1(0x78400000); + PPCMtmmcr0(0xc08b); +} diff --git a/src/musyx/runtime/s_data.c b/src/musyx/runtime/s_data.c new file mode 100644 index 00000000..5b3726d0 --- /dev/null +++ b/src/musyx/runtime/s_data.c @@ -0,0 +1,326 @@ +#include "musyx/assert.h" +#include "musyx/musyx_priv.h" + +static GSTACK gs[128]; +static s16 sp; + +void dataInitStack() { sp = 0; } + +static MEM_DATA* GetPoolAddr(u16 id, MEM_DATA* m) { + while (m->nextOff != 0xFFFFFFFF) { + if (m->id == id) { + return m; + } + + m = (MEM_DATA*)((u8*)m + m->nextOff); + } + return NULL; +} + +static MEM_DATA* GetMacroAddr(u16 id, POOL_DATA* pool) { + return pool == NULL ? NULL : GetPoolAddr(id, (MEM_DATA*)((u8*)pool + pool->macroOff)); +} + +static MEM_DATA* GetCurveAddr(u16 id, POOL_DATA* pool) { + return pool == NULL ? NULL : GetPoolAddr(id, (MEM_DATA*)((u8*)pool + pool->curveOff)); +} +static MEM_DATA* GetKeymapAddr(u16 id, POOL_DATA* pool) { + return pool == NULL ? NULL : GetPoolAddr(id, (MEM_DATA*)((u8*)pool + pool->keymapOff)); +} +static MEM_DATA* GetLayerAddr(u16 id, POOL_DATA* pool) { + return pool == NULL ? NULL : GetPoolAddr(id, (MEM_DATA*)((u8*)pool + pool->layerOff)); +} + +static void InsertData(u16 id, void* data, u8 dataType, u32 remove) { + MEM_DATA* m; // r30 + + switch (dataType) { + case 0: + if (!remove) { + if ((m = GetMacroAddr(id, data)) != NULL) { + dataInsertMacro(id, &m->data.cmd); + + } else { + dataInsertMacro(id, NULL); + } + } else { + dataRemoveMacro(id); + } + break; + case 2: { + id |= 0x4000; + if (!remove) { + if ((m = GetKeymapAddr(id, data)) != NULL) { + dataInsertKeymap(id, &m->data.map); + } else { + dataInsertKeymap(id, NULL); + } + } else { + dataRemoveKeymap(id); + } + } break; + case 3: { + id |= 0x8000; + if (!remove) { + if ((m = GetLayerAddr(id, data)) != NULL) { + dataInsertLayer(id, &m->data.layer.entry, m->data.layer.num); + } else { + dataInsertLayer(id, NULL, 0); + } + } else { + dataRemoveLayer(id); + } + } break; + case 4: + if (!remove) { + if ((m = GetCurveAddr(id, data)) != NULL) { + dataInsertCurve(id, &m->data.tab); + } else { + dataInsertCurve(id, NULL); + } + } else { + dataRemoveCurve(id); + } + break; + case 1: + if (!remove) { + dataAddSampleReference(id); + } else { + dataRemoveSampleReference(id); + } + break; + } +} + +static void ScanIDList(u16* ref, void* data, u8 dataType, u32 remove) { + u16 id; // r30 + + while (*ref != 0xFFFF) { + if ((*ref & 0x8000)) { + id = *ref & 0x3fff; + while (id <= ref[1]) { + InsertData(id, data, dataType, remove); + ++id; + } + ref += 2; + + } else { + InsertData(*ref++, data, dataType, remove); + } + } +} + +static void ScanIDListReverse(u16* refBase, void* data, u8 dataType, u32 remove) { + s16 id; + u16* ref; + + if (*refBase != 0xffff) { + ref = refBase; + while (*ref != 0xffff) { + ref++; + } + ref--; + + while (ref >= refBase) { + if (ref != refBase) { + if ((ref[-1] & 0x8000) != 0) { + id = *ref; + while (id >= (s16)(ref[-1] & 0x3fff)) { + InsertData(id, data, dataType, remove); + id--; + } + ref -= 2; + } else { + InsertData(*ref, data, dataType, remove); + ref--; + } + } else { + InsertData(*ref, data, dataType, remove); + ref--; + } + } + } +} + +static void InsertMacros(unsigned short* ref, void* pool) { ScanIDList(ref, pool, 0, 0); } + +static void InsertCurves(unsigned short* ref, void* pool) { ScanIDList(ref, pool, 4, 0); } + +static void InsertKeymaps(unsigned short* ref, void* pool) { ScanIDList(ref, pool, 2, 0); } + +static void InsertLayers(unsigned short* ref, void* pool) { ScanIDList(ref, pool, 3, 0); } + +static void RemoveMacros(unsigned short* ref) { ScanIDList(ref, NULL, 0, 1); } + +static void RemoveCurves(unsigned short* ref) { ScanIDList(ref, NULL, 4, 1); } + +static void RemoveKeymaps(unsigned short* ref) { ScanIDList(ref, NULL, 2, 1); } + +static void RemoveLayers(unsigned short* ref) { ScanIDList(ref, NULL, 3, 1); } + +static void InsertSamples(u16* ref, void* samples, void* sdir) { + samples = hwTransAddr(samples); + if (dataInsertSDir((SDIR_DATA*)sdir, samples)) { + ScanIDList(ref, sdir, 1, 0); + } +} + +static void RemoveSamples(unsigned short* ref, void* sdir) { + ScanIDListReverse(ref, NULL, 1, 1); + dataRemoveSDir(sdir); +} + +static void InsertFXTab(unsigned short gid, FX_DATA* fd) { dataInsertFX(gid, fd->fx, fd->num); } + +static void RemoveFXTab(unsigned short gid) { dataRemoveFX(gid); } + +void sndSetSampleDataUploadCallback(void* (*callback)(unsigned long, unsigned long), + unsigned long chunckSize) { + hwSetSaveSampleCallback(callback, chunckSize); +} + +u32 sndPushGroup(void* prj_data, u16 gid, void* samples, void* sdir, void* pool) { + GROUP_DATA* g; // r31 +#line 0x18d + ASSERT_MSG(prj_data != NULL, "Project data pointer is NULL"); + ASSERT_MSG(sdir != NULL, "Sample directory pointer is NULL"); + + if (sndActive && sp < 128) { + g = prj_data; + + while (g->nextOff != 0xFFFFFFFF) { + if (g->id == gid) { + gs[sp].gAddr = g; + gs[sp].prjAddr = prj_data; + gs[sp].sdirAddr = sdir; + InsertSamples((u16*)((u8*)prj_data + g->sampleOff), samples, sdir); + InsertMacros((u16*)((u8*)prj_data + g->macroOff), pool); + InsertCurves((u16*)((u8*)prj_data + g->curveOff), pool); + InsertKeymaps((u16*)((u8*)prj_data + g->keymapOff), pool); + InsertLayers((u16*)((u8*)prj_data + g->layerOff), pool); + if (g->type == 1) { + InsertFXTab(gid, (FX_DATA*)((u8*)prj_data + g->data.song.normpageOff)); + } + hwSyncSampleMem(); + ++sp; + return 1; + } + + g = (GROUP_DATA*)((u8*)prj_data + g->nextOff); + } + } + + MUSY_DEBUG("Group ID=%d could not be pushed.\n", gid); + return 0; +} + +/* + + + + + + + + + + +*/ +unsigned long sndPopGroup() { + struct GROUP_DATA* g; + struct SDIR_DATA* sdir; + void* prj; + struct FX_DATA* fd; + + ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized."); + ASSERT_MSG(sp != 0, "Soundstack is empty."); + g = gs[--sp].gAddr; + prj = gs[sp].prjAddr; + sdir = gs[sp].sdirAddr; + hwDisableIrq(); + + if (g->type == 1) { + fd = (FX_DATA*)((u8*)prj + g->data.song.normpageOff); + s3dKillEmitterByFXID(fd->fx, fd->num); + } else { + seqKillInstancesByGroupID(g->id); + } + + synthKillVoicesByMacroReferences((u16*)((u8*)prj + g->macroOff)); + hwEnableIrq(); + RemoveSamples((u16*)((u8*)prj + g->sampleOff), sdir); + RemoveMacros((u16*)((u8*)prj + g->macroOff)); + RemoveCurves((u16*)((u8*)prj + g->curveOff)); + RemoveKeymaps((u16*)((u8*)prj + g->keymapOff)); + RemoveLayers((u16*)((u8*)prj + g->layerOff)); + if (g->type == 1) { + RemoveFXTab(g->id); + } + return 1; +} + +/* + + + + + + + + + + + +*/ + +u32 seqPlaySong(u16 sgid, u16 sid, void* arrfile, SND_PLAYPARA* para, u8 irq_call, u8 studio) { + int i; + GROUP_DATA* g; + PAGE* norm; + PAGE* drum; + MIDISETUP* midiSetup; + u32 seqId; + void* prj; + ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized."); + + for (i = 0; i < sp; ++i) { + if (sgid != gs[i].gAddr->id) { + continue; + } + + if (gs[i].gAddr->type == 0) { + g = gs[i].gAddr; + prj = gs[i].prjAddr; + norm = (PAGE*)((u32)prj + g->data.song.normpageOff); + drum = (PAGE*)((u32)prj + g->data.song.drumpageOff); + midiSetup = (MIDISETUP*)((u32)prj + g->data.song.midiSetupOff); + while (midiSetup->songId != 0xFFFF) { + if (midiSetup->songId == sid) { + if (irq_call != 0) { + seqId = seqStartPlay(norm, drum, midiSetup, arrfile, para, studio, sgid); + } else { + hwDisableIrq(); + seqId = seqStartPlay(norm, drum, midiSetup, arrfile, para, studio, sgid); + hwEnableIrq(); + } + return seqId; + } + + ++midiSetup; + } + + MUSY_DEBUG("Song ID=%d is not in group ID=%d.", sid, sgid); + return 0xffffffff; + } else { + MUSY_DEBUG("Group ID=%d is no songgroup.", sgid); + return 0xffffffff; + } + } + + MUSY_DEBUG("Group ID=%d is not on soundstack.", sgid); + return 0xffffffff; +} + +u32 sndSeqPlayEx(u16 sgid, u16 sid, void* arrfile, SND_PLAYPARA* para, u8 studio) { + return seqPlaySong(sgid, sid, arrfile, para, 0, studio); +}