More hardware.c, start hw_volconv

This commit is contained in:
Phillip Stephens 2023-02-21 07:31:10 -08:00
parent 033f8f5881
commit 5516c3b4b8
5 changed files with 185 additions and 42 deletions

View File

@ -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],

View File

@ -323,23 +323,23 @@ typedef struct SND_VIRTUALSAMPLE_INFO {
typedef struct VS_BUFFER { typedef struct VS_BUFFER {
// total size: 0x24 // total size: 0x24
unsigned char state; // offset 0x0, size 0x1 unsigned char state; // offset 0x0, size 0x1
unsigned char hwId; // offset 0x1, size 0x1 unsigned char hwId; // offset 0x1, size 0x1
unsigned char smpType; // offset 0x2, size 0x1 unsigned char smpType; // offset 0x2, size 0x1
unsigned char voice; // offset 0x3, size 0x1 unsigned char voice; // offset 0x3, size 0x1
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,
struct SND_VIRTUALSAMPLE_INFO*); // offset 0x94C, size 0x4 struct SND_VIRTUALSAMPLE_INFO*); // offset 0x94C, size 0x4
} VS; } VS;
@ -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

View File

@ -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; }

View File

@ -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())

99
src/musyx/hw_volconv.c Normal file
View File

@ -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;
}
}