mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-26 07:35:40 +00:00
Added front/rear speaker balance (actually the master/slave SCSP balance). Balance setting is stored in CSoundBoardConfig and can be set on the command line (-balance) or config file (Balance). Valid range is 100 (front speaker volume doubled, rear muted) to -100. The default is 0, both sets at full volume. Balance is applied in the SCSP core before overall sound and music volume settings.
This commit is contained in:
parent
6814ef1ed8
commit
c5d0cb0d97
|
@ -53,7 +53,7 @@ public:
|
||||||
bool emulateDSB; // DSB emulation (enabled if true)
|
bool emulateDSB; // DSB emulation (enabled if true)
|
||||||
|
|
||||||
// Sound (SCSP) volume (0-200, 100 being full amplitude)
|
// Sound (SCSP) volume (0-200, 100 being full amplitude)
|
||||||
inline void SetSoundVolume(unsigned vol)
|
inline void SetSoundVolume(int vol)
|
||||||
{
|
{
|
||||||
if (vol > 200)
|
if (vol > 200)
|
||||||
{
|
{
|
||||||
|
@ -61,7 +61,13 @@ public:
|
||||||
vol = 100;
|
vol = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
soundVol = vol;
|
if (vol < 0)
|
||||||
|
{
|
||||||
|
ErrorLog("Sound volume cannot be negative; setting to 0%%.\n");
|
||||||
|
vol = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
soundVol = (unsigned) vol;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned GetSoundVolume(void)
|
inline unsigned GetSoundVolume(void)
|
||||||
|
@ -70,7 +76,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Music (DSB MPEG) volume (0-200)
|
// Music (DSB MPEG) volume (0-200)
|
||||||
inline void SetMusicVolume(unsigned vol)
|
inline void SetMusicVolume(int vol)
|
||||||
{
|
{
|
||||||
if (vol > 200)
|
if (vol > 200)
|
||||||
{
|
{
|
||||||
|
@ -78,7 +84,13 @@ public:
|
||||||
vol = 100;
|
vol = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
musicVol = vol;
|
if (vol < 0)
|
||||||
|
{
|
||||||
|
ErrorLog("Music volume cannot be negative; setting to 0%%.\n");
|
||||||
|
vol = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
musicVol = (unsigned) vol;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned GetMusicVolume(void)
|
inline unsigned GetMusicVolume(void)
|
||||||
|
|
|
@ -43,11 +43,38 @@ class CSoundBoardConfig
|
||||||
public:
|
public:
|
||||||
bool emulateSound; // sound board emulation (enabled if true)
|
bool emulateSound; // sound board emulation (enabled if true)
|
||||||
|
|
||||||
|
// Master/slave SCSP relative balance (0-100, with 100 meaning master volume doubled, slave silenced)
|
||||||
|
inline void SetSCSPBalance(int bal)
|
||||||
|
{
|
||||||
|
if (bal > 100)
|
||||||
|
{
|
||||||
|
ErrorLog("Front/rear balance cannot exceed 100%%; setting to 100%%.\n");
|
||||||
|
bal = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bal < -100)
|
||||||
|
{
|
||||||
|
ErrorLog("Front/rear balance cannot be less than -100%%; setting to -100%%.\n");
|
||||||
|
bal = -100;
|
||||||
|
}
|
||||||
|
|
||||||
|
scspBalance = bal;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int GetSCSPBalance(void)
|
||||||
|
{
|
||||||
|
return scspBalance;
|
||||||
|
}
|
||||||
|
|
||||||
// Defaults
|
// Defaults
|
||||||
CSoundBoardConfig(void)
|
CSoundBoardConfig(void)
|
||||||
{
|
{
|
||||||
emulateSound = true;
|
emulateSound = true;
|
||||||
|
scspBalance = 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int scspBalance;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -355,6 +355,7 @@ static bool ConfigureInputs(CInputs *Inputs, bool configure)
|
||||||
static void ApplySettings(CINIFile *INI, const char *section)
|
static void ApplySettings(CINIFile *INI, const char *section)
|
||||||
{
|
{
|
||||||
unsigned x;
|
unsigned x;
|
||||||
|
int y;
|
||||||
string String;
|
string String;
|
||||||
|
|
||||||
// Model 3
|
// Model 3
|
||||||
|
@ -374,6 +375,8 @@ static void ApplySettings(CINIFile *INI, const char *section)
|
||||||
g_Config.SetSoundVolume(x);
|
g_Config.SetSoundVolume(x);
|
||||||
if (OKAY == INI->Get(section, "MusicVolume", x))
|
if (OKAY == INI->Get(section, "MusicVolume", x))
|
||||||
g_Config.SetMusicVolume(x);
|
g_Config.SetMusicVolume(x);
|
||||||
|
if (OKAY == INI->Get(section, "Balance", y))
|
||||||
|
g_Config.SetSCSPBalance(y);
|
||||||
if (OKAY == INI->Get(section, "EmulateSound", x))
|
if (OKAY == INI->Get(section, "EmulateSound", x))
|
||||||
g_Config.emulateSound = x ? true : false;
|
g_Config.emulateSound = x ? true : false;
|
||||||
if (OKAY == INI->Get(section, "EmulateDSB", x))
|
if (OKAY == INI->Get(section, "EmulateDSB", x))
|
||||||
|
@ -464,6 +467,7 @@ static void LogConfig(void)
|
||||||
|
|
||||||
// CSoundBoardConfig
|
// CSoundBoardConfig
|
||||||
InfoLog("\tEmulateSound = %d", g_Config.emulateSound);
|
InfoLog("\tEmulateSound = %d", g_Config.emulateSound);
|
||||||
|
InfoLog("\tBalance = %d", g_Config.GetSCSPBalance());
|
||||||
|
|
||||||
// CDSBConfig
|
// CDSBConfig
|
||||||
InfoLog("\tEmulateDSB = %d", g_Config.emulateDSB);
|
InfoLog("\tEmulateDSB = %d", g_Config.emulateDSB);
|
||||||
|
@ -1205,7 +1209,7 @@ static void Help(void)
|
||||||
puts(" -print-games List supported games and quit");
|
puts(" -print-games List supported games and quit");
|
||||||
puts("");
|
puts("");
|
||||||
puts("Core Options:");
|
puts("Core Options:");
|
||||||
printf(" -ppc-frequency=<f> PowerPC frequency in MHz [Default: %d]\n", g_Config.GetPowerPCFrequency());
|
printf(" -ppc-frequency=<freq> PowerPC frequency in MHz [Default: %d]\n", g_Config.GetPowerPCFrequency());
|
||||||
puts(" -no-threads Disable multi-threading");
|
puts(" -no-threads Disable multi-threading");
|
||||||
puts("");
|
puts("");
|
||||||
puts("Video Options:");
|
puts("Video Options:");
|
||||||
|
@ -1218,8 +1222,9 @@ static void Help(void)
|
||||||
puts(" -print-gl-info Print OpenGL driver information and quit");
|
puts(" -print-gl-info Print OpenGL driver information and quit");
|
||||||
puts("");
|
puts("");
|
||||||
puts("Audio Options:");
|
puts("Audio Options:");
|
||||||
puts(" -sound-volume=<v> Volume of sound effects in % [Default: 100]");
|
puts(" -sound-volume=<vol> Volume of sound effects in % [Default: 100]");
|
||||||
puts(" -music-volume=<v> Volume of MPEG music in % [Default: 100]");
|
puts(" -music-volume=<vol> Volume of MPEG music in % [Default: 100]");
|
||||||
|
puts(" -balance=<bal> Relative front/rear balance in % front [Default: 0]");
|
||||||
puts(" -flip-stereo Swap left and right audio channels");
|
puts(" -flip-stereo Swap left and right audio channels");
|
||||||
puts(" -no-sound Disable sound board emulation (sound effects)");
|
puts(" -no-sound Disable sound board emulation (sound effects)");
|
||||||
puts(" -no-dsb Disable Digital Sound Board (MPEG music)");
|
puts(" -no-dsb Disable Digital Sound Board (MPEG music)");
|
||||||
|
@ -1277,6 +1282,7 @@ int main(int argc, char **argv)
|
||||||
#endif // SUPERMODEL_DEBUGGER
|
#endif // SUPERMODEL_DEBUGGER
|
||||||
char *inputSystem = NULL; // use default input system
|
char *inputSystem = NULL; // use default input system
|
||||||
unsigned n;
|
unsigned n;
|
||||||
|
int m;
|
||||||
UINT32 addr;
|
UINT32 addr;
|
||||||
|
|
||||||
Title();
|
Title();
|
||||||
|
@ -1358,6 +1364,14 @@ int main(int argc, char **argv)
|
||||||
else
|
else
|
||||||
CmdLine.Set("Global", "MusicVolume", n);
|
CmdLine.Set("Global", "MusicVolume", n);
|
||||||
}
|
}
|
||||||
|
else if (!strncmp(argv[i],"-balance",8))
|
||||||
|
{
|
||||||
|
ret = sscanf(&argv[i][8],"=%d",&m);
|
||||||
|
if (ret != 1)
|
||||||
|
ErrorLog("'-balance' requires a front/rear balance setting.");
|
||||||
|
else
|
||||||
|
CmdLine.Set("Global", "Balance", m);
|
||||||
|
}
|
||||||
else if (!strcmp(argv[i], "-flip-stereo"))
|
else if (!strcmp(argv[i], "-flip-stereo"))
|
||||||
{
|
{
|
||||||
n = 1;
|
n = 1;
|
||||||
|
|
|
@ -968,7 +968,7 @@ void SCSP_w8(unsigned int addr,unsigned char val)
|
||||||
int slot=addr/0x20;
|
int slot=addr/0x20;
|
||||||
addr&=0x1f;
|
addr&=0x1f;
|
||||||
//DebugLog("Slot %02X Reg %02X write byte %04X\n",slot,addr^1,val);
|
//DebugLog("Slot %02X Reg %02X write byte %04X\n",slot,addr^1,val);
|
||||||
//printf("Slot %02X Reg %02X write byte %04X\n",slot,addr^1,val);
|
//printf("\tSlot %02X Reg %02X write byte %04X\n",slot,addr^1,val);
|
||||||
*(unsigned char *) &(SCSP->Slots[slot].datab[addr^1]) = val;
|
*(unsigned char *) &(SCSP->Slots[slot].datab[addr^1]) = val;
|
||||||
SCSP_UpdateSlotReg(slot,(addr^1)&0x1f);
|
SCSP_UpdateSlotReg(slot,(addr^1)&0x1f);
|
||||||
}
|
}
|
||||||
|
@ -1008,7 +1008,7 @@ void SCSP_w16(unsigned int addr,unsigned short val)
|
||||||
int slot=addr/0x20;
|
int slot=addr/0x20;
|
||||||
addr&=0x1f;
|
addr&=0x1f;
|
||||||
//DebugLog("Slot %02X Reg %02X write word %04X\n",slot,addr,val);
|
//DebugLog("Slot %02X Reg %02X write word %04X\n",slot,addr,val);
|
||||||
//printf("Slot %02X Reg %02X write word %04X\n",slot,addr,val);
|
//printf("\tSlot %02X Reg %02X write word %04X\n",slot,addr,val);
|
||||||
*(unsigned short *) &(SCSP->Slots[slot].datab[addr]) = val;
|
*(unsigned short *) &(SCSP->Slots[slot].datab[addr]) = val;
|
||||||
SCSP_UpdateSlotReg(slot,addr&0x1f);
|
SCSP_UpdateSlotReg(slot,addr&0x1f);
|
||||||
}
|
}
|
||||||
|
@ -1042,13 +1042,12 @@ void SCSP_w16(unsigned int addr,unsigned short val)
|
||||||
void SCSP_w32(unsigned int addr,unsigned int val)
|
void SCSP_w32(unsigned int addr,unsigned int val)
|
||||||
{
|
{
|
||||||
addr&=0xffff;
|
addr&=0xffff;
|
||||||
|
|
||||||
if(addr<0x400)
|
if(addr<0x400)
|
||||||
{
|
{
|
||||||
int slot=addr/0x20;
|
int slot=addr/0x20;
|
||||||
addr&=0x1f;
|
addr&=0x1f;
|
||||||
//DebugLog("Slot %02X Reg %02X write dword %08X\n",slot,addr,val);
|
//DebugLog("Slot %02X Reg %02X write dword %08X\n",slot,addr,val);
|
||||||
//printf("Slot %02X Reg %02X write dword %08X\n",slot,addr,val);
|
//printf("\tSlot %02X Reg %02X write dword %08X\n",slot,addr,val);
|
||||||
rotl(val, 16);
|
rotl(val, 16);
|
||||||
|
|
||||||
*(unsigned int *) &(SCSP->Slots[slot].datab[addr]) = val;
|
*(unsigned int *) &(SCSP->Slots[slot].datab[addr]) = val;
|
||||||
|
@ -1765,6 +1764,19 @@ void SCSP_DoMasterSamples(int nsamples)
|
||||||
int slice=12000000/(SysFPS*nsamples); // 68K cycles/sample
|
int slice=12000000/(SysFPS*nsamples); // 68K cycles/sample
|
||||||
static int lastdiff=0;
|
static int lastdiff=0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute relative master/slave SCSP balance (note: master is often used
|
||||||
|
* for the front speakers). Equal balance is a 1.0 scale factor for both.
|
||||||
|
* When one SCSP is fully attenuated, the other's samples will be multiplied
|
||||||
|
* by 2.
|
||||||
|
*/
|
||||||
|
float balance = (float) g_Config.GetSCSPBalance() / 100.0f;
|
||||||
|
float masterBalance = 1.0f+balance;
|
||||||
|
float slaveBalance = 1.0f-balance;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate samples
|
||||||
|
*/
|
||||||
for(int s=0;s<nsamples;++s)
|
for(int s=0;s<nsamples;++s)
|
||||||
{
|
{
|
||||||
signed int smpl=0;
|
signed int smpl=0;
|
||||||
|
@ -1778,12 +1790,12 @@ void SCSP_DoMasterSamples(int nsamples)
|
||||||
unsigned short Enc=((TL(slot))<<0x8)|((DIPAN(slot))<<0x0)|((DISDL(slot))<<0x5);
|
unsigned short Enc=((TL(slot))<<0x8)|((DIPAN(slot))<<0x0)|((DISDL(slot))<<0x5);
|
||||||
RBUFDST=SCSPs[0].RINGBUF+SCSPs[0].BUFPTR;
|
RBUFDST=SCSPs[0].RINGBUF+SCSPs[0].BUFPTR;
|
||||||
signed int sample;
|
signed int sample;
|
||||||
//signed int sample=SCSP_UpdateSlot(slot);
|
//signed int sample=(int) (masterBalance*(float)SCSP_UpdateSlot(slot));
|
||||||
//if(SA(slot)!=0x2ccf4)
|
//if(SA(slot)!=0x2ccf4)
|
||||||
/*if(SA(slot)!=0x1c77e)
|
/*if(SA(slot)!=0x1c77e)
|
||||||
sample=0;
|
sample=0;
|
||||||
else*/
|
else*/
|
||||||
sample=SCSP_UpdateSlot(slot);
|
sample= (int) (masterBalance*(float)SCSP_UpdateSlot(slot));
|
||||||
|
|
||||||
|
|
||||||
/*unsigned char ef=EFSDL(slot);
|
/*unsigned char ef=EFSDL(slot);
|
||||||
|
@ -1816,7 +1828,7 @@ void SCSP_DoMasterSamples(int nsamples)
|
||||||
_SLOT *slot=SCSPs[1].Slots+sl;
|
_SLOT *slot=SCSPs[1].Slots+sl;
|
||||||
unsigned short Enc=((TL(slot))<<0x8)|((DIPAN(slot))<<0x0)|((DISDL(slot))<<0x5);
|
unsigned short Enc=((TL(slot))<<0x8)|((DIPAN(slot))<<0x0)|((DISDL(slot))<<0x5);
|
||||||
RBUFDST=SCSPs[1].RINGBUF+SCSPs[1].BUFPTR;
|
RBUFDST=SCSPs[1].RINGBUF+SCSPs[1].BUFPTR;
|
||||||
signed int sample=SCSP_UpdateSlot(slot);
|
signed int sample=(int) (slaveBalance*(float)SCSP_UpdateSlot(slot));
|
||||||
#ifdef USEDSP
|
#ifdef USEDSP
|
||||||
SCSPDSP_SetSample(&SCSPs[1].DSP,(sample*LPANTABLE[(Enc|0xE0)&0xFFE0])>>(SHIFT+3),ISEL(slot),IMXL(slot));
|
SCSPDSP_SetSample(&SCSPs[1].DSP,(sample*LPANTABLE[(Enc|0xE0)&0xFFE0])>>(SHIFT+3),ISEL(slot),IMXL(slot));
|
||||||
#endif
|
#endif
|
||||||
|
@ -1847,8 +1859,10 @@ void SCSP_DoMasterSamples(int nsamples)
|
||||||
if(ef)
|
if(ef)
|
||||||
{
|
{
|
||||||
unsigned short Enc=0|((EFPAN(slot))<<0x0)|((EFSDL(slot))<<0x5);
|
unsigned short Enc=0|((EFPAN(slot))<<0x0)|((EFSDL(slot))<<0x5);
|
||||||
smpl+=(SCSPs[0].DSP.EFREG[i]*LPANTABLE[Enc])>>SHIFT;
|
signed int leftSample = (int) (masterBalance*(float)((SCSPs[0].DSP.EFREG[i]*LPANTABLE[Enc])>>SHIFT));
|
||||||
smpr+=(SCSPs[0].DSP.EFREG[i]*RPANTABLE[Enc])>>SHIFT;
|
signed int rightSample = (int) (masterBalance*(float)((SCSPs[0].DSP.EFREG[i]*RPANTABLE[Enc])>>SHIFT));
|
||||||
|
smpl+=leftSample;
|
||||||
|
smpr+=rightSample;
|
||||||
}
|
}
|
||||||
if(HasSlaveSCSP)
|
if(HasSlaveSCSP)
|
||||||
{
|
{
|
||||||
|
@ -1857,8 +1871,10 @@ void SCSP_DoMasterSamples(int nsamples)
|
||||||
if(ef)
|
if(ef)
|
||||||
{
|
{
|
||||||
unsigned short Enc=0|((EFPAN(slot))<<0x0)|((EFSDL(slot))<<0x5);
|
unsigned short Enc=0|((EFPAN(slot))<<0x0)|((EFSDL(slot))<<0x5);
|
||||||
smpl+=(SCSPs[1].DSP.EFREG[i]*LPANTABLE[Enc])>>SHIFT;
|
signed int leftSample = (int) (slaveBalance*(float)((SCSPs[1].DSP.EFREG[i]*LPANTABLE[Enc])>>SHIFT));
|
||||||
smpr+=(SCSPs[1].DSP.EFREG[i]*RPANTABLE[Enc])>>SHIFT;
|
signed int rightSample = (int) (slaveBalance*(float)((SCSPs[1].DSP.EFREG[i]*RPANTABLE[Enc])>>SHIFT));
|
||||||
|
smpl+=leftSample;
|
||||||
|
smpr+=rightSample;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue