mirror of https://github.com/PrimeDecomp/prime.git
Major seq.c progress & musyx header cleanup
Former-commit-id: f60291726a
This commit is contained in:
parent
c58e1e3565
commit
acd57e6a19
|
@ -1,13 +1,13 @@
|
|||
#ifndef _MUSYX_HARDWARE
|
||||
#define _MUSYX_HARDWARE
|
||||
|
||||
|
||||
#include "musyx/musyx_priv.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
u32 hwIsStudioActive(u8 studio);
|
||||
bool hwIsStudioActive(u8 studio);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -434,16 +434,16 @@ bool sndAuxCallbackPrepareChorus(SND_AUX_CHORUS* ch);
|
|||
bool sndAuxCallbackShutdownChorus(SND_AUX_CHORUS* ch);
|
||||
bool sndAuxCallbackUpdateSettingsChorus(SND_AUX_CHORUS* ch);
|
||||
|
||||
#define SND_CROSSFADE_STOP 0 // Stop old song after fadedown
|
||||
#define SND_CROSSFADE_PAUSE 1 // Pause old song after fadedown
|
||||
#define SND_CROSSFADE_CONTINUE 2 // Continue previously paused song as new one
|
||||
#define SND_CROSSFADE_START 0 // Start new song (no continue)
|
||||
#define SND_CROSSFADE_SYNC 4 // Crossfade should start syncronized by sync-controller (104)
|
||||
#define SND_CROSSFADE_PAUSENEW 8 // Pause new song before even starting it
|
||||
#define SND_CROSSFADE_TRACKMUTE 16 // Use trackmute informtion
|
||||
#define SND_CROSSFADE_SPEED 32 // Use speed informtion
|
||||
#define SND_CROSSFADE_MUTE 64 // Old song continues playing & gets muted after fade down
|
||||
#define SND_CROSSFADE_MUTENEW 128 // Mute new song after starting it
|
||||
#define SND_CROSSFADE_STOP 0x0 // Stop old song after fadedown
|
||||
#define SND_CROSSFADE_PAUSE 0x1 // Pause old song after fadedown
|
||||
#define SND_CROSSFADE_CONTINUE 0x2 // Continue previously paused song as new one
|
||||
#define SND_CROSSFADE_START 0x0 // Start new song (no continue)
|
||||
#define SND_CROSSFADE_SYNC 0x4 // Crossfade should start syncronized by sync-controller (104)
|
||||
#define SND_CROSSFADE_PAUSENEW 0x8 // Pause new song before even starting it
|
||||
#define SND_CROSSFADE_TRACKMUTE 0x10 // Use trackmute informtion
|
||||
#define SND_CROSSFADE_SPEED 0x20 // Use speed informtion
|
||||
#define SND_CROSSFADE_MUTE 0x40 // Old song continues playing & gets muted after fade down
|
||||
#define SND_CROSSFADE_MUTENEW 0x80 // Mute new song after starting it
|
||||
|
||||
#define SND_CROSSFADE_DEFAULT 0
|
||||
|
||||
|
@ -517,6 +517,33 @@ typedef struct SND_PROFILE_INFO {
|
|||
|
||||
typedef void (*SND_PROF_USERCALLBACK)(struct SND_PROFILE_INFO*);
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define _MUSYX_MUSYX_PRIV
|
||||
|
||||
#include "musyx/musyx.h"
|
||||
|
||||
#include "musyx/assert.h"
|
||||
#include "musyx/hardware.h"
|
||||
|
||||
|
@ -149,7 +150,7 @@ typedef struct _PBADPCM {
|
|||
u16 pred_scale; // offset 0x22, size 0x2
|
||||
u16 yn1; // offset 0x24, size 0x2
|
||||
u16 yn2; // offset 0x26, size 0x2
|
||||
} _PDADPCM;
|
||||
} _PBADPCM;
|
||||
|
||||
typedef struct _PBSRC {
|
||||
// total size: 0xE
|
||||
|
@ -177,16 +178,16 @@ typedef struct _PB {
|
|||
u16 mixerCtrl; // offset 0xC, size 0x2
|
||||
u16 state; // offset 0xE, size 0x2
|
||||
u16 loopType; // offset 0x10, size 0x2
|
||||
struct _PBMIX mix; // offset 0x12, size 0x24
|
||||
struct _PBITD itd; // offset 0x36, size 0xE
|
||||
struct _PBUPDATE update; // offset 0x44, size 0xE
|
||||
struct _PBDPOP dpop; // offset 0x52, size 0x12
|
||||
struct _PBVE ve; // offset 0x64, size 0x4
|
||||
struct _PBFIR fir; // offset 0x68, size 0x6
|
||||
struct _PBADDR addr; // offset 0x6E, size 0x10
|
||||
struct _PBADPCM adpcm; // offset 0x7E, size 0x28
|
||||
struct _PBSRC src; // offset 0xA6, size 0xE
|
||||
struct _PBADPCMLOOP adpcmLoop; // offset 0xB4, size 0x6
|
||||
_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;
|
||||
|
||||
|
@ -240,13 +241,13 @@ typedef struct SDIR_DATA {
|
|||
u16 ref_cnt; // offset 0x2, size 0x2
|
||||
u32 offset; // offset 0x4, 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
|
||||
} SDIR_DATA;
|
||||
|
||||
typedef struct SDIR_TAB {
|
||||
// total size: 0xC
|
||||
struct SDIR_DATA* data; // offset 0x0, size 0x4
|
||||
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
|
||||
|
@ -283,8 +284,8 @@ typedef struct MAC_SUBTAB {
|
|||
|
||||
typedef struct GSTACK {
|
||||
// total size: 0xC
|
||||
struct GROUP_DATA* gAddr; // offset 0x0, size 0x4
|
||||
struct SDIR_DATA* sdirAddr; // offset 0x4, size 0x4
|
||||
GROUP_DATA* gAddr; // offset 0x0, size 0x4
|
||||
SDIR_DATA* sdirAddr; // offset 0x4, size 0x4
|
||||
void* prjAddr; // offset 0x8, size 0x4
|
||||
} GSTACK;
|
||||
|
||||
|
@ -296,7 +297,7 @@ typedef struct VSampleInfo {
|
|||
} VSampleInfo;
|
||||
|
||||
typedef struct DSPvoice {
|
||||
struct _PB* pb;
|
||||
_PB* pb;
|
||||
void* patchData;
|
||||
void* itdBuffer;
|
||||
struct DSPvoice* next;
|
||||
|
@ -374,8 +375,8 @@ typedef struct MSTEP {
|
|||
} MSTEP;
|
||||
|
||||
typedef struct CALLSTACK {
|
||||
struct MSTEP* addr;
|
||||
struct MSTEP* curAddr;
|
||||
MSTEP* addr;
|
||||
MSTEP* curAddr;
|
||||
} CALLSTACK;
|
||||
|
||||
typedef struct SYNTH_QUEUE {
|
||||
|
@ -407,16 +408,16 @@ typedef struct SYNTH_LFO {
|
|||
|
||||
typedef struct SYNTHMasterFader {
|
||||
// total size: 0x30
|
||||
float volume; // offset 0x0, size 0x4
|
||||
float target; // offset 0x4, size 0x4
|
||||
float start; // offset 0x8, size 0x4
|
||||
float time; // offset 0xC, size 0x4
|
||||
float deltaTime; // offset 0x10, size 0x4
|
||||
float pauseVol; // offset 0x14, size 0x4
|
||||
float pauseTarget; // offset 0x18, size 0x4
|
||||
float pauseStart; // offset 0x1C, size 0x4
|
||||
float pauseTime; // offset 0x20, size 0x4
|
||||
float pauseDeltaTime; // offset 0x24, size 0x4
|
||||
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
|
||||
|
@ -425,7 +426,7 @@ typedef struct SYNTHMasterFader {
|
|||
typedef struct CTRL_SOURCE {
|
||||
u8 midiCtrl;
|
||||
u8 combine;
|
||||
long scale;
|
||||
s32 scale;
|
||||
} CTRL_SOURCE;
|
||||
|
||||
typedef struct CTRL_DEST {
|
||||
|
@ -469,7 +470,7 @@ typedef struct _VS {
|
|||
u8 voices[64]; // offset 0x908, size 0x40
|
||||
u16 nextInstID; // offset 0x948, size 0x2
|
||||
u32 (*callback)(u8,
|
||||
struct SND_VIRTUALSAMPLE_INFO*); // offset 0x94C, size 0x4
|
||||
SND_VIRTUALSAMPLE_INFO*); // offset 0x94C, size 0x4
|
||||
} VS;
|
||||
|
||||
extern VS vs;
|
||||
|
@ -500,7 +501,7 @@ typedef struct SYNTH_VOICE {
|
|||
u64 waitTime;
|
||||
u8 timeUsedByInput;
|
||||
u16 loop;
|
||||
long local_vars[16];
|
||||
s32 local_vars[16];
|
||||
u32 child;
|
||||
u32 parent;
|
||||
u32 id;
|
||||
|
@ -537,37 +538,37 @@ typedef struct SYNTH_VOICE {
|
|||
u8 vibCentRange; // offset 0x141, size 0x1
|
||||
u32 vibPeriod; // offset 0x144, 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
|
||||
u32 volume; // offset 0x154, 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 lastSPan; // offset 0x164, size 0x4
|
||||
float treCurScale; // offset 0x168, size 0x4
|
||||
f32 treCurScale; // offset 0x168, size 0x4
|
||||
u16 treScale; // offset 0x16C, size 0x2
|
||||
u16 treModAddScale; // offset 0x16E, size 0x2
|
||||
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 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
|
||||
long envDelta; // offset 0x194, size 0x4
|
||||
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
|
||||
long sweepAdd[2]; // offset 0x1A8, size 0x8
|
||||
long sweepCnt[2]; // offset 0x1B0, size 0x8
|
||||
s32 sweepAdd[2]; // offset 0x1A8, size 0x8
|
||||
s32 sweepCnt[2]; // offset 0x1B0, size 0x8
|
||||
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 pbLowerKeyRange; // offset 0x1D6, size 0x1
|
||||
u8 pbUpperKeyRange; // offset 0x1D7, size 0x1
|
||||
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
|
||||
u16 curPitch; // offset 0x206, size 0x2
|
||||
struct setup {
|
||||
|
@ -598,7 +599,7 @@ typedef struct SYNTH_VOICE {
|
|||
u8 mesgNum; // offset 0x3EC, size 0x1
|
||||
u8 mesgRead; // offset 0x3ED, 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
|
||||
} SYNTH_VOICE;
|
||||
|
||||
|
@ -658,15 +659,15 @@ typedef struct POOL_DATA {
|
|||
|
||||
typedef struct SAL_VOLINFO {
|
||||
// total size: 0x24
|
||||
float volL; // offset 0x0, size 0x4
|
||||
float volR; // offset 0x4, size 0x4
|
||||
float volS; // offset 0x8, size 0x4
|
||||
float volAuxAL; // offset 0xC, size 0x4
|
||||
float volAuxAR; // offset 0x10, size 0x4
|
||||
float volAuxAS; // offset 0x14, size 0x4
|
||||
float volAuxBL; // offset 0x18, size 0x4
|
||||
float volAuxBR; // offset 0x1C, size 0x4
|
||||
float volAuxBS; // offset 0x20, size 0x4
|
||||
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 {
|
||||
|
@ -677,12 +678,12 @@ typedef struct SAL_PANINFO {
|
|||
u32 span_im; // offset 0xC, size 0x4
|
||||
u32 rpan_i; // offset 0x10, size 0x4
|
||||
u32 rpan_im; // offset 0x14, size 0x4
|
||||
float pan_f; // offset 0x18, size 0x4
|
||||
float pan_fm; // offset 0x1C, size 0x4
|
||||
float span_f; // offset 0x20, size 0x4
|
||||
float span_fm; // offset 0x24, size 0x4
|
||||
float rpan_f; // offset 0x28, size 0x4
|
||||
float rpan_fm; // offset 0x2C, 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 {
|
||||
|
@ -718,15 +719,15 @@ typedef struct _SPB {
|
|||
|
||||
typedef struct DSPhostDPop {
|
||||
// total size: 0x24
|
||||
long l; // offset 0x0, size 0x4
|
||||
long r; // offset 0x4, size 0x4
|
||||
long s; // offset 0x8, size 0x4
|
||||
long lA; // offset 0xC, size 0x4
|
||||
long rA; // offset 0x10, size 0x4
|
||||
long sA; // offset 0x14, size 0x4
|
||||
long lB; // offset 0x18, size 0x4
|
||||
long rB; // offset 0x1C, size 0x4
|
||||
long sB; // offset 0x20, size 0x4
|
||||
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 {
|
||||
|
@ -735,23 +736,23 @@ typedef struct DSPinput {
|
|||
u16 vol; // offset 0x2, size 0x2
|
||||
u16 volA; // offset 0x4, 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;
|
||||
|
||||
typedef struct DSPstudioinfo {
|
||||
// total size: 0xBC
|
||||
struct _SPB* spb; // offset 0x0, size 0x4
|
||||
struct DSPhostDPop hostDPopSum; // offset 0x4, size 0x24
|
||||
long* main[2]; // offset 0x28, size 0x8
|
||||
long* auxA[3]; // offset 0x30, size 0xC
|
||||
long* auxB[3]; // offset 0x3C, size 0xC
|
||||
struct DSPvoice* voiceRoot; // offset 0x48, size 0x4
|
||||
struct DSPvoice* alienVoiceRoot; // offset 0x4C, size 0x4
|
||||
_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
|
||||
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 auxBHandler; // offset 0xB0, size 0x4
|
||||
void* auxAUser; // offset 0xB4, size 0x4
|
||||
|
@ -769,6 +770,7 @@ 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
|
||||
|
@ -785,14 +787,14 @@ typedef struct FX_DATA {
|
|||
// total size: 0xE
|
||||
u16 num; // offset 0x0, 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;
|
||||
|
||||
typedef struct FX_GROUP {
|
||||
// total size: 0x8
|
||||
u16 gid; // offset 0x0, 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;
|
||||
|
||||
typedef struct PAGE {
|
||||
|
@ -825,12 +827,12 @@ typedef struct ADSR_INFO {
|
|||
union ai_data {
|
||||
struct {
|
||||
// total size: 0x14
|
||||
long atime; // offset 0x0, size 0x4
|
||||
long dtime; // offset 0x4, size 0x4
|
||||
s32 atime; // offset 0x0, size 0x4
|
||||
s32 dtime; // offset 0x4, size 0x4
|
||||
u16 slevel; // offset 0x8, size 0x2
|
||||
u16 rtime; // offset 0xA, size 0x2
|
||||
long ascale; // offset 0xC, size 0x4
|
||||
long dscale; // offset 0x10, size 0x4
|
||||
s32 ascale; // offset 0xC, size 0x4
|
||||
s32 dscale; // offset 0x10, size 0x4
|
||||
} dls;
|
||||
struct {
|
||||
// total size: 0x8
|
||||
|
@ -850,7 +852,7 @@ u32 dataInsertMacro(u16 mid, void* macroaddr);
|
|||
u32 dataRemoveMacro(u16 mid);
|
||||
u32 dataInsertCurve(u16 cid, void* curvedata);
|
||||
u32 dataRemoveCurve(u16 sid);
|
||||
long dataGetSample(u16 sid, SAMPLE_INFO* newsmp);
|
||||
s32 dataGetSample(u16 sid, SAMPLE_INFO* newsmp);
|
||||
void* dataGetCurve(u16 cid);
|
||||
u32 dataAddSampleReference(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 */
|
||||
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, 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 hwEnableIrq();
|
||||
void hwDisableIrq();
|
||||
|
@ -885,14 +887,14 @@ void synthSetBpm(u32 pbm, u8 set, u8 section);
|
|||
void synthFXCloneMidiSetup(SYNTH_VOICE* dest, SYNTH_VOICE* src);
|
||||
void synthSetMusicVolumeType(u8 vGroup, u8 type);
|
||||
|
||||
extern long synthGlobalVariable[16];
|
||||
extern s32 synthGlobalVariable[16];
|
||||
extern u16 voicePrioSortRootListRoot;
|
||||
extern u8 voiceMusicRunning;
|
||||
extern u8 voiceFxRunning;
|
||||
extern u8 voiceListInsert;
|
||||
extern u8 voiceListRoot;
|
||||
void voiceSetPriority(struct SYNTH_VOICE* svoice, u8 prio);
|
||||
u32 voiceIsLastStarted(struct SYNTH_VOICE* svoice);
|
||||
void voiceSetPriority(SYNTH_VOICE* svoice, u8 prio);
|
||||
u32 voiceIsLastStarted(SYNTH_VOICE* svoice);
|
||||
s32 voiceKillSound(u32 voiceid);
|
||||
|
||||
extern u64 synthRealTime;
|
||||
|
@ -933,7 +935,7 @@ extern SND_MESSAGE_CALLBACK salMessageCallback;
|
|||
extern SYNTH_MESSAGE_CALLBACK synthMessageCallback;
|
||||
/* Math */
|
||||
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 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 salDeactivateStudio(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,
|
||||
float auxb, u32 itd, u32 dpl2);
|
||||
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);
|
||||
|
@ -1015,8 +1017,9 @@ typedef struct STREAM_INFO {
|
|||
void streamOutputModeChanged();
|
||||
u8 inpTranslateExCtrl(u8 ctrl);
|
||||
void inpSetGlobalMIDIDirtyFlag(u8 chan, u8 midiSet, s32 flag);
|
||||
void inpAddCtrl(struct CTRL_DEST* dest, u8 ctrl, long scale, u8 comb, u32 isVar);
|
||||
void inpSetMidiCtrl(unsigned char ctrl, unsigned char channel, unsigned char set, unsigned char value);
|
||||
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 inpSetMidiCtrl14(unsigned char ctrl, unsigned char channel, unsigned char set, u16 value);
|
||||
void inpSetExCtrl(SYNTH_VOICE* svoice, u8 ctrl, s16 v);
|
||||
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);
|
||||
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);
|
||||
/* TODO: Figure out what `unk` is */
|
||||
void hwSetSRCType(u32 v, u8 salSRCType);
|
||||
void hwSetITDMode(u32 v, u8 mode);
|
||||
|
|
|
@ -9,15 +9,18 @@ extern "C" {
|
|||
|
||||
typedef struct ARR {
|
||||
// total size: 0x58
|
||||
unsigned long tTab; // offset 0x0, size 0x4
|
||||
unsigned long pTab; // offset 0x4, size 0x4
|
||||
unsigned long tmTab; // offset 0x8, size 0x4
|
||||
unsigned long mTrack; // offset 0xC, size 0x4
|
||||
unsigned long info; // offset 0x10, size 0x4
|
||||
unsigned long loopPoint[16]; // offset 0x14, size 0x40
|
||||
unsigned long tsTab; // offset 0x54, size 0x4
|
||||
u32 tTab; // offset 0x0, size 0x4
|
||||
u32 pTab; // offset 0x4, size 0x4
|
||||
u32 tmTab; // offset 0x8, size 0x4
|
||||
u32 mTrack; // offset 0xC, size 0x4
|
||||
u32 info; // offset 0x10, size 0x4
|
||||
u32 loopPoint[16]; // offset 0x14, size 0x40
|
||||
u32 tsTab; // offset 0x54, size 0x4
|
||||
} 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 {
|
||||
// total size: 0xC
|
||||
u32 time; // offset 0x0, size 0x4
|
||||
|
@ -117,7 +120,7 @@ typedef struct TICKS {
|
|||
|
||||
typedef struct SEQ_SECTION {
|
||||
// total size: 0x38
|
||||
struct MTRACK mTrack; // offset 0x0, size 0x8
|
||||
MTRACK mTrack; // offset 0x0, size 0x8
|
||||
u32 bpm; // offset 0x8, size 0x4
|
||||
TICKS tickDelta[2]; // offset 0xC, size 0x10
|
||||
SEQ_EVENT* globalEventRoot; // offset 0x1C, size 0x4
|
||||
|
@ -159,21 +162,30 @@ typedef struct SEQ_INSTANCE {
|
|||
SEQ_SECTION section[16]; // offset 0x14E8, size 0x380
|
||||
} 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 SEQ_INSTANCE seqInstance[8];
|
||||
extern u16 seqMIDIPriority[8][16];
|
||||
|
||||
void seqSpeed(unsigned long seqId, unsigned short speed);
|
||||
void seqVolume(unsigned char volume, unsigned short time, unsigned long seqId, unsigned char mode);
|
||||
void seqSpeed(u32 seqId, u16 speed);
|
||||
void seqVolume(u8 volume, u16 time, u32 seqId, u8 mode);
|
||||
void sndSeqStop(s32 unk);
|
||||
void sndSeqSpeed(u32 seqId, u16 speed);
|
||||
void sndSeqContinue(s32 unk);
|
||||
void sndSeqMute(s32 unk1, s32 unk2, s32 unk3);
|
||||
void sndSeqVolume(unsigned char volume, unsigned short time, unsigned long seqId,
|
||||
unsigned char mode);
|
||||
void seqStop(unsigned long seqId);
|
||||
void sndSeqVolume(u8 volume, u16 time, u32 seqId, u8 mode);
|
||||
u32 sndSeqPlayEx(u16 sgid, u16 sid, void* arrfile, SND_PLAYPARA* para, u8 studio);
|
||||
void seqStop(u32 seqId);
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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* winOpenWindow(s32 x1, s32 y1, s32 x2, s32 y2, char* caption, void* func, u32 flags);
|
||||
|
||||
WXOpenWindow();
|
||||
// WXOpenWindow();
|
||||
|
||||
#ifdef __cpluplus
|
||||
}
|
||||
|
|
|
@ -222,7 +222,7 @@ static void HandleKeyOffNotes() {
|
|||
n = cseq->noteKeyOff;
|
||||
while (n != NULL) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -238,22 +238,43 @@ static void InitPublicIds() { seq_next_id = 0; }
|
|||
static u32 GetPublicId(u32 seqId) {
|
||||
u32 pub_id; // r30
|
||||
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) {
|
||||
SEQ_INSTANCE* si; // r31
|
||||
for (si = seqActiveRoot; si != NULL; si = si->next) {
|
||||
if (si->publicId == (seqId & 0x7fffffff)) {
|
||||
return seqId & 0x80000000 | si->index;
|
||||
if (si->publicId == (seqId & ~SND_SEQ_CROSSFADE_ID)) {
|
||||
return si->index | seqId & SND_SEQ_CROSSFADE_ID;
|
||||
}
|
||||
}
|
||||
for (si = seqPausedRoot; si != NULL; si = si->next) {
|
||||
if (si->publicId == (seqId & 0x7fffffff)) {
|
||||
return seqId & 0x80000000 | si->index;
|
||||
if (si->publicId == (seqId & ~SND_SEQ_CROSSFADE_ID)) {
|
||||
return si->index | seqId & SND_SEQ_CROSSFADE_ID;
|
||||
}
|
||||
}
|
||||
return 0xffffffff;
|
||||
return SND_ID_ERROR;
|
||||
}
|
||||
|
||||
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,
|
||||
u8 studio, u16 sgid) {
|
||||
ARR* arr; // r27
|
||||
|
@ -303,15 +327,15 @@ u32 seqStartPlay(PAGE* norm, PAGE* drum, MIDISETUP* midiSetup, u32* song, SND_PL
|
|||
u32 bpm; // r25
|
||||
|
||||
if ((nseq = seqFreeRoot) == NULL) {
|
||||
return -1;
|
||||
};
|
||||
if ((seqFreeRoot = seqFreeRoot->next) != NULL) {
|
||||
return SND_ID_ERROR;
|
||||
}
|
||||
if ((seqFreeRoot = nseq->next) != NULL) {
|
||||
seqFreeRoot->prev = NULL;
|
||||
}
|
||||
|
||||
if ((nseq->next = seqActiveRoot) != NULL) {
|
||||
seqActiveRoot->prev = nseq;
|
||||
}
|
||||
|
||||
nseq->prev = NULL;
|
||||
seqActiveRoot = nseq;
|
||||
nseq->state = 1;
|
||||
|
@ -340,7 +364,7 @@ u32 seqStartPlay(PAGE* norm, PAGE* drum, MIDISETUP* midiSetup, u32* song, SND_PL
|
|||
nseq->section[i].speed = 256;
|
||||
}
|
||||
|
||||
synthVolume(127, 0, nseq->defVGroup, 0, -1);
|
||||
synthVolume(SND_PAUSEVOL_NORMAL, 0, nseq->defVGroup, 0, SND_ID_ERROR);
|
||||
} else {
|
||||
if (para->flags & SND_PLAYPARA_TRACKMUTE) {
|
||||
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) {
|
||||
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) {
|
||||
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;
|
||||
if (arr->info & 0x80000000) {
|
||||
nseq->trackSectionTab = (u8*)(arr->tsTab + (u32)arr);
|
||||
nseq->trackSectionTab = ARR_GET(arr, arr->tsTab);
|
||||
} else {
|
||||
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);
|
||||
|
||||
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;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
tracktab = &arr->tTab;
|
||||
|
||||
tracktab = ARR_GET(arr, arr->tTab);
|
||||
for (i = 0; i < 64; ++i) {
|
||||
synthTrackVolume[i] = 127;
|
||||
synthTrackVolume[i] = SND_PAUSEVOL_NORMAL;
|
||||
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) {
|
||||
|
@ -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) {
|
||||
return;
|
||||
}
|
||||
|
@ -479,11 +552,11 @@ void seqPause(u32 seqId) {
|
|||
SEQ_INSTANCE* si; // r31
|
||||
seqId = seqGetPrivateId(seqId);
|
||||
|
||||
if (seqId == -1) {
|
||||
if (seqId == SND_SEQ_ERROR_ID) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(seqId & 0x80000000)) {
|
||||
if ((seqId & SND_SEQ_CROSSFADE_ID) == 0) {
|
||||
si = &seqInstance[seqId];
|
||||
if (si->state == 1) {
|
||||
StartPause(si);
|
||||
|
@ -491,22 +564,21 @@ void seqPause(u32 seqId) {
|
|||
ResetNotes(si);
|
||||
}
|
||||
} else {
|
||||
si = &seqInstance[seqId & 0x7fffffff];
|
||||
si = &seqInstance[seqId & ~SND_SEQ_CROSSFADE_ID];
|
||||
if (si->state != 0) {
|
||||
si->syncCrossInfo.flags |= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void seqStop(unsigned long seqId) {
|
||||
void seqStop(u32 seqId) {
|
||||
SEQ_INSTANCE* si; // r31
|
||||
;
|
||||
|
||||
if ((seqId = seqGetPrivateId(seqId)) == -1) {
|
||||
if ((seqId = seqGetPrivateId(seqId)) == SND_SEQ_ERROR_ID) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(seqId & 0x80000000)) {
|
||||
if ((seqId & SND_SEQ_CROSSFADE_ID) == 0) {
|
||||
si = &seqInstance[seqId];
|
||||
switch (si->state) {
|
||||
case 1:
|
||||
|
@ -539,7 +611,7 @@ void seqStop(unsigned long seqId) {
|
|||
si->prev = NULL;
|
||||
seqFreeRoot = si;
|
||||
} else {
|
||||
si = &seqInstance[seqId & 0x7fffffff];
|
||||
si = &seqInstance[seqId & ~SND_SEQ_CROSSFADE_ID];
|
||||
if (si->state != 0) {
|
||||
si->syncSeqIdPtr = NULL;
|
||||
}
|
||||
|
@ -557,7 +629,7 @@ void seqKillAllInstances() {
|
|||
}
|
||||
}
|
||||
|
||||
void seqKillInstancesByGroupID(unsigned short sgid) {
|
||||
void seqKillInstancesByGroupID(u16 sgid) {
|
||||
SEQ_INSTANCE* si; // r31
|
||||
|
||||
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
|
||||
|
||||
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) {
|
||||
seqInstance[seqId].section[i].speed = speed;
|
||||
}
|
||||
} else {
|
||||
seqId &= 0x7FFFFFFF;
|
||||
seqInstance[seqId].syncCrossInfo.flags |= 0x20;
|
||||
seqId &= ~SND_SEQ_CROSSFADE_ID;
|
||||
seqInstance[seqId].syncCrossInfo.flags |= SND_CROSSFADE_SPEED;
|
||||
seqInstance[seqId].syncCrossInfo.speed2 = speed;
|
||||
}
|
||||
}
|
||||
|
@ -593,9 +666,10 @@ void seqContinue(u32 seqId) {
|
|||
struct SEQ_INSTANCE* si; // r31
|
||||
|
||||
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];
|
||||
|
||||
if (si->state == 2) {
|
||||
|
@ -618,130 +692,370 @@ void seqContinue(u32 seqId) {
|
|||
si->state = 1;
|
||||
}
|
||||
} 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);
|
||||
if (seqId == 0xffffffff) {
|
||||
if (seqId == SND_SEQ_ERROR_ID) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(seqId & 0x80000000)) {
|
||||
if ((seqId & SND_SEQ_CROSSFADE_ID) == 0) {
|
||||
seqInstance[seqId].trackMute[0] = mask1;
|
||||
seqInstance[seqId].trackMute[1] = mask2;
|
||||
} else {
|
||||
seqId &= 0x7fffffff;
|
||||
seqInstance[seqId].syncCrossInfo.flags |= 0x10;
|
||||
seqId &= ~SND_SEQ_CROSSFADE_ID;
|
||||
seqInstance[seqId].syncCrossInfo.flags |= SND_CROSSFADE_TRACKMUTE;
|
||||
seqInstance[seqId].syncCrossInfo.trackMute2[0] = mask1;
|
||||
seqInstance[seqId].syncCrossInfo.trackMute2[1] = mask2;
|
||||
}
|
||||
}
|
||||
|
||||
void seqVolume(unsigned char volume, unsigned short time, unsigned long seqId, unsigned char mode) {
|
||||
unsigned long i; // r29
|
||||
unsigned long pub_id; // r27
|
||||
// TODO
|
||||
// pub_id = seqId;
|
||||
seqId = seqGetPrivateId(seqId);
|
||||
void seqVolume(u8 volume, u16 time, u32 seqId, u8 mode) {
|
||||
u32 i; // r29
|
||||
u32 pub_id; // r27
|
||||
|
||||
if (seqId == -1) {
|
||||
pub_id = seqId;
|
||||
seqId = seqGetPrivateId(seqId);
|
||||
if (seqId == SND_SEQ_ERROR_ID) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(seqId & 0x80000000)) {
|
||||
if ((seqId & SND_SEQ_CROSSFADE_ID) == 0) {
|
||||
synthVolume(volume, time, seqInstance[seqId].defVGroup, mode, pub_id);
|
||||
for (i = 0; i < 64; ++i) {
|
||||
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 {
|
||||
seqId &= 0x7fffffff;
|
||||
switch (mode & 0xf) {
|
||||
case 0:
|
||||
seqId &= ~SND_SEQ_CROSSFADE_ID;
|
||||
switch (mode & SND_SEQVOL_MODEMASK) {
|
||||
case SND_SEQVOL_CONTINUE:
|
||||
seqInstance[seqId].syncCrossInfo.vol2 = volume;
|
||||
break;
|
||||
case 1:
|
||||
case SND_SEQVOL_STOP:
|
||||
seqInstance[seqId].syncSeqIdPtr = NULL;
|
||||
break;
|
||||
case 2:
|
||||
seqInstance[seqId].syncCrossInfo.flags |= 8;
|
||||
case SND_SEQVOL_PAUSE:
|
||||
seqInstance[seqId].syncCrossInfo.flags |= SND_CROSSFADE_PAUSENEW;
|
||||
seqInstance[seqId].syncCrossInfo.vol2 = volume;
|
||||
break;
|
||||
case 3:
|
||||
seqInstance[seqId].syncCrossInfo.flags |= 0x80;
|
||||
case SND_SEQVOL_MUTE:
|
||||
seqInstance[seqId].syncCrossInfo.flags |= SND_CROSSFADE_MUTENEW;
|
||||
seqInstance[seqId].syncCrossInfo.vol2 = volume;
|
||||
break;
|
||||
default:
|
||||
#line 1153
|
||||
MUSY_FATAL("Illegal sequencere fade mode detected.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: very incomplete
|
||||
void seqCrossFade(SND_CROSSFADE* ci, unsigned long* new_seqId, unsigned char irq_call) {
|
||||
void seqCrossFade(SND_CROSSFADE* ci, u32* new_seqId, bool8 irq_call) {
|
||||
SND_PLAYPARA pp; // r1+0x14
|
||||
unsigned long seqId; // r29
|
||||
unsigned short time; // r27
|
||||
seqId = seqGetPrivateId(ci->seqId1);
|
||||
u32 seqId; // r29
|
||||
u16 time; // r27
|
||||
|
||||
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].syncActive = TRUE;
|
||||
seqInstance[seqId].syncSeqIdPtr = new_seqId;
|
||||
seqInstance[seqId].syncCrossInfo.flags &= ~0x4;
|
||||
*new_seqId = ci->seqId1 | 0x80000000;
|
||||
seqInstance[seqId].syncCrossInfo.flags &= ~SND_CROSSFADE_SYNC;
|
||||
*new_seqId = ci->seqId1 | SND_SEQ_CROSSFADE_ID;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((irq_call & 0xff) != 0) {
|
||||
time = 5;
|
||||
if (ci->time1 > 4) {
|
||||
time = ci->time1;
|
||||
}
|
||||
|
||||
if ((ci->flags & 0x1) != 0) {
|
||||
seqVolume(0, time, seqId, 2);
|
||||
} else if ((ci->flags & 0x40) != 0) {
|
||||
seqVolume(0, time, seqId, 3);
|
||||
if (irq_call) {
|
||||
time = ci->time1 < 5 ? 5 : ci->time1;
|
||||
if ((ci->flags & SND_CROSSFADE_PAUSE) != 0) {
|
||||
seqVolume(0, time, ci->seqId1, SND_SEQVOL_PAUSE);
|
||||
} else if ((ci->flags & SND_CROSSFADE_MUTE) != 0) {
|
||||
seqVolume(0, time, ci->seqId1, SND_SEQVOL_MUTE);
|
||||
} 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 ((ci->flags & 0x2) != 0) {
|
||||
seqId = seqGetPrivateId(ci->seqId2);
|
||||
if (seqId != 0xffffffff) {
|
||||
if ((irq_call & 0xff) != 0) {
|
||||
seqStop(ci->seqId2);
|
||||
if (new_seqId == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ci->flags & SND_CROSSFADE_CONTINUE) != 0) {
|
||||
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 {
|
||||
sndSeqContinue(ci->seqId2);
|
||||
sndSeqVolume(ci->vol2, ci->time2, ci->seqId2, 0);
|
||||
if ((ci->flags & 0x10) != 0) {
|
||||
sndSeqVolume(ci->vol2, ci->time2, ci->seqId2, SND_SEQVOL_CONTINUE);
|
||||
if ((ci->flags & SND_CROSSFADE_TRACKMUTE) != 0) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
*new_seqId = ci->seqId2;
|
||||
} else {
|
||||
*new_seqId = 0xffffffff;
|
||||
*new_seqId = SND_SEQ_ERROR_ID;
|
||||
}
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ci->flags & 0x1) != 0) {
|
||||
sndSeqVolume(0, ci->time1, seqId, 2);
|
||||
} else if ((ci->flags & 0x40) != 0) {
|
||||
sndSeqVolume(0, ci->time1, seqId, 3);
|
||||
event->prev = last_el;
|
||||
if (last_el != NULL) {
|
||||
last_el->next = event;
|
||||
} else {
|
||||
sndSeqVolume(0, ci->time1, seqId, 1);
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue