mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-22 05:45:38 +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)
|
||||
|
||||
// Sound (SCSP) volume (0-200, 100 being full amplitude)
|
||||
inline void SetSoundVolume(unsigned vol)
|
||||
inline void SetSoundVolume(int vol)
|
||||
{
|
||||
if (vol > 200)
|
||||
{
|
||||
|
@ -61,7 +61,13 @@ public:
|
|||
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)
|
||||
|
@ -70,7 +76,7 @@ public:
|
|||
}
|
||||
|
||||
// Music (DSB MPEG) volume (0-200)
|
||||
inline void SetMusicVolume(unsigned vol)
|
||||
inline void SetMusicVolume(int vol)
|
||||
{
|
||||
if (vol > 200)
|
||||
{
|
||||
|
@ -78,7 +84,13 @@ public:
|
|||
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)
|
||||
|
|
|
@ -43,11 +43,38 @@ class CSoundBoardConfig
|
|||
public:
|
||||
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
|
||||
CSoundBoardConfig(void)
|
||||
{
|
||||
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)
|
||||
{
|
||||
unsigned x;
|
||||
int y;
|
||||
string String;
|
||||
|
||||
// Model 3
|
||||
|
@ -374,6 +375,8 @@ static void ApplySettings(CINIFile *INI, const char *section)
|
|||
g_Config.SetSoundVolume(x);
|
||||
if (OKAY == INI->Get(section, "MusicVolume", x))
|
||||
g_Config.SetMusicVolume(x);
|
||||
if (OKAY == INI->Get(section, "Balance", y))
|
||||
g_Config.SetSCSPBalance(y);
|
||||
if (OKAY == INI->Get(section, "EmulateSound", x))
|
||||
g_Config.emulateSound = x ? true : false;
|
||||
if (OKAY == INI->Get(section, "EmulateDSB", x))
|
||||
|
@ -464,6 +467,7 @@ static void LogConfig(void)
|
|||
|
||||
// CSoundBoardConfig
|
||||
InfoLog("\tEmulateSound = %d", g_Config.emulateSound);
|
||||
InfoLog("\tBalance = %d", g_Config.GetSCSPBalance());
|
||||
|
||||
// CDSBConfig
|
||||
InfoLog("\tEmulateDSB = %d", g_Config.emulateDSB);
|
||||
|
@ -1205,7 +1209,7 @@ static void Help(void)
|
|||
puts(" -print-games List supported games and quit");
|
||||
puts("");
|
||||
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("");
|
||||
puts("Video Options:");
|
||||
|
@ -1218,8 +1222,9 @@ static void Help(void)
|
|||
puts(" -print-gl-info Print OpenGL driver information and quit");
|
||||
puts("");
|
||||
puts("Audio Options:");
|
||||
puts(" -sound-volume=<v> Volume of sound effects in % [Default: 100]");
|
||||
puts(" -music-volume=<v> Volume of MPEG music in % [Default: 100]");
|
||||
puts(" -sound-volume=<vol> Volume of sound effects 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(" -no-sound Disable sound board emulation (sound effects)");
|
||||
puts(" -no-dsb Disable Digital Sound Board (MPEG music)");
|
||||
|
@ -1277,6 +1282,7 @@ int main(int argc, char **argv)
|
|||
#endif // SUPERMODEL_DEBUGGER
|
||||
char *inputSystem = NULL; // use default input system
|
||||
unsigned n;
|
||||
int m;
|
||||
UINT32 addr;
|
||||
|
||||
Title();
|
||||
|
@ -1358,6 +1364,14 @@ int main(int argc, char **argv)
|
|||
else
|
||||
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"))
|
||||
{
|
||||
n = 1;
|
||||
|
|
|
@ -968,7 +968,7 @@ void SCSP_w8(unsigned int addr,unsigned char val)
|
|||
int slot=addr/0x20;
|
||||
addr&=0x1f;
|
||||
//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;
|
||||
SCSP_UpdateSlotReg(slot,(addr^1)&0x1f);
|
||||
}
|
||||
|
@ -1008,7 +1008,7 @@ void SCSP_w16(unsigned int addr,unsigned short val)
|
|||
int slot=addr/0x20;
|
||||
addr&=0x1f;
|
||||
//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;
|
||||
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)
|
||||
{
|
||||
addr&=0xffff;
|
||||
|
||||
if(addr<0x400)
|
||||
{
|
||||
int slot=addr/0x20;
|
||||
addr&=0x1f;
|
||||
//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);
|
||||
|
||||
*(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
|
||||
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)
|
||||
{
|
||||
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);
|
||||
RBUFDST=SCSPs[0].RINGBUF+SCSPs[0].BUFPTR;
|
||||
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)!=0x1c77e)
|
||||
sample=0;
|
||||
else*/
|
||||
sample=SCSP_UpdateSlot(slot);
|
||||
sample= (int) (masterBalance*(float)SCSP_UpdateSlot(slot));
|
||||
|
||||
|
||||
/*unsigned char ef=EFSDL(slot);
|
||||
|
@ -1816,7 +1828,7 @@ void SCSP_DoMasterSamples(int nsamples)
|
|||
_SLOT *slot=SCSPs[1].Slots+sl;
|
||||
unsigned short Enc=((TL(slot))<<0x8)|((DIPAN(slot))<<0x0)|((DISDL(slot))<<0x5);
|
||||
RBUFDST=SCSPs[1].RINGBUF+SCSPs[1].BUFPTR;
|
||||
signed int sample=SCSP_UpdateSlot(slot);
|
||||
signed int sample=(int) (slaveBalance*(float)SCSP_UpdateSlot(slot));
|
||||
#ifdef USEDSP
|
||||
SCSPDSP_SetSample(&SCSPs[1].DSP,(sample*LPANTABLE[(Enc|0xE0)&0xFFE0])>>(SHIFT+3),ISEL(slot),IMXL(slot));
|
||||
#endif
|
||||
|
@ -1847,8 +1859,10 @@ void SCSP_DoMasterSamples(int nsamples)
|
|||
if(ef)
|
||||
{
|
||||
unsigned short Enc=0|((EFPAN(slot))<<0x0)|((EFSDL(slot))<<0x5);
|
||||
smpl+=(SCSPs[0].DSP.EFREG[i]*LPANTABLE[Enc])>>SHIFT;
|
||||
smpr+=(SCSPs[0].DSP.EFREG[i]*RPANTABLE[Enc])>>SHIFT;
|
||||
signed int leftSample = (int) (masterBalance*(float)((SCSPs[0].DSP.EFREG[i]*LPANTABLE[Enc])>>SHIFT));
|
||||
signed int rightSample = (int) (masterBalance*(float)((SCSPs[0].DSP.EFREG[i]*RPANTABLE[Enc])>>SHIFT));
|
||||
smpl+=leftSample;
|
||||
smpr+=rightSample;
|
||||
}
|
||||
if(HasSlaveSCSP)
|
||||
{
|
||||
|
@ -1857,8 +1871,10 @@ void SCSP_DoMasterSamples(int nsamples)
|
|||
if(ef)
|
||||
{
|
||||
unsigned short Enc=0|((EFPAN(slot))<<0x0)|((EFSDL(slot))<<0x5);
|
||||
smpl+=(SCSPs[1].DSP.EFREG[i]*LPANTABLE[Enc])>>SHIFT;
|
||||
smpr+=(SCSPs[1].DSP.EFREG[i]*RPANTABLE[Enc])>>SHIFT;
|
||||
signed int leftSample = (int) (slaveBalance*(float)((SCSPs[1].DSP.EFREG[i]*LPANTABLE[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