#ifndef _MUSYX_MUSYX_PRIV #define _MUSYX_MUSYX_PRIV #include "musyx/musyx.h" #include "musyx/assert.h" #include "musyx/hardware.h" #ifdef __cplusplus extern "C" { #endif #define CLAMP(value, min, max) ((value) > (max) ? (max) : (value) < (min) ? (min) : (value)) // TODO matching hack #define CLAMP_INV(value, min, max) ((value) < (min) ? (min) : (value) > (max) ? (max) : (value)) typedef struct SYNTH_VOICELIST { // total size: 0x4 u8 prev; // offset 0x0, size 0x1 u8 next; // offset 0x1, size 0x1 u16 user; // offset 0x2, size 0x2 } SYNTH_VOICELIST; extern SYNTH_VOICELIST voicePrioSortVoices[64]; extern u8 voicePrioSortVoicesRoot[256]; extern SYNTH_VOICELIST voicePrioSortVoices[64]; typedef struct SYNTH_ROOTLIST { // total size: 0x4 u16 next; // offset 0x0, size 0x2 u16 prev; // offset 0x2, size 0x2 } SYNTH_ROOTLIST; extern SYNTH_ROOTLIST voicePrioSortRootList[256]; typedef struct synthInfo { u32 mixFrq; u32 numSamples; SND_PLAYBACKINFO pbInfo; u8 voiceNum; u8 maxMusic; u8 maxSFX; u8 studioNum; } SynthInfo; typedef struct ADSR_VARS { u8 mode; u8 state; u32 cnt; s32 currentVolume; s32 currentIndex; s32 currentDelta; union data { struct _dls { u32 aTime; u32 dTime; u16 sLevel; u32 rTime; u16 cutOff; u8 aMode; } dls; struct _linear { u32 aTime; u32 dTime; u16 sLevel; u32 rTime; } linear; } data; } ADSR_VARS; typedef struct _PBMIX { // total size: 0x24 u16 vL; // offset 0x0, size 0x2 u16 vDeltaL; // offset 0x2, size 0x2 u16 vR; // offset 0x4, size 0x2 u16 vDeltaR; // offset 0x6, size 0x2 u16 vAuxAL; // offset 0x8, size 0x2 u16 vDeltaAuxAL; // offset 0xA, size 0x2 u16 vAuxAR; // offset 0xC, size 0x2 u16 vDeltaAuxAR; // offset 0xE, size 0x2 u16 vAuxBL; // offset 0x10, size 0x2 u16 vDeltaAuxBL; // offset 0x12, size 0x2 u16 vAuxBR; // offset 0x14, size 0x2 u16 vDeltaAuxBR; // offset 0x16, size 0x2 u16 vAuxBS; // offset 0x18, size 0x2 u16 vDeltaAuxBS; // offset 0x1A, size 0x2 u16 vS; // offset 0x1C, size 0x2 u16 vDeltaS; // offset 0x1E, size 0x2 u16 vAuxAS; // offset 0x20, size 0x2 u16 vDeltaAuxAS; // offset 0x22, size 0x2 } _PBMIX; typedef struct _PBITD { // total size: 0xE u16 flag; // offset 0x0, size 0x2 u16 bufferHi; // offset 0x2, size 0x2 u16 bufferLo; // offset 0x4, size 0x2 u16 shiftL; // offset 0x6, size 0x2 u16 shiftR; // offset 0x8, size 0x2 u16 targetShiftL; // offset 0xA, size 0x2 u16 targetShiftR; // offset 0xC, size 0x2 } _PBITD; typedef struct _PBUPDATE { // total size: 0xE u16 updNum[5]; // offset 0x0, size 0xA u16 dataHi; // offset 0xA, size 0x2 u16 dataLo; // offset 0xC, size 0x2 } _PBUPDATE; typedef struct _PBDPOP { // total size: 0x12 u16 aL; // offset 0x0, size 0x2 u16 aAuxAL; // offset 0x2, size 0x2 u16 aAuxBL; // offset 0x4, size 0x2 u16 aR; // offset 0x6, size 0x2 u16 aAuxAR; // offset 0x8, size 0x2 u16 aAuxBR; // offset 0xA, size 0x2 u16 aS; // offset 0xC, size 0x2 u16 aAuxAS; // offset 0xE, size 0x2 u16 aAuxBS; // offset 0x10, size 0x2 } _PBDPOP; typedef struct _PBVE { // total size: 0x4 u16 currentVolume; // offset 0x0, size 0x2 u16 currentDelta; // offset 0x2, size 0x2 } _PBVE; typedef struct _PBFIR { // total size: 0x6 u16 numCoefs; // offset 0x0, size 0x2 u16 coefsHi; // offset 0x2, size 0x2 u16 coefsLo; // offset 0x4, size 0x2 } _PBFIR; typedef struct _PBADDR { // total size: 0x10 u16 loopFlag; // offset 0x0, size 0x2 u16 format; // offset 0x2, size 0x2 u16 loopAddressHi; // offset 0x4, size 0x2 u16 loopAddressLo; // offset 0x6, size 0x2 u16 endAddressHi; // offset 0x8, size 0x2 u16 endAddressLo; // offset 0xA, size 0x2 u16 currentAddressHi; // offset 0xC, size 0x2 u16 currentAddressLo; // offset 0xE, size 0x2 } _PBADDR; typedef struct _PBADPCM { // total size: 0x28 u16 a[8][2]; // offset 0x0, size 0x20 u16 gain; // offset 0x20, size 0x2 u16 pred_scale; // offset 0x22, size 0x2 u16 yn1; // offset 0x24, size 0x2 u16 yn2; // offset 0x26, size 0x2 } _PBADPCM; typedef struct _PBSRC { // total size: 0xE u16 ratioHi; // offset 0x0, size 0x2 u16 ratioLo; // offset 0x2, size 0x2 u16 currentAddressFrac; // offset 0x4, size 0x2 u16 last_samples[4]; // offset 0x6, size 0x8 } _PBSRC; typedef struct _PBADPCMLOOP { // total size: 0x6 u16 loop_pred_scale; // offset 0x0, size 0x2 u16 loop_yn1; // offset 0x2, size 0x2 u16 loop_yn2; // offset 0x4, size 0x2 } _PBADPCMLOOP; typedef struct _PB { // total size: 0xBC u16 nextHi; // offset 0x0, size 0x2 u16 nextLo; // offset 0x2, size 0x2 u16 currHi; // offset 0x4, size 0x2 u16 currLo; // offset 0x6, size 0x2 u16 srcSelect; // offset 0x8, size 0x2 u16 coefSelect; // offset 0xA, size 0x2 u16 mixerCtrl; // offset 0xC, size 0x2 u16 state; // offset 0xE, size 0x2 u16 loopType; // offset 0x10, size 0x2 _PBMIX mix; // offset 0x12, size 0x24 _PBITD itd; // offset 0x36, size 0xE _PBUPDATE update; // offset 0x44, size 0xE _PBDPOP dpop; // offset 0x52, size 0x12 _PBVE ve; // offset 0x64, size 0x4 _PBFIR fir; // offset 0x68, size 0x6 _PBADDR addr; // offset 0x6E, size 0x10 _PBADPCM adpcm; // offset 0x7E, size 0x28 _PBSRC src; // offset 0xA6, size 0xE _PBADPCMLOOP adpcmLoop; // offset 0xB4, size 0x6 u16 streamLoopCnt; // offset 0xBA, size 0x2 } _PB; typedef struct SAMPLE_INFO { // total size: 0x20 u32 info; // offset 0x0, size 0x4 void* addr; // offset 0x4, size 0x4 void* extraData; // offset 0x8, size 0x4 u32 offset; // offset 0xC, size 0x4 u32 length; // offset 0x10, size 0x4 u32 loop; // offset 0x14, size 0x4 u32 loopLength; // offset 0x18, size 0x4 u8 compType; // offset 0x1C, size 0x1 } SAMPLE_INFO; typedef struct GROUP_DATA { // total size: 0x28 u32 nextOff; // offset 0x0, size 0x4 u16 id; // offset 0x4, size 0x2 u16 type; // offset 0x6, size 0x2 u32 macroOff; // offset 0x8, size 0x4 u32 sampleOff; // offset 0xC, size 0x4 u32 curveOff; // offset 0x10, size 0x4 u32 keymapOff; // offset 0x14, size 0x4 u32 layerOff; // offset 0x18, size 0x4 union { struct fx { // total size: 0x4 u32 tableOff; // offset 0x0, size 0x4 } fx; struct song { // total size: 0xC u32 normpageOff; // offset 0x0, size 0x4 u32 drumpageOff; // offset 0x4, size 0x4 u32 midiSetupOff; // offset 0x8, size 0x4 } song; } data; // offset 0x1C, size 0xC } GROUP_DATA; typedef struct SAMPLE_HEADER { // total size: 0x10 u32 info; // offset 0x0, size 0x4 u32 length; // offset 0x4, size 0x4 u32 loopOffset; // offset 0x8, size 0x4 u32 loopLength; // offset 0xC, size 0x4 } SAMPLE_HEADER; typedef struct SDIR_DATA { // total size: 0x20 u16 id; // offset 0x0, size 0x2 u16 ref_cnt; // offset 0x2, size 0x2 u32 offset; // offset 0x4, size 0x4 void* addr; // offset 0x8, size 0x4 SAMPLE_HEADER header; // offset 0xC, size 0x10 u32 extraData; // offset 0x1C, size 0x4 } SDIR_DATA; typedef struct SDIR_TAB { // total size: 0xC SDIR_DATA* data; // offset 0x0, size 0x4 void* base; // offset 0x4, size 0x4 u16 numSmp; // offset 0x8, size 0x2 u16 res; // offset 0xA, size 0x2 } SDIR_TAB; typedef struct DATA_TAB { // total size: 0x8 void* data; // offset 0x0, size 0x4 u16 id; // offset 0x4, size 0x2 u16 refCount; // offset 0x6, size 0x2 } DATA_TAB; typedef struct LAYER_TAB { // total size: 0xC void* data; // offset 0x0, size 0x4 u16 id; // offset 0x4, size 0x2 u16 num; // offset 0x6, size 0x2 u16 refCount; // offset 0x8, size 0x2 u16 reserved; // offset 0xA, size 0x2 } LAYER_TAB; typedef struct MAC_MAINTAB { // total size: 0x4 u16 num; // offset 0x0, size 0x2 u16 subTabIndex; // offset 0x2, size 0x2 } MAC_MAINTAB; typedef struct MAC_SUBTAB { // total size: 0x8 void* data; // offset 0x0, size 0x4 u16 id; // offset 0x4, size 0x2 u16 refCount; // offset 0x6, size 0x2 } MAC_SUBTAB; typedef struct GSTACK { // total size: 0xC GROUP_DATA* gAddr; // offset 0x0, size 0x4 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 u32 loopBufferLength; // offset 0x4, size 0x4 u8 inLoopBuffer; // offset 0x8, size 0x1 } VSampleInfo; typedef struct DSPvoice { _PB* pb; void* patchData; void* itdBuffer; struct DSPvoice* next; struct DSPvoice* prev; struct DSPvoice* nextAlien; u32 mesgCallBackUserValue; u32 prio; u32 currentAddr; u32 changed[5]; u32 pitch[5]; u16 volL; u16 volR; u16 volS; u16 volLa; u16 volRa; u16 volSa; u16 volLb; u16 volRb; u16 volSb; u16 lastVolL; u16 lastVolR; u16 lastVolS; u16 lastVolLa; u16 lastVolRa; u16 lastVolSa; u16 lastVolLb; u16 lastVolRb; u16 lastVolSb; u16 smp_id; SAMPLE_INFO smp_info; VSampleInfo vSampleInfo; u8 streamLoopPS; ADSR_VARS adsr; u16 srcTypeSelect; u16 srcCoefSelect; u16 itdShiftL; u16 itdShiftR; u8 singleOffset; struct { u32 posHi; u32 posLo; u32 pitch; } playInfo; struct { u8 pitch; u8 vol; u8 volA; u8 volB; } lastUpdate; u32 virtualSampleID; u8 state; u8 postBreak; u8 startupBreak; u8 studio; u32 flags; } DSPvoice; typedef struct VID_LIST { struct VID_LIST* next; struct VID_LIST* prev; u32 vid; u32 root; } VID_LIST; typedef enum { MAC_STATE_RUNNABLE = 0, MAC_STATE_YIELDED, MAC_STATE_STOPPED, } MAC_STATE; typedef struct MSTEP { u32 para[2]; } MSTEP; typedef struct CALLSTACK { MSTEP* addr; MSTEP* curAddr; } CALLSTACK; typedef struct SYNTH_QUEUE { // total size: 0xC struct SYNTH_QUEUE* next; // offset 0x0, size 0x4 struct SYNTH_QUEUE* prev; // offset 0x4, size 0x4 u8 voice; // offset 0x8, size 0x1 u8 jobTabIndex; // offset 0x9, size 0x1 } SYNTH_QUEUE; typedef enum { SYNTH_JOBTYPE_LOW = 0, SYNTH_JOBTYPE_ZERO = 1, SYNTH_JOBTYPE_EVENT = 2, } SYNTH_JOBTYPE; typedef struct { // total size: 0xC SYNTH_QUEUE* lowPrecision; // offset 0x0, size 0x4 SYNTH_QUEUE* event; // offset 0x4, size 0x4 SYNTH_QUEUE* zeroOffset; // offset 0x8, size 0x4 } SYNTH_JOBTAB; typedef struct SYNTH_LFO { u32 time; u32 period; s16 value; s16 lastValue; } SYNTH_LFO; typedef struct SYNTHMasterFader { // total size: 0x30 f32 volume; // offset 0x0, size 0x4 f32 target; // offset 0x4, size 0x4 f32 start; // offset 0x8, size 0x4 f32 time; // offset 0xC, size 0x4 f32 deltaTime; // offset 0x10, size 0x4 f32 pauseVol; // offset 0x14, size 0x4 f32 pauseTarget; // offset 0x18, size 0x4 f32 pauseStart; // offset 0x1C, size 0x4 f32 pauseTime; // offset 0x20, size 0x4 f32 pauseDeltaTime; // offset 0x24, size 0x4 u32 seqId; // offset 0x28, size 0x4 u8 seqMode; // offset 0x2C, size 0x1 u8 type; // offset 0x2D, size 0x1 } SYNTHMasterFader; typedef struct CTRL_SOURCE { u8 midiCtrl; u8 combine; s32 scale; } CTRL_SOURCE; typedef struct CTRL_DEST { CTRL_SOURCE source[4]; u16 oldValue; u8 numSource; } CTRL_DEST; typedef struct SND_VIRTUALSAMPLE_INFO { // total size: 0x14 u16 smpID; // offset 0x0, size 0x2 u16 instID; // offset 0x2, size 0x2 union vsData { struct vsUpdate { // total size: 0x10 u32 off1; // offset 0x0, size 0x4 u32 len1; // offset 0x4, size 0x4 u32 off2; // offset 0x8, size 0x4 u32 len2; // offset 0xC, size 0x4 } update; } data; } SND_VIRTUALSAMPLE_INFO; typedef struct VS_BUFFER { // total size: 0x24 u8 state; // offset 0x0, size 0x1 u8 hwId; // offset 0x1, size 0x1 u8 smpType; // offset 0x2, size 0x1 u8 voice; // offset 0x3, size 0x1 u32 last; // offset 0x4, size 0x4 u32 finalGoodSamples; // offset 0x8, size 0x4 u32 finalLast; // offset 0xC, size 0x4 SND_VIRTUALSAMPLE_INFO info; // offset 0x10, size 0x14 } VS_BUFFER; typedef struct _VS { // total size: 0x950 u8 numBuffers; // offset 0x0, size 0x1 u32 bufferLength; // offset 0x4, size 0x4 VS_BUFFER streamBuffer[64]; // offset 0x8, size 0x900 u8 voices[64]; // offset 0x908, size 0x40 u16 nextInstID; // offset 0x948, size 0x2 u32 (*callback)(u8, SND_VIRTUALSAMPLE_INFO*); // offset 0x94C, size 0x4 } VS; extern VS vs; #pragma push #pragma pack(4) typedef struct SYNTH_VOICE { // total size: 0x404 SYNTH_QUEUE lowPrecisionJob; // offset 0x0, size 0xC SYNTH_QUEUE zeroOffsetJob; // offset 0xC, size 0xC SYNTH_QUEUE eventJob; // offset 0x18, size 0xC u64 lastLowCallTime; // offset 0x24, size 0x8 u64 lastZeroCallTime; // offset 0x2C, size 0x8 MSTEP* addr; // offset 0x34, size 0x4 MSTEP* curAddr; // offset 0x38, size 0x4 struct SYNTH_VOICE* nextMacActive; // offset 0x3C, size 0x4 struct SYNTH_VOICE* prevMacActive; // offset 0x40, size 0x4 struct SYNTH_VOICE* nextTimeQueueMacro; // offset 0x44, size 0x4 struct SYNTH_VOICE* prevTimeQueueMacro; // offset 0x48, size 0x4 MAC_STATE macState; // offset 0x4C, size 0x4 MSTEP* trapEventAddr[3]; // offset 0x50, size 0xC MSTEP* trapEventCurAddr[3]; // offset 0x5C, size 0xC u8 trapEventAny; // offset 0x68, size 0x1 CALLSTACK callStack[4]; // offset 0x6C, size 0x20 u8 callStackEntryNum; // offset 0x8C, size 0x1 u8 callStackIndex; // offset 0x8D, size 0x1 u64 macStartTime; // offset 0x90, size 0x8 u64 wait; // offset 0x98, size 0x8 u64 waitTime; // offset 0xA0, size 0x8 u8 timeUsedByInput; // offset 0xA8, size 0x1 u16 loop; // offset 0xAA, size 0x2 s32 local_vars[16]; // offset 0xAC, size 0x40 u32 child; // offset 0xEC, size 0x4 u32 parent; // offset 0xF0, size 0x4 u32 id; // offset 0xF4, size 0x4 VID_LIST* vidList; // offset 0xF8, size 0x4 VID_LIST* vidMasterList; // offset 0xFC, size 0x4 #if MUSY_VERSION > MUSY_VERSION_CHECK(1, 5, 3) && MUSY_VERSION <= MUSY_VERSION_CHECK(2, 0, 0) u16 allocId; // offset 0x100, size 0x2 #else u32 allocId; #endif u16 macroId; // offset 0x102, size 0x2 u8 keyGroup; // offset 0x104, size 0x1 u32 lastVID; // offset 0x108, size 0x4 u8 prio; // offset 0x10C, size 0x1 u16 ageSpeed; // offset 0x10E, size 0x2 u32 age; // offset 0x110, size 0x4 u64 cFlags; // offset 0x114, size 0x8 u8 block; // offset 0x11C, size 0x1 u8 fxFlag; // offset 0x11D, size 0x1 u8 vGroup; // offset 0x11E, size 0x1 u8 studio; // offset 0x11F, size 0x1 u8 track; // offset 0x120, size 0x1 u8 midi; // offset 0x121, size 0x1 u8 midiSet; // offset 0x122, size 0x1 u8 section; // offset 0x123, size 0x1 #if MUSY_VERSION <= MUSY_VERSION_CHECK(1, 5, 0) void* sAddr; #endif u32 sInfo; // offset 0x124, size 0x4 u32 playFrq; // offset 0x128, size 0x4 #if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) u16 sampleId; #endif u16 curNote; // offset 0x12C, size 0x2 s8 curDetune; // offset 0x12E, size 0x1 u8 orgNote; // offset 0x12F, size 0x1 u8 lastNote; // offset 0x130, size 0x1 u8 portType; // offset 0x131, size 0x1 u16 portLastCtrlState; // offset 0x132, size 0x2 u32 portDuration; // offset 0x134, size 0x4 u32 portCurPitch; // offset 0x138, size 0x4 u32 portTime; // offset 0x13C, size 0x4 u8 vibKeyRange; // offset 0x140, size 0x1 u8 vibCentRange; // offset 0x141, size 0x1 u32 vibPeriod; // offset 0x144, size 0x4 u32 vibCurTime; // offset 0x148, size 0x4 s32 vibCurOffset; // offset 0x14C, size 0x4 s16 vibModAddScale; // offset 0x150, size 0x2 u32 volume; // offset 0x154, size 0x4 u32 orgVolume; // offset 0x158, size 0x4 float lastVolFaderScale; // offset 0x15C, size 0x4 u32 lastPan; // offset 0x160, size 0x4 u32 lastSPan; // offset 0x164, size 0x4 float treCurScale; // offset 0x168, size 0x4 u16 treScale; // offset 0x16C, size 0x2 u16 treModAddScale; // offset 0x16E, size 0x2 u32 panning[2]; // offset 0x170, size 0x8 s32 panDelta[2]; // offset 0x178, size 0x8 u32 panTarget[2]; // offset 0x180, size 0x8 u32 panTime[2]; // offset 0x188, size 0x8 u8 revVolScale; // offset 0x190, size 0x1 u8 revVolOffset; // offset 0x191, size 0x1 u8 volTable; // offset 0x192, size 0x1 u8 itdMode; // offset 0x193, size 0x1 s32 envDelta; // offset 0x194, size 0x4 u32 envTarget; // offset 0x198, size 0x4 u32 envCurrent; // offset 0x19C, size 0x4 u32 sweepOff[2]; // offset 0x1A0, size 0x8 s32 sweepAdd[2]; // offset 0x1A8, size 0x8 s32 sweepCnt[2]; // offset 0x1B0, size 0x8 u8 sweepNum[2]; // offset 0x1B8, size 0x2 SYNTH_LFO lfo[2]; // offset 0x1BC, size 0x18 u8 lfoUsedByInput[2]; // offset 0x1D4, size 0x2 u8 pbLowerKeyRange; // offset 0x1D6, size 0x1 u8 pbUpperKeyRange; // offset 0x1D7, size 0x1 u16 pbLast; // offset 0x1D8, size 0x2 #if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) u32 lpfLowerFrqBoundary; u32 lpfUpperFrqBoundary; #endif ADSR_VARS pitchADSR; // offset 0x1DC, size 0x28 s16 pitchADSRRange; // offset 0x204, size 0x2 u16 curPitch; // offset 0x206, size 0x2 struct setup { // total size: 0x9 u8 vol; // offset 0x0, size 0x1 u8 pan; // offset 0x1, size 0x1 u8 midi; // offset 0x2, size 0x1 u8 midiSet; // offset 0x3, size 0x1 u8 section; // offset 0x4, size 0x1 u8 track; // offset 0x5, size 0x1 u8 vGroup; // offset 0x6, size 0x1 u8 studio; // offset 0x7, size 0x1 u8 itdMode; // offset 0x8, size 0x1 } setup; // offset 0x208, size 0x9 u32 midiDirtyFlags; // offset 0x214, size 0x4 CTRL_DEST inpVolume; // offset 0x218, size 0x24 CTRL_DEST inpPanning; // offset 0x23C, size 0x24 CTRL_DEST inpSurroundPanning; // offset 0x260, size 0x24 CTRL_DEST inpPitchBend; // offset 0x284, size 0x24 CTRL_DEST inpDoppler; // offset 0x2A8, size 0x24 CTRL_DEST inpModulation; // offset 0x2CC, size 0x24 CTRL_DEST inpPedal; // offset 0x2F0, size 0x24 CTRL_DEST inpPortamento; // offset 0x314, size 0x24 CTRL_DEST inpPreAuxA; // offset 0x338, size 0x24 CTRL_DEST inpReverb; // offset 0x35C, size 0x24 CTRL_DEST inpPreAuxB; // offset 0x380, size 0x24 CTRL_DEST inpPostAuxB; // offset 0x3A4, size 0x24 CTRL_DEST inpTremolo; // offset 0x3C8, size 0x24 #if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) CTRL_DEST inpFilterSwitch; // offset 0x3F8, size 0x24 CTRL_DEST inpFilterParameter; // offset 0x41C, size 0x24 #endif u8 mesgNum; // offset 0x3EC, size 0x1 u8 mesgRead; // offset 0x3ED, size 0x1 u8 mesgWrite; // offset 0x3EE, size 0x1 s32 mesgQueue[4]; // offset 0x3F0, size 0x10 u16 curOutputVolume; // offset 0x400, size 0x2 } SYNTH_VOICE; typedef struct synthITDInfo { // total size: 0x2 u8 music; // offset 0x0, size 0x1 u8 sfx; // offset 0x1, size 0x1 } synthITDInfo; #pragma pop typedef struct LAYER { // total size: 0xC u16 id; // offset 0x0, size 0x2 u8 keyLow; // offset 0x2, size 0x1 u8 keyHigh; // offset 0x3, size 0x1 s8 transpose; // offset 0x4, size 0x1 u8 volume; // offset 0x5, size 0x1 s16 prioOffset; // offset 0x6, size 0x2 u8 panning; // offset 0x8, size 0x1 u8 reserved[3]; // offset 0x9, size 0x3 } LAYER; typedef struct KEYMAP { // total size: 0x8 u16 id; // offset 0x0, size 0x2 s8 transpose; // offset 0x2, size 0x1 u8 panning; // offset 0x3, size 0x1 s16 prioOffset; // offset 0x4, size 0x2 u8 reserved[2]; // offset 0x6, size 0x2 } KEYMAP; typedef struct MEM_DATA { // total size: 0x408 u32 nextOff; // offset 0x0, size 0x4 u16 id; // offset 0x4, size 0x2 u16 reserved; // offset 0x6, size 0x2 union { struct { // total size: 0x10 u32 num; // offset 0x0, size 0x4 LAYER entry[1]; // offset 0x4, size 0xC } layer; KEYMAP map[128]; u8 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 f32 volL; // offset 0x0, size 0x4 f32 volR; // offset 0x4, size 0x4 f32 volS; // offset 0x8, size 0x4 f32 volAuxAL; // offset 0xC, size 0x4 f32 volAuxAR; // offset 0x10, size 0x4 f32 volAuxAS; // offset 0x14, size 0x4 f32 volAuxBL; // offset 0x18, size 0x4 f32 volAuxBR; // offset 0x1C, size 0x4 f32 volAuxBS; // offset 0x20, size 0x4 } SAL_VOLINFO; typedef struct SAL_PANINFO { // total size: 0x30 u32 pan_i; // offset 0x0, size 0x4 u32 pan_im; // offset 0x4, size 0x4 u32 span_i; // offset 0x8, size 0x4 u32 span_im; // offset 0xC, size 0x4 u32 rpan_i; // offset 0x10, size 0x4 u32 rpan_im; // offset 0x14, size 0x4 f32 pan_f; // offset 0x18, size 0x4 f32 pan_fm; // offset 0x1C, size 0x4 f32 span_f; // offset 0x20, size 0x4 f32 span_fm; // offset 0x24, size 0x4 f32 rpan_f; // offset 0x28, size 0x4 f32 rpan_fm; // offset 0x2C, size 0x4 } SAL_PANINFO; typedef struct _SPB { // total size: 0x36 u16 dpopLHi; // offset 0x0, size 0x2 u16 dpopLLo; // offset 0x2, size 0x2 u16 dpopLDelta; // offset 0x4, size 0x2 u16 dpopRHi; // offset 0x6, size 0x2 u16 dpopRLo; // offset 0x8, size 0x2 u16 dpopRDelta; // offset 0xA, size 0x2 u16 dpopSHi; // offset 0xC, size 0x2 u16 dpopSLo; // offset 0xE, size 0x2 u16 dpopSDelta; // offset 0x10, size 0x2 u16 dpopALHi; // offset 0x12, size 0x2 u16 dpopALLo; // offset 0x14, size 0x2 u16 dpopALDelta; // offset 0x16, size 0x2 u16 dpopARHi; // offset 0x18, size 0x2 u16 dpopARLo; // offset 0x1A, size 0x2 u16 dpopARDelta; // offset 0x1C, size 0x2 u16 dpopASHi; // offset 0x1E, size 0x2 u16 dpopASLo; // offset 0x20, size 0x2 u16 dpopASDelta; // offset 0x22, size 0x2 u16 dpopBLHi; // offset 0x24, size 0x2 u16 dpopBLLo; // offset 0x26, size 0x2 u16 dpopBLDelta; // offset 0x28, size 0x2 u16 dpopBRHi; // offset 0x2A, size 0x2 u16 dpopBRLo; // offset 0x2C, size 0x2 u16 dpopBRDelta; // offset 0x2E, size 0x2 u16 dpopBSHi; // offset 0x30, size 0x2 u16 dpopBSLo; // offset 0x32, size 0x2 u16 dpopBSDelta; // offset 0x34, size 0x2 } _SPB; typedef struct DSPhostDPop { // total size: 0x24 s32 l; // offset 0x0, size 0x4 s32 r; // offset 0x4, size 0x4 s32 s; // offset 0x8, size 0x4 s32 lA; // offset 0xC, size 0x4 s32 rA; // offset 0x10, size 0x4 s32 sA; // offset 0x14, size 0x4 s32 lB; // offset 0x18, size 0x4 s32 rB; // offset 0x1C, size 0x4 s32 sB; // offset 0x20, size 0x4 } DSPhostDPop; typedef struct DSPinput { // total size: 0xC u8 studio; // offset 0x0, size 0x1 u16 vol; // offset 0x2, size 0x2 u16 volA; // offset 0x4, size 0x2 u16 volB; // offset 0x6, size 0x2 SND_STUDIO_INPUT* desc; // offset 0x8, size 0x4 } DSPinput; typedef struct DSPstudioinfo { // total size: 0xBC _SPB* spb; // offset 0x0, size 0x4 DSPhostDPop hostDPopSum; // offset 0x4, size 0x24 s32* main[2]; // offset 0x28, size 0x8 s32* auxA[3]; // offset 0x30, size 0xC s32* auxB[3]; // offset 0x3C, size 0xC DSPvoice* voiceRoot; // offset 0x48, size 0x4 DSPvoice* alienVoiceRoot; // offset 0x4C, size 0x4 u8 state; // offset 0x50, size 0x1 u8 isMaster; // offset 0x51, size 0x1 u8 numInputs; // offset 0x52, size 0x1 SND_STUDIO_TYPE type; // offset 0x54, size 0x4 DSPinput in[7]; // offset 0x58, size 0x54 SND_AUX_CALLBACK auxAHandler; // offset 0xAC, size 0x4 SND_AUX_CALLBACK auxBHandler; // offset 0xB0, size 0x4 void* auxAUser; // offset 0xB4, size 0x4 void* auxBUser; // offset 0xB8, size 0x4 } DSPstudioinfo; extern DSPstudioinfo dspStudio[8]; extern SYNTH_VOICE* synthVoice; extern DSPvoice* dspVoice; typedef s32 (*SND_COMPARE)(void*, void*); typedef struct CHANNEL_DEFAULTS { // total size: 0x1 u8 pbRange; // offset 0x0, size 0x1 } CHANNEL_DEFAULTS; typedef struct FX_TAB { // total size: 0xA u16 id; // offset 0x0, size 0x2 u16 macro; // offset 0x2, size 0x2 u8 maxVoices; // offset 0x4, size 0x1 u8 priority; // offset 0x5, size 0x1 u8 volume; // offset 0x6, size 0x1 u8 panning; // offset 0x7, size 0x1 u8 key; // offset 0x8, size 0x1 u8 vGroup; // offset 0x9, size 0x1 } FX_TAB; typedef struct FX_DATA { // total size: 0xE u16 num; // offset 0x0, size 0x2 u16 reserverd; // offset 0x2, size 0x2 FX_TAB fx[1]; // offset 0x4, size 0xA } FX_DATA; typedef struct FX_GROUP { // total size: 0x8 u16 gid; // offset 0x0, size 0x2 u16 fxNum; // offset 0x2, size 0x2 FX_TAB* fxTab; // offset 0x4, size 0x4 } FX_GROUP; typedef struct PAGE { // total size: 0x6 u16 macro; // offset 0x0, size 0x2 u8 prio; // offset 0x2, size 0x1 u8 maxVoices; // offset 0x3, size 0x1 u8 index; // offset 0x4, size 0x1 u8 reserved; // offset 0x5, size 0x1 } PAGE; typedef struct MIDI_CHANNEL_SETUP { // total size: 0x5 u8 program; // offset 0x0, size 0x1 u8 volume; // offset 0x1, size 0x1 u8 panning; // offset 0x2, size 0x1 u8 reverb; // offset 0x3, size 0x1 u8 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; typedef struct ADSR_INFO { // total size: 0x14 union ai_data { struct { // total size: 0x14 s32 atime; // offset 0x0, size 0x4 s32 dtime; // offset 0x4, size 0x4 u16 slevel; // offset 0x8, size 0x2 u16 rtime; // offset 0xA, size 0x2 s32 ascale; // offset 0xC, size 0x4 s32 dscale; // offset 0x10, size 0x4 } dls; struct { // total size: 0x8 u16 atime; // offset 0x0, size 0x2 u16 dtime; // offset 0x2, size 0x2 u16 slevel; // offset 0x4, size 0x2 u16 rtime; // offset 0x6, size 0x2 } linear; } data; // offset 0x0, size 0x14 } ADSR_INFO; void dataInit(u32, u32); /* extern */ #if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) void dataInitStack(unsigned long aramBase, unsigned long aramSize); #else void dataInitStack(); /* extern */ #endif 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); s32 dataGetSample(u16 sid, SAMPLE_INFO* newsmp); void* dataGetCurve(u16 cid); 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); void* dataGetLayer(u16 cid, u16* n); void* dataGetKeymap(u16 cid); s32 hwInit(u32* frq, u16 numVoices, u16 numStudios, u32 flags); /* extern */ void hwInitSamplePlayback(u32 v, u16 smpID, void* newsmp, u32 set_defadsr, u32 prio, u32 callbackUserValue, u32 setSRC, u8 itdMode); void hwSetVolume(u32 v, u8 table, f32 vol, u32 pan, u32 span, f32 auxa, f32 auxb); void hwSetPitch(u32 v, u16 speed); void hwEnableIrq(); void hwDisableIrq(); void* hwTransAddr(void* samples); void seqInit(); /* extern */ u32 seqStartPlay(PAGE* norm, PAGE* drum, MIDISETUP* midiSetup, u32* song, SND_PLAYPARA* para, u8 studio, u16 sgid); u32 seqGetPrivateId(u32 seqId); void streamInit(); /* extern */ void vsInit(); /* extern */ u32 vsSampleStartNotify(u8 voice); void vsSampleEndNotify(u32 pubID); void hwExit(); void dataExit(); void s3dInit(u32); /* extern */ void s3dKillEmitterByFXID(FX_TAB* fxTab, u32 num); void s3dExit(); void synthInit(u32 mixFrq, u32 numVoices); void synthSetBpm(u32 pbm, u8 set, u8 section); void synthFXCloneMidiSetup(SYNTH_VOICE* dest, SYNTH_VOICE* src); void synthSetMusicVolumeType(u8 vGroup, u8 type); extern s32 synthGlobalVariable[16]; extern u16 voicePrioSortRootListRoot; extern u8 voiceMusicRunning; extern u8 voiceFxRunning; extern u8 voiceListInsert; extern u8 voiceListRoot; void voiceSetPriority(SYNTH_VOICE* svoice, u8 prio); u32 voiceIsLastStarted(SYNTH_VOICE* svoice); void voiceSetLastStarted(SYNTH_VOICE* svoice); void voiceResetLastStarted(SYNTH_VOICE* svoice); void voiceInitLastStarted(); s32 voiceKillSound(u32 voiceid); void voiceKill(u32 vi); extern u64 synthRealTime; u32 synthGetTicksPerSecond(SYNTH_VOICE* svoice); void synthKillVoicesByMacroReferences(u16* ref); void synthExit(); u16 sndRand(void); s16 sndSin(u16 angle); 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); u32 sndStreamAllocLength(u32 num, u32 flags); void sndStreamFree(u32 stid); u32 sndStreamActivate(u32 stid); void sndStreamDeactivate(u32 stid); void hwActivateStudio(u8 studio, u32 isMaster, SND_STUDIO_TYPE type); void hwDeactivateStudio(u8); void hwSetPriority(u32 v, u32 prio); u32 hwIsActive(u32); u32 hwGlobalActivity(); void hwSetAUXProcessingCallbacks(u8 studio, SND_AUX_CALLBACK auxA, void* userA, SND_AUX_CALLBACK auxB, void* userB); u8 hwInitStream(u32 len); u8 hwGetTimeOffset(); u32 hwGetVirtualSampleID(u32 v); s16 varGet(SYNTH_VOICE* svoice, u32 ctrl, u8 index); u32 sndGetPitch(u8 key, u32 sInfo); s32 sndPitchUpOne(u16 note); extern SND_HOOKS salHooks; extern u8 sndActive; extern u8 synthIdleWaitActive; extern SynthInfo synthInfo; typedef s32 (*SND_MESSAGE_CALLBACK)(u32, u32); typedef void (*SYNTH_MESSAGE_CALLBACK)(u32, s32); typedef void (*SND_SOME_CALLBACK)(); extern SND_MESSAGE_CALLBACK salMessageCallback; extern SYNTH_MESSAGE_CALLBACK synthMessageCallback; /* Math */ void salApplyMatrix(const SND_FMATRIX* a, const SND_FVECTOR* b, SND_FVECTOR* out); f32 salNormalizeVector(SND_FVECTOR* vec); void salCrossProduct(SND_FVECTOR* out, const SND_FVECTOR* a, const SND_FVECTOR* b); #define SAL_CROSS_PRODUCT(out, a, b) \ do { \ out.x = (a.y * b.z) - (a.z * b.y); \ out.y = (a.z * b.x) - (a.x * b.z); \ out.z = (a.x * b.y) - (a.y * b.x); \ } while (0) void salInvertMatrix(SND_FMATRIX* out, const SND_FMATRIX* in); /* hardware */ u32 salInitAi(SND_SOME_CALLBACK, u32, u32*); u32 salInitDsp(u32); u32 salInitDspCtrl(u8 numVoices, u8 numStudios, u32 defaultStudioDPL2); u32 salStartAi(); void salInitHRTFBuffer(); void salActivateVoice(DSPvoice* dsp_vptr, u8 studio); void salDeactivateVoice(DSPvoice* dsp_vptr); void salActivateStudio(u8 studio, u32 isMaster, SND_STUDIO_TYPE type); void salDeactivateStudio(u8 studio); void salActivateVoice(DSPvoice* dsp_vptr, u8 studio); void salCalcVolume(u8 voltab_index, SAL_VOLINFO* vi, f32 vol, u32 pan, u32 span, f32 auxa, f32 auxb, u32 itd, u32 dpl2); void salReconnectVoice(DSPvoice* dsp_vptr, u8 studio); void* salMalloc(u32 len); void salFree(void* addr); #define SAL_MAX_STUDIONUM 8 extern u8 salMaxStudioNum; extern u8 salNumVoices; /* Stream */ typedef s32 (*SND_STREAM_UPDATE_CALLBACK)(void* buffer1, u32 len1, void* buffer2, u32 len2, u32 user); typedef struct SNDADPCMinfo { // total size: 0x28 u16 numCoef; // offset 0x0, size 0x2 u8 initialPS; // offset 0x2, size 0x1 u8 loopPS; // offset 0x3, size 0x1 s16 loopY0; // offset 0x4, size 0x2 s16 loopY1; // offset 0x6, size 0x2 s16 coefTab[8][2]; // offset 0x8, size 0x20 } SNDADPCMinfo; typedef struct STREAM_INFO { #if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4) u32 nextStreamHandle; #endif u32 stid; u32 flags; u8 state; u8 type; /* These were moved to near the start of the structure in later versions */ #if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4) u8 hwStreamHandle; u8 lastPSFromBuffer; #endif SND_STREAM_UPDATE_CALLBACK updateFunction; s16* buffer; u32 size; u32 bytes; u32 last; SNDADPCMinfo adpcmInfo; volatile SND_VOICEID voice; u32 user; u32 frq; u8 prio; u8 vol; u8 pan; u8 span; u8 auxa; u8 auxb; #if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4) u8 orgPan; u8 orgSPan; #endif u8 studio; /* These were moved to near the start of the structure in later versions */ #if MUSY_VERSION <= MUSY_VERSION_CHECK(1, 5, 3) u8 hwStreamHandle; u32 nextStreamHandle; #endif } STREAM_INFO; #if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4) void streamOutputModeChanged(); #endif u8 inpTranslateExCtrl(u8 ctrl); void inpSetGlobalMIDIDirtyFlag(u8 chan, u8 midiSet, s32 flag); void inpAddCtrl(CTRL_DEST* dest, u8 ctrl, s32 scale, u8 comb, u32 isVar); void inpSetMidiCtrl(u8 ctrl, u8 channel, u8 set, u8 value); void inpSetMidiCtrl14(u8 ctrl, u8 channel, u8 set, u16 value); void inpSetExCtrl(SYNTH_VOICE* svoice, u8 ctrl, s16 v); CHANNEL_DEFAULTS* inpGetChannelDefaults(u8 midi, u8 midiSet); #if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) unsigned short inpGetFilterSwitch(struct SYNTH_VOICE* svoice); unsigned short inpGetFilterParameter(struct SYNTH_VOICE* svoice); void inpSetLPFDefaultRange(u32 lowFrq, u32 highFrq); #endif extern CTRL_DEST inpAuxA[8][4]; extern CTRL_DEST inpAuxB[8][4]; void inpSetMidiLastNote(u8 midi, u8 midiSet, u8 key); u8 inpGetMidiLastNote(u8 midi, u8 midiSet); u16 inpGetExCtrl(SYNTH_VOICE* svoice, u8 ctrl); u16 inpGetMidiCtrl(u8 ctrl, u8 channel, u8 set); void inpSetMidiLastNote(u8 midi, u8 midiSet, u8 key); u16 inpGetModulation(SYNTH_VOICE* svoice); void inpResetMidiCtrl(u8 ch, u8 set, u32 coldReset); void inpResetChannelDefaults(u8 midi, u8 midiSet); u16 inpGetPitchBend(SYNTH_VOICE* svoice); u16 inpGetDoppler(SYNTH_VOICE* svoice); u16 inpGetTremolo(SYNTH_VOICE* svoice); u16 inpGetPanning(SYNTH_VOICE* svoice); u16 inpGetSurPanning(SYNTH_VOICE* svoice); u16 inpGetVolume(SYNTH_VOICE* svoice); u16 inpGetReverb(SYNTH_VOICE* svoice); u16 inpGetPreAuxA(SYNTH_VOICE* svoice); u16 inpGetPostAuxA(SYNTH_VOICE* svoice); u16 inpGetPreAuxB(SYNTH_VOICE* svoice); u16 inpGetPostAuxB(SYNTH_VOICE* svoice); u16 inpGetPedal(SYNTH_VOICE* svoice); u16 inpGetAuxA(u8 studio, u8 index, u8 midi, u8 midiSet); u16 inpGetAuxB(u8 studio, u8 index, u8 midi, u8 midiSet); void inpInit(SYNTH_VOICE* svoice); /* TODO: Figure out what `unk` is */ void hwSetSRCType(u32 v, u8 salSRCType); void hwSetITDMode(u32 v, u8 mode); void hwSetPolyPhaseFilter(u32 v, u8 salCoefSel); bool hwAddInput(u8 studio, SND_STUDIO_INPUT* in_desc); bool hwRemoveInput(u8 studio, SND_STUDIO_INPUT* in_desc); void hwChangeStudio(u32 v, u8 studio); void hwDisableHRTF(); void hwStart(u32 v, u8 studio); void hwKeyOff(u32 v); void hwFrameDone(); extern u32 dspHRTFOn; extern u16* dspCmdList; extern u16 dspCmdFirstSize; extern u8 dspScale2IndexTab[1024]; typedef void* (*ARAMUploadCallback)(u32, u32); u32 aramGetStreamBufferAddress(u8 id, u32* len); void aramUploadData(void* mram, u32 aram, u32 len, u32 highPrio, void (*callback)(u32), u32 user); void aramFreeStreamBuffer(u8 id); void* aramStoreData(void* src, u32 len); void aramRemoveData(void* aram, u32 len); u8 aramAllocateStreamBuffer(u32 len); u32 macStart(u16 macid, u8 priority, u8 maxVoices, u16 allocId, u8 key, u8 vol, u8 panning, u8 midi, u8 midiSet, u8 section, u16 step, u16 trackid, u8 new_vid, u8 vGroup, u8 studio, u32 itd); void macHandle(u32 deltaTime); void macMakeInactive(SYNTH_VOICE* svoice, MAC_STATE); void macSetPedalState(SYNTH_VOICE* svoice, u32 state); void macSetExternalKeyoff(SYNTH_VOICE* svoice); void macSampleEndNotify(SYNTH_VOICE* sv); void sndProfUpdateMisc(SND_PROFILE_INFO* info); void sndProfResetPMC(SND_PROFILE_DATA* info); void sndProfStartPMC(SND_PROFILE_DATA* info); void vidRemoveVoiceReferences(SYNTH_VOICE* svoice); u32 vidMakeNew(SYNTH_VOICE* svoice, u32 isMaster); u32 vidMakeRoot(SYNTH_VOICE* svoice); u32 adsrHandleLowPrecision(ADSR_VARS* adsr, u16* adsr_start, u16* adsr_delta); bool adsrRelease(ADSR_VARS* adsr); #ifdef __cplusplus } #endif #endif // _MUSYX_MUSYX_PRIV