mirror of https://github.com/PrimeDecomp/prime.git
More hardware.c, start hw_volconv
This commit is contained in:
parent
033f8f5881
commit
5516c3b4b8
|
@ -937,7 +937,7 @@ LIBS = [
|
||||||
["musyx/synth_dbtab", True],
|
["musyx/synth_dbtab", True],
|
||||||
"musyx/s_data",
|
"musyx/s_data",
|
||||||
"musyx/hw_dspctrl",
|
"musyx/hw_dspctrl",
|
||||||
"musyx/hw_volconv",
|
["musyx/hw_volconv", False],
|
||||||
["musyx/snd3d", False],
|
["musyx/snd3d", False],
|
||||||
["musyx/snd_init", True],
|
["musyx/snd_init", True],
|
||||||
["musyx/snd_math", True],
|
["musyx/snd_math", True],
|
||||||
|
|
|
@ -330,14 +330,14 @@ typedef struct VS_BUFFER {
|
||||||
unsigned long last; // offset 0x4, size 0x4
|
unsigned long last; // offset 0x4, size 0x4
|
||||||
unsigned long finalGoodSamples; // offset 0x8, size 0x4
|
unsigned long finalGoodSamples; // offset 0x8, size 0x4
|
||||||
unsigned long finalLast; // offset 0xC, size 0x4
|
unsigned long finalLast; // offset 0xC, size 0x4
|
||||||
struct SND_VIRTUALSAMPLE_INFO info; // offset 0x10, size 0x14
|
SND_VIRTUALSAMPLE_INFO info; // offset 0x10, size 0x14
|
||||||
} VS_BUFFER;
|
} VS_BUFFER;
|
||||||
|
|
||||||
typedef struct _VS {
|
typedef struct _VS {
|
||||||
// total size: 0x950
|
// total size: 0x950
|
||||||
unsigned char numBuffers; // offset 0x0, size 0x1
|
unsigned char numBuffers; // offset 0x0, size 0x1
|
||||||
unsigned long bufferLength; // offset 0x4, size 0x4
|
unsigned long bufferLength; // offset 0x4, size 0x4
|
||||||
struct VS_BUFFER streamBuffer[64]; // offset 0x8, size 0x900
|
VS_BUFFER streamBuffer[64]; // offset 0x8, size 0x900
|
||||||
unsigned char voices[64]; // offset 0x908, size 0x40
|
unsigned char voices[64]; // offset 0x908, size 0x40
|
||||||
unsigned short nextInstID; // offset 0x948, size 0x2
|
unsigned short nextInstID; // offset 0x948, size 0x2
|
||||||
unsigned long (*callback)(unsigned char,
|
unsigned long (*callback)(unsigned char,
|
||||||
|
@ -488,6 +488,22 @@ typedef struct SAL_VOLINFO {
|
||||||
float volAuxBS; // offset 0x20, size 0x4
|
float volAuxBS; // offset 0x20, size 0x4
|
||||||
} SAL_VOLINFO;
|
} SAL_VOLINFO;
|
||||||
|
|
||||||
|
typedef struct SAL_PANINFO {
|
||||||
|
// total size: 0x30
|
||||||
|
u32 pan_i; // offset 0x0, size 0x4
|
||||||
|
u32 pan_im; // offset 0x4, size 0x4
|
||||||
|
u32 span_i; // offset 0x8, size 0x4
|
||||||
|
u32 span_im; // offset 0xC, size 0x4
|
||||||
|
u32 rpan_i; // offset 0x10, size 0x4
|
||||||
|
u32 rpan_im; // offset 0x14, size 0x4
|
||||||
|
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
|
||||||
|
} SAL_PANINFO;
|
||||||
|
|
||||||
typedef struct _SPB {
|
typedef struct _SPB {
|
||||||
// total size: 0x36
|
// total size: 0x36
|
||||||
unsigned short dpopLHi; // offset 0x0, size 0x2
|
unsigned short dpopLHi; // offset 0x0, size 0x2
|
||||||
|
@ -621,6 +637,8 @@ void salReconnectVoice(DSPvoice* dsp_vptr, u8 studio);
|
||||||
void* salMalloc(u32 len);
|
void* salMalloc(u32 len);
|
||||||
void salFree(void* addr);
|
void salFree(void* addr);
|
||||||
|
|
||||||
|
extern float dspDLSVolTab[128];
|
||||||
|
|
||||||
/* Stream */
|
/* Stream */
|
||||||
typedef s32 (*SND_STREAM_UPDATE_CALLBACK)(void* buffer1, u32 len1, void* buffer2, u32 len2,
|
typedef s32 (*SND_STREAM_UPDATE_CALLBACK)(void* buffer1, u32 len1, void* buffer2, u32 len2,
|
||||||
void* user);
|
void* user);
|
||||||
|
@ -648,16 +666,20 @@ bool hwRemoveInput(u8 studio, SND_STUDIO_INPUT* in_desc);
|
||||||
void hwChangeStudio(u32 v, u8 studio);
|
void hwChangeStudio(u32 v, u8 studio);
|
||||||
void hwDisableHRTF();
|
void hwDisableHRTF();
|
||||||
|
|
||||||
|
extern bool dspHRTFOn;
|
||||||
|
|
||||||
extern u32 dspCmdList;
|
extern u32 dspCmdList;
|
||||||
extern u16 dspCmdFirstSize;
|
extern u16 dspCmdFirstSize;
|
||||||
|
|
||||||
extern u8 dspScale2IndexTab[1024];
|
extern u8 dspScale2IndexTab[1024];
|
||||||
|
|
||||||
|
typedef void* (*ARAMUploadCallback)(u32, u32);
|
||||||
|
|
||||||
u32 aramGetStreamBufferAddress(unsigned char id, unsigned long* len);
|
u32 aramGetStreamBufferAddress(unsigned char id, unsigned long* len);
|
||||||
void aramUploadData(void* mram, unsigned long aram, unsigned long len, unsigned long highPrio,
|
void aramUploadData(void* mram, unsigned long aram, unsigned long len, unsigned long highPrio,
|
||||||
void (*callback)(unsigned long), unsigned long user);
|
void (*callback)(unsigned long), unsigned long user);
|
||||||
void aramFreeStreamBuffer(u8 id);
|
void aramFreeStreamBuffer(u8 id);
|
||||||
void * aramStoreData(void * src, unsigned long len);
|
void* aramStoreData(void* src, unsigned long len);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "musyx/musyx_priv.h"
|
#include "musyx/musyx_priv.h"
|
||||||
|
|
||||||
static u16 itdOffTab[128] = {
|
extern void DCStoreRange(void* addr, u32 nBytes);
|
||||||
|
|
||||||
|
static volatile const 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,
|
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,
|
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,
|
9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 16, 16, 17,
|
||||||
|
@ -110,7 +112,7 @@ void hwSetMesgCallback(SND_MESSAGE_CALLBACK callback) { salMessageCallback = cal
|
||||||
void hwSetPriority(s32 idx, s32 priority) { dspVoice[idx].prio = priority; }
|
void hwSetPriority(s32 idx, s32 priority) { dspVoice[idx].prio = priority; }
|
||||||
|
|
||||||
void hwInitSamplePlayback(s32 v, u16 smpID, void* newsmp, u32 set_defadsr, u32 priority,
|
void hwInitSamplePlayback(s32 v, u16 smpID, void* newsmp, u32 set_defadsr, u32 priority,
|
||||||
u32 callbackUserValue, u32 setSRC, u32 itdMode) {
|
u32 callbackUserValue, u32 setSRC, u8 itdMode) {
|
||||||
unsigned char i; // r30
|
unsigned char i; // r30
|
||||||
unsigned long bf; // r29
|
unsigned long bf; // r29
|
||||||
bf = 0;
|
bf = 0;
|
||||||
|
@ -272,9 +274,11 @@ void hwSetPolyPhaseFilter(unsigned long v, unsigned char salCoefSel) {
|
||||||
dsp_vptr->changed[0] |= 0x80;
|
dsp_vptr->changed[0] |= 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupITD(DSPvoice* dsp_vptr, u8 pan) {
|
inline void SetupITD(DSPvoice* dsp_vptr, u8 pan) {
|
||||||
dsp_vptr->itdShiftL = itdOffTab[pan];
|
u16 panA = itdOffTab[pan];
|
||||||
dsp_vptr->itdShiftR = 32 - itdOffTab[pan];
|
u16 panB = itdOffTab[pan];
|
||||||
|
dsp_vptr->itdShiftL = panA;
|
||||||
|
dsp_vptr->itdShiftR = 32 - panB;
|
||||||
dsp_vptr->changed[0] |= 0x200;
|
dsp_vptr->changed[0] |= 0x200;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,7 +331,7 @@ void hwSetVolume(unsigned long v, unsigned char table, float vol, unsigned long
|
||||||
ir = 32767.f * vi.volAuxAR;
|
ir = 32767.f * vi.volAuxAR;
|
||||||
is = 32767.f * vi.volAuxAS;
|
is = 32767.f * vi.volAuxAS;
|
||||||
|
|
||||||
if (dsp_vptr->lastUpdate.volA == 0xff | dsp_vptr->volLa != il || dsp_vptr->volRa != ir ||
|
if (dsp_vptr->lastUpdate.volA == 0xff || dsp_vptr->volLa != il || dsp_vptr->volRa != ir ||
|
||||||
dsp_vptr->volSa != is) {
|
dsp_vptr->volSa != is) {
|
||||||
dsp_vptr->volLa = il;
|
dsp_vptr->volLa = il;
|
||||||
dsp_vptr->volRa = ir;
|
dsp_vptr->volRa = ir;
|
||||||
|
@ -384,19 +388,18 @@ bool hwRemoveInput(u8 studio, SND_STUDIO_INPUT* in_desc) {
|
||||||
|
|
||||||
void hwChangeStudio(u32 v, u8 studio) { salReconnectVoice(&dspVoice[v], studio); }
|
void hwChangeStudio(u32 v, u8 studio) { salReconnectVoice(&dspVoice[v], studio); }
|
||||||
|
|
||||||
u32 hwGetPos(unsigned long v) {}
|
u32 hwGetPos(u32 v) {}
|
||||||
|
|
||||||
void hwFlushStream(void* base, unsigned long offset, unsigned long bytes,
|
void hwFlushStream(void* base, unsigned long offset, unsigned long bytes,
|
||||||
unsigned char hwStreamHandle, void (*callback)(unsigned long),
|
unsigned char hwStreamHandle, void (*callback)(unsigned long),
|
||||||
unsigned long user) {
|
unsigned long user) {
|
||||||
unsigned long mram; // r29
|
|
||||||
unsigned long aram; // r28
|
unsigned long aram; // r28
|
||||||
|
unsigned long mram; // r29
|
||||||
unsigned long len;
|
unsigned long len;
|
||||||
aram = aramGetStreamBufferAddress(hwStreamHandle, &len);
|
aram = aramGetStreamBufferAddress(hwStreamHandle, &len);
|
||||||
bytes += ((offset & 31) + 31) & ~31;
|
DCStoreRange((void*)((u32)base + (offset & ~31)), bytes + ((offset & 31) + 31) & ~31);
|
||||||
mram = (u32)base + (offset & ~31);
|
aramUploadData((void*)((u32)base + (offset & ~31)), aram + (offset & ~31),
|
||||||
DCStoreRange((void*)mram, len);
|
bytes + ((offset & 31) + 31) & ~31, 1, callback, user);
|
||||||
aramUploadData((void*)mram, aram + (offset & ~31), bytes, 1, callback, user);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 hwInitStream(u32 len) { return aramAllocateStreamBuffer(len); }
|
u32 hwInitStream(u32 len) { return aramAllocateStreamBuffer(len); }
|
||||||
|
@ -415,19 +418,38 @@ void hwInitSampleMem(u32 baseAddr, u32 length) { aramInit(length); }
|
||||||
|
|
||||||
void hwExitSampleMem() { aramExit(); }
|
void hwExitSampleMem() { aramExit(); }
|
||||||
|
|
||||||
u32 convert_length(u32 len, u8 type) {
|
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) {
|
void hwSaveSample(void* header, void* data) {
|
||||||
//convert_length
|
u32 len;
|
||||||
|
u8 type;
|
||||||
|
|
||||||
|
header = ((u32*)header);
|
||||||
|
len = ((u32*)header)[0];
|
||||||
|
type = ((u32*)header)[1] >> 0x18;
|
||||||
|
*((u32*)data) = (u32)aramStoreData((void*)*((u32*)data), convert_length(len, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hwSetSaveSampleCallback(ARAMUploadCallback callback, unsigned long chunckSize) {
|
||||||
|
aramSetUploadCallback(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hwRemoveSample(void* header, void* data) {}
|
||||||
|
|
||||||
|
void hwSyncSampleMem() { aramSyncTransferQueue(); }
|
||||||
|
|
||||||
|
void hwFrameDone() {}
|
||||||
|
|
||||||
|
void sndSetHooks(SND_HOOKS* hooks) { salHooks = *hooks; }
|
||||||
|
|
||||||
|
void hwDisableHRTF() { dspHRTFOn = FALSE; }
|
||||||
|
|
||||||
|
u32 hwGetVirtualSampleID(u32 v) {
|
||||||
|
if (dspVoice[v].state == 0) {
|
||||||
|
return ~0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dspVoice[v].virtualSampleID;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hwVoiceInStartup(u32 v) { return dspVoice[v].state == 1; }
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/* Is this actually what factor 5 did? They specify 0x2000 for the dram size, but the next TU winds
|
/* Is this actually what factor 5 did? They specify 0x2000 for the dram size, but the next TU winds
|
||||||
* up incorrectly aligned */
|
* up incorrectly aligned */
|
||||||
static u8 dram_image[0x2008] ATTRIBUTE_ALIGN(32);
|
static u8 dram_image[0x2008] ATTRIBUTE_ALIGN(32);
|
||||||
static DSPTaskInfo dsp_task;
|
static DSPTaskInfo dsp_task ATTRIBUTE_ALIGN(8);
|
||||||
|
|
||||||
static volatile u32 oldState = 0;
|
static volatile u32 oldState = 0;
|
||||||
static volatile u16 hwIrqLevel = 0;
|
static volatile u16 hwIrqLevel = 0;
|
||||||
|
@ -134,7 +134,7 @@ u32 salExitDsp() {
|
||||||
void salStartDsp(u32 cmdList) {
|
void salStartDsp(u32 cmdList) {
|
||||||
salDspIsDone = FALSE;
|
salDspIsDone = FALSE;
|
||||||
PPCSync();
|
PPCSync();
|
||||||
// "Failed assertion ((u32)cmdList & 0x1F)==0"
|
ASSERT(((u32)cmdList & 0x1F)==0);
|
||||||
DSPSendMailToDSP(dspCmdFirstSize | 0xbabe0000);
|
DSPSendMailToDSP(dspCmdFirstSize | 0xbabe0000);
|
||||||
|
|
||||||
while (DSPCheckMailToDSP())
|
while (DSPCheckMailToDSP())
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
#include "musyx/musyx_priv.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
static float musyx_vol_tab[129] = {
|
||||||
|
|
||||||
|
};
|
||||||
|
static float pan_tab[4] = {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
static float pan_tab_dpl2[4] = {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void CalcBus(float* vol_tab, float* vl, float* vr, float* vs, float vol, struct SAL_PANINFO* pi) {
|
||||||
|
u32 i; // r29
|
||||||
|
float f; // r62
|
||||||
|
float v; // r63
|
||||||
|
|
||||||
|
i = vol * 127.f;
|
||||||
|
v = (vol * 127) - (float)i;
|
||||||
|
f = (1.f - v) * vol_tab[i] + v * vol_tab[i + 1];
|
||||||
|
*vs = f * ((1.f - pi->span_f) * pan_tab[pi->span_i] + pi->span_f * pan_tab[pi->span_i + 1]) *
|
||||||
|
0.7079f;
|
||||||
|
f = f * ((1.f - pi->span_fm) * pan_tab[pi->span_im] + pi->span_fm * pan_tab[pi->span_im + 1]);
|
||||||
|
*vr = f * ((1.f - pi->span_f) * pan_tab[pi->pan_i] + pi->pan_f * pan_tab[pi->pan_i + 1]);
|
||||||
|
*vl = f * ((1.f - pi->pan_fm) * pan_tab[pi->pan_im] + pi->pan_fm * pan_tab[pi->pan_im + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CalcBusDPL2(float* vol_tab, float* fvl, float* fvr, float* rvl, float* rvr, float vol,
|
||||||
|
struct SAL_PANINFO* pi) {
|
||||||
|
u32 i; // r29
|
||||||
|
float f; // r62
|
||||||
|
float v; // r63
|
||||||
|
float vs; // r61
|
||||||
|
|
||||||
|
i = vol * 127;
|
||||||
|
v = (vol * 127.f) - (float)i * ((1.f - v) * vol_tab[i] + v * vol_tab[i + 1]);
|
||||||
|
f = v * ((1.f - pi->span_f) * pan_tab[pi->span_i] + pi->span_f * pan_tab[pi->span_i + 1]);
|
||||||
|
vs = v * ((1.f - pi->span_fm) * pan_tab[pi->span_im] + pi->span_fm * pan_tab[pi->span_im + 1]);
|
||||||
|
*fvr = vs * ((1.f - pi->pan_f) * pan_tab[pi->pan_i] + pi->pan_f * pan_tab[pi->pan_i + 1]);
|
||||||
|
*fvl = vs * ((1.f - pi->pan_fm) * pan_tab[pi->pan_im] + pi->pan_fm * pan_tab[pi->pan_im + 1]);
|
||||||
|
*rvr = f * ((1.f - pi->rpan_f) * pan_tab_dpl2[pi->rpan_i] + pi->rpan_f * pan_tab[pi->rpan_i + 1]);
|
||||||
|
*rvl = f *
|
||||||
|
((1.f - pi->rpan_fm) * pan_tab_dpl2[pi->rpan_im] + pi->rpan_fm * pan_tab[pi->rpan_im + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void salCalcVolume(u8 voltab_index, SAL_VOLINFO* vi, float vol, u32 pan, u32 span, float auxa,
|
||||||
|
float auxb, u32 itd, u32 dpl2) {
|
||||||
|
float* vol_tab; // r30
|
||||||
|
float p; // r63
|
||||||
|
float sp; // r62
|
||||||
|
SAL_PANINFO pi; // r1+0x2C
|
||||||
|
|
||||||
|
if (voltab_index == 0) {
|
||||||
|
vol_tab = musyx_vol_tab;
|
||||||
|
} else {
|
||||||
|
vol_tab = dspDLSVolTab;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pan == 0x800000) {
|
||||||
|
pan = 0;
|
||||||
|
span = 0x7f0000;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = (float)(pan <= 0x10000 ? 0 : pan - 0x10000) * 2.42203e-07f;
|
||||||
|
sp = (float)(span <= 0x10000 ? 0 : span - 0x10000) * 2.42203e-07f;
|
||||||
|
|
||||||
|
if (dpl2 != FALSE) {
|
||||||
|
pi.rpan_f = fmod(p, 1.f);
|
||||||
|
pi.rpan_i = p;
|
||||||
|
pi.rpan_fm = fmod(2.f - p, 1.f);
|
||||||
|
pi.rpan_im = 2.f - p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itd != FALSE) {
|
||||||
|
p = (p - 1.f) * 0.76604f + 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
pi.pan_f = fmod(p, 1.f);
|
||||||
|
pi.pan_i = p;
|
||||||
|
pi.span_f = fmod(sp, 1.f);
|
||||||
|
pi.span_i = sp;
|
||||||
|
pi.pan_fm = fmod(2.f - p, 1.f);
|
||||||
|
pi.pan_im = 2.f - p;
|
||||||
|
pi.span_fm = fmod(2.f - sp, 1.f);
|
||||||
|
pi.span_im = 2.f - p;
|
||||||
|
|
||||||
|
if (!dpl2) {
|
||||||
|
CalcBus(vol_tab, &vi->volL, &vi->volR, &vi->volS, vol, &pi);
|
||||||
|
CalcBus(vol_tab, &vi->volAuxAL, &vi->volAuxAR, &vi->volAuxAS, auxa, &pi);
|
||||||
|
CalcBus(vol_tab, &vi->volAuxBL, &vi->volAuxBR, &vi->volAuxBS, auxb, &pi);
|
||||||
|
} else {
|
||||||
|
CalcBusDPL2(vol_tab, &vi->volL, &vi->volR, &vi->volAuxBL, &vi->volAuxBR, vol, &pi);
|
||||||
|
CalcBus(vol_tab, &vi->volAuxAL, &vi->volAuxAR, &vi->volAuxAS, auxa, &pi);
|
||||||
|
vi->volS = 0.f;
|
||||||
|
vi->volAuxBS = 0.f;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue