Major seq.c progress & musyx header cleanup

Former-commit-id: f60291726a
This commit is contained in:
Luke Street 2023-06-29 19:12:29 -04:00
parent c58e1e3565
commit acd57e6a19
7 changed files with 660 additions and 302 deletions

View File

@ -1,13 +1,13 @@
#ifndef _MUSYX_HARDWARE #ifndef _MUSYX_HARDWARE
#define _MUSYX_HARDWARE #define _MUSYX_HARDWARE
#include "musyx/musyx_priv.h" #include "musyx/musyx_priv.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
u32 hwIsStudioActive(u8 studio); bool hwIsStudioActive(u8 studio);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -434,16 +434,16 @@ bool sndAuxCallbackPrepareChorus(SND_AUX_CHORUS* ch);
bool sndAuxCallbackShutdownChorus(SND_AUX_CHORUS* ch); bool sndAuxCallbackShutdownChorus(SND_AUX_CHORUS* ch);
bool sndAuxCallbackUpdateSettingsChorus(SND_AUX_CHORUS* ch); bool sndAuxCallbackUpdateSettingsChorus(SND_AUX_CHORUS* ch);
#define SND_CROSSFADE_STOP 0 // Stop old song after fadedown #define SND_CROSSFADE_STOP 0x0 // Stop old song after fadedown
#define SND_CROSSFADE_PAUSE 1 // Pause old song after fadedown #define SND_CROSSFADE_PAUSE 0x1 // Pause old song after fadedown
#define SND_CROSSFADE_CONTINUE 2 // Continue previously paused song as new one #define SND_CROSSFADE_CONTINUE 0x2 // Continue previously paused song as new one
#define SND_CROSSFADE_START 0 // Start new song (no continue) #define SND_CROSSFADE_START 0x0 // Start new song (no continue)
#define SND_CROSSFADE_SYNC 4 // Crossfade should start syncronized by sync-controller (104) #define SND_CROSSFADE_SYNC 0x4 // Crossfade should start syncronized by sync-controller (104)
#define SND_CROSSFADE_PAUSENEW 8 // Pause new song before even starting it #define SND_CROSSFADE_PAUSENEW 0x8 // Pause new song before even starting it
#define SND_CROSSFADE_TRACKMUTE 16 // Use trackmute informtion #define SND_CROSSFADE_TRACKMUTE 0x10 // Use trackmute informtion
#define SND_CROSSFADE_SPEED 32 // Use speed informtion #define SND_CROSSFADE_SPEED 0x20 // Use speed informtion
#define SND_CROSSFADE_MUTE 64 // Old song continues playing & gets muted after fade down #define SND_CROSSFADE_MUTE 0x40 // Old song continues playing & gets muted after fade down
#define SND_CROSSFADE_MUTENEW 128 // Mute new song after starting it #define SND_CROSSFADE_MUTENEW 0x80 // Mute new song after starting it
#define SND_CROSSFADE_DEFAULT 0 #define SND_CROSSFADE_DEFAULT 0
@ -517,6 +517,33 @@ typedef struct SND_PROFILE_INFO {
typedef void (*SND_PROF_USERCALLBACK)(struct SND_PROFILE_INFO*); typedef void (*SND_PROF_USERCALLBACK)(struct SND_PROFILE_INFO*);
extern SND_PROF_USERCALLBACK sndProfUserCallback; extern SND_PROF_USERCALLBACK sndProfUserCallback;
#define SND_MIDICTRL_MODULATION 0x01
#define SND_MIDICTRL_VOLUME 0x07
#define SND_MIDICTRL_PANNING 0x0A
#define SND_MIDICTRL_PEDAL 0x40
#define SND_MIDICTRL_PORTAMENTO 0x41
#define SND_MIDICTRL_REVERB 0x5B
#define SND_MIDICTRL_CHORUS 0x5D
#define SND_MIDICTRL_PITCHBEND 0x80
#define SND_MIDICTRL_SPANNING 0x83
#define SND_MIDICTRL_DOPPLER 0x84
#define SND_SEQVOL_CONTINUE 0
#define SND_SEQVOL_STOP 1
#define SND_SEQVOL_PAUSE 2
#define SND_SEQVOL_MUTE 3
#define SND_SEQVOL_MODEMASK 0xF
#define SND_ID_ERROR 0xFFFFFFFF // ID is invalid
#define SND_MAX_SEQINSTANCES 8
#define SND_SEQ_ERROR_ID 0xFFFFFFFF
#define SND_SEQ_CROSSFADE_ID 0x80000000
#define SND_PAUSEVOL_NORMAL 127
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -2,6 +2,7 @@
#define _MUSYX_MUSYX_PRIV #define _MUSYX_MUSYX_PRIV
#include "musyx/musyx.h" #include "musyx/musyx.h"
#include "musyx/assert.h" #include "musyx/assert.h"
#include "musyx/hardware.h" #include "musyx/hardware.h"
@ -149,7 +150,7 @@ typedef struct _PBADPCM {
u16 pred_scale; // offset 0x22, size 0x2 u16 pred_scale; // offset 0x22, size 0x2
u16 yn1; // offset 0x24, size 0x2 u16 yn1; // offset 0x24, size 0x2
u16 yn2; // offset 0x26, size 0x2 u16 yn2; // offset 0x26, size 0x2
} _PDADPCM; } _PBADPCM;
typedef struct _PBSRC { typedef struct _PBSRC {
// total size: 0xE // total size: 0xE
@ -177,16 +178,16 @@ typedef struct _PB {
u16 mixerCtrl; // offset 0xC, size 0x2 u16 mixerCtrl; // offset 0xC, size 0x2
u16 state; // offset 0xE, size 0x2 u16 state; // offset 0xE, size 0x2
u16 loopType; // offset 0x10, size 0x2 u16 loopType; // offset 0x10, size 0x2
struct _PBMIX mix; // offset 0x12, size 0x24 _PBMIX mix; // offset 0x12, size 0x24
struct _PBITD itd; // offset 0x36, size 0xE _PBITD itd; // offset 0x36, size 0xE
struct _PBUPDATE update; // offset 0x44, size 0xE _PBUPDATE update; // offset 0x44, size 0xE
struct _PBDPOP dpop; // offset 0x52, size 0x12 _PBDPOP dpop; // offset 0x52, size 0x12
struct _PBVE ve; // offset 0x64, size 0x4 _PBVE ve; // offset 0x64, size 0x4
struct _PBFIR fir; // offset 0x68, size 0x6 _PBFIR fir; // offset 0x68, size 0x6
struct _PBADDR addr; // offset 0x6E, size 0x10 _PBADDR addr; // offset 0x6E, size 0x10
struct _PBADPCM adpcm; // offset 0x7E, size 0x28 _PBADPCM adpcm; // offset 0x7E, size 0x28
struct _PBSRC src; // offset 0xA6, size 0xE _PBSRC src; // offset 0xA6, size 0xE
struct _PBADPCMLOOP adpcmLoop; // offset 0xB4, size 0x6 _PBADPCMLOOP adpcmLoop; // offset 0xB4, size 0x6
u16 streamLoopCnt; // offset 0xBA, size 0x2 u16 streamLoopCnt; // offset 0xBA, size 0x2
} _PB; } _PB;
@ -240,13 +241,13 @@ typedef struct SDIR_DATA {
u16 ref_cnt; // offset 0x2, size 0x2 u16 ref_cnt; // offset 0x2, size 0x2
u32 offset; // offset 0x4, size 0x4 u32 offset; // offset 0x4, size 0x4
void* addr; // offset 0x8, size 0x4 void* addr; // offset 0x8, size 0x4
struct SAMPLE_HEADER header; // offset 0xC, size 0x10 SAMPLE_HEADER header; // offset 0xC, size 0x10
u32 extraData; // offset 0x1C, size 0x4 u32 extraData; // offset 0x1C, size 0x4
} SDIR_DATA; } SDIR_DATA;
typedef struct SDIR_TAB { typedef struct SDIR_TAB {
// total size: 0xC // total size: 0xC
struct SDIR_DATA* data; // offset 0x0, size 0x4 SDIR_DATA* data; // offset 0x0, size 0x4
void* base; // offset 0x4, size 0x4 void* base; // offset 0x4, size 0x4
u16 numSmp; // offset 0x8, size 0x2 u16 numSmp; // offset 0x8, size 0x2
u16 res; // offset 0xA, size 0x2 u16 res; // offset 0xA, size 0x2
@ -283,8 +284,8 @@ typedef struct MAC_SUBTAB {
typedef struct GSTACK { typedef struct GSTACK {
// total size: 0xC // total size: 0xC
struct GROUP_DATA* gAddr; // offset 0x0, size 0x4 GROUP_DATA* gAddr; // offset 0x0, size 0x4
struct SDIR_DATA* sdirAddr; // offset 0x4, size 0x4 SDIR_DATA* sdirAddr; // offset 0x4, size 0x4
void* prjAddr; // offset 0x8, size 0x4 void* prjAddr; // offset 0x8, size 0x4
} GSTACK; } GSTACK;
@ -296,7 +297,7 @@ typedef struct VSampleInfo {
} VSampleInfo; } VSampleInfo;
typedef struct DSPvoice { typedef struct DSPvoice {
struct _PB* pb; _PB* pb;
void* patchData; void* patchData;
void* itdBuffer; void* itdBuffer;
struct DSPvoice* next; struct DSPvoice* next;
@ -374,8 +375,8 @@ typedef struct MSTEP {
} MSTEP; } MSTEP;
typedef struct CALLSTACK { typedef struct CALLSTACK {
struct MSTEP* addr; MSTEP* addr;
struct MSTEP* curAddr; MSTEP* curAddr;
} CALLSTACK; } CALLSTACK;
typedef struct SYNTH_QUEUE { typedef struct SYNTH_QUEUE {
@ -407,16 +408,16 @@ typedef struct SYNTH_LFO {
typedef struct SYNTHMasterFader { typedef struct SYNTHMasterFader {
// total size: 0x30 // total size: 0x30
float volume; // offset 0x0, size 0x4 f32 volume; // offset 0x0, size 0x4
float target; // offset 0x4, size 0x4 f32 target; // offset 0x4, size 0x4
float start; // offset 0x8, size 0x4 f32 start; // offset 0x8, size 0x4
float time; // offset 0xC, size 0x4 f32 time; // offset 0xC, size 0x4
float deltaTime; // offset 0x10, size 0x4 f32 deltaTime; // offset 0x10, size 0x4
float pauseVol; // offset 0x14, size 0x4 f32 pauseVol; // offset 0x14, size 0x4
float pauseTarget; // offset 0x18, size 0x4 f32 pauseTarget; // offset 0x18, size 0x4
float pauseStart; // offset 0x1C, size 0x4 f32 pauseStart; // offset 0x1C, size 0x4
float pauseTime; // offset 0x20, size 0x4 f32 pauseTime; // offset 0x20, size 0x4
float pauseDeltaTime; // offset 0x24, size 0x4 f32 pauseDeltaTime; // offset 0x24, size 0x4
u32 seqId; // offset 0x28, size 0x4 u32 seqId; // offset 0x28, size 0x4
u8 seqMode; // offset 0x2C, size 0x1 u8 seqMode; // offset 0x2C, size 0x1
u8 type; // offset 0x2D, size 0x1 u8 type; // offset 0x2D, size 0x1
@ -425,7 +426,7 @@ typedef struct SYNTHMasterFader {
typedef struct CTRL_SOURCE { typedef struct CTRL_SOURCE {
u8 midiCtrl; u8 midiCtrl;
u8 combine; u8 combine;
long scale; s32 scale;
} CTRL_SOURCE; } CTRL_SOURCE;
typedef struct CTRL_DEST { typedef struct CTRL_DEST {
@ -469,7 +470,7 @@ typedef struct _VS {
u8 voices[64]; // offset 0x908, size 0x40 u8 voices[64]; // offset 0x908, size 0x40
u16 nextInstID; // offset 0x948, size 0x2 u16 nextInstID; // offset 0x948, size 0x2
u32 (*callback)(u8, u32 (*callback)(u8,
struct SND_VIRTUALSAMPLE_INFO*); // offset 0x94C, size 0x4 SND_VIRTUALSAMPLE_INFO*); // offset 0x94C, size 0x4
} VS; } VS;
extern VS vs; extern VS vs;
@ -500,7 +501,7 @@ typedef struct SYNTH_VOICE {
u64 waitTime; u64 waitTime;
u8 timeUsedByInput; u8 timeUsedByInput;
u16 loop; u16 loop;
long local_vars[16]; s32 local_vars[16];
u32 child; u32 child;
u32 parent; u32 parent;
u32 id; u32 id;
@ -537,37 +538,37 @@ typedef struct SYNTH_VOICE {
u8 vibCentRange; // offset 0x141, size 0x1 u8 vibCentRange; // offset 0x141, size 0x1
u32 vibPeriod; // offset 0x144, size 0x4 u32 vibPeriod; // offset 0x144, size 0x4
u32 vibCurTime; // offset 0x148, size 0x4 u32 vibCurTime; // offset 0x148, size 0x4
long vibCurOffset; // offset 0x14C, size 0x4 s32 vibCurOffset; // offset 0x14C, size 0x4
s16 vibModAddScale; // offset 0x150, size 0x2 s16 vibModAddScale; // offset 0x150, size 0x2
u32 volume; // offset 0x154, size 0x4 u32 volume; // offset 0x154, size 0x4
u32 orgVolume; // offset 0x158, size 0x4 u32 orgVolume; // offset 0x158, size 0x4
float lastVolFaderScale; // offset 0x15C, size 0x4 f32 lastVolFaderScale; // offset 0x15C, size 0x4
u32 lastPan; // offset 0x160, size 0x4 u32 lastPan; // offset 0x160, size 0x4
u32 lastSPan; // offset 0x164, size 0x4 u32 lastSPan; // offset 0x164, size 0x4
float treCurScale; // offset 0x168, size 0x4 f32 treCurScale; // offset 0x168, size 0x4
u16 treScale; // offset 0x16C, size 0x2 u16 treScale; // offset 0x16C, size 0x2
u16 treModAddScale; // offset 0x16E, size 0x2 u16 treModAddScale; // offset 0x16E, size 0x2
u32 panning[2]; // offset 0x170, size 0x8 u32 panning[2]; // offset 0x170, size 0x8
long panDelta[2]; // offset 0x178, size 0x8 s32 panDelta[2]; // offset 0x178, size 0x8
u32 panTarget[2]; // offset 0x180, size 0x8 u32 panTarget[2]; // offset 0x180, size 0x8
u32 panTime[2]; // offset 0x188, size 0x8 u32 panTime[2]; // offset 0x188, size 0x8
u8 revVolScale; // offset 0x190, size 0x1 u8 revVolScale; // offset 0x190, size 0x1
u8 revVolOffset; // offset 0x191, size 0x1 u8 revVolOffset; // offset 0x191, size 0x1
u8 volTable; // offset 0x192, size 0x1 u8 volTable; // offset 0x192, size 0x1
u8 itdMode; // offset 0x193, size 0x1 u8 itdMode; // offset 0x193, size 0x1
long envDelta; // offset 0x194, size 0x4 s32 envDelta; // offset 0x194, size 0x4
u32 envTarget; // offset 0x198, size 0x4 u32 envTarget; // offset 0x198, size 0x4
u32 envCurrent; // offset 0x19C, size 0x4 u32 envCurrent; // offset 0x19C, size 0x4
u32 sweepOff[2]; // offset 0x1A0, size 0x8 u32 sweepOff[2]; // offset 0x1A0, size 0x8
long sweepAdd[2]; // offset 0x1A8, size 0x8 s32 sweepAdd[2]; // offset 0x1A8, size 0x8
long sweepCnt[2]; // offset 0x1B0, size 0x8 s32 sweepCnt[2]; // offset 0x1B0, size 0x8
u8 sweepNum[2]; // offset 0x1B8, size 0x2 u8 sweepNum[2]; // offset 0x1B8, size 0x2
struct SYNTH_LFO lfo[2]; // offset 0x1BC, size 0x18 SYNTH_LFO lfo[2]; // offset 0x1BC, size 0x18
u8 lfoUsedByInput[2]; // offset 0x1D4, size 0x2 u8 lfoUsedByInput[2]; // offset 0x1D4, size 0x2
u8 pbLowerKeyRange; // offset 0x1D6, size 0x1 u8 pbLowerKeyRange; // offset 0x1D6, size 0x1
u8 pbUpperKeyRange; // offset 0x1D7, size 0x1 u8 pbUpperKeyRange; // offset 0x1D7, size 0x1
u16 pbLast; // offset 0x1D8, size 0x2 u16 pbLast; // offset 0x1D8, size 0x2
struct ADSR_VARS pitchADSR; // offset 0x1DC, size 0x28 ADSR_VARS pitchADSR; // offset 0x1DC, size 0x28
s16 pitchADSRRange; // offset 0x204, size 0x2 s16 pitchADSRRange; // offset 0x204, size 0x2
u16 curPitch; // offset 0x206, size 0x2 u16 curPitch; // offset 0x206, size 0x2
struct setup { struct setup {
@ -598,7 +599,7 @@ typedef struct SYNTH_VOICE {
u8 mesgNum; // offset 0x3EC, size 0x1 u8 mesgNum; // offset 0x3EC, size 0x1
u8 mesgRead; // offset 0x3ED, size 0x1 u8 mesgRead; // offset 0x3ED, size 0x1
u8 mesgWrite; // offset 0x3EE, size 0x1 u8 mesgWrite; // offset 0x3EE, size 0x1
long mesgQueue[4]; // offset 0x3F0, size 0x10 s32 mesgQueue[4]; // offset 0x3F0, size 0x10
u16 curOutputVolume; // offset 0x400, size 0x2 u16 curOutputVolume; // offset 0x400, size 0x2
} SYNTH_VOICE; } SYNTH_VOICE;
@ -658,15 +659,15 @@ typedef struct POOL_DATA {
typedef struct SAL_VOLINFO { typedef struct SAL_VOLINFO {
// total size: 0x24 // total size: 0x24
float volL; // offset 0x0, size 0x4 f32 volL; // offset 0x0, size 0x4
float volR; // offset 0x4, size 0x4 f32 volR; // offset 0x4, size 0x4
float volS; // offset 0x8, size 0x4 f32 volS; // offset 0x8, size 0x4
float volAuxAL; // offset 0xC, size 0x4 f32 volAuxAL; // offset 0xC, size 0x4
float volAuxAR; // offset 0x10, size 0x4 f32 volAuxAR; // offset 0x10, size 0x4
float volAuxAS; // offset 0x14, size 0x4 f32 volAuxAS; // offset 0x14, size 0x4
float volAuxBL; // offset 0x18, size 0x4 f32 volAuxBL; // offset 0x18, size 0x4
float volAuxBR; // offset 0x1C, size 0x4 f32 volAuxBR; // offset 0x1C, size 0x4
float volAuxBS; // offset 0x20, size 0x4 f32 volAuxBS; // offset 0x20, size 0x4
} SAL_VOLINFO; } SAL_VOLINFO;
typedef struct SAL_PANINFO { typedef struct SAL_PANINFO {
@ -677,12 +678,12 @@ typedef struct SAL_PANINFO {
u32 span_im; // offset 0xC, size 0x4 u32 span_im; // offset 0xC, size 0x4
u32 rpan_i; // offset 0x10, size 0x4 u32 rpan_i; // offset 0x10, size 0x4
u32 rpan_im; // offset 0x14, size 0x4 u32 rpan_im; // offset 0x14, size 0x4
float pan_f; // offset 0x18, size 0x4 f32 pan_f; // offset 0x18, size 0x4
float pan_fm; // offset 0x1C, size 0x4 f32 pan_fm; // offset 0x1C, size 0x4
float span_f; // offset 0x20, size 0x4 f32 span_f; // offset 0x20, size 0x4
float span_fm; // offset 0x24, size 0x4 f32 span_fm; // offset 0x24, size 0x4
float rpan_f; // offset 0x28, size 0x4 f32 rpan_f; // offset 0x28, size 0x4
float rpan_fm; // offset 0x2C, size 0x4 f32 rpan_fm; // offset 0x2C, size 0x4
} SAL_PANINFO; } SAL_PANINFO;
typedef struct _SPB { typedef struct _SPB {
@ -718,15 +719,15 @@ typedef struct _SPB {
typedef struct DSPhostDPop { typedef struct DSPhostDPop {
// total size: 0x24 // total size: 0x24
long l; // offset 0x0, size 0x4 s32 l; // offset 0x0, size 0x4
long r; // offset 0x4, size 0x4 s32 r; // offset 0x4, size 0x4
long s; // offset 0x8, size 0x4 s32 s; // offset 0x8, size 0x4
long lA; // offset 0xC, size 0x4 s32 lA; // offset 0xC, size 0x4
long rA; // offset 0x10, size 0x4 s32 rA; // offset 0x10, size 0x4
long sA; // offset 0x14, size 0x4 s32 sA; // offset 0x14, size 0x4
long lB; // offset 0x18, size 0x4 s32 lB; // offset 0x18, size 0x4
long rB; // offset 0x1C, size 0x4 s32 rB; // offset 0x1C, size 0x4
long sB; // offset 0x20, size 0x4 s32 sB; // offset 0x20, size 0x4
} DSPhostDPop; } DSPhostDPop;
typedef struct DSPinput { typedef struct DSPinput {
@ -735,23 +736,23 @@ typedef struct DSPinput {
u16 vol; // offset 0x2, size 0x2 u16 vol; // offset 0x2, size 0x2
u16 volA; // offset 0x4, size 0x2 u16 volA; // offset 0x4, size 0x2
u16 volB; // offset 0x6, size 0x2 u16 volB; // offset 0x6, size 0x2
struct SND_STUDIO_INPUT* desc; // offset 0x8, size 0x4 SND_STUDIO_INPUT* desc; // offset 0x8, size 0x4
} DSPinput; } DSPinput;
typedef struct DSPstudioinfo { typedef struct DSPstudioinfo {
// total size: 0xBC // total size: 0xBC
struct _SPB* spb; // offset 0x0, size 0x4 _SPB* spb; // offset 0x0, size 0x4
struct DSPhostDPop hostDPopSum; // offset 0x4, size 0x24 DSPhostDPop hostDPopSum; // offset 0x4, size 0x24
long* main[2]; // offset 0x28, size 0x8 s32* main[2]; // offset 0x28, size 0x8
long* auxA[3]; // offset 0x30, size 0xC s32* auxA[3]; // offset 0x30, size 0xC
long* auxB[3]; // offset 0x3C, size 0xC s32* auxB[3]; // offset 0x3C, size 0xC
struct DSPvoice* voiceRoot; // offset 0x48, size 0x4 DSPvoice* voiceRoot; // offset 0x48, size 0x4
struct DSPvoice* alienVoiceRoot; // offset 0x4C, size 0x4 DSPvoice* alienVoiceRoot; // offset 0x4C, size 0x4
u8 state; // offset 0x50, size 0x1 u8 state; // offset 0x50, size 0x1
u8 isMaster; // offset 0x51, size 0x1 u8 isMaster; // offset 0x51, size 0x1
u8 numInputs; // offset 0x52, size 0x1 u8 numInputs; // offset 0x52, size 0x1
SND_STUDIO_TYPE type; // offset 0x54, size 0x4 SND_STUDIO_TYPE type; // offset 0x54, size 0x4
struct DSPinput in[7]; // offset 0x58, size 0x54 DSPinput in[7]; // offset 0x58, size 0x54
SND_AUX_CALLBACK auxAHandler; // offset 0xAC, size 0x4 SND_AUX_CALLBACK auxAHandler; // offset 0xAC, size 0x4
SND_AUX_CALLBACK auxBHandler; // offset 0xB0, size 0x4 SND_AUX_CALLBACK auxBHandler; // offset 0xB0, size 0x4
void* auxAUser; // offset 0xB4, size 0x4 void* auxAUser; // offset 0xB4, size 0x4
@ -769,6 +770,7 @@ typedef struct CHANNEL_DEFAULTS {
// total size: 0x1 // total size: 0x1
u8 pbRange; // offset 0x0, size 0x1 u8 pbRange; // offset 0x0, size 0x1
} CHANNEL_DEFAULTS; } CHANNEL_DEFAULTS;
typedef struct FX_TAB { typedef struct FX_TAB {
// total size: 0xA // total size: 0xA
u16 id; // offset 0x0, size 0x2 u16 id; // offset 0x0, size 0x2
@ -785,14 +787,14 @@ typedef struct FX_DATA {
// total size: 0xE // total size: 0xE
u16 num; // offset 0x0, size 0x2 u16 num; // offset 0x0, size 0x2
u16 reserverd; // offset 0x2, size 0x2 u16 reserverd; // offset 0x2, size 0x2
struct FX_TAB fx[1]; // offset 0x4, size 0xA FX_TAB fx[1]; // offset 0x4, size 0xA
} FX_DATA; } FX_DATA;
typedef struct FX_GROUP { typedef struct FX_GROUP {
// total size: 0x8 // total size: 0x8
u16 gid; // offset 0x0, size 0x2 u16 gid; // offset 0x0, size 0x2
u16 fxNum; // offset 0x2, size 0x2 u16 fxNum; // offset 0x2, size 0x2
struct FX_TAB* fxTab; // offset 0x4, size 0x4 FX_TAB* fxTab; // offset 0x4, size 0x4
} FX_GROUP; } FX_GROUP;
typedef struct PAGE { typedef struct PAGE {
@ -825,12 +827,12 @@ typedef struct ADSR_INFO {
union ai_data { union ai_data {
struct { struct {
// total size: 0x14 // total size: 0x14
long atime; // offset 0x0, size 0x4 s32 atime; // offset 0x0, size 0x4
long dtime; // offset 0x4, size 0x4 s32 dtime; // offset 0x4, size 0x4
u16 slevel; // offset 0x8, size 0x2 u16 slevel; // offset 0x8, size 0x2
u16 rtime; // offset 0xA, size 0x2 u16 rtime; // offset 0xA, size 0x2
long ascale; // offset 0xC, size 0x4 s32 ascale; // offset 0xC, size 0x4
long dscale; // offset 0x10, size 0x4 s32 dscale; // offset 0x10, size 0x4
} dls; } dls;
struct { struct {
// total size: 0x8 // total size: 0x8
@ -850,7 +852,7 @@ u32 dataInsertMacro(u16 mid, void* macroaddr);
u32 dataRemoveMacro(u16 mid); u32 dataRemoveMacro(u16 mid);
u32 dataInsertCurve(u16 cid, void* curvedata); u32 dataInsertCurve(u16 cid, void* curvedata);
u32 dataRemoveCurve(u16 sid); u32 dataRemoveCurve(u16 sid);
long dataGetSample(u16 sid, SAMPLE_INFO* newsmp); s32 dataGetSample(u16 sid, SAMPLE_INFO* newsmp);
void* dataGetCurve(u16 cid); void* dataGetCurve(u16 cid);
u32 dataAddSampleReference(u16 sid); u32 dataAddSampleReference(u16 sid);
u32 dataRemoveSampleReference(u16 sid); u32 dataRemoveSampleReference(u16 sid);
@ -863,7 +865,7 @@ FX_TAB* dataGetFX(u16 fid);
s32 hwInit(u32* frq, u16 numVoices, u16 numStudios, u32 flags); /* extern */ s32 hwInit(u32* frq, u16 numVoices, u16 numStudios, u32 flags); /* extern */
void hwInitSamplePlayback(u32 v, u16 smpID, void* newsmp, u32 set_defadsr, u32 prio, void hwInitSamplePlayback(u32 v, u16 smpID, void* newsmp, u32 set_defadsr, u32 prio,
u32 callbackUserValue, u32 setSRC, u8 itdMode); u32 callbackUserValue, u32 setSRC, u8 itdMode);
void hwSetVolume(u32 v, u8 table, float vol, u32 pan, u32 span, float auxa, float auxb); void hwSetVolume(u32 v, u8 table, f32 vol, u32 pan, u32 span, f32 auxa, f32 auxb);
void hwSetPitch(u32 v, u16 speed); void hwSetPitch(u32 v, u16 speed);
void hwEnableIrq(); void hwEnableIrq();
void hwDisableIrq(); void hwDisableIrq();
@ -885,14 +887,14 @@ void synthSetBpm(u32 pbm, u8 set, u8 section);
void synthFXCloneMidiSetup(SYNTH_VOICE* dest, SYNTH_VOICE* src); void synthFXCloneMidiSetup(SYNTH_VOICE* dest, SYNTH_VOICE* src);
void synthSetMusicVolumeType(u8 vGroup, u8 type); void synthSetMusicVolumeType(u8 vGroup, u8 type);
extern long synthGlobalVariable[16]; extern s32 synthGlobalVariable[16];
extern u16 voicePrioSortRootListRoot; extern u16 voicePrioSortRootListRoot;
extern u8 voiceMusicRunning; extern u8 voiceMusicRunning;
extern u8 voiceFxRunning; extern u8 voiceFxRunning;
extern u8 voiceListInsert; extern u8 voiceListInsert;
extern u8 voiceListRoot; extern u8 voiceListRoot;
void voiceSetPriority(struct SYNTH_VOICE* svoice, u8 prio); void voiceSetPriority(SYNTH_VOICE* svoice, u8 prio);
u32 voiceIsLastStarted(struct SYNTH_VOICE* svoice); u32 voiceIsLastStarted(SYNTH_VOICE* svoice);
s32 voiceKillSound(u32 voiceid); s32 voiceKillSound(u32 voiceid);
extern u64 synthRealTime; extern u64 synthRealTime;
@ -933,7 +935,7 @@ extern SND_MESSAGE_CALLBACK salMessageCallback;
extern SYNTH_MESSAGE_CALLBACK synthMessageCallback; extern SYNTH_MESSAGE_CALLBACK synthMessageCallback;
/* Math */ /* Math */
void salApplyMatrix(const SND_FMATRIX* a, const SND_FVECTOR* b, SND_FVECTOR* out); void salApplyMatrix(const SND_FMATRIX* a, const SND_FVECTOR* b, SND_FVECTOR* out);
float salNormalizeVector(SND_FVECTOR* vec); f32 salNormalizeVector(SND_FVECTOR* vec);
void salCrossProduct(SND_FVECTOR* out, const SND_FVECTOR* a, const SND_FVECTOR* b); void salCrossProduct(SND_FVECTOR* out, const SND_FVECTOR* a, const SND_FVECTOR* b);
void salInvertMatrix(SND_FMATRIX* out, const SND_FMATRIX* in); void salInvertMatrix(SND_FMATRIX* out, const SND_FMATRIX* in);
@ -948,8 +950,8 @@ void salDeactivateVoice(DSPvoice* dsp_vptr);
void salActivateStudio(u8 studio, u32 isMaster, SND_STUDIO_TYPE type); void salActivateStudio(u8 studio, u32 isMaster, SND_STUDIO_TYPE type);
void salDeactivateStudio(u8 studio); void salDeactivateStudio(u8 studio);
void salActivateVoice(DSPvoice* dsp_vptr, u8 studio); void salActivateVoice(DSPvoice* dsp_vptr, u8 studio);
void salCalcVolume(u8 voltab_index, SAL_VOLINFO* vi, float vol, u32 pan, u32 span, float auxa, void salCalcVolume(u8 voltab_index, SAL_VOLINFO* vi, f32 vol, u32 pan, u32 span, f32 auxa, f32 auxb,
float auxb, u32 itd, u32 dpl2); u32 itd, u32 dpl2);
void salReconnectVoice(DSPvoice* dsp_vptr, u8 studio); void salReconnectVoice(DSPvoice* dsp_vptr, u8 studio);
void* salMalloc(u32 len); void* salMalloc(u32 len);
void salFree(void* addr); void salFree(void* addr);
@ -1015,8 +1017,9 @@ typedef struct STREAM_INFO {
void streamOutputModeChanged(); void streamOutputModeChanged();
u8 inpTranslateExCtrl(u8 ctrl); u8 inpTranslateExCtrl(u8 ctrl);
void inpSetGlobalMIDIDirtyFlag(u8 chan, u8 midiSet, s32 flag); void inpSetGlobalMIDIDirtyFlag(u8 chan, u8 midiSet, s32 flag);
void inpAddCtrl(struct CTRL_DEST* dest, u8 ctrl, long scale, u8 comb, u32 isVar); void inpAddCtrl(CTRL_DEST* dest, u8 ctrl, s32 scale, u8 comb, u32 isVar);
void inpSetMidiCtrl(unsigned char ctrl, unsigned char channel, unsigned char set, unsigned char value); void inpSetMidiCtrl(unsigned char ctrl, unsigned char channel, unsigned char set,
unsigned char value);
void inpSetMidiCtrl14(unsigned char ctrl, unsigned char channel, unsigned char set, u16 value); void inpSetMidiCtrl14(unsigned char ctrl, unsigned char channel, unsigned char set, u16 value);
void inpSetExCtrl(SYNTH_VOICE* svoice, u8 ctrl, s16 v); void inpSetExCtrl(SYNTH_VOICE* svoice, u8 ctrl, s16 v);
CHANNEL_DEFAULTS* inpGetChannelDefaults(u8 midi, u8 midiSet); CHANNEL_DEFAULTS* inpGetChannelDefaults(u8 midi, u8 midiSet);
@ -1028,6 +1031,8 @@ u16 inpGetExCtrl(SYNTH_VOICE* svoice, u8 ctrl);
u16 inpGetMidiCtrl(u8 ctrl, u8 channel, u8 set); u16 inpGetMidiCtrl(u8 ctrl, u8 channel, u8 set);
void inpSetMidiLastNote(u8 midi, u8 midiSet, u8 key); void inpSetMidiLastNote(u8 midi, u8 midiSet, u8 key);
u16 inpGetModulation(SYNTH_VOICE* svoice); u16 inpGetModulation(SYNTH_VOICE* svoice);
void inpResetMidiCtrl(u8 ch, u8 set, u32 coldReset);
void inpResetChannelDefaults(u8 midi, u8 midiSet);
/* TODO: Figure out what `unk` is */ /* TODO: Figure out what `unk` is */
void hwSetSRCType(u32 v, u8 salSRCType); void hwSetSRCType(u32 v, u8 salSRCType);
void hwSetITDMode(u32 v, u8 mode); void hwSetITDMode(u32 v, u8 mode);

View File

@ -9,15 +9,18 @@ extern "C" {
typedef struct ARR { typedef struct ARR {
// total size: 0x58 // total size: 0x58
unsigned long tTab; // offset 0x0, size 0x4 u32 tTab; // offset 0x0, size 0x4
unsigned long pTab; // offset 0x4, size 0x4 u32 pTab; // offset 0x4, size 0x4
unsigned long tmTab; // offset 0x8, size 0x4 u32 tmTab; // offset 0x8, size 0x4
unsigned long mTrack; // offset 0xC, size 0x4 u32 mTrack; // offset 0xC, size 0x4
unsigned long info; // offset 0x10, size 0x4 u32 info; // offset 0x10, size 0x4
unsigned long loopPoint[16]; // offset 0x14, size 0x40 u32 loopPoint[16]; // offset 0x14, size 0x40
unsigned long tsTab; // offset 0x54, size 0x4 u32 tsTab; // offset 0x54, size 0x4
} ARR; } ARR;
#define ARR_GET(arr, offset) ((void*)(offset + (u32)arr))
#define ARR_GET_TYPE(arr, offset, ty) ((ty)ARR_GET(arr, offset))
typedef struct TENTRY { typedef struct TENTRY {
// total size: 0xC // total size: 0xC
u32 time; // offset 0x0, size 0x4 u32 time; // offset 0x0, size 0x4
@ -117,7 +120,7 @@ typedef struct TICKS {
typedef struct SEQ_SECTION { typedef struct SEQ_SECTION {
// total size: 0x38 // total size: 0x38
struct MTRACK mTrack; // offset 0x0, size 0x8 MTRACK mTrack; // offset 0x0, size 0x8
u32 bpm; // offset 0x8, size 0x4 u32 bpm; // offset 0x8, size 0x4
TICKS tickDelta[2]; // offset 0xC, size 0x10 TICKS tickDelta[2]; // offset 0xC, size 0x10
SEQ_EVENT* globalEventRoot; // offset 0x1C, size 0x4 SEQ_EVENT* globalEventRoot; // offset 0x1C, size 0x4
@ -159,21 +162,30 @@ typedef struct SEQ_INSTANCE {
SEQ_SECTION section[16]; // offset 0x14E8, size 0x380 SEQ_SECTION section[16]; // offset 0x14E8, size 0x380
} SEQ_INSTANCE; } SEQ_INSTANCE;
typedef struct SEQ_PATTERN {
// total size: 0x10
u32 headerLen; // offset 0x0, size 0x4
u32 pitchBend; // offset 0x4, size 0x4
u32 modulation; // offset 0x8, size 0x4
u32 noteData; // offset 0xC, size 0x4
} SEQ_PATTERN;
extern u8 synthTrackVolume[64]; extern u8 synthTrackVolume[64];
extern SEQ_INSTANCE seqInstance[8]; extern SEQ_INSTANCE seqInstance[8];
extern u16 seqMIDIPriority[8][16]; extern u16 seqMIDIPriority[8][16];
void seqSpeed(unsigned long seqId, unsigned short speed); void seqSpeed(u32 seqId, u16 speed);
void seqVolume(unsigned char volume, unsigned short time, unsigned long seqId, unsigned char mode); void seqVolume(u8 volume, u16 time, u32 seqId, u8 mode);
void sndSeqStop(s32 unk); void sndSeqStop(s32 unk);
void sndSeqSpeed(u32 seqId, u16 speed); void sndSeqSpeed(u32 seqId, u16 speed);
void sndSeqContinue(s32 unk); void sndSeqContinue(s32 unk);
void sndSeqMute(s32 unk1, s32 unk2, s32 unk3); void sndSeqMute(s32 unk1, s32 unk2, s32 unk3);
void sndSeqVolume(unsigned char volume, unsigned short time, unsigned long seqId, void sndSeqVolume(u8 volume, u16 time, u32 seqId, u8 mode);
unsigned char mode); u32 sndSeqPlayEx(u16 sgid, u16 sid, void* arrfile, SND_PLAYPARA* para, u8 studio);
void seqStop(unsigned long seqId); void seqStop(u32 seqId);
u16 seqGetMIDIPriority(u8 set, u8 channel); u16 seqGetMIDIPriority(u8 set, u8 channel);
void seqCrossFade(SND_CROSSFADE* ci, unsigned long* new_seqId, unsigned char irq_call); void seqCrossFade(SND_CROSSFADE* ci, u32* new_seqId, bool8 irq_call);
u32 seqPlaySong(u16 sgid, u16 sid, void* arrfile, SND_PLAYPARA* para, u8 irq_call, u8 studio);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -41,7 +41,7 @@ void winSetFontSize(u16 size);
sWIN* winOpenLogWindow(s32 x1, s32 y1, s32 x2, s32 y2, char* caption, u16 num_lines, u32 flags); sWIN* winOpenLogWindow(s32 x1, s32 y1, s32 x2, s32 y2, char* caption, u16 num_lines, u32 flags);
sWIN* winOpenWindow(s32 x1, s32 y1, s32 x2, s32 y2, char* caption, void* func, u32 flags); sWIN* winOpenWindow(s32 x1, s32 y1, s32 x2, s32 y2, char* caption, void* func, u32 flags);
WXOpenWindow(); // WXOpenWindow();
#ifdef __cpluplus #ifdef __cpluplus
} }

View File

@ -134,7 +134,7 @@ u32 salExitDsp() {
void salStartDsp(u16* cmdList) { void salStartDsp(u16* cmdList) {
salDspIsDone = FALSE; salDspIsDone = FALSE;
PPCSync(); PPCSync();
MUSY_ASSERT(((u32)cmdList & 0x1F)==0); MUSY_ASSERT(((u32)cmdList & 0x1F) == 0);
DSPSendMailToDSP(dspCmdFirstSize | 0xbabe0000); DSPSendMailToDSP(dspCmdFirstSize | 0xbabe0000);
while (DSPCheckMailToDSP()) while (DSPCheckMailToDSP())

View File

@ -222,7 +222,7 @@ static void HandleKeyOffNotes() {
n = cseq->noteKeyOff; n = cseq->noteKeyOff;
while (n != NULL) { while (n != NULL) {
nn = n->next; nn = n->next;
if (n->id != -1 && sndFXCheck(n->id) == -1) { if (n->id != SND_ID_ERROR && sndFXCheck(n->id) == SND_ID_ERROR) {
seqFreeKeyOffNote(n); seqFreeKeyOffNote(n);
} }
@ -238,22 +238,43 @@ static void InitPublicIds() { seq_next_id = 0; }
static u32 GetPublicId(u32 seqId) { static u32 GetPublicId(u32 seqId) {
u32 pub_id; // r30 u32 pub_id; // r30
SEQ_INSTANCE* si; // r31 SEQ_INSTANCE* si; // r31
si = &seqInstance[seqId];
do {
pub_id = seq_next_id;
seq_next_id = pub_id + 1;
seq_next_id &= ~SND_SEQ_CROSSFADE_ID;
for (si = seqActiveRoot; si != NULL; si = si->next) {
if (si->publicId == pub_id) {
pub_id = SND_SEQ_ERROR_ID;
break;
}
}
for (si = seqPausedRoot; si != NULL; si = si->next) {
if (si->publicId == pub_id) {
pub_id = SND_SEQ_ERROR_ID;
break;
}
}
} while (pub_id == SND_SEQ_ERROR_ID);
seqInstance[seqId].publicId = pub_id;
return pub_id;
} }
u32 seqGetPrivateId(u32 seqId) { u32 seqGetPrivateId(u32 seqId) {
SEQ_INSTANCE* si; // r31 SEQ_INSTANCE* si; // r31
for (si = seqActiveRoot; si != NULL; si = si->next) { for (si = seqActiveRoot; si != NULL; si = si->next) {
if (si->publicId == (seqId & 0x7fffffff)) { if (si->publicId == (seqId & ~SND_SEQ_CROSSFADE_ID)) {
return seqId & 0x80000000 | si->index; return si->index | seqId & SND_SEQ_CROSSFADE_ID;
} }
} }
for (si = seqPausedRoot; si != NULL; si = si->next) { for (si = seqPausedRoot; si != NULL; si = si->next) {
if (si->publicId == (seqId & 0x7fffffff)) { if (si->publicId == (seqId & ~SND_SEQ_CROSSFADE_ID)) {
return seqId & 0x80000000 | si->index; return si->index | seqId & SND_SEQ_CROSSFADE_ID;
} }
} }
return 0xffffffff; return SND_ID_ERROR;
} }
static void DoPrgChange(SEQ_INSTANCE* seq, u8 prg, u8 midi) { static void DoPrgChange(SEQ_INSTANCE* seq, u8 prg, u8 midi) {
@ -292,6 +313,9 @@ static void BuildTransTab(u8* tab, PAGE* page) {
} }
} }
static void StartPause(SEQ_INSTANCE* si);
static void InitTrackEvents();
u32 seqStartPlay(PAGE* norm, PAGE* drum, MIDISETUP* midiSetup, u32* song, SND_PLAYPARA* para, u32 seqStartPlay(PAGE* norm, PAGE* drum, MIDISETUP* midiSetup, u32* song, SND_PLAYPARA* para,
u8 studio, u16 sgid) { u8 studio, u16 sgid) {
ARR* arr; // r27 ARR* arr; // r27
@ -303,15 +327,15 @@ u32 seqStartPlay(PAGE* norm, PAGE* drum, MIDISETUP* midiSetup, u32* song, SND_PL
u32 bpm; // r25 u32 bpm; // r25
if ((nseq = seqFreeRoot) == NULL) { if ((nseq = seqFreeRoot) == NULL) {
return -1; return SND_ID_ERROR;
}; }
if ((seqFreeRoot = seqFreeRoot->next) != NULL) { if ((seqFreeRoot = nseq->next) != NULL) {
seqFreeRoot->prev = NULL; seqFreeRoot->prev = NULL;
} }
if ((nseq->next = seqActiveRoot) != NULL) { if ((nseq->next = seqActiveRoot) != NULL) {
seqActiveRoot->prev = nseq; seqActiveRoot->prev = nseq;
} }
nseq->prev = NULL; nseq->prev = NULL;
seqActiveRoot = nseq; seqActiveRoot = nseq;
nseq->state = 1; nseq->state = 1;
@ -340,7 +364,7 @@ u32 seqStartPlay(PAGE* norm, PAGE* drum, MIDISETUP* midiSetup, u32* song, SND_PL
nseq->section[i].speed = 256; nseq->section[i].speed = 256;
} }
synthVolume(127, 0, nseq->defVGroup, 0, -1); synthVolume(SND_PAUSEVOL_NORMAL, 0, nseq->defVGroup, 0, SND_ID_ERROR);
} else { } else {
if (para->flags & SND_PLAYPARA_TRACKMUTE) { if (para->flags & SND_PLAYPARA_TRACKMUTE) {
nseq->trackMute[0] = para->trackMute[0]; nseq->trackMute[0] = para->trackMute[0];
@ -368,17 +392,19 @@ u32 seqStartPlay(PAGE* norm, PAGE* drum, MIDISETUP* midiSetup, u32* song, SND_PL
} }
if (para->flags & SND_PLAYPARA_VOLUME) { if (para->flags & SND_PLAYPARA_VOLUME) {
synthVolume(para->volume.target, para->volume.time, nseq->defVGroup, 0, -1); synthVolume(para->volume.target, para->volume.time, nseq->defVGroup, SND_SEQVOL_CONTINUE,
SND_SEQ_ERROR_ID);
for (i = 0; i < para->numFaded; ++i) { for (i = 0; i < para->numFaded; ++i) {
synthVolume(para->volume.target, para->volume.time, para->faded[i], 0, -1); synthVolume(para->volume.target, para->volume.time, para->faded[i], SND_SEQVOL_CONTINUE,
SND_SEQ_ERROR_ID);
} }
} }
} }
arr = (ARR*)song; arr = (ARR*)song;
if (arr->info & 0x80000000) { if (arr->info & 0x80000000) {
nseq->trackSectionTab = (u8*)(arr->tsTab + (u32)arr); nseq->trackSectionTab = ARR_GET(arr, arr->tsTab);
} else { } else {
nseq->trackSectionTab = NULL; nseq->trackSectionTab = NULL;
} }
@ -394,7 +420,7 @@ u32 seqStartPlay(PAGE* norm, PAGE* drum, MIDISETUP* midiSetup, u32* song, SND_PL
synthSetBpm(bpm >> 10, seqId & 0xFF, i & 0xFF); synthSetBpm(bpm >> 10, seqId & 0xFF, i & 0xFF);
if (arr->mTrack != NULL) { if (arr->mTrack != NULL) {
nseq->section[i].mTrack.base = (MTRACK_DATA*)(arr->mTrack + (u32)arr); nseq->section[i].mTrack.base = ARR_GET(arr, arr->mTrack);
nseq->section[i].mTrack.addr = nseq->section[i].mTrack.base; nseq->section[i].mTrack.addr = nseq->section[i].mTrack.base;
} else { } else {
nseq->section[i].mTrack.base = NULL; nseq->section[i].mTrack.base = NULL;
@ -404,14 +430,61 @@ u32 seqStartPlay(PAGE* norm, PAGE* drum, MIDISETUP* midiSetup, u32* song, SND_PL
nseq->section[i].loopCnt = 0; nseq->section[i].loopCnt = 0;
} }
tracktab = &arr->tTab; tracktab = ARR_GET(arr, arr->tTab);
for (i = 0; i < 64; ++i) { for (i = 0; i < 64; ++i) {
synthTrackVolume[i] = 127; synthTrackVolume[i] = SND_PAUSEVOL_NORMAL;
nseq->pattern[i].addr = NULL; nseq->pattern[i].addr = NULL;
// TODO: Finish if (tracktab[i] != 0) {
nseq->track[i].addr = nseq->track[i].base = ARR_GET(arr, tracktab[i]);
} else {
nseq->track[i].addr = nseq->track[i].base = NULL;
} }
return -1; }
nseq->noteUsed[0] = NULL;
nseq->noteUsed[1] = NULL;
nseq->noteKeyOff = NULL;
for (i = 0; i < 16; ++i) {
inpResetMidiCtrl(i, seqId, 1);
}
for (i = 0; i < 16; ++i) {
nseq->prgState[i].macId = 0xffff;
}
for (i = 0; i < 16; ++i) {
inpResetChannelDefaults(i, seqId);
}
if (midiSetup != NULL) {
for (i = 0; i < 16; ++i) {
DoPrgChange(nseq, midiSetup->channel[i].program, i);
inpSetMidiCtrl(SND_MIDICTRL_VOLUME, i, seqId, midiSetup->channel[i].volume);
inpSetMidiCtrl(SND_MIDICTRL_PANNING, i, seqId, midiSetup->channel[i].panning);
inpSetMidiCtrl(SND_MIDICTRL_REVERB, i, seqId, midiSetup->channel[i].reverb);
inpSetMidiCtrl(SND_MIDICTRL_CHORUS, i, seqId, midiSetup->channel[i].chorus);
}
}
for (i = 0; i < 16; ++i) {
seqMIDIPriority[seqId][i] = 0xffff;
}
for (i = 0; i < 16; ++i) {
nseq->section[i].time[0].high = 0;
nseq->section[i].time[0].low = 0;
nseq->section[i].time[1].high = 0;
nseq->section[i].time[1].low = 0;
nseq->section[i].timeIndex = 0;
}
nseq->keyOffCheck = 0;
if (para != NULL && (para->flags & SND_PLAYPARA_PAUSE) != 0) {
StartPause(nseq);
}
oldCSeq = cseq;
cseq = nseq;
InitTrackEvents();
cseq = oldCSeq;
seqId = GetPublicId(seqId);
return seqId;
} }
static void SetTickDelta(SEQ_SECTION* section, u32 deltaTime) { static void SetTickDelta(SEQ_SECTION* section, u32 deltaTime) {
@ -446,7 +519,7 @@ static void HandleMasterTrack(u8 secIndex) {
} }
} }
static void RewindMTrack(unsigned char secIndex, unsigned long deltaTime) { static void RewindMTrack(u8 secIndex, u32 deltaTime) {
if (cseq->section[secIndex].mTrack.base == NULL) { if (cseq->section[secIndex].mTrack.base == NULL) {
return; return;
} }
@ -479,11 +552,11 @@ void seqPause(u32 seqId) {
SEQ_INSTANCE* si; // r31 SEQ_INSTANCE* si; // r31
seqId = seqGetPrivateId(seqId); seqId = seqGetPrivateId(seqId);
if (seqId == -1) { if (seqId == SND_SEQ_ERROR_ID) {
return; return;
} }
if (!(seqId & 0x80000000)) { if ((seqId & SND_SEQ_CROSSFADE_ID) == 0) {
si = &seqInstance[seqId]; si = &seqInstance[seqId];
if (si->state == 1) { if (si->state == 1) {
StartPause(si); StartPause(si);
@ -491,22 +564,21 @@ void seqPause(u32 seqId) {
ResetNotes(si); ResetNotes(si);
} }
} else { } else {
si = &seqInstance[seqId & 0x7fffffff]; si = &seqInstance[seqId & ~SND_SEQ_CROSSFADE_ID];
if (si->state != 0) { if (si->state != 0) {
si->syncCrossInfo.flags |= 8; si->syncCrossInfo.flags |= 8;
} }
} }
} }
void seqStop(unsigned long seqId) { void seqStop(u32 seqId) {
SEQ_INSTANCE* si; // r31 SEQ_INSTANCE* si; // r31
;
if ((seqId = seqGetPrivateId(seqId)) == -1) { if ((seqId = seqGetPrivateId(seqId)) == SND_SEQ_ERROR_ID) {
return; return;
} }
if (!(seqId & 0x80000000)) { if ((seqId & SND_SEQ_CROSSFADE_ID) == 0) {
si = &seqInstance[seqId]; si = &seqInstance[seqId];
switch (si->state) { switch (si->state) {
case 1: case 1:
@ -539,7 +611,7 @@ void seqStop(unsigned long seqId) {
si->prev = NULL; si->prev = NULL;
seqFreeRoot = si; seqFreeRoot = si;
} else { } else {
si = &seqInstance[seqId & 0x7fffffff]; si = &seqInstance[seqId & ~SND_SEQ_CROSSFADE_ID];
if (si->state != 0) { if (si->state != 0) {
si->syncSeqIdPtr = NULL; si->syncSeqIdPtr = NULL;
} }
@ -557,7 +629,7 @@ void seqKillAllInstances() {
} }
} }
void seqKillInstancesByGroupID(unsigned short sgid) { void seqKillInstancesByGroupID(u16 sgid) {
SEQ_INSTANCE* si; // r31 SEQ_INSTANCE* si; // r31
for (si = seqActiveRoot; si != NULL; si = si->next) { for (si = seqActiveRoot; si != NULL; si = si->next) {
@ -572,19 +644,20 @@ void seqKillInstancesByGroupID(unsigned short sgid) {
} }
} }
void seqSpeed(unsigned long seqId, unsigned short speed) { void seqSpeed(u32 seqId, u16 speed) {
u32 i; // r30 u32 i; // r30
seqId = seqGetPrivateId(seqId); seqId = seqGetPrivateId(seqId);
MUSY_ASSERT_MSG(seqId != -1, "Sequencer ID is not valid."); #line 1018
MUSY_ASSERT_MSG(seqId != SND_SEQ_ERROR_ID, "Sequencer ID is not valid.");
if (!(seqId & 0x80000000)) { if ((seqId & SND_SEQ_CROSSFADE_ID) == 0) {
for (i = 0; i < 16; ++i) { for (i = 0; i < 16; ++i) {
seqInstance[seqId].section[i].speed = speed; seqInstance[seqId].section[i].speed = speed;
} }
} else { } else {
seqId &= 0x7FFFFFFF; seqId &= ~SND_SEQ_CROSSFADE_ID;
seqInstance[seqId].syncCrossInfo.flags |= 0x20; seqInstance[seqId].syncCrossInfo.flags |= SND_CROSSFADE_SPEED;
seqInstance[seqId].syncCrossInfo.speed2 = speed; seqInstance[seqId].syncCrossInfo.speed2 = speed;
} }
} }
@ -593,9 +666,10 @@ void seqContinue(u32 seqId) {
struct SEQ_INSTANCE* si; // r31 struct SEQ_INSTANCE* si; // r31
seqId = seqGetPrivateId(seqId); seqId = seqGetPrivateId(seqId);
MUSY_ASSERT_MSG(seqId != -1, "Sequencer ID is not valid."); #line 1043
MUSY_ASSERT_MSG(seqId != SND_SEQ_ERROR_ID, "Sequencer ID is not valid.");
if (!(seqId & 0x80000000)) { if ((seqId & SND_SEQ_CROSSFADE_ID) == 0) {
si = &seqInstance[seqId]; si = &seqInstance[seqId];
if (si->state == 2) { if (si->state == 2) {
@ -618,130 +692,370 @@ void seqContinue(u32 seqId) {
si->state = 1; si->state = 1;
} }
} else { } else {
seqInstance[seqId & 0x7FFFFFFF].syncCrossInfo.flags &= ~0x8; seqInstance[seqId & ~SND_SEQ_CROSSFADE_ID].syncCrossInfo.flags &= ~SND_CROSSFADE_PAUSENEW;
} }
} }
void seqMute(unsigned long seqId, unsigned long mask1, unsigned long mask2) { void seqMute(u32 seqId, u32 mask1, u32 mask2) {
seqId = seqGetPrivateId(seqId); seqId = seqGetPrivateId(seqId);
if (seqId == 0xffffffff) { if (seqId == SND_SEQ_ERROR_ID) {
return; return;
} }
if (!(seqId & 0x80000000)) { if ((seqId & SND_SEQ_CROSSFADE_ID) == 0) {
seqInstance[seqId].trackMute[0] = mask1; seqInstance[seqId].trackMute[0] = mask1;
seqInstance[seqId].trackMute[1] = mask2; seqInstance[seqId].trackMute[1] = mask2;
} else { } else {
seqId &= 0x7fffffff; seqId &= ~SND_SEQ_CROSSFADE_ID;
seqInstance[seqId].syncCrossInfo.flags |= 0x10; seqInstance[seqId].syncCrossInfo.flags |= SND_CROSSFADE_TRACKMUTE;
seqInstance[seqId].syncCrossInfo.trackMute2[0] = mask1; seqInstance[seqId].syncCrossInfo.trackMute2[0] = mask1;
seqInstance[seqId].syncCrossInfo.trackMute2[1] = mask2; seqInstance[seqId].syncCrossInfo.trackMute2[1] = mask2;
} }
} }
void seqVolume(unsigned char volume, unsigned short time, unsigned long seqId, unsigned char mode) { void seqVolume(u8 volume, u16 time, u32 seqId, u8 mode) {
unsigned long i; // r29 u32 i; // r29
unsigned long pub_id; // r27 u32 pub_id; // r27
// TODO
// pub_id = seqId;
seqId = seqGetPrivateId(seqId);
if (seqId == -1) { pub_id = seqId;
seqId = seqGetPrivateId(seqId);
if (seqId == SND_SEQ_ERROR_ID) {
return; return;
} }
if (!(seqId & 0x80000000)) { if ((seqId & SND_SEQ_CROSSFADE_ID) == 0) {
synthVolume(volume, time, seqInstance[seqId].defVGroup, mode, pub_id); synthVolume(volume, time, seqInstance[seqId].defVGroup, mode, pub_id);
for (i = 0; i < 64; ++i) { for (i = 0; i < 64; ++i) {
if (seqInstance[seqId].trackVolGroup[i] != seqInstance[seqId].defVGroup) { if (seqInstance[seqId].trackVolGroup[i] != seqInstance[seqId].defVGroup) {
synthVolume(volume, time, seqInstance[seqId].trackVolGroup[i], 0, -1); synthVolume(volume, time, seqInstance[seqId].trackVolGroup[i], SND_SEQVOL_CONTINUE,
SND_SEQ_ERROR_ID);
} }
} }
} else { } else {
seqId &= 0x7fffffff; seqId &= ~SND_SEQ_CROSSFADE_ID;
switch (mode & 0xf) { switch (mode & SND_SEQVOL_MODEMASK) {
case 0: case SND_SEQVOL_CONTINUE:
seqInstance[seqId].syncCrossInfo.vol2 = volume; seqInstance[seqId].syncCrossInfo.vol2 = volume;
break; break;
case 1: case SND_SEQVOL_STOP:
seqInstance[seqId].syncSeqIdPtr = NULL; seqInstance[seqId].syncSeqIdPtr = NULL;
break; break;
case 2: case SND_SEQVOL_PAUSE:
seqInstance[seqId].syncCrossInfo.flags |= 8; seqInstance[seqId].syncCrossInfo.flags |= SND_CROSSFADE_PAUSENEW;
seqInstance[seqId].syncCrossInfo.vol2 = volume; seqInstance[seqId].syncCrossInfo.vol2 = volume;
break; break;
case 3: case SND_SEQVOL_MUTE:
seqInstance[seqId].syncCrossInfo.flags |= 0x80; seqInstance[seqId].syncCrossInfo.flags |= SND_CROSSFADE_MUTENEW;
seqInstance[seqId].syncCrossInfo.vol2 = volume; seqInstance[seqId].syncCrossInfo.vol2 = volume;
break; break;
default: default:
#line 1153
MUSY_FATAL("Illegal sequencere fade mode detected."); MUSY_FATAL("Illegal sequencere fade mode detected.");
break; break;
} }
} }
} }
// TODO: very incomplete void seqCrossFade(SND_CROSSFADE* ci, u32* new_seqId, bool8 irq_call) {
void seqCrossFade(SND_CROSSFADE* ci, unsigned long* new_seqId, unsigned char irq_call) {
SND_PLAYPARA pp; // r1+0x14 SND_PLAYPARA pp; // r1+0x14
unsigned long seqId; // r29 u32 seqId; // r29
unsigned short time; // r27 u16 time; // r27
seqId = seqGetPrivateId(ci->seqId1);
if ((ci->flags & 0x4) != 0) { seqId = seqGetPrivateId(ci->seqId1);
#line 1170
MUSY_ASSERT_MSG(seqId != SND_SEQ_ERROR_ID, "Sequencer ID is not valid.");
if ((ci->flags & SND_CROSSFADE_SYNC) != 0) {
seqInstance[seqId].syncCrossInfo = *ci; seqInstance[seqId].syncCrossInfo = *ci;
seqInstance[seqId].syncActive = TRUE; seqInstance[seqId].syncActive = TRUE;
seqInstance[seqId].syncSeqIdPtr = new_seqId; seqInstance[seqId].syncSeqIdPtr = new_seqId;
seqInstance[seqId].syncCrossInfo.flags &= ~0x4; seqInstance[seqId].syncCrossInfo.flags &= ~SND_CROSSFADE_SYNC;
*new_seqId = ci->seqId1 | 0x80000000; *new_seqId = ci->seqId1 | SND_SEQ_CROSSFADE_ID;
return; return;
} }
if ((irq_call & 0xff) != 0) { if (irq_call) {
time = 5; time = ci->time1 < 5 ? 5 : ci->time1;
if (ci->time1 > 4) { if ((ci->flags & SND_CROSSFADE_PAUSE) != 0) {
time = ci->time1; seqVolume(0, time, ci->seqId1, SND_SEQVOL_PAUSE);
} } else if ((ci->flags & SND_CROSSFADE_MUTE) != 0) {
seqVolume(0, time, ci->seqId1, SND_SEQVOL_MUTE);
if ((ci->flags & 0x1) != 0) {
seqVolume(0, time, seqId, 2);
} else if ((ci->flags & 0x40) != 0) {
seqVolume(0, time, seqId, 3);
} else { } else {
seqVolume(0, time, seqId, 1); seqVolume(0, time, ci->seqId1, SND_SEQVOL_STOP);
}
} else {
if ((ci->flags & SND_CROSSFADE_PAUSE) != 0) {
sndSeqVolume(0, ci->time1, ci->seqId1, SND_SEQVOL_PAUSE);
} else if ((ci->flags & SND_CROSSFADE_MUTE) != 0) {
sndSeqVolume(0, ci->time1, ci->seqId1, SND_SEQVOL_MUTE);
} else {
sndSeqVolume(0, ci->time1, ci->seqId1, SND_SEQVOL_STOP);
}
} }
if (new_seqId != NULL) { if (new_seqId == NULL) {
if ((ci->flags & 0x2) != 0) { return;
seqId = seqGetPrivateId(ci->seqId2); }
if (seqId != 0xffffffff) {
if ((irq_call & 0xff) != 0) { if ((ci->flags & SND_CROSSFADE_CONTINUE) != 0) {
seqStop(ci->seqId2); if (seqGetPrivateId(ci->seqId2) != SND_SEQ_ERROR_ID) {
if (irq_call) {
seqContinue(ci->seqId2);
seqVolume(ci->vol2, ci->time2, ci->seqId2, SND_SEQVOL_CONTINUE);
if ((ci->flags & SND_CROSSFADE_TRACKMUTE) != 0) {
seqMute(ci->seqId2, ci->trackMute2[0], ci->trackMute2[1]);
}
if ((ci->flags & SND_CROSSFADE_SPEED) != 0) {
seqSpeed(ci->seqId2, ci->speed2);
}
} else { } else {
sndSeqContinue(ci->seqId2); sndSeqContinue(ci->seqId2);
sndSeqVolume(ci->vol2, ci->time2, ci->seqId2, 0); sndSeqVolume(ci->vol2, ci->time2, ci->seqId2, SND_SEQVOL_CONTINUE);
if ((ci->flags & 0x10) != 0) { if ((ci->flags & SND_CROSSFADE_TRACKMUTE) != 0) {
sndSeqMute(ci->seqId2, ci->trackMute2[0], ci->trackMute2[1]); sndSeqMute(ci->seqId2, ci->trackMute2[0], ci->trackMute2[1]);
} }
if ((ci->flags & 0x20) != 0) { if ((ci->flags & SND_CROSSFADE_SPEED) != 0) {
sndSeqSpeed(ci->seqId2, ci->speed2); sndSeqSpeed(ci->seqId2, ci->speed2);
} }
} }
*new_seqId = ci->seqId2; *new_seqId = ci->seqId2;
} else { } else {
*new_seqId = 0xffffffff; *new_seqId = SND_SEQ_ERROR_ID;
} }
}
}
return;
}
if ((ci->flags & 0x1) != 0) {
sndSeqVolume(0, ci->time1, seqId, 2);
} else if ((ci->flags & 0x40) != 0) {
sndSeqVolume(0, ci->time1, seqId, 3);
} else { } else {
sndSeqVolume(0, ci->time1, seqId, 1); pp.flags = SND_PLAYPARA_VOLUME;
if ((ci->flags & SND_CROSSFADE_PAUSENEW) != 0) {
pp.flags |= SND_PLAYPARA_PAUSE;
}
if ((ci->flags & SND_CROSSFADE_SPEED) != 0) {
pp.flags |= SND_PLAYPARA_SPEED;
pp.speed = ci->speed2;
}
if ((ci->flags & SND_CROSSFADE_TRACKMUTE) != 0) {
pp.flags |= SND_PLAYPARA_TRACKMUTE;
pp.trackMute[0] = ci->trackMute2[0];
pp.trackMute[1] = ci->trackMute2[1];
}
pp.volume.time = ci->time2;
pp.volume.target = ci->vol2;
pp.numFaded = 0;
if (irq_call != 0) {
if ((*new_seqId = seqPlaySong(ci->gid2, ci->sid2, ci->arr2, &pp, TRUE, ci->studio2)) !=
SND_SEQ_ERROR_ID &&
(ci->flags & SND_CROSSFADE_MUTENEW) != 0) {
seqMute(*new_seqId, 0, 0);
}
} else {
if ((*new_seqId = sndSeqPlayEx(ci->gid2, ci->sid2, ci->arr2, &pp, ci->studio2)) !=
SND_SEQ_ERROR_ID &&
(ci->flags & SND_CROSSFADE_MUTENEW) != 0) {
sndSeqMute(*new_seqId, 0, 0);
}
}
} }
} }
static u8* GetStreamValue(u8* stream, u16* deltaTime, s16* deltaData) {
u8 b1; // r31
u8 b2; // r29
s16 v; // r30
b1 = stream[0];
b2 = stream[1];
if (b1 == 0x80 && b2 == 0) {
return NULL;
}
if ((b1 & 0x80) != 0) {
*deltaTime = ((b1 & 0x7f) << 8) | b2;
stream += 2;
} else {
*deltaTime = b1;
stream += 1;
}
b1 = stream[0];
b2 = stream[1];
if ((b1 & 0x80) != 0) {
v = ((b1 & 0x7f) << 8) | b2;
v <<= 1;
v >>= 1;
*deltaData = v;
stream += 2;
} else {
v = b1;
v <<= 9;
v >>= 9;
*deltaData = v;
stream += 1;
}
return stream;
}
static void InitStream(SEQ_STREAM* stream, u32 streamDataOffset) {
u16 delta; // r1+0x10
if (streamDataOffset != 0) {
if ((stream->nextAddr = GetStreamValue(ARR_GET(cseq->arrbase, streamDataOffset), &delta,
&stream->nextDelta)) != NULL) {
stream->nextTime = delta;
} else {
stream->nextTime = 0x7fffffff;
}
} else {
stream->nextTime = 0x7fffffff;
}
}
static u16 HandleStream(SEQ_STREAM* stream) {
u16 delta; // r1+0xC
stream->value += stream->nextDelta;
if (stream->nextAddr != NULL) {
if ((stream->nextAddr = GetStreamValue(stream->nextAddr, &delta, &stream->nextDelta)) != NULL) {
stream->nextTime += delta;
} else {
stream->nextTime = 0x7fffffff;
}
} else {
stream->nextTime = 0x7fffffff;
}
return stream->value;
}
static SEQ_EVENT* GenerateNextTrackEvent(u8 trackId) {
TRACK* track; // r29
CPAT* pattern; // r31
SEQ_EVENT* ev; // r30
u32 patternTime; // r28
u32 pitchTime; // r27
u32 modTime; // r26
track = &cseq->track[trackId];
pattern = &cseq->pattern[trackId];
if (track->addr != NULL) {
ev = &cseq->event[trackId];
ev->trackId = trackId;
ev->info.pattern.base = pattern;
if (pattern->addr == NULL) {
null_pattern_addr:
if (track->addr->pattern == 0xffff) {
track->addr = NULL;
return NULL;
} else if (track->addr->pattern == 0xfffe) {
if (cseq->trackSectionTab == NULL) {
if (cseq->section[0].loopDisable) {
track->addr = NULL;
return NULL;
}
} else if (cseq->section[cseq->trackSectionTab[trackId]].loopDisable) {
track->addr = NULL;
return NULL;
}
ev->type = 3;
ev->time = track->addr->time;
track->addr = &track->base[*((u16*)&track->addr->transpose)];
return ev;
}
ev->type = 4;
ev->time = track->addr->time;
ev->info.trackAddr = track->addr;
++track->addr;
return ev;
}
pitchTime = pattern->pitchBend.nextTime;
modTime = pattern->modulation.nextTime;
loop:
patternTime = pattern->addr->time + pattern->lTime;
if (patternTime >= pitchTime) {
goto use_pitch_time;
}
if (patternTime >= modTime) {
goto use_mod_time;
}
if (pattern->addr->key == 0xff && pattern->addr->velocity == 0xff) {
pattern->addr = NULL;
goto null_pattern_addr;
}
ev->info.trackAddr = (TENTRY*)pattern->addr;
pattern->lTime = patternTime;
if ((pattern->addr->key & 0x80) != 0) {
pattern->addr = (NOTE_DATA*)((u8*)pattern->addr + 4);
goto use_pattern_time;
}
if ((pattern->addr->key | pattern->addr->velocity) == 0) {
pattern->addr = (NOTE_DATA*)((u8*)pattern->addr + 4);
goto loop;
}
++pattern->addr;
use_pattern_time:
ev->type = 0;
ev->time = patternTime + pattern->baseTime;
goto end;
use_pitch_time:
if (pitchTime < modTime) {
ev->time = pitchTime + pattern->baseTime;
ev->type = 2;
} else {
use_mod_time:
ev->time = modTime + pattern->baseTime;
ev->type = 1;
}
end:
return ev;
}
return NULL;
}
static void InsertGlobalEvent(SEQ_SECTION* section, SEQ_EVENT* event) {
SEQ_EVENT* el; // r31
SEQ_EVENT* last_el; // r30
last_el = NULL;
el = section->globalEventRoot;
for (; el != NULL; last_el = el, el = el->next) {
if (el->time > event->time) {
event->next = el;
event->prev = last_el;
if (last_el != NULL) {
last_el->next = event;
} else {
section->globalEventRoot = event;
}
el->prev = event;
return;
}
}
event->prev = last_el;
if (last_el != NULL) {
last_el->next = event;
} else {
section->globalEventRoot = event;
}
event->next = NULL;
}
static u32 GetNextEventTime(SEQ_SECTION* section) {
return section->globalEventRoot == NULL ? 0 : section->globalEventRoot->time;
}
static SEQ_EVENT* GetGlobalEvent(SEQ_SECTION* section) {
SEQ_EVENT* ev; // r31
ev = section->globalEventRoot;
if (ev != NULL && ((section->globalEventRoot = ev->next) != NULL)) {
section->globalEventRoot->prev = NULL;
}
return ev;
}