mirror of https://github.com/PrimeDecomp/prime.git
parent
e0fb3afb11
commit
b750480182
|
@ -107,6 +107,13 @@ void sndSilence();
|
||||||
#define SND_AUX_REASON_BUFFERUPDATE 0
|
#define SND_AUX_REASON_BUFFERUPDATE 0
|
||||||
#define SND_AUX_REASON_PARAMETERUPDATE 1
|
#define SND_AUX_REASON_PARAMETERUPDATE 1
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SND_STUDIO_TYPE_STD = 0,
|
||||||
|
SND_STUDIO_TYPE_RESERVED0 = 1,
|
||||||
|
SND_STUDIO_TYPE_RESERVED1 = 2,
|
||||||
|
SND_STUDIO_TYPE_RESERVED2 = 3,
|
||||||
|
} SND_STUDIO_TYPE;
|
||||||
|
|
||||||
typedef struct SND_AUX_INFO {
|
typedef struct SND_AUX_INFO {
|
||||||
union SND_AUX_DATA {
|
union SND_AUX_DATA {
|
||||||
struct SND_AUX_BUFFERUPDATE {
|
struct SND_AUX_BUFFERUPDATE {
|
||||||
|
@ -173,6 +180,8 @@ typedef struct SND_AUX_DELAY {
|
||||||
u32 output[3]; // Output volume in % per channel
|
u32 output[3]; // Output volume in % per channel
|
||||||
} SND_AUX_DELAY;
|
} SND_AUX_DELAY;
|
||||||
|
|
||||||
|
typedef void (*SND_AUX_CALLBACK)(u8 reason, SND_AUX_INFO* info, void* user);
|
||||||
|
|
||||||
void sndAuxCallbackDelay(u8 reason, SND_AUX_INFO* info, void* user);
|
void sndAuxCallbackDelay(u8 reason, SND_AUX_INFO* info, void* user);
|
||||||
bool sndAuxCallbackUpdateSettingsDelay(SND_AUX_DELAY* delay);
|
bool sndAuxCallbackUpdateSettingsDelay(SND_AUX_DELAY* delay);
|
||||||
bool sndAuxCallbackPrepareDelay(SND_AUX_DELAY* rev);
|
bool sndAuxCallbackPrepareDelay(SND_AUX_DELAY* rev);
|
||||||
|
|
|
@ -105,7 +105,7 @@ typedef struct _PBDPOP {
|
||||||
unsigned short aAuxBS; // offset 0x10, size 0x2
|
unsigned short aAuxBS; // offset 0x10, size 0x2
|
||||||
} _PBDPOP;
|
} _PBDPOP;
|
||||||
|
|
||||||
struct _PBVE {
|
typedef struct _PBVE {
|
||||||
// total size: 0x4
|
// total size: 0x4
|
||||||
unsigned short currentVolume; // offset 0x0, size 0x2
|
unsigned short currentVolume; // offset 0x0, size 0x2
|
||||||
unsigned short currentDelta; // offset 0x2, size 0x2
|
unsigned short currentDelta; // offset 0x2, size 0x2
|
||||||
|
@ -139,7 +139,7 @@ typedef struct _PBADPCM {
|
||||||
unsigned short yn2; // offset 0x26, size 0x2
|
unsigned short yn2; // offset 0x26, size 0x2
|
||||||
} _PDADPCM;
|
} _PDADPCM;
|
||||||
|
|
||||||
struct _PBSRC {
|
typedef struct _PBSRC {
|
||||||
// total size: 0xE
|
// total size: 0xE
|
||||||
unsigned short ratioHi; // offset 0x0, size 0x2
|
unsigned short ratioHi; // offset 0x0, size 0x2
|
||||||
unsigned short ratioLo; // offset 0x2, size 0x2
|
unsigned short ratioLo; // offset 0x2, size 0x2
|
||||||
|
@ -306,7 +306,7 @@ typedef struct CTRL_DEST {
|
||||||
u8 numSource;
|
u8 numSource;
|
||||||
} CTRL_DEST;
|
} CTRL_DEST;
|
||||||
|
|
||||||
struct SND_VIRTUALSAMPLE_INFO {
|
typedef struct SND_VIRTUALSAMPLE_INFO {
|
||||||
// total size: 0x14
|
// total size: 0x14
|
||||||
unsigned short smpID; // offset 0x0, size 0x2
|
unsigned short smpID; // offset 0x0, size 0x2
|
||||||
unsigned short instID; // offset 0x2, size 0x2
|
unsigned short instID; // offset 0x2, size 0x2
|
||||||
|
@ -474,6 +474,95 @@ typedef struct SYNTH_VOICE {
|
||||||
u16 curOutputVolume; // offset 0x400, size 0x2
|
u16 curOutputVolume; // offset 0x400, size 0x2
|
||||||
} SYNTH_VOICE;
|
} SYNTH_VOICE;
|
||||||
#pragma pop
|
#pragma pop
|
||||||
|
|
||||||
|
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
|
||||||
|
} SAL_VOLINFO;
|
||||||
|
|
||||||
|
typedef struct _SPB {
|
||||||
|
// total size: 0x36
|
||||||
|
unsigned short dpopLHi; // offset 0x0, size 0x2
|
||||||
|
unsigned short dpopLLo; // offset 0x2, size 0x2
|
||||||
|
unsigned short dpopLDelta; // offset 0x4, size 0x2
|
||||||
|
unsigned short dpopRHi; // offset 0x6, size 0x2
|
||||||
|
unsigned short dpopRLo; // offset 0x8, size 0x2
|
||||||
|
unsigned short dpopRDelta; // offset 0xA, size 0x2
|
||||||
|
unsigned short dpopSHi; // offset 0xC, size 0x2
|
||||||
|
unsigned short dpopSLo; // offset 0xE, size 0x2
|
||||||
|
unsigned short dpopSDelta; // offset 0x10, size 0x2
|
||||||
|
unsigned short dpopALHi; // offset 0x12, size 0x2
|
||||||
|
unsigned short dpopALLo; // offset 0x14, size 0x2
|
||||||
|
unsigned short dpopALDelta; // offset 0x16, size 0x2
|
||||||
|
unsigned short dpopARHi; // offset 0x18, size 0x2
|
||||||
|
unsigned short dpopARLo; // offset 0x1A, size 0x2
|
||||||
|
unsigned short dpopARDelta; // offset 0x1C, size 0x2
|
||||||
|
unsigned short dpopASHi; // offset 0x1E, size 0x2
|
||||||
|
unsigned short dpopASLo; // offset 0x20, size 0x2
|
||||||
|
unsigned short dpopASDelta; // offset 0x22, size 0x2
|
||||||
|
unsigned short dpopBLHi; // offset 0x24, size 0x2
|
||||||
|
unsigned short dpopBLLo; // offset 0x26, size 0x2
|
||||||
|
unsigned short dpopBLDelta; // offset 0x28, size 0x2
|
||||||
|
unsigned short dpopBRHi; // offset 0x2A, size 0x2
|
||||||
|
unsigned short dpopBRLo; // offset 0x2C, size 0x2
|
||||||
|
unsigned short dpopBRDelta; // offset 0x2E, size 0x2
|
||||||
|
unsigned short dpopBSHi; // offset 0x30, size 0x2
|
||||||
|
unsigned short dpopBSLo; // offset 0x32, size 0x2
|
||||||
|
unsigned short dpopBSDelta; // offset 0x34, size 0x2
|
||||||
|
} _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
|
||||||
|
} DSPhostDPop;
|
||||||
|
|
||||||
|
typedef struct DSPinput {
|
||||||
|
// total size: 0xC
|
||||||
|
unsigned char studio; // offset 0x0, size 0x1
|
||||||
|
unsigned short vol; // offset 0x2, size 0x2
|
||||||
|
unsigned short volA; // offset 0x4, size 0x2
|
||||||
|
unsigned short volB; // offset 0x6, size 0x2
|
||||||
|
struct 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
|
||||||
|
unsigned char state; // offset 0x50, size 0x1
|
||||||
|
unsigned char isMaster; // offset 0x51, size 0x1
|
||||||
|
unsigned char numInputs; // offset 0x52, size 0x1
|
||||||
|
SND_STUDIO_TYPE type; // offset 0x54, size 0x4
|
||||||
|
struct DSPinput in[7]; // offset 0x58, size 0x54
|
||||||
|
SND_AUX_CALLBACK auxAHandler; // offset 0xAC, size 0x4
|
||||||
|
SND_AUX_CALLBACK auxBHandler; // offset 0xB0, size 0x4
|
||||||
|
void* auxAUser; // offset 0xB4, size 0x4
|
||||||
|
void* auxBUser; // offset 0xB8, size 0x4
|
||||||
|
} DSPstudioinfo;
|
||||||
|
|
||||||
|
extern DSPstudioinfo dspStudio[8];
|
||||||
|
|
||||||
extern SYNTH_VOICE* synthVoice;
|
extern SYNTH_VOICE* synthVoice;
|
||||||
|
|
||||||
extern DSPvoice* dspVoice;
|
extern DSPvoice* dspVoice;
|
||||||
|
@ -500,7 +589,7 @@ u8* sndBSearch(u16* key, u8* subTab, s32 mainTab, s32 len, SND_COMPARE cmp);
|
||||||
void sndConvertMs(u32* time);
|
void sndConvertMs(u32* time);
|
||||||
void sndConvertTicks(u32* out, u32 seconds);
|
void sndConvertTicks(u32* out, u32 seconds);
|
||||||
u32 sndConvert2Ms(u32 time);
|
u32 sndConvert2Ms(u32 time);
|
||||||
void hwActivateStudio(u8 studio, u32 arg1, u32 arg2);
|
void hwActivateStudio(unsigned char studio, unsigned long isMaster, SND_STUDIO_TYPE type);
|
||||||
void hwDeactivateStudio(u8);
|
void hwDeactivateStudio(u8);
|
||||||
u32 hwIsActive(s32);
|
u32 hwIsActive(s32);
|
||||||
|
|
||||||
|
@ -523,7 +612,12 @@ u32 salInitAi(SND_SOME_CALLBACK, u32, u32*);
|
||||||
u32 salInitDsp(u32);
|
u32 salInitDsp(u32);
|
||||||
u32 salInitDspCtrl(u32, u32, u16);
|
u32 salInitDspCtrl(u32, u32, u16);
|
||||||
u32 salStartAi();
|
u32 salStartAi();
|
||||||
|
void salActivateStudio(u8 studio, u32 isMaster, SND_STUDIO_TYPE type);
|
||||||
|
void salDeactivateStudio(unsigned char 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 salReconnectVoice(DSPvoice* dsp_vptr, u8 studio);
|
||||||
void* salMalloc(u32 len);
|
void* salMalloc(u32 len);
|
||||||
void salFree(void* addr);
|
void salFree(void* addr);
|
||||||
|
|
||||||
|
@ -546,12 +640,24 @@ typedef struct SND_STREAM_INFO {
|
||||||
void streamOutputModeChanged();
|
void streamOutputModeChanged();
|
||||||
|
|
||||||
/* TODO: Figure out what `unk` is */
|
/* TODO: Figure out what `unk` is */
|
||||||
bool hwAddInput(u8 studio, void* unk);
|
void hwSetSRCType(u32 v, u8 salSRCType);
|
||||||
bool hwRemoveInput(u8 studio, void* unk);
|
void hwSetITDMode(u32 v, u8 mode);
|
||||||
|
void hwSetPolyPhaseFilter(unsigned long v, unsigned char salCoefSel);
|
||||||
|
bool hwAddInput(u8 studio, SND_STUDIO_INPUT* in_desc);
|
||||||
|
bool hwRemoveInput(u8 studio, SND_STUDIO_INPUT* in_desc);
|
||||||
|
void hwChangeStudio(u32 v, u8 studio);
|
||||||
void hwDisableHRTF();
|
void hwDisableHRTF();
|
||||||
|
|
||||||
extern u32 dspCmdList;
|
extern u32 dspCmdList;
|
||||||
extern u16 dspCmdFirstSize;
|
extern u16 dspCmdFirstSize;
|
||||||
|
|
||||||
|
extern u8 dspScale2IndexTab[1024];
|
||||||
|
|
||||||
|
u32 aramGetStreamBufferAddress(unsigned char id, unsigned long* len);
|
||||||
|
void aramUploadData(void* mram, unsigned long aram, unsigned long len, unsigned long highPrio,
|
||||||
|
void (*callback)(unsigned long), unsigned long user);
|
||||||
|
void aramFreeStreamBuffer(u8 id);
|
||||||
|
void * aramStoreData(void * src, unsigned long len);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef void (*SND_AUX_CALLBACK)(u8 reason, SND_AUX_INFO* info, void* user);
|
|
||||||
|
|
||||||
extern SND_AUX_CALLBACK synthAuxACallback[8];
|
extern SND_AUX_CALLBACK synthAuxACallback[8];
|
||||||
extern u8 synthAuxAMIDI[8];
|
extern u8 synthAuxAMIDI[8];
|
||||||
extern u8 synthAuxAMIDISet[8];
|
extern u8 synthAuxAMIDISet[8];
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
#include "musyx/musyx_priv.h"
|
#include "musyx/musyx_priv.h"
|
||||||
|
|
||||||
|
static u16 itdOffTab[128] = {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
|
||||||
|
2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8,
|
||||||
|
9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 16, 16, 17,
|
||||||
|
17, 17, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 25,
|
||||||
|
25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30,
|
||||||
|
31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
||||||
|
};
|
||||||
|
|
||||||
u8 salFrame;
|
u8 salFrame;
|
||||||
u8 salAuxFrame;
|
u8 salAuxFrame;
|
||||||
u8 salNumVoices;
|
u8 salNumVoices;
|
||||||
|
@ -28,7 +37,7 @@ void snd_handle_irq() {
|
||||||
|
|
||||||
for (i = 0; i < salNumVoices; ++i) {
|
for (i = 0; i < salNumVoices; ++i) {
|
||||||
for (j = 0; j < 5; ++j) {
|
for (j = 0; j < 5; ++j) {
|
||||||
dspVoice[i].flags = 0;
|
dspVoice[i].changed[j] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +113,6 @@ void hwInitSamplePlayback(s32 v, u16 smpID, void* newsmp, u32 set_defadsr, u32 p
|
||||||
u32 callbackUserValue, u32 setSRC, u32 itdMode) {
|
u32 callbackUserValue, u32 setSRC, u32 itdMode) {
|
||||||
unsigned char i; // r30
|
unsigned char i; // r30
|
||||||
unsigned long bf; // r29
|
unsigned long bf; // r29
|
||||||
DSPvoice* voice;
|
|
||||||
bf = 0;
|
bf = 0;
|
||||||
for (i = 0; i <= salTimeOffset; ++i) {
|
for (i = 0; i <= salTimeOffset; ++i) {
|
||||||
bf |= dspVoice[v].changed[i] & 0x20;
|
bf |= dspVoice[v].changed[i] & 0x20;
|
||||||
|
@ -116,16 +124,8 @@ void hwInitSamplePlayback(s32 v, u16 smpID, void* newsmp, u32 set_defadsr, u32 p
|
||||||
dspVoice[v].mesgCallBackUserValue = callbackUserValue;
|
dspVoice[v].mesgCallBackUserValue = callbackUserValue;
|
||||||
dspVoice[v].flags = 0;
|
dspVoice[v].flags = 0;
|
||||||
dspVoice[v].smp_id = smpID;
|
dspVoice[v].smp_id = smpID;
|
||||||
voice = &dspVoice[v];
|
dspVoice[v].smp_info = *(SAMPLE_INFO*)newsmp;
|
||||||
((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) {
|
if (set_defadsr != 0) {
|
||||||
dspVoice[v].adsr.mode = 0;
|
dspVoice[v].adsr.mode = 0;
|
||||||
dspVoice[v].adsr.data.dls.aTime = 0;
|
dspVoice[v].adsr.data.dls.aTime = 0;
|
||||||
|
@ -152,9 +152,282 @@ void hwBreak(s32 vid) {
|
||||||
dspVoice[vid].startupBreak = 1;
|
dspVoice[vid].startupBreak = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// dspVoice[vid].flags[salTimeOffset] |= 0x20;
|
dspVoice[vid].changed[salTimeOffset] |= 0x20;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hwSetADSR(s32 vid, u32* param_2, u8 param_3) {}
|
typedef struct ADSR_INFO {
|
||||||
|
// total size: 0x14
|
||||||
|
union ai_data {
|
||||||
|
struct {
|
||||||
|
// total size: 0x14
|
||||||
|
long atime; // offset 0x0, size 0x4
|
||||||
|
long dtime; // offset 0x4, size 0x4
|
||||||
|
unsigned short slevel; // offset 0x8, size 0x2
|
||||||
|
unsigned short rtime; // offset 0xA, size 0x2
|
||||||
|
long ascale; // offset 0xC, size 0x4
|
||||||
|
long dscale; // offset 0x10, size 0x4
|
||||||
|
} dls;
|
||||||
|
struct {
|
||||||
|
// total size: 0x8
|
||||||
|
unsigned short atime; // offset 0x0, size 0x2
|
||||||
|
unsigned short dtime; // offset 0x2, size 0x2
|
||||||
|
unsigned short slevel; // offset 0x4, size 0x2
|
||||||
|
unsigned short rtime; // offset 0x6, size 0x2
|
||||||
|
} linear;
|
||||||
|
} data; // offset 0x0, size 0x14
|
||||||
|
} ADSR_INFO;
|
||||||
|
|
||||||
|
void hwSetADSR(u32 v, void* _adsr, u8 mode) {
|
||||||
|
u32 sl; // r29
|
||||||
|
ADSR_INFO* adsr = (ADSR_INFO*)_adsr; // r30
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case 0: {
|
||||||
|
dspVoice[v].adsr.mode = 0;
|
||||||
|
dspVoice[v].adsr.data.linear.aTime = adsr->data.linear.atime;
|
||||||
|
dspVoice[v].adsr.data.linear.dTime = adsr->data.linear.dtime;
|
||||||
|
sl = adsr->data.linear.slevel << 3;
|
||||||
|
if (sl > 0x7fff) {
|
||||||
|
sl = 0x7fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
dspVoice[v].adsr.data.linear.sLevel = sl;
|
||||||
|
dspVoice[v].adsr.data.linear.rTime = adsr->data.linear.rtime;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
dspVoice[v].adsr.mode = 1;
|
||||||
|
dspVoice[v].adsr.data.dls.aMode = 0;
|
||||||
|
if (mode == 1) {
|
||||||
|
dspVoice[v].adsr.data.dls.aTime = adsrConvertTimeCents(adsr->data.dls.atime) & 0xFFFF;
|
||||||
|
dspVoice[v].adsr.data.dls.dTime = adsrConvertTimeCents(adsr->data.dls.dtime) & 0xFFFF;
|
||||||
|
|
||||||
|
sl = adsr->data.dls.slevel >> 2;
|
||||||
|
if (sl > 0x3ff) {
|
||||||
|
sl = 0x3ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
dspVoice[v].adsr.data.dls.sLevel = 193 - dspScale2IndexTab[sl];
|
||||||
|
} else {
|
||||||
|
dspVoice[v].adsr.data.dls.aTime = adsr->data.dls.atime & 0xFFFF;
|
||||||
|
dspVoice[v].adsr.data.dls.dTime = adsr->data.dls.dtime & 0xFFFF;
|
||||||
|
dspVoice[v].adsr.data.dls.sLevel = adsr->data.dls.slevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
dspVoice[v].adsr.data.dls.rTime = adsr->data.dls.rtime;
|
||||||
|
}
|
||||||
|
|
||||||
|
dspVoice[v].changed[0] |= 0x10;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hwSetVirtualSampleLoopBuffer(u32 voice, void* addr, u32 len) {
|
||||||
|
dspVoice[voice].vSampleInfo.loopBufferAddr = addr;
|
||||||
|
dspVoice[voice].vSampleInfo.loopBufferLength = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 hwGetVirtualSampleState(u32 voice) { return dspVoice[voice].vSampleInfo.inLoopBuffer; }
|
||||||
|
|
||||||
|
u8 hwGetSampleType(u32 voice) { return dspVoice[voice].smp_info.compType; }
|
||||||
|
|
||||||
|
u16 hwGetSampleID(u32 voice) { return dspVoice[voice].smp_id; }
|
||||||
|
|
||||||
|
void hwSetStreamLoopPS(u32 voice, u8 ps) { dspVoice[voice].streamLoopPS = ps; }
|
||||||
|
|
||||||
|
void hwStart(u32 v, u8 studio) {
|
||||||
|
dspVoice[v].singleOffset = salTimeOffset;
|
||||||
|
salActivateVoice(&dspVoice[v], studio);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hwKeyOff(u32 v) { dspVoice[v].changed[salTimeOffset] |= 0x40; }
|
||||||
|
|
||||||
|
void hwSetPitch(unsigned long v, unsigned short speed) {
|
||||||
|
struct DSPvoice* dsp_vptr = &dspVoice[v];
|
||||||
|
|
||||||
|
if (speed >= 0x4000) {
|
||||||
|
speed = 0x3fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dsp_vptr->lastUpdate.pitch != 0xff &&
|
||||||
|
dsp_vptr->pitch[dsp_vptr->lastUpdate.pitch] == speed * 16) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dsp_vptr->pitch[salTimeOffset] = speed * 16;
|
||||||
|
dsp_vptr->changed[salTimeOffset] |= 8;
|
||||||
|
dsp_vptr->lastUpdate.pitch = salTimeOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hwSetSRCType(u32 v, u8 salSRCType) {
|
||||||
|
static u16 dspSRCType[3] = {0, 1, 2};
|
||||||
|
struct DSPvoice* dsp_vptr = &dspVoice[v];
|
||||||
|
dsp_vptr->srcTypeSelect = dspSRCType[salSRCType];
|
||||||
|
dsp_vptr->changed[0] |= 0x100;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hwSetPolyPhaseFilter(unsigned long v, unsigned char salCoefSel) {
|
||||||
|
static u16 dspCoefSel[3] = {0, 1, 2};
|
||||||
|
struct DSPvoice* dsp_vptr = &dspVoice[v];
|
||||||
|
dsp_vptr->srcCoefSelect = dspCoefSel[salCoefSel];
|
||||||
|
dsp_vptr->changed[0] |= 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupITD(DSPvoice* dsp_vptr, u8 pan) {
|
||||||
|
dsp_vptr->itdShiftL = itdOffTab[pan];
|
||||||
|
dsp_vptr->itdShiftR = 32 - itdOffTab[pan];
|
||||||
|
dsp_vptr->changed[0] |= 0x200;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hwSetITDMode(u32 v, u8 mode) {
|
||||||
|
if (!mode) {
|
||||||
|
dspVoice[v].flags |= 0x80000000;
|
||||||
|
dspVoice[v].itdShiftL = 16;
|
||||||
|
dspVoice[v].itdShiftR = 16;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dspVoice[v].flags &= ~0x80000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hwSetVolume(unsigned long v, unsigned char table, float vol, unsigned long pan,
|
||||||
|
unsigned long span, float auxa, float auxb) {
|
||||||
|
struct SAL_VOLINFO vi; // r1+0x24
|
||||||
|
unsigned short il; // r30
|
||||||
|
unsigned short ir; // r29
|
||||||
|
unsigned short is; // r28
|
||||||
|
DSPvoice* dsp_vptr = &dspVoice[v]; // r31
|
||||||
|
if (vol >= 1.f) {
|
||||||
|
vol = 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auxa >= 1.f) {
|
||||||
|
auxa = 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auxb >= 1.f) {
|
||||||
|
auxb = 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
salCalcVolume(table, &vi, vol, pan, span, auxa, auxb, (dsp_vptr->flags & 0x80000000) != 0,
|
||||||
|
dspStudio[dsp_vptr->studio].type == SND_STUDIO_TYPE_RESERVED0);
|
||||||
|
|
||||||
|
il = 32767.f * vi.volL;
|
||||||
|
ir = 32767.f * vi.volR;
|
||||||
|
is = 32767.f * vi.volS;
|
||||||
|
|
||||||
|
if (dsp_vptr->lastUpdate.vol == 0xff || dsp_vptr->volL != il || dsp_vptr->volR != ir ||
|
||||||
|
dsp_vptr->volS != is) {
|
||||||
|
dsp_vptr->volL = il;
|
||||||
|
dsp_vptr->volR = ir;
|
||||||
|
dsp_vptr->volS = is;
|
||||||
|
dsp_vptr->changed[0] |= 1;
|
||||||
|
dsp_vptr->lastUpdate.vol = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
il = 32767.f * vi.volAuxAL;
|
||||||
|
ir = 32767.f * vi.volAuxAR;
|
||||||
|
is = 32767.f * vi.volAuxAS;
|
||||||
|
|
||||||
|
if (dsp_vptr->lastUpdate.volA == 0xff | dsp_vptr->volLa != il || dsp_vptr->volRa != ir ||
|
||||||
|
dsp_vptr->volSa != is) {
|
||||||
|
dsp_vptr->volLa = il;
|
||||||
|
dsp_vptr->volRa = ir;
|
||||||
|
dsp_vptr->volSa = is;
|
||||||
|
dsp_vptr->changed[0] |= 2;
|
||||||
|
dsp_vptr->lastUpdate.volA = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
il = 32767.f * vi.volAuxBL;
|
||||||
|
ir = 32767.f * vi.volAuxBR;
|
||||||
|
is = 32767.f * vi.volAuxBS;
|
||||||
|
|
||||||
|
if (dsp_vptr->lastUpdate.volB == 0xff || dsp_vptr->volLb != il || dsp_vptr->volRb != ir ||
|
||||||
|
dsp_vptr->volSb != is) {
|
||||||
|
dsp_vptr->volLb = il;
|
||||||
|
dsp_vptr->volRb = ir;
|
||||||
|
dsp_vptr->volSb = is;
|
||||||
|
dsp_vptr->changed[0] |= 4;
|
||||||
|
dsp_vptr->lastUpdate.volB = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dsp_vptr->flags & 0x80000000) {
|
||||||
|
SetupITD(dsp_vptr, pan >> 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void hwOff(s32 vid) { salDeactivateVoice(&dspVoice[vid]); }
|
void hwOff(s32 vid) { salDeactivateVoice(&dspVoice[vid]); }
|
||||||
|
|
||||||
|
void hwSetAUXProcessingCallbacks(u8 studio, SND_AUX_CALLBACK auxA, void* userA,
|
||||||
|
SND_AUX_CALLBACK auxB, void* userB) {
|
||||||
|
dspStudio[studio].auxAHandler = auxA;
|
||||||
|
dspStudio[studio].auxAUser = userA;
|
||||||
|
dspStudio[studio].auxBHandler = auxB;
|
||||||
|
dspStudio[studio].auxBUser = userB;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hwActivateStudio(unsigned char studio, unsigned long isMaster, SND_STUDIO_TYPE type) {
|
||||||
|
salActivateStudio(studio, isMaster, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hwDeactivateStudio(u8 studio) { salDeactivateStudio(studio); }
|
||||||
|
|
||||||
|
void hwChangeStudioMix(u8 studio, u32 isMaster) { dspStudio[studio].isMaster = isMaster; }
|
||||||
|
|
||||||
|
bool hwIsStudioActive(u32 studio) { return dspStudio[studio].state == 1; }
|
||||||
|
|
||||||
|
bool hwAddInput(u8 studio, SND_STUDIO_INPUT* in_desc) {
|
||||||
|
return salAddStudioInput(&dspStudio[studio], in_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hwRemoveInput(u8 studio, SND_STUDIO_INPUT* in_desc) {
|
||||||
|
return salRemoveStudioInput(&dspStudio[studio], in_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hwChangeStudio(u32 v, u8 studio) { salReconnectVoice(&dspVoice[v], studio); }
|
||||||
|
|
||||||
|
u32 hwGetPos(unsigned long v) {}
|
||||||
|
|
||||||
|
void hwFlushStream(void* base, unsigned long offset, unsigned long bytes,
|
||||||
|
unsigned char hwStreamHandle, void (*callback)(unsigned long),
|
||||||
|
unsigned long user) {
|
||||||
|
unsigned long mram; // r29
|
||||||
|
unsigned long aram; // r28
|
||||||
|
unsigned long len;
|
||||||
|
aram = aramGetStreamBufferAddress(hwStreamHandle, &len);
|
||||||
|
bytes += ((offset & 31) + 31) & ~31;
|
||||||
|
mram = (u32)base + (offset & ~31);
|
||||||
|
DCStoreRange((void*)mram, len);
|
||||||
|
aramUploadData((void*)mram, aram + (offset & ~31), bytes, 1, callback, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 hwInitStream(u32 len) { return aramAllocateStreamBuffer(len); }
|
||||||
|
|
||||||
|
void hwExitStream(u8 id) { aramFreeStreamBuffer(id); }
|
||||||
|
|
||||||
|
void* hwGetStreamPlayBuffer(u8 hwStreamHandle) {
|
||||||
|
return (void*)aramGetStreamBufferAddress(hwStreamHandle, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* hwTransAddr(void* samples) { return samples; }
|
||||||
|
|
||||||
|
u32 hwFrq2Pitch(u32 frq) { return (frq * 4096.f) / synthInfo.mixFrq; }
|
||||||
|
|
||||||
|
void hwInitSampleMem(u32 baseAddr, u32 length) { aramInit(length); }
|
||||||
|
|
||||||
|
void hwExitSampleMem() { aramExit(); }
|
||||||
|
|
||||||
|
u32 convert_length(u32 len, u8 type) {
|
||||||
|
switch (type) {
|
||||||
|
case 0:
|
||||||
|
return ((len + 13) / 14) * 8;
|
||||||
|
case 2:
|
||||||
|
return len * 2;
|
||||||
|
case 3:
|
||||||
|
return len;
|
||||||
|
default:
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hwSaveSample(void* header, void* data) {
|
||||||
|
//convert_length
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue