More MusyX structs from DWARF information

Former-commit-id: a989dbd499
This commit is contained in:
Phillip Stephens 2023-02-18 20:27:24 -08:00
parent 1204c8ede6
commit e0fb3afb11
10 changed files with 601 additions and 280 deletions

1
.gitignore vendored
View File

@ -17,3 +17,4 @@ versions/
build.ninja
.ninja_deps
.ninja_log
dwarfD/

View File

@ -11,6 +11,7 @@ typedef signed short s16;
typedef unsigned short u16;
typedef signed long s32;
typedef unsigned long u32;
typedef unsigned long long u64;
typedef float f32;
typedef double f64;

View File

@ -7,83 +7,476 @@
extern "C" {
#endif
typedef struct _SynthInfo {
u32 freq;
u32 _4;
u8 unk[0x208];
u8 voices;
u8 music;
u8 sfx;
u8 studios;
typedef struct SND_STUDIO_INPUT {
// total size: 0x4
unsigned char vol; // offset 0x0, size 0x1
unsigned char volA; // offset 0x1, size 0x1
unsigned char volB; // offset 0x2, size 0x1
unsigned char srcStudio; // offset 0x3, size 0x1
} SND_STUDIO_INPUT;
typedef struct synthInfo {
u32 mixFrq;
u32 numSamples;
SND_PLAYBACKINFO pbInfo;
u8 voiceNum;
u8 maxMusic;
u8 maxSFX;
u8 studioNum;
} SynthInfo;
typedef struct DSPVoice {
char data1[0x18];
u32 _18;
u32 priority;
u32 _20;
u32 flags[5];
char data2[0x70 - 0x38];
u16 sampleId;
u16 _72;
u32 _74;
u32 _78;
u32 _7c;
u32 _80;
u32 _84;
u32 _88;
u32 _8c;
u32 sampleType;
u32 _94;
u32 _98;
u32 _9c;
u32 _a0;
u8 _a4;
u8 _a5;
u8 _a6;
u8 _a7;
u32 _a8;
u32 _ac;
u32 _b0;
u32 _b4;
u32 _b8;
u32 _bc;
u16 _c0;
u16 _c2;
u32 _c4;
u32 _c8;
u32 _cc;
u32 _d0;
u32 _d4;
u32 _d8;
u32 _dc;
u32 _e0;
u8 _e4;
u8 _e5;
u8 _e6;
u8 _e7;
u32 _e8;
u8 status;
u8 _ed;
u8 breakSet;
u8 _ef;
u32 itdFlags;
} DSPVoice;
typedef struct ADSR_VARS {
u8 mode;
u8 state;
u32 cnt;
s32 currentVolume;
s32 currentIndex;
s32 currentDelta;
typedef struct SND_VS {
u8 _0;
u8 _1;
u8 _2;
u8 _3;
u8 unk1[0x908 - 0x4];
u8 _908[64];
u16 _948;
u32 _94c;
} SND_VS;
union data {
struct _dls {
u32 aTime;
u32 dTime;
u16 sLevel;
u32 rTime;
u16 cutOff;
u8 aMode;
} dls;
extern SND_VS vs;
struct _linear {
u32 aTime;
u32 dTime;
u16 sLevel;
u32 rTime;
} linear;
} data;
} ADSR_VARS;
extern DSPVoice* dspVoice;
typedef struct _PBMIX {
// total size: 0x24
unsigned short vL; // offset 0x0, size 0x2
unsigned short vDeltaL; // offset 0x2, size 0x2
unsigned short vR; // offset 0x4, size 0x2
unsigned short vDeltaR; // offset 0x6, size 0x2
unsigned short vAuxAL; // offset 0x8, size 0x2
unsigned short vDeltaAuxAL; // offset 0xA, size 0x2
unsigned short vAuxAR; // offset 0xC, size 0x2
unsigned short vDeltaAuxAR; // offset 0xE, size 0x2
unsigned short vAuxBL; // offset 0x10, size 0x2
unsigned short vDeltaAuxBL; // offset 0x12, size 0x2
unsigned short vAuxBR; // offset 0x14, size 0x2
unsigned short vDeltaAuxBR; // offset 0x16, size 0x2
unsigned short vAuxBS; // offset 0x18, size 0x2
unsigned short vDeltaAuxBS; // offset 0x1A, size 0x2
unsigned short vS; // offset 0x1C, size 0x2
unsigned short vDeltaS; // offset 0x1E, size 0x2
unsigned short vAuxAS; // offset 0x20, size 0x2
unsigned short vDeltaAuxAS; // offset 0x22, size 0x2
} _PBMIX;
typedef struct _PBITD {
// total size: 0xE
unsigned short flag; // offset 0x0, size 0x2
unsigned short bufferHi; // offset 0x2, size 0x2
unsigned short bufferLo; // offset 0x4, size 0x2
unsigned short shiftL; // offset 0x6, size 0x2
unsigned short shiftR; // offset 0x8, size 0x2
unsigned short targetShiftL; // offset 0xA, size 0x2
unsigned short targetShiftR; // offset 0xC, size 0x2
} _PBITD;
typedef struct _PBUPDATE {
// total size: 0xE
unsigned short updNum[5]; // offset 0x0, size 0xA
unsigned short dataHi; // offset 0xA, size 0x2
unsigned short dataLo; // offset 0xC, size 0x2
} _PBUPDATE;
typedef struct _PBDPOP {
// total size: 0x12
unsigned short aL; // offset 0x0, size 0x2
unsigned short aAuxAL; // offset 0x2, size 0x2
unsigned short aAuxBL; // offset 0x4, size 0x2
unsigned short aR; // offset 0x6, size 0x2
unsigned short aAuxAR; // offset 0x8, size 0x2
unsigned short aAuxBR; // offset 0xA, size 0x2
unsigned short aS; // offset 0xC, size 0x2
unsigned short aAuxAS; // offset 0xE, size 0x2
unsigned short aAuxBS; // offset 0x10, size 0x2
} _PBDPOP;
struct _PBVE {
// total size: 0x4
unsigned short currentVolume; // offset 0x0, size 0x2
unsigned short currentDelta; // offset 0x2, size 0x2
} _PBVE;
typedef struct _PBFIR {
// total size: 0x6
unsigned short numCoefs; // offset 0x0, size 0x2
unsigned short coefsHi; // offset 0x2, size 0x2
unsigned short coefsLo; // offset 0x4, size 0x2
} _PBFIR;
typedef struct _PBADDR {
// total size: 0x10
unsigned short loopFlag; // offset 0x0, size 0x2
unsigned short format; // offset 0x2, size 0x2
unsigned short loopAddressHi; // offset 0x4, size 0x2
unsigned short loopAddressLo; // offset 0x6, size 0x2
unsigned short endAddressHi; // offset 0x8, size 0x2
unsigned short endAddressLo; // offset 0xA, size 0x2
unsigned short currentAddressHi; // offset 0xC, size 0x2
unsigned short currentAddressLo; // offset 0xE, size 0x2
} _PBADDR;
typedef struct _PBADPCM {
// total size: 0x28
unsigned short a[8][2]; // offset 0x0, size 0x20
unsigned short gain; // offset 0x20, size 0x2
unsigned short pred_scale; // offset 0x22, size 0x2
unsigned short yn1; // offset 0x24, size 0x2
unsigned short yn2; // offset 0x26, size 0x2
} _PDADPCM;
struct _PBSRC {
// total size: 0xE
unsigned short ratioHi; // offset 0x0, size 0x2
unsigned short ratioLo; // offset 0x2, size 0x2
unsigned short currentAddressFrac; // offset 0x4, size 0x2
unsigned short last_samples[4]; // offset 0x6, size 0x8
} _PBSRC;
typedef struct _PBADPCMLOOP {
// total size: 0x6
unsigned short loop_pred_scale; // offset 0x0, size 0x2
unsigned short loop_yn1; // offset 0x2, size 0x2
unsigned short loop_yn2; // offset 0x4, size 0x2
} _PBADPCMLOOP;
typedef struct _PB {
// total size: 0xBC
unsigned short nextHi; // offset 0x0, size 0x2
unsigned short nextLo; // offset 0x2, size 0x2
unsigned short currHi; // offset 0x4, size 0x2
unsigned short currLo; // offset 0x6, size 0x2
unsigned short srcSelect; // offset 0x8, size 0x2
unsigned short coefSelect; // offset 0xA, size 0x2
unsigned short mixerCtrl; // offset 0xC, size 0x2
unsigned short state; // offset 0xE, size 0x2
unsigned short 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
unsigned short streamLoopCnt; // offset 0xBA, size 0x2
} _PB;
typedef struct SAMPLE_INFO {
// total size: 0x20
u32 info; // offset 0x0, size 0x4
void* addr; // offset 0x4, size 0x4
void* extraData; // offset 0x8, size 0x4
u32 offset; // offset 0xC, size 0x4
u32 length; // offset 0x10, size 0x4
u32 loop; // offset 0x14, size 0x4
u32 loopLength; // offset 0x18, size 0x4
u8 compType; // offset 0x1C, size 0x1
} SAMPLE_INFO;
typedef struct VSampleInfo {
// total size: 0xC
void* loopBufferAddr; // offset 0x0, size 0x4
u32 loopBufferLength; // offset 0x4, size 0x4
u8 inLoopBuffer; // offset 0x8, size 0x1
} VSampleInfo;
typedef struct DSPvoice {
struct _PB* pb;
void* patchData;
void* itdBuffer;
struct DSPvoice* next;
struct DSPvoice* prev;
struct DSPvoice* nextAlien;
u32 mesgCallBackUserValue;
u32 prio;
u32 currentAddr;
u32 changed[5];
u32 pitch[5];
u16 volL;
u16 volR;
u16 volS;
u16 volLa;
u16 volRa;
u16 volSa;
u16 volLb;
u16 volRb;
u16 volSb;
u16 lastVolL;
u16 lastVolR;
u16 lastVolS;
u16 lastVolLa;
u16 lastVolRa;
u16 lastVolSa;
u16 lastVolLb;
u16 lastVolRb;
u16 lastVolSb;
u16 smp_id;
SAMPLE_INFO smp_info;
VSampleInfo vSampleInfo;
u8 streamLoopPS;
ADSR_VARS adsr;
u16 srcTypeSelect;
u16 srcCoefSelect;
u16 itdShiftL;
u16 itdShiftR;
u8 singleOffset;
struct {
u32 posHi;
u32 posLo;
u32 pitch;
} playInfo;
struct {
u8 pitch;
u8 vol;
u8 volA;
u8 volB;
} lastUpdate;
u32 virtualSampleID;
u8 state;
u8 postBreak;
u8 startupBreak;
u8 studio;
u32 flags;
} DSPvoice;
typedef struct VID_LIST {
struct VID_LIST* next;
struct VID_LIST* prev;
u32 vid;
u32 root;
} VID_LIST;
typedef enum {
MAC_STATE_RUNNABLE = 0,
MAC_STATE_YIELDED,
MAC_STATE_STOPPED,
} MAC_STATE;
typedef struct MSTEP {
u32 para[2];
} MSTEP;
typedef struct CALLSTACK {
struct MSTEP* addr;
struct MSTEP* curAddr;
} CALLSTACK;
typedef struct SYNTH_QUEUE {
struct SYNTH_QUEUE* next;
struct SYNTH_QUEUE* prev;
u8 voice;
u8 jobTabIndex;
} SYNTH_QUEUE;
typedef struct SYNTH_LFO {
u32 time;
u32 period;
s16 value;
s16 lastValue;
} SYNTH_LFO;
typedef struct CTRL_SOURCE {
u8 midiCtrl;
u8 combine;
long scale;
} CTRL_SOURCE;
typedef struct CTRL_DEST {
CTRL_SOURCE source[4];
u16 oldValue;
u8 numSource;
} CTRL_DEST;
struct SND_VIRTUALSAMPLE_INFO {
// total size: 0x14
unsigned short smpID; // offset 0x0, size 0x2
unsigned short instID; // offset 0x2, size 0x2
union vsData {
struct vsUpdate {
// total size: 0x10
unsigned long off1; // offset 0x0, size 0x4
unsigned long len1; // offset 0x4, size 0x4
unsigned long off2; // offset 0x8, size 0x4
unsigned long len2; // offset 0xC, size 0x4
} update;
} data;
} SND_VIRTUALSAMPLE_INFO;
typedef struct VS_BUFFER {
// total size: 0x24
unsigned char state; // offset 0x0, size 0x1
unsigned char hwId; // offset 0x1, size 0x1
unsigned char smpType; // offset 0x2, size 0x1
unsigned char voice; // offset 0x3, size 0x1
unsigned long last; // offset 0x4, size 0x4
unsigned long finalGoodSamples; // offset 0x8, size 0x4
unsigned long finalLast; // offset 0xC, size 0x4
struct SND_VIRTUALSAMPLE_INFO info; // offset 0x10, size 0x14
} VS_BUFFER;
typedef struct _VS {
// total size: 0x950
unsigned char numBuffers; // offset 0x0, size 0x1
unsigned long bufferLength; // offset 0x4, size 0x4
struct VS_BUFFER streamBuffer[64]; // offset 0x8, size 0x900
unsigned char voices[64]; // offset 0x908, size 0x40
unsigned short nextInstID; // offset 0x948, size 0x2
unsigned long (*callback)(unsigned char,
struct SND_VIRTUALSAMPLE_INFO*); // offset 0x94C, size 0x4
} VS;
extern VS vs;
#pragma push
#pragma pack(4)
typedef struct SYNTH_VOICE {
SYNTH_QUEUE lowPrecisionJob;
SYNTH_QUEUE zeroOffsetJob; // offset 0xC, size 0xC
SYNTH_QUEUE eventJob; // offset 0x18, size 0xC
u64 lastLowCallTime;
u64 lastZeroCallTime;
MSTEP* addr;
MSTEP* curAddr;
struct SYNTH_VOICE* nextMacActive;
struct SYNTH_VOICE* prevMacActive;
struct SYNTH_VOICE* nextTimeQueueMacro;
struct SYNTH_VOICE* prevTimeQueueMacro;
MAC_STATE state;
MSTEP* trapEventAddr[3];
MSTEP* trapEventCurAddr[3];
u8 trapEventAny;
CALLSTACK callStack[4];
u8 callStackEntryNum;
u8 callStackIndex;
u64 macStartTime;
u64 wait;
u64 waitTime;
u8 timeUsedByInput;
u16 loop;
long local_vars[16];
u32 child;
u32 parent;
u32 id;
VID_LIST* vidList;
VID_LIST* vidListMaster;
u16 allocId;
u16 macroId;
u8 keyGroup;
u32 lastVID;
u8 prio;
u16 ageSpeed;
u32 age;
u64 cFlags;
u8 block;
u8 fxFlag;
u8 vGroup;
u8 studio;
u8 track;
u8 midi;
u8 midiSet;
u8 section;
u32 sInfo;
u32 playFrq;
u16 curNote;
s8 curDetune;
u8 orgNote;
u8 lastNote;
u8 portType;
u16 portLastCtrlState;
u32 portDuration;
u32 portCurPitch;
u32 portTime; // offset 0x13C, size 0x4
u8 vibKeyRange; // offset 0x140, size 0x1
u8 vibCentRange; // offset 0x141, size 0x1
u32 vibPeriod; // offset 0x144, size 0x4
u32 vibCurTime; // offset 0x148, size 0x4
long vibCurOffset; // offset 0x14C, size 0x4
s16 vibModAddScale; // offset 0x150, size 0x2
u32 volume; // offset 0x154, size 0x4
u32 orgVolume; // offset 0x158, size 0x4
float lastVolFaderScale; // offset 0x15C, size 0x4
u32 lastPan; // offset 0x160, size 0x4
u32 lastSPan; // offset 0x164, size 0x4
float treCurScale; // offset 0x168, size 0x4
u16 treScale; // offset 0x16C, size 0x2
u16 treModAddScale; // offset 0x16E, size 0x2
u32 panning[2]; // offset 0x170, size 0x8
long 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
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
u8 sweepNum[2]; // offset 0x1B8, size 0x2
struct 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
s16 pitchADSRRange; // offset 0x204, size 0x2
u16 curPitch; // offset 0x206, size 0x2
struct setup {
u8 vol; // offset 0x0, size 0x1
u8 pan; // offset 0x1, size 0x1
u8 midi; // offset 0x2, size 0x1
u8 midiSet; // offset 0x3, size 0x1
u8 section; // offset 0x4, size 0x1
u8 track; // offset 0x5, size 0x1
u8 vGroup; // offset 0x6, size 0x1
u8 studio; // offset 0x7, size 0x1
u8 itdMode; // offset 0x8, size 0x1
} setup; // offset 0x208, size 0x9
u32 midiDirtyFlags; // offset 0x214, size 0x4
CTRL_DEST inpVolume; // offset 0x218, size 0x24
CTRL_DEST inpPanning; // offset 0x23C, size 0x24
CTRL_DEST inpSurroundPanning; // offset 0x260, size 0x24
CTRL_DEST inpPitchBend; // offset 0x284, size 0x24
CTRL_DEST inpDoppler; // offset 0x2A8, size 0x24
CTRL_DEST inpModulation; // offset 0x2CC, size 0x24
CTRL_DEST inpPedal; // offset 0x2F0, size 0x24
CTRL_DEST inpPortamento; // offset 0x314, size 0x24
CTRL_DEST inpPreAuxA; // offset 0x338, size 0x24
CTRL_DEST inpReverb; // offset 0x35C, size 0x24
CTRL_DEST inpPreAuxB; // offset 0x380, size 0x24
CTRL_DEST inpPostAuxB; // offset 0x3A4, size 0x24
CTRL_DEST inpTremolo; // offset 0x3C8, size 0x24
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
u16 curOutputVolume; // offset 0x400, size 0x2
} SYNTH_VOICE;
#pragma pop
extern SYNTH_VOICE* synthVoice;
extern DSPvoice* dspVoice;
typedef s32 (*SND_COMPARE)(u16*, u8*);
void dataInit(u32, s32); /* extern */
@ -135,7 +528,8 @@ void* salMalloc(u32 len);
void salFree(void* addr);
/* Stream */
typedef s32 (*SND_STREAM_UPDATE_CALLBACK)(void * buffer1, u32 len1, void * buffer2, u32 len2, void* user);
typedef s32 (*SND_STREAM_UPDATE_CALLBACK)(void* buffer1, u32 len1, void* buffer2, u32 len2,
void* user);
typedef struct SND_STREAM_INFO {
u32 x0_;
u32 x4_;

View File

@ -6,31 +6,6 @@
extern "C" {
#endif
typedef struct VoiceID VoiceID;
struct VoiceID {
VoiceID* next;
VoiceID* prev;
s32 pubId;
s32 privId;
};
typedef struct SynthVoice {
char data1[0xf4];
u32 _f4;
VoiceID* voiceId;
char data2[0x18];
u32 _114[2];
u8 _11c;
u8 _11d;
u8 _11e;
u8 studio;
char data3[0x404 - 0x120];
} SynthVoice;
extern SynthVoice* synthVoice;
typedef void (*SND_AUX_CALLBACK)(u8 reason, SND_AUX_INFO* info, void* user);
extern SND_AUX_CALLBACK synthAuxACallback[8];

View File

@ -28,7 +28,7 @@ void snd_handle_irq() {
for (i = 0; i < salNumVoices; ++i) {
for (j = 0; j < 5; ++j) {
dspVoice[i].flags[j] = 0;
dspVoice[i].flags = 0;
}
}
@ -94,74 +94,67 @@ void hwSetTimeOffset(u8 offset) { salTimeOffset = offset; }
u8 hwGetTimeOffset() { return salTimeOffset; }
u32 hwIsActive(s32 idx) { return dspVoice[idx].status != 0; }
u32 hwIsActive(s32 idx) { return dspVoice[idx].state != 0; }
void hwSetMesgCallback(SND_MESSAGE_CALLBACK callback) { salMessageCallback = callback; }
void hwSetPriority(s32 idx, s32 priority) { dspVoice[idx].priority = priority; }
void hwSetPriority(s32 idx, s32 priority) { dspVoice[idx].prio = priority; }
void hwInitSamplePlayback(s32 vid, u16 sampleId, u32* param_3, u32 param_4, u32 priority,
u32 param_6, u32 param_7, u32 itdMode) {
u8 i;
u32 j;
u32 k;
s32 flags;
s32 tmpFlags;
u32* tmp;
u32 tmp2;
u32 tmp3;
flags = 0;
void hwInitSamplePlayback(s32 v, u16 smpID, void* newsmp, u32 set_defadsr, u32 priority,
u32 callbackUserValue, u32 setSRC, u32 itdMode) {
unsigned char i; // r30
unsigned long bf; // r29
DSPvoice* voice;
bf = 0;
for (i = 0; i <= salTimeOffset; ++i) {
tmpFlags = dspVoice[vid].flags[i];
dspVoice[vid].flags[i] = 0;
flags |= tmpFlags & 0x20;
bf |= dspVoice[v].changed[i] & 0x20;
dspVoice[v].changed[i] = 0;
}
dspVoice[vid].flags[0] = flags;
dspVoice[vid].priority = priority;
dspVoice[vid]._18 = param_6;
dspVoice[vid].itdFlags = 0;
dspVoice[vid].sampleId = sampleId;
tmp = &dspVoice[vid]._74;
for (j = 4; j > 0; --j) {
tmp[0] = param_3[0];
tmp[1] = param_3[1];
tmp += 2;
param_3 += 2;
dspVoice[v].changed[0] = bf;
dspVoice[v].prio = priority;
dspVoice[v].mesgCallBackUserValue = callbackUserValue;
dspVoice[v].flags = 0;
dspVoice[v].smp_id = smpID;
voice = &dspVoice[v];
((u32*)&voice->smp_info)[0] = ((u32*)newsmp)[0];
((u32*)&voice->smp_info)[1] = ((u32*)newsmp)[1];
((u32*)&voice->smp_info)[2] = ((u32*)newsmp)[2];
((u32*)&voice->smp_info)[3] = ((u32*)newsmp)[3];
((u32*)&voice->smp_info)[4] = ((u32*)newsmp)[4];
((u32*)&voice->smp_info)[5] = ((u32*)newsmp)[5];
((u32*)&voice->smp_info)[6] = ((u32*)newsmp)[6];
((u32*)&voice->smp_info)[7] = ((u32*)newsmp)[7];
if (set_defadsr != 0) {
dspVoice[v].adsr.mode = 0;
dspVoice[v].adsr.data.dls.aTime = 0;
dspVoice[v].adsr.data.dls.dTime = 0;
dspVoice[v].adsr.data.dls.sLevel = 0x7FFF;
dspVoice[v].adsr.data.dls.rTime = 0;
}
if (param_4 != 0) {
dspVoice[vid]._a4 = 0;
dspVoice[vid]._b8 = 0;
dspVoice[vid]._bc = 0;
dspVoice[vid]._c0 = 0x7FFF;
dspVoice[vid]._c4 = 0;
dspVoice[v].lastUpdate.pitch = 0xff;
dspVoice[v].lastUpdate.vol = 0xff;
dspVoice[v].lastUpdate.volA = 0xff;
dspVoice[v].lastUpdate.volB = 0xff;
if (setSRC != 0) {
hwSetSRCType(v, 0);
hwSetPolyPhaseFilter(v, 1);
}
dspVoice[vid]._e4 = 0xff;
dspVoice[vid]._e5 = 0xff;
dspVoice[vid]._e6 = 0xff;
dspVoice[vid]._e7 = 0xff;
if (param_7 != 0) {
hwSetSRCType(vid, 0);
hwSetPolyPhaseFilter(vid, 1);
}
hwSetITDMode(vid, itdMode);
hwSetITDMode(v, itdMode);
}
void hwBreak(s32 vid) {
if (dspVoice[vid].status == 1 && salTimeOffset == 0) {
dspVoice[vid].breakSet = 1;
if (dspVoice[vid].state == 1 && salTimeOffset == 0) {
dspVoice[vid].startupBreak = 1;
}
dspVoice[vid].flags[salTimeOffset] |= 0x20;
// dspVoice[vid].flags[salTimeOffset] |= 0x20;
}
void hwSetADSR(s32 vid, u32 *param_2, u8 param_3) {
}
void hwSetADSR(s32 vid, u32* param_2, u8 param_3) {}
void hwOff(s32 vid) {
salDeactivateVoice(&dspVoice[vid]);
}
void hwOff(s32 vid) { salDeactivateVoice(&dspVoice[vid]); }

View File

@ -77,7 +77,7 @@ u32 salInitAi(SND_SOME_CALLBACK callback, u32 unk, u32* outFreq) {
userCallback = callback;
AIRegisterDMACallback(salCallback);
AIInitDMA(OSCachedToPhysical((u32)salAIBufferBase) + (salAIBufferIndex * 0x280), 0x280);
synthInfo._4 = 0x20;
synthInfo.numSamples = 0x20;
*outFreq = 32000;
return TRUE;
}

View File

@ -22,21 +22,21 @@ s32 sndInit(u8 voices, u8 music, u8 sfx, u8 studios, u32 flags, u32 aramSize) {
sndActive = 0;
if (voices <= 64) {
synthInfo.voices = voices;
synthInfo.voiceNum = voices;
} else {
synthInfo.voices = 64;
synthInfo.voiceNum = 64;
}
if (studios <= 8) {
synthInfo.studios = studios;
synthInfo.studioNum = studios;
} else {
synthInfo.studios = 8;
synthInfo.studioNum = 8;
}
rate = 32000;
synthInfo.music = music;
synthInfo.sfx = sfx;
ret = hwInit(&rate, synthInfo.voices, synthInfo.studios, flags);
synthInfo.maxMusic = music;
synthInfo.maxSFX = sfx;
ret = hwInit(&rate, synthInfo.voiceNum, synthInfo.studioNum, flags);
if (ret == 0) {
ret = DoInit(32000, aramSize, synthInfo.voices, flags);
ret = DoInit(32000, aramSize, synthInfo.voiceNum, flags);
}
return ret;
}
@ -50,8 +50,8 @@ void sndQuit() {
}
void sndSetMaxVoices(u8 music, u8 sfx) {
ASSERT_MSG(music > synthInfo.voices, "Music voices are above maximum voice number.");
ASSERT_MSG(sfx > synthInfo.voices, "Sfx voices are above maximum voice number.");
synthInfo.music = music;
synthInfo.sfx = sfx;
ASSERT_MSG(music > synthInfo.voiceNum, "Music voices are above maximum voice number.");
ASSERT_MSG(sfx > synthInfo.voiceNum, "Sfx voices are above maximum voice number.");
synthInfo.maxMusic = music;
synthInfo.maxSFX = sfx;
}

View File

@ -1,9 +1,19 @@
#include "musyx/assert.h"
#include "musyx/musyx_priv.h"
#define SYNTH_FX_MIDISET 0xFF
u32 inpGlobalMIDIDirtyFlags[8][16];
s32 midi_ctrl;
typedef struct CHANNEL_DEFAULTS {
unsigned char pbRange;
} CHANNEL_DEFAULTS;
static u8 fx_lastNote[64];
static u8 midi_lastNote[8][16];
static CHANNEL_DEFAULTS inpFXChannelDefaults[64];
static u8 fx_ctrl[64][134];
static CHANNEL_DEFAULTS inpChannelDefaults[8][16];
static u8 midi_ctrl[8][16][134];
static u32 inpGlobalMIDIDirtyFlags[8][16];
inline bool GetGlobalFlagSet(u8 chan, u8 midiSet, s32 flag) {
return (flag & inpGlobalMIDIDirtyFlags[midiSet][chan]) != 0;
@ -32,19 +42,50 @@ void inpSetGlobalMIDIDirtyFlag(u8 chan, u8 midiSet, s32 flag) {
inpGlobalMIDIDirtyFlags[midiSet][chan] |= flag;
}
void inpSetRPNHi(u8 a, u8 b, u8 c) {
void inpSetRPNHi(u8 set, u8 channel, u8 value) {
u16 rpn; // r28
u32 i; // r31
u8 range; // r29
if ((midi_ctrl[set][channel][100] | midi_ctrl[set][channel][101]) != 0) {
return;
}
inpChannelDefaults[set][channel].pbRange = value;
for (i = 0; i < synthInfo.voiceNum; ++i) {
if (set != synthVoice[i].midiSet || channel != synthVoice[i].midi){
continue;
}
synthVoice[i].pbUpperKeyRange = value;
synthVoice[i].pbLowerKeyRange = value;
}
}
void inpSetRPNLo(u8 a, u8 b, u8 c) {
}
void inpSetRPNDec(u8 a, u8 b) {
}
void inpSetRPNInc(u8 a, u8 b) {
void inpSetRPNLo(u8 a, u8 b, u8 c) {}
void inpSetRPNDec(u8 a, u8 b) {}
void inpSetRPNInc(u8 a, u8 b) {}
void inpSetMidiCtrl(u8 ctrl, u8 channel, u8 set, u8 value) {
u32 i;
if (channel == 0xFF) {
return;
}
if (set != 0xFF) {
switch(ctrl) {
case 38:
inpSetRPNInc(0xFF, channel);
break;
case 97:
inpSetRPNInc(0xFF, channel);
break;
case 6:
inpSetRPNHi(0xff, channel, value);
break;
}
} else {
}
}

View File

@ -65,17 +65,9 @@ void sndMasterVolume(u8 volume, u16 time, u8 music, u8 fx) {
hwEnableIrq();
}
static sndSwapVoices(u32* vals) {
u32 tmp = vals[0];
vals[0] = vals[1];
vals[1] = tmp | 0x2000;
}
#if NONMATCHING
/* This function is nearly matching, relevant scratch: https://decomp.me/scratch/WY9Z1 */
void sndOutputMode(SND_OUTPUTMODE output) {
u32 i;
u32 oldSynthFlags = synthFlags;
u32 oldFlags = synthFlags;
switch (output) {
case SND_OUTPUTMODE_MONO:
@ -95,94 +87,15 @@ void sndOutputMode(SND_OUTPUTMODE output) {
break;
}
if (oldSynthFlags == synthFlags) {
if (oldFlags == synthFlags) {
return;
}
/* ???? */
for (i = 0; i < synthInfo.voices; ++i) {
sndSwapVoices((u32*)&synthVoice[i]._114);
for (i = 0; i < synthInfo.voiceNum; ++i) {
synthVoice[i].cFlags |= 0x0000200000000000;
}
streamOutputModeChanged();
}
#else
/* clang-format off */
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
asm void sndOutputMode(SND_OUTPUTMODE output) {
nofralloc
/* 8039C448 003993A8 94 21 FF F0 */ stwu r1, -0x10(r1)
/* 8039C44C 003993AC 7C 08 02 A6 */ mflr r0
/* 8039C450 003993B0 2C 03 00 01 */ cmpwi r3, 1
/* 8039C454 003993B4 90 01 00 14 */ stw r0, 0x14(r1)
/* 8039C458 003993B8 93 E1 00 0C */ stw r31, 0xc(r1)
/* 8039C45C 003993BC 83 ED AE 74 */ lwz r31, synthFlags
/* 8039C460 003993C0 41 82 00 38 */ beq lbl_8039C498
/* 8039C464 003993C4 40 80 00 10 */ bge lbl_8039C474
/* 8039C468 003993C8 2C 03 00 00 */ cmpwi r3, 0
/* 8039C46C 003993CC 40 80 00 14 */ bge lbl_8039C480
/* 8039C470 003993D0 48 00 00 54 */ b lbl_8039C4C4
lbl_8039C474:
/* 8039C474 003993D4 2C 03 00 03 */ cmpwi r3, 3
/* 8039C478 003993D8 40 80 00 4C */ bge lbl_8039C4C4
/* 8039C47C 003993DC 48 00 00 34 */ b lbl_8039C4B0
lbl_8039C480:
/* 8039C480 003993E0 63 E0 00 01 */ ori r0, r31, 1
/* 8039C484 003993E4 90 0D AE 74 */ stw r0, synthFlags
/* 8039C488 003993E8 54 00 07 FA */ rlwinm r0, r0, 0, 0x1f, 0x1d
/* 8039C48C 003993EC 90 0D AE 74 */ stw r0, synthFlags
/* 8039C490 003993F0 48 01 7A 8D */ bl hwDisableHRTF
/* 8039C494 003993F4 48 00 00 30 */ b lbl_8039C4C4
lbl_8039C498:
/* 8039C498 003993F8 57 E3 00 3C */ rlwinm r3, r31, 0, 0, 0x1e
/* 8039C49C 003993FC 57 E0 00 3A */ rlwinm r0, r31, 0, 0, 0x1d
/* 8039C4A0 00399400 90 6D AE 74 */ stw r3, synthFlags
/* 8039C4A4 00399404 90 0D AE 74 */ stw r0, synthFlags
/* 8039C4A8 00399408 48 01 7A 75 */ bl hwDisableHRTF
/* 8039C4AC 0039940C 48 00 00 18 */ b lbl_8039C4C4
lbl_8039C4B0:
/* 8039C4B0 00399410 57 E0 00 3C */ rlwinm r0, r31, 0, 0, 0x1e
/* 8039C4B4 00399414 90 0D AE 74 */ stw r0, synthFlags
/* 8039C4B8 00399418 60 00 00 02 */ ori r0, r0, 2
/* 8039C4BC 0039941C 90 0D AE 74 */ stw r0, synthFlags
/* 8039C4C0 00399420 48 01 7A 5D */ bl hwDisableHRTF
lbl_8039C4C4:
/* 8039C4C4 00399424 80 0D AE 74 */ lwz r0, synthFlags
/* 8039C4C8 00399428 7C 1F 00 40 */ cmplw r31, r0
/* 8039C4CC 0039942C 41 82 00 54 */ beq lbl_8039C520
/* 8039C4D0 00399430 3C 60 80 55 */ lis r3, synthInfo@ha
/* 8039C4D4 00399434 38 E0 00 00 */ li r7, 0
/* 8039C4D8 00399438 38 A3 00 50 */ addi r5, r3, synthInfo@l
/* 8039C4DC 0039943C 38 C0 00 00 */ li r6, 0
/* 8039C4E0 00399440 48 00 00 30 */ b lbl_8039C510
lbl_8039C4E4:
/* 8039C4E4 00399444 80 6D AE 78 */ lwz r3, synthVoice
/* 8039C4E8 00399448 38 06 01 14 */ addi r0, r6, 0x114
/* 8039C4EC 0039944C 38 C6 04 04 */ addi r6, r6, 0x404
/* 8039C4F0 00399450 38 E7 00 01 */ addi r7, r7, 1
/* 8039C4F4 00399454 7C 83 02 14 */ add r4, r3, r0
/* 8039C4F8 00399458 7C 63 02 14 */ add r3, r3, r0
/* 8039C4FC 0039945C 80 04 00 00 */ lwz r0, 0(r4)
/* 8039C500 00399460 80 84 00 04 */ lwz r4, 4(r4)
/* 8039C504 00399464 60 00 20 00 */ ori r0, r0, 0x2000
/* 8039C508 00399468 90 83 00 04 */ stw r4, 4(r3)
/* 8039C50C 0039946C 90 03 00 00 */ stw r0, 0(r3)
lbl_8039C510:
/* 8039C510 00399470 88 05 02 10 */ lbz r0, 0x210(r5)
/* 8039C514 00399474 7C 07 00 40 */ cmplw r7, r0
/* 8039C518 00399478 41 80 FF CC */ blt lbl_8039C4E4
/* 8039C51C 0039947C 48 00 12 81 */ bl streamOutputModeChanged
lbl_8039C520:
/* 8039C520 00399480 80 01 00 14 */ lwz r0, 0x14(r1)
/* 8039C524 00399484 83 E1 00 0C */ lwz r31, 0xc(r1)
/* 8039C528 00399488 7C 08 03 A6 */ mtlr r0
/* 8039C52C 0039948C 38 21 00 10 */ addi r1, r1, 0x10
/* 8039C530 00399490 4E 80 00 20 */ blr
}
#pragma pop
/* clang-format on */
#endif
// clang-format off
void sndSetAuxProcessingCallbacks(u8 studio,
@ -233,10 +146,10 @@ void synthActivateStudio(u8 studio, u32 arg1, u32 arg2) {
void synthDeactivateStudio(u8 studio) {
u32 i;
for (i = 0; i < synthInfo.voices; ++i) {
for (i = 0; i < synthInfo.voiceNum; ++i) {
if (studio == synthVoice[i].studio) {
if (synthVoice[i]._f4 != 0xFFFFFFFF) {
voiceKillSound(synthVoice[i].voiceId->pubId);
if (synthVoice[i].id != 0xFFFFFFFF) {
voiceKillSound(synthVoice[i].vidList->vid);
} else if (hwIsActive(i)) {
hwOff(i);
}
@ -251,7 +164,10 @@ void synthDeactivateStudio(u8 studio) {
hwDeactivateStudio(studio);
}
/* TODO: Figure out what `unk` is */
bool synthAddStudioInput(u8 studio, void* unk) { return hwAddInput(studio, unk); }
bool synthAddStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc) {
return hwAddInput(studio, in_desc);
}
bool synthRemoveStudioInput(u8 studio, void* unk) { return hwRemoveInput(studio, unk); }
bool synthRemoveStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc) {
return hwRemoveInput(studio, in_desc);
}

View File

@ -66,5 +66,5 @@ u32 sndGetPitch(u8 arg0, u32 arg1) {
? (f32)((arg1 & 0xFFFFFF) * (temp_r6 < arg0 ? toneup_tab[(arg0 - temp_r6)]
: tonedown_tab[temp_r6 - arg0]))
: (f32)(arg1 & 0xFFFFFF));
return pitch / synthInfo.freq;
return pitch / synthInfo.mixFrq;
}