mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-26 07:35:40 +00:00
Merge branch 'master' of https://github.com/trzy/Supermodel
This commit is contained in:
commit
9348fd852d
|
@ -91,7 +91,7 @@ const char* CInput::GetInputGroup()
|
||||||
case Game::INPUT_JOYSTICK1: // Fall through to below
|
case Game::INPUT_JOYSTICK1: // Fall through to below
|
||||||
case Game::INPUT_JOYSTICK2: return "4-Way Joysticks";
|
case Game::INPUT_JOYSTICK2: return "4-Way Joysticks";
|
||||||
case Game::INPUT_FIGHTING: return "Fighting Game Buttons";
|
case Game::INPUT_FIGHTING: return "Fighting Game Buttons";
|
||||||
case Game::INPUT_SPIKEOUT: return "Spikeout Buttons";
|
case Game::INPUT_SPIKEOUT: return "Spikeout Buttons";
|
||||||
case Game::INPUT_SOCCER: return "Virtua Striker Buttons";
|
case Game::INPUT_SOCCER: return "Virtua Striker Buttons";
|
||||||
case Game::INPUT_VEHICLE: return "Racing Game Steering Controls";
|
case Game::INPUT_VEHICLE: return "Racing Game Steering Controls";
|
||||||
case Game::INPUT_SHIFT4: return "Racing Game Gear 4-Way Shift";
|
case Game::INPUT_SHIFT4: return "Racing Game Gear 4-Way Shift";
|
||||||
|
@ -108,8 +108,8 @@ const char* CInput::GetInputGroup()
|
||||||
case Game::INPUT_ANALOG_GUN2: return "Analog Guns";
|
case Game::INPUT_ANALOG_GUN2: return "Analog Guns";
|
||||||
case Game::INPUT_SKI: return "Ski Controls";
|
case Game::INPUT_SKI: return "Ski Controls";
|
||||||
case Game::INPUT_MAGTRUCK: return "Magical Truck Controls";
|
case Game::INPUT_MAGTRUCK: return "Magical Truck Controls";
|
||||||
case Game::INPUT_FISHING: return "Fishing Controls";
|
case Game::INPUT_FISHING: return "Fishing Controls";
|
||||||
default: return "Misc";
|
default: return "Misc";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ void CInput::AppendMapping(const char *mapping)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Otherwise, append to mapping string and recreate source from new mapping string
|
// Otherwise, append to mapping string and recreate source from new mapping string
|
||||||
int size = MAX_MAPPING_LENGTH - strlen(m_mapping);
|
size_t size = MAX_MAPPING_LENGTH - strlen(m_mapping);
|
||||||
strncat(m_mapping, ",", size--);
|
strncat(m_mapping, ",", size--);
|
||||||
strncat(m_mapping, mapping, size);
|
strncat(m_mapping, mapping, size);
|
||||||
CreateSource();
|
CreateSource();
|
||||||
|
|
|
@ -125,52 +125,31 @@ void CDSBResampler::Reset(void)
|
||||||
pFrac = 1<<8; // previous sample (1.0->0 as x moves p->n)
|
pFrac = 1<<8; // previous sample (1.0->0 as x moves p->n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mixes 16-bit samples (sign extended in a and b)
|
|
||||||
static inline INT16 MixAndClip(INT32 a, INT32 b)
|
|
||||||
{
|
|
||||||
a += b;
|
|
||||||
if (a > 32767)
|
|
||||||
a = 32767;
|
|
||||||
else if (a < -32768)
|
|
||||||
a = -32768;
|
|
||||||
return (INT16) a;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mixes audio and returns number of samples copied back to start of buffer (ie. offset at which new samples should be written)
|
// Mixes audio and returns number of samples copied back to start of buffer (ie. offset at which new samples should be written)
|
||||||
int CDSBResampler::UpSampleAndMix(INT16 *outL, INT16 *outR, INT16 *inL, INT16 *inR, UINT8 volumeL, UINT8 volumeR, int sizeOut, int sizeIn, int outRate, int inRate)
|
int CDSBResampler::UpSampleAndMix(float *outL, float *outR, INT16 *inL, INT16 *inR, UINT8 volumeL, UINT8 volumeR, int sizeOut, int sizeIn, int outRate, int inRate)
|
||||||
{
|
{
|
||||||
int delta = (inRate<<8)/outRate; // (1/fout)/(1/fin)=fin/fout, 24.8 fixed point
|
int delta = (inRate<<8)/outRate; // (1/fout)/(1/fin)=fin/fout, 24.8 fixed point
|
||||||
int outIdx = 0;
|
int outIdx = 0;
|
||||||
int inIdx = 0;
|
int inIdx = 0;
|
||||||
INT32 leftSample, rightSample, leftSoundSample, rightSoundSample;
|
float v[2], musicVol;
|
||||||
INT32 v[2], musicVol;
|
|
||||||
|
|
||||||
// Obtain program volume settings and convert to 24.8 fixed point (0-200 -> 0x00-0x200)
|
// Obtain program volume settings
|
||||||
musicVol = m_config["MusicVolume"].ValueAs<int>();
|
musicVol = (float)std::max(0,std::min(200,m_config["MusicVolume"].ValueAs<int>()));
|
||||||
musicVol = (INT32) ((float) 0x100 * (float) musicVol / 100.0f);
|
musicVol = musicVol * (float) (1.0 / 100.0);
|
||||||
|
|
||||||
// Scale volume from 0x00-0xFF -> 0x00-0x100 (24.8 fixed point)
|
v[0] = musicVol * (float) volumeL * (float) (1.0 / (255.0*256.0)); // 256 is there to correct for fixed point interpolation below
|
||||||
v[0] = (INT16) ((float) 0x100 * (float) volumeL / 255.0f);
|
v[1] = musicVol * (float) volumeR * (float) (1.0 / (255.0*256.0));
|
||||||
v[1] = (INT16) ((float) 0x100 * (float) volumeR / 255.0f);
|
|
||||||
|
|
||||||
// Up-sample and mix!
|
// Up-sample and mix!
|
||||||
while (outIdx < sizeOut)
|
while (outIdx < sizeOut)
|
||||||
{
|
{
|
||||||
// nFrac, pFrac will never exceed 1.0 (0x100) (only true if delta does not exceed 1)
|
// nFrac, pFrac will never exceed 1.0 (0x100) (only true if delta does not exceed 1)
|
||||||
leftSample = ((int)inL[inIdx]*pFrac+(int)inL[inIdx+1]*nFrac) >> 8; // left channel
|
INT32 leftSample = (int)inL[inIdx]*pFrac+(int)inL[inIdx+1]*nFrac; // left channel
|
||||||
rightSample = ((int)inR[inIdx]*pFrac+(int)inR[inIdx+1]*nFrac) >> 8; // right channel
|
INT32 rightSample = (int)inR[inIdx]*pFrac+(int)inR[inIdx+1]*nFrac; // right channel
|
||||||
|
|
||||||
// Apply DSB volume and then overall music volume setting
|
// Apply DSB volume+overall music volume setting, and mix into output
|
||||||
leftSample = (leftSample*v[0]*musicVol) >> 16; // multiplied by two 24.8 numbers, shift back by 16
|
outL[outIdx] += (float)leftSample * v[0];
|
||||||
rightSample = (rightSample*v[0]*musicVol) >> 16;
|
outR[outIdx] += (float)rightSample * v[1];
|
||||||
|
|
||||||
// Apply sound volume setting
|
|
||||||
leftSoundSample = outL[outIdx];
|
|
||||||
rightSoundSample = outR[outIdx];
|
|
||||||
|
|
||||||
// Mix and output
|
|
||||||
outL[outIdx] = MixAndClip(leftSoundSample, leftSample);
|
|
||||||
outR[outIdx] = MixAndClip(rightSoundSample, rightSample);
|
|
||||||
outIdx++;
|
outIdx++;
|
||||||
|
|
||||||
// Time step
|
// Time step
|
||||||
|
@ -422,11 +401,8 @@ void CDSB1::SendCommand(UINT8 data)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDSB1::RunFrame(INT16 *audioL, INT16 *audioR)
|
void CDSB1::RunFrame(float *audioL, float *audioR)
|
||||||
{
|
{
|
||||||
int cycles;
|
|
||||||
UINT8 v;
|
|
||||||
|
|
||||||
if (!m_config["EmulateDSB"].ValueAs<bool>())
|
if (!m_config["EmulateDSB"].ValueAs<bool>())
|
||||||
{
|
{
|
||||||
// DSB code applies SCSP volume, too, so we must still mix
|
// DSB code applies SCSP volume, too, so we must still mix
|
||||||
|
@ -436,6 +412,7 @@ void CDSB1::RunFrame(INT16 *audioL, INT16 *audioR)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cycles;
|
||||||
// While FIFO not empty, fire interrupts, run for up to one frame
|
// While FIFO not empty, fire interrupts, run for up to one frame
|
||||||
for (cycles = (4000000/60); (cycles > 0) && (fifoIdxR != fifoIdxW); )
|
for (cycles = (4000000/60); (cycles > 0) && (fifoIdxR != fifoIdxW); )
|
||||||
{
|
{
|
||||||
|
@ -450,7 +427,7 @@ void CDSB1::RunFrame(INT16 *audioL, INT16 *audioR)
|
||||||
//printf("VOLUME=%02X STEREO=%02X\n", volume, stereo);
|
//printf("VOLUME=%02X STEREO=%02X\n", volume, stereo);
|
||||||
|
|
||||||
// Convert volume from 0x00-0x7F -> 0x00-0xFF
|
// Convert volume from 0x00-0x7F -> 0x00-0xFF
|
||||||
v = (UINT8) ((float) 255.0f * (float) volume /127.0f);
|
UINT8 v = (UINT8) ((float) volume * (float)(255.0/127.0));
|
||||||
|
|
||||||
// Decode MPEG for this frame
|
// Decode MPEG for this frame
|
||||||
MpegDec::DecodeAudio(&mpegL[retainedSamples], &mpegR[retainedSamples], 32000 / 60 - retainedSamples + 2);
|
MpegDec::DecodeAudio(&mpegL[retainedSamples], &mpegR[retainedSamples], 32000 / 60 - retainedSamples + 2);
|
||||||
|
@ -991,14 +968,14 @@ void CDSB2::SendCommand(UINT8 data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CDSB2::RunFrame(INT16 *audioL, INT16 *audioR)
|
void CDSB2::RunFrame(float *audioL, float *audioR)
|
||||||
{
|
{
|
||||||
if (!m_config["EmulateDSB"].ValueAs<bool>())
|
if (!m_config["EmulateDSB"].ValueAs<bool>())
|
||||||
{
|
{
|
||||||
// DSB code applies SCSP volume, too, so we must still mix
|
// DSB code applies SCSP volume, too, so we must still mix
|
||||||
memset(mpegL, 0, (32000 / 60 + 2) * sizeof(INT16));
|
memset(mpegL, 0, (32000/60+2) * sizeof(INT16));
|
||||||
memset(mpegR, 0, (32000 / 60 + 2) * sizeof(INT16));
|
memset(mpegR, 0, (32000/60+2) * sizeof(INT16));
|
||||||
retainedSamples = Resampler.UpSampleAndMix(audioL, audioR, mpegL, mpegR, volume[0], volume[1], NUM_SAMPLES_PER_FRAME, 32000 / 60 + 2, 44100, 32000);
|
retainedSamples = Resampler.UpSampleAndMix(audioL, audioR, mpegL, mpegR, 0, 0, NUM_SAMPLES_PER_FRAME, 32000/60+2, 44100, 32000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1069,7 +1046,7 @@ void CDSB2::RunFrame(INT16 *audioL, INT16 *audioR)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
retainedSamples = Resampler.UpSampleAndMix(audioL, audioR, leftChannelSource, rightChannelSource, volL, volR, NUM_SAMPLES_PER_FRAME, 32000 / 60 + 2, 44100, 32000);
|
retainedSamples = Resampler.UpSampleAndMix(audioL, audioR, leftChannelSource, rightChannelSource, volL, volR, NUM_SAMPLES_PER_FRAME, 32000/60+2, 44100, 32000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDSB2::Reset(void)
|
void CDSB2::Reset(void)
|
||||||
|
|
|
@ -71,7 +71,7 @@
|
||||||
class CDSBResampler
|
class CDSBResampler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int UpSampleAndMix(INT16 *outL, INT16 *outR, INT16 *inL, INT16 *inR, UINT8 volumeL, UINT8 volumeR, int sizeOut, int sizeIn, int outRate, int inRate);
|
int UpSampleAndMix(float *outL, float *outR, INT16 *inL, INT16 *inR, UINT8 volumeL, UINT8 volumeR, int sizeOut, int sizeIn, int outRate, int inRate);
|
||||||
void Reset(void);
|
void Reset(void);
|
||||||
CDSBResampler(const Util::Config::Node &config)
|
CDSBResampler(const Util::Config::Node &config)
|
||||||
: m_config(config)
|
: m_config(config)
|
||||||
|
@ -114,7 +114,7 @@ public:
|
||||||
* audioL Left audio channel, one frame (44 KHz, 1/60th second).
|
* audioL Left audio channel, one frame (44 KHz, 1/60th second).
|
||||||
* audioR Right audio channel.
|
* audioR Right audio channel.
|
||||||
*/
|
*/
|
||||||
virtual void RunFrame(INT16 *audioL, INT16 *audioR) = 0;
|
virtual void RunFrame(float *audioL, float *audioR) = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset(void):
|
* Reset(void):
|
||||||
|
@ -187,7 +187,7 @@ public:
|
||||||
|
|
||||||
// DSB interface (see CDSB definition)
|
// DSB interface (see CDSB definition)
|
||||||
void SendCommand(UINT8 data);
|
void SendCommand(UINT8 data);
|
||||||
void RunFrame(INT16 *audioL, INT16 *audioR);
|
void RunFrame(float *audioL, float *audioR);
|
||||||
void Reset(void);
|
void Reset(void);
|
||||||
void SaveState(CBlockFile *StateFile);
|
void SaveState(CBlockFile *StateFile);
|
||||||
void LoadState(CBlockFile *StateFile);
|
void LoadState(CBlockFile *StateFile);
|
||||||
|
@ -264,7 +264,7 @@ public:
|
||||||
|
|
||||||
// DSB interface (see definition of CDSB)
|
// DSB interface (see definition of CDSB)
|
||||||
void SendCommand(UINT8 data);
|
void SendCommand(UINT8 data);
|
||||||
void RunFrame(INT16 *audioL, INT16 *audioR);
|
void RunFrame(float *audioL, float *audioR);
|
||||||
void Reset(void);
|
void Reset(void);
|
||||||
void SaveState(CBlockFile *StateFile);
|
void SaveState(CBlockFile *StateFile);
|
||||||
void LoadState(CBlockFile *StateFile);
|
void LoadState(CBlockFile *StateFile);
|
||||||
|
|
|
@ -70,11 +70,11 @@ static FILE *soundFP;
|
||||||
// Offsets of memory regions within sound board's pool
|
// Offsets of memory regions within sound board's pool
|
||||||
#define OFFSET_RAM1 0 // 1 MB SCSP1 RAM
|
#define OFFSET_RAM1 0 // 1 MB SCSP1 RAM
|
||||||
#define OFFSET_RAM2 0x100000 // 1 MB SCSP2 RAM
|
#define OFFSET_RAM2 0x100000 // 1 MB SCSP2 RAM
|
||||||
#define LENGTH_CHANNEL_BUFFER (sizeof(INT16)*NUM_SAMPLES_PER_FRAME) // 1470 bytes (16 bits x 44.1 KHz x 1/60th second)
|
#define LENGTH_CHANNEL_BUFFER (sizeof(float)*NUM_SAMPLES_PER_FRAME) // 2940 bytes (32 bits x 44.1 KHz x 1/60th second)
|
||||||
#define OFFSET_AUDIO_FRONTLEFT 0x200000 // 1470 bytes (16 bits, 44.1 KHz, 1/60th second) left audio channel
|
#define OFFSET_AUDIO_FRONTLEFT 0x200000 // 2940 bytes (32 bits, 44.1 KHz, 1/60th second) left audio channel
|
||||||
#define OFFSET_AUDIO_FRONTRIGHT (OFFSET_AUDIO_FRONTLEFT + LENGTH_CHANNEL_BUFFER) // 1470 bytes right audio channel
|
#define OFFSET_AUDIO_FRONTRIGHT (OFFSET_AUDIO_FRONTLEFT + LENGTH_CHANNEL_BUFFER) // 2940 bytes right audio channel
|
||||||
#define OFFSET_AUDIO_REARLEFT (OFFSET_AUDIO_FRONTRIGHT + LENGTH_CHANNEL_BUFFER) // 1470 bytes (16 bits, 44.1 KHz, 1/60th second) left audio channel
|
#define OFFSET_AUDIO_REARLEFT (OFFSET_AUDIO_FRONTRIGHT + LENGTH_CHANNEL_BUFFER) // 2940 bytes (32 bits, 44.1 KHz, 1/60th second) left audio channel
|
||||||
#define OFFSET_AUDIO_REARRIGHT (OFFSET_AUDIO_REARLEFT + LENGTH_CHANNEL_BUFFER) // 1470 bytes right audio channel
|
#define OFFSET_AUDIO_REARRIGHT (OFFSET_AUDIO_REARLEFT + LENGTH_CHANNEL_BUFFER) // 2940 bytes right audio channel
|
||||||
|
|
||||||
#define MEMORY_POOL_SIZE (0x100000 + 0x100000 + 4*LENGTH_CHANNEL_BUFFER)
|
#define MEMORY_POOL_SIZE (0x100000 + 0x100000 + 4*LENGTH_CHANNEL_BUFFER)
|
||||||
|
|
||||||
|
@ -351,6 +351,18 @@ void CSoundBoard::WriteMIDIPort(UINT8 data)
|
||||||
DSB->SendCommand(data);
|
DSB->SendCommand(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static INT16 ClampINT16(float x)
|
||||||
|
{
|
||||||
|
INT32 xi = (INT32)x;
|
||||||
|
if (xi > INT16_MAX) {
|
||||||
|
xi = INT16_MAX;
|
||||||
|
}
|
||||||
|
if (xi < INT16_MIN) {
|
||||||
|
xi = INT16_MIN;
|
||||||
|
}
|
||||||
|
return (INT16)xi;
|
||||||
|
}
|
||||||
|
|
||||||
bool CSoundBoard::RunFrame(void)
|
bool CSoundBoard::RunFrame(void)
|
||||||
{
|
{
|
||||||
// Run sound board first to generate SCSP audio
|
// Run sound board first to generate SCSP audio
|
||||||
|
@ -369,15 +381,15 @@ bool CSoundBoard::RunFrame(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute sound volume as
|
// Compute sound volume as
|
||||||
INT32 soundVol = m_config["SoundVolume"].ValueAs<int>();
|
float soundVol = (float)std::max(0,std::min(200,m_config["SoundVolume"].ValueAs<int>()));
|
||||||
soundVol = (INT32)((float)0x100 * (float)soundVol / 100.0f);
|
soundVol = soundVol * (float)(1.0 / 100.0);
|
||||||
|
|
||||||
// Apply sound volume setting to SCSP channels only
|
// Apply sound volume setting to SCSP channels only
|
||||||
for (int i = 0; i < NUM_SAMPLES_PER_FRAME; i++) {
|
for (int i = 0; i < NUM_SAMPLES_PER_FRAME; i++) {
|
||||||
audioFL[i] = (audioFL[i]*soundVol) >> 8;
|
audioFL[i] *= soundVol;
|
||||||
audioFR[i] = (audioFR[i]*soundVol) >> 8;
|
audioFR[i] *= soundVol;
|
||||||
audioRL[i] = (audioRL[i]*soundVol) >> 8;
|
audioRL[i] *= soundVol;
|
||||||
audioRR[i] = (audioRR[i]*soundVol) >> 8;
|
audioRR[i] *= soundVol;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run DSB and mix with existing audio, apply music volume
|
// Run DSB and mix with existing audio, apply music volume
|
||||||
|
@ -399,9 +411,13 @@ bool CSoundBoard::RunFrame(void)
|
||||||
INT16 s;
|
INT16 s;
|
||||||
for (int i = 0; i < NUM_SAMPLES_PER_FRAME; i++)
|
for (int i = 0; i < NUM_SAMPLES_PER_FRAME; i++)
|
||||||
{
|
{
|
||||||
s = audioL[i];
|
s = ClampINT16(audioFL[i]);
|
||||||
fwrite(&s, sizeof(INT16), 1, soundFP); // left channel
|
fwrite(&s, sizeof(INT16), 1, soundFP); // left channel
|
||||||
s = audioR[i];
|
s = ClampINT16(audioFR[i]);
|
||||||
|
fwrite(&s, sizeof(INT16), 1, soundFP); // right channel
|
||||||
|
s = ClampINT16(audioRL[i]);
|
||||||
|
fwrite(&s, sizeof(INT16), 1, soundFP); // left channel
|
||||||
|
s = ClampINT16(audioRR[i]);
|
||||||
fwrite(&s, sizeof(INT16), 1, soundFP); // right channel
|
fwrite(&s, sizeof(INT16), 1, soundFP); // right channel
|
||||||
}
|
}
|
||||||
#endif // SUPERMODEL_LOG_AUDIO
|
#endif // SUPERMODEL_LOG_AUDIO
|
||||||
|
@ -496,10 +512,10 @@ bool CSoundBoard::Init(const UINT8 *soundROMPtr, const UINT8 *sampleROMPtr)
|
||||||
// Set up memory pointers
|
// Set up memory pointers
|
||||||
ram1 = &memoryPool[OFFSET_RAM1];
|
ram1 = &memoryPool[OFFSET_RAM1];
|
||||||
ram2 = &memoryPool[OFFSET_RAM2];
|
ram2 = &memoryPool[OFFSET_RAM2];
|
||||||
audioFL = (INT16*)&memoryPool[OFFSET_AUDIO_FRONTLEFT];
|
audioFL = (float*)&memoryPool[OFFSET_AUDIO_FRONTLEFT];
|
||||||
audioFR = (INT16*)&memoryPool[OFFSET_AUDIO_FRONTRIGHT];
|
audioFR = (float*)&memoryPool[OFFSET_AUDIO_FRONTRIGHT];
|
||||||
audioRL = (INT16*)&memoryPool[OFFSET_AUDIO_REARLEFT];
|
audioRL = (float*)&memoryPool[OFFSET_AUDIO_REARLEFT];
|
||||||
audioRR = (INT16*)&memoryPool[OFFSET_AUDIO_REARRIGHT];
|
audioRR = (float*)&memoryPool[OFFSET_AUDIO_REARRIGHT];
|
||||||
|
|
||||||
// Initialize 68K core
|
// Initialize 68K core
|
||||||
M68KSetContext(&M68K);
|
M68KSetContext(&M68K);
|
||||||
|
|
|
@ -203,8 +203,8 @@ private:
|
||||||
UINT8 ctrlReg; // control register: ROM banking
|
UINT8 ctrlReg; // control register: ROM banking
|
||||||
|
|
||||||
// Audio
|
// Audio
|
||||||
INT16* audioFL, * audioFR; // left and right front audio channels (1/60th second, 44.1 KHz)
|
float* audioFL, * audioFR; // left and right front audio channels (1/60th second, 44.1 KHz)
|
||||||
INT16* audioRL, * audioRR; // left and right rear audio channels (1/60th second, 44.1 KHz)
|
float* audioRL, * audioRR; // left and right rear audio channels (1/60th second, 44.1 KHz)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ extern bool OpenAudio(const Util::Config::Node& config);
|
||||||
*
|
*
|
||||||
* Sends a chunk of two-channel audio with the given number of samples to the audio system.
|
* Sends a chunk of two-channel audio with the given number of samples to the audio system.
|
||||||
*/
|
*/
|
||||||
extern bool OutputAudio(unsigned numSamples, INT16* leftFrontBuffer, INT16* rightFrontBuffer, INT16* leftRearBuffer, INT16* rightRearBuffer, bool flipStereo);
|
extern bool OutputAudio(unsigned numSamples, const float* leftFrontBuffer, const float* rightFrontBuffer, const float* leftRearBuffer, const float* rightRearBuffer, bool flipStereo);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CloseAudio()
|
* CloseAudio()
|
||||||
|
|
|
@ -166,6 +166,35 @@ static INT16 MixINT16(INT32 x, INT32 y)
|
||||||
return (INT16)sum;
|
return (INT16)sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static INT16 MixINT16(float x, float y)
|
||||||
|
{
|
||||||
|
INT32 sum = (INT32)((x + y)*0.5f); //!! dither
|
||||||
|
if (sum > INT16_MAX) {
|
||||||
|
sum = INT16_MAX;
|
||||||
|
}
|
||||||
|
if (sum < INT16_MIN) {
|
||||||
|
sum = INT16_MIN;
|
||||||
|
}
|
||||||
|
return (INT16)sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float MixFloat(float x, float y)
|
||||||
|
{
|
||||||
|
return (x + y)*0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INT16 ClampINT16(float x)
|
||||||
|
{
|
||||||
|
INT32 xi = (INT32)x;
|
||||||
|
if (xi > INT16_MAX) {
|
||||||
|
xi = INT16_MAX;
|
||||||
|
}
|
||||||
|
if (xi < INT16_MIN) {
|
||||||
|
xi = INT16_MIN;
|
||||||
|
}
|
||||||
|
return (INT16)xi;
|
||||||
|
}
|
||||||
|
|
||||||
static void PlayCallback(void* data, Uint8* stream, int len)
|
static void PlayCallback(void* data, Uint8* stream, int len)
|
||||||
{
|
{
|
||||||
//printf("PlayCallback(%d) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u]\n",
|
//printf("PlayCallback(%d) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u]\n",
|
||||||
|
@ -271,15 +300,15 @@ static void PlayCallback(void* data, Uint8* stream, int len)
|
||||||
callback(callbackData);
|
callback(callbackData);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MixChannels(unsigned numSamples, INT16* leftFrontBuffer, INT16* rightFrontBuffer, INT16* leftRearBuffer, INT16* rightRearBuffer, void* dest, bool flipStereo)
|
static void MixChannels(unsigned numSamples, const float* leftFrontBuffer, const float* rightFrontBuffer, const float* leftRearBuffer, const float* rightRearBuffer, void* dest, bool flipStereo)
|
||||||
{
|
{
|
||||||
INT16* p = (INT16*)dest;
|
INT16* p = (INT16*)dest;
|
||||||
|
|
||||||
if (nbHostAudioChannels == 1) {
|
if (nbHostAudioChannels == 1) {
|
||||||
for (unsigned i = 0; i < numSamples; i++) {
|
for (unsigned i = 0; i < numSamples; i++) {
|
||||||
INT16 monovalue = MixINT16(
|
INT16 monovalue = MixINT16(
|
||||||
MixINT16((INT32)(leftFrontBuffer[i] * balanceFactorFrontLeft), (INT32)(rightFrontBuffer[i] * balanceFactorFrontRight)),
|
MixFloat(leftFrontBuffer[i] * balanceFactorFrontLeft,rightFrontBuffer[i] * balanceFactorFrontRight),
|
||||||
MixINT16((INT32)(leftRearBuffer[i] * balanceFactorRearLeft), (INT32)(rightRearBuffer[i] * balanceFactorRearRight)));
|
MixFloat(leftRearBuffer[i] * balanceFactorRearLeft, rightRearBuffer[i] * balanceFactorRearRight));
|
||||||
*p++ = monovalue;
|
*p++ = monovalue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -295,8 +324,8 @@ static void MixChannels(unsigned numSamples, INT16* leftFrontBuffer, INT16* righ
|
||||||
// Now order channels according to audio type
|
// Now order channels according to audio type
|
||||||
if (nbHostAudioChannels == 2) {
|
if (nbHostAudioChannels == 2) {
|
||||||
for (unsigned i = 0; i < numSamples; i++) {
|
for (unsigned i = 0; i < numSamples; i++) {
|
||||||
INT16 leftvalue = MixINT16((INT32)(leftFrontBuffer[i] * balanceFactorFrontLeft), (INT32)(leftRearBuffer[i] * balanceFactorRearLeft));
|
INT16 leftvalue = MixINT16(leftFrontBuffer[i] * balanceFactorFrontLeft, leftRearBuffer[i] * balanceFactorRearLeft);
|
||||||
INT16 rightvalue = MixINT16((INT32)(rightFrontBuffer[i]*balanceFactorFrontRight), (INT32)(rightRearBuffer[i]*balanceFactorRearRight));
|
INT16 rightvalue = MixINT16(rightFrontBuffer[i]*balanceFactorFrontRight, rightRearBuffer[i]*balanceFactorRearRight);
|
||||||
if (flipStereo) // swap left and right channels
|
if (flipStereo) // swap left and right channels
|
||||||
{
|
{
|
||||||
*p++ = rightvalue;
|
*p++ = rightvalue;
|
||||||
|
@ -308,15 +337,15 @@ static void MixChannels(unsigned numSamples, INT16* leftFrontBuffer, INT16* righ
|
||||||
}
|
}
|
||||||
} else if (nbHostAudioChannels == 4) {
|
} else if (nbHostAudioChannels == 4) {
|
||||||
for (unsigned i = 0; i < numSamples; i++) {
|
for (unsigned i = 0; i < numSamples; i++) {
|
||||||
INT16 frontLeftValue = (INT16)(leftFrontBuffer[i]*balanceFactorFrontLeft);
|
float frontLeftValue = leftFrontBuffer[i]*balanceFactorFrontLeft;
|
||||||
INT16 frontRightValue = (INT16)(rightFrontBuffer[i]*balanceFactorFrontRight);
|
float frontRightValue = rightFrontBuffer[i]*balanceFactorFrontRight;
|
||||||
INT16 rearLeftValue = (INT16)(leftRearBuffer[i]*balanceFactorRearLeft);
|
float rearLeftValue = leftRearBuffer[i]*balanceFactorRearLeft;
|
||||||
INT16 rearRightValue = (INT16)(rightRearBuffer[i]*balanceFactorRearRight);
|
float rearRightValue = rightRearBuffer[i]*balanceFactorRearRight;
|
||||||
|
|
||||||
// Check game audio type
|
// Check game audio type
|
||||||
switch (AudioType) {
|
switch (AudioType) {
|
||||||
case Game::MONO: {
|
case Game::MONO: {
|
||||||
INT16 monovalue = MixINT16(MixINT16(frontLeftValue, frontRightValue), MixINT16(rearLeftValue, rearRightValue));
|
INT16 monovalue = MixINT16(MixFloat(frontLeftValue, frontRightValue), MixFloat(rearLeftValue, rearRightValue));
|
||||||
*p++ = monovalue;
|
*p++ = monovalue;
|
||||||
*p++ = monovalue;
|
*p++ = monovalue;
|
||||||
*p++ = monovalue;
|
*p++ = monovalue;
|
||||||
|
@ -346,15 +375,15 @@ static void MixChannels(unsigned numSamples, INT16* leftFrontBuffer, INT16* righ
|
||||||
// Normal channels Front Left/Right then Rear Left/Right
|
// Normal channels Front Left/Right then Rear Left/Right
|
||||||
if (flipStereo) // swap left and right channels
|
if (flipStereo) // swap left and right channels
|
||||||
{
|
{
|
||||||
*p++ = frontRightValue;
|
*p++ = ClampINT16(frontRightValue);
|
||||||
*p++ = frontLeftValue;
|
*p++ = ClampINT16(frontLeftValue);
|
||||||
*p++ = rearRightValue;
|
*p++ = ClampINT16(rearRightValue);
|
||||||
*p++ = rearLeftValue;
|
*p++ = ClampINT16(rearLeftValue);
|
||||||
} else {
|
} else {
|
||||||
*p++ = frontLeftValue;
|
*p++ = ClampINT16(frontLeftValue);
|
||||||
*p++ = frontRightValue;
|
*p++ = ClampINT16(frontRightValue);
|
||||||
*p++ = rearLeftValue;
|
*p++ = ClampINT16(rearLeftValue);
|
||||||
*p++ = rearRightValue;
|
*p++ = ClampINT16(rearRightValue);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -363,15 +392,15 @@ static void MixChannels(unsigned numSamples, INT16* leftFrontBuffer, INT16* righ
|
||||||
// Reversed channels Front/Rear Left then Front/Rear Right
|
// Reversed channels Front/Rear Left then Front/Rear Right
|
||||||
if (flipStereo) // swap left and right channels
|
if (flipStereo) // swap left and right channels
|
||||||
{
|
{
|
||||||
*p++ = rearRightValue;
|
*p++ = ClampINT16(rearRightValue);
|
||||||
*p++ = rearLeftValue;
|
*p++ = ClampINT16(rearLeftValue);
|
||||||
*p++ = frontRightValue;
|
*p++ = ClampINT16(frontRightValue);
|
||||||
*p++ = frontLeftValue;
|
*p++ = ClampINT16(frontLeftValue);
|
||||||
} else {
|
} else {
|
||||||
*p++ = rearLeftValue;
|
*p++ = ClampINT16(rearLeftValue);
|
||||||
*p++ = rearRightValue;
|
*p++ = ClampINT16(rearRightValue);
|
||||||
*p++ = frontLeftValue;
|
*p++ = ClampINT16(frontLeftValue);
|
||||||
*p++ = frontRightValue;
|
*p++ = ClampINT16(frontRightValue);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -440,19 +469,11 @@ bool OpenAudio(const Util::Config::Node& config)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Mixer Balance
|
// Mixer Balance
|
||||||
float balancelr = (float)s_config->Get("BalanceLeftRight").ValueAs<float>();
|
float balancelr = std::max(-100.f, std::min(100.f, s_config->Get("BalanceLeftRight").ValueAs<float>()));
|
||||||
if (balancelr < -100.0f)
|
|
||||||
balancelr = -100.0f;
|
|
||||||
else if (balancelr > 100.0f)
|
|
||||||
balancelr = 100.0f;
|
|
||||||
balancelr *= 0.01f;
|
balancelr *= 0.01f;
|
||||||
BalanceLeftRight = balancelr;
|
BalanceLeftRight = balancelr;
|
||||||
|
|
||||||
float balancefr = (float)s_config->Get("BalanceFrontRear").ValueAs<float>();
|
float balancefr = std::max(-100.f, std::min(100.f, s_config->Get("BalanceFrontRear").ValueAs<float>()));
|
||||||
if (balancefr < -100.0f)
|
|
||||||
balancefr = -100.0f;
|
|
||||||
else if (balancefr > 100.0f)
|
|
||||||
balancefr = 100.0f;
|
|
||||||
balancefr *= 0.01f;
|
balancefr *= 0.01f;
|
||||||
BalanceFrontRear = balancefr;
|
BalanceFrontRear = balancefr;
|
||||||
|
|
||||||
|
@ -462,8 +483,7 @@ bool OpenAudio(const Util::Config::Node& config)
|
||||||
balanceFactorRearRight = (BalanceLeftRight > 0.f ? 1.f - BalanceLeftRight : 1.f) * (BalanceFrontRear > 0 ? 1.f - BalanceFrontRear : 1.f);
|
balanceFactorRearRight = (BalanceLeftRight > 0.f ? 1.f - BalanceLeftRight : 1.f) * (BalanceFrontRear > 0 ? 1.f - BalanceFrontRear : 1.f);
|
||||||
|
|
||||||
// Set up audio specification
|
// Set up audio specification
|
||||||
SDL_AudioSpec desired;
|
SDL_AudioSpec desired{};
|
||||||
memset(&desired, 0, sizeof(SDL_AudioSpec));
|
|
||||||
desired.freq = SAMPLE_RATE_M3;
|
desired.freq = SAMPLE_RATE_M3;
|
||||||
// Number of host channels to use (choice limited to 1,2,4)
|
// Number of host channels to use (choice limited to 1,2,4)
|
||||||
desired.channels = nbHostAudioChannels;
|
desired.channels = nbHostAudioChannels;
|
||||||
|
@ -533,7 +553,7 @@ bool OpenAudio(const Util::Config::Node& config)
|
||||||
return OKAY;
|
return OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OutputAudio(unsigned numSamples, INT16* leftFrontBuffer, INT16* rightFrontBuffer, INT16* leftRearBuffer, INT16* rightRearBuffer, bool flipStereo)
|
bool OutputAudio(unsigned numSamples, const float* leftFrontBuffer, const float* rightFrontBuffer, const float* leftRearBuffer, const float* rightRearBuffer, bool flipStereo)
|
||||||
{
|
{
|
||||||
//printf("OutputAudio(%u) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u]\n",
|
//printf("OutputAudio(%u) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u]\n",
|
||||||
// numSamples, writePos, (writeWrapped ? "true" : "false"), playPos, audioBufferSize);
|
// numSamples, writePos, (writeWrapped ? "true" : "false"), playPos, audioBufferSize);
|
||||||
|
@ -559,7 +579,7 @@ bool OutputAudio(unsigned numSamples, INT16* leftFrontBuffer, INT16* rightFrontB
|
||||||
// Get end of current play region (writing must occur past this point)
|
// Get end of current play region (writing must occur past this point)
|
||||||
UINT32 playEndPos = playPos + bytes_per_frame_host;
|
UINT32 playEndPos = playPos + bytes_per_frame_host;
|
||||||
|
|
||||||
// Undo any wrap-around of the write position that may have occured to create following ordering: playPos < playEndPos < writePos
|
// Undo any wrap-around of the write position that may have occurred to create following ordering: playPos < playEndPos < writePos
|
||||||
if (playEndPos > writePos && writeWrapped)
|
if (playEndPos > writePos && writeWrapped)
|
||||||
writePos += audioBufferSize;
|
writePos += audioBufferSize;
|
||||||
|
|
||||||
|
@ -619,9 +639,9 @@ bool OutputAudio(unsigned numSamples, INT16* leftFrontBuffer, INT16* rightFrontB
|
||||||
bufferFull = true;
|
bufferFull = true;
|
||||||
|
|
||||||
// Discard current chunk of data
|
// Discard current chunk of data
|
||||||
goto Finish;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
src = mixBuffer;
|
src = mixBuffer;
|
||||||
INT8* dst1;
|
INT8* dst1;
|
||||||
INT8* dst2;
|
INT8* dst2;
|
||||||
|
@ -641,9 +661,9 @@ bool OutputAudio(unsigned numSamples, INT16* leftFrontBuffer, INT16* rightFrontB
|
||||||
{
|
{
|
||||||
// Otherwise, just copy whole region
|
// Otherwise, just copy whole region
|
||||||
dst1 = audioBuffer + writePos;
|
dst1 = audioBuffer + writePos;
|
||||||
dst2 = 0;
|
dst2 = NULL;
|
||||||
len1 = numBytes;
|
len1 = numBytes;
|
||||||
len2 = 0;
|
len2 = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy chunk to write position in buffer
|
// Copy chunk to write position in buffer
|
||||||
|
@ -672,8 +692,8 @@ bool OutputAudio(unsigned numSamples, INT16* leftFrontBuffer, INT16* rightFrontB
|
||||||
writePos -= audioBufferSize;
|
writePos -= audioBufferSize;
|
||||||
writeWrapped = true;
|
writeWrapped = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Finish:
|
|
||||||
// Unlock SDL audio callback
|
// Unlock SDL audio callback
|
||||||
SDL_UnlockAudio();
|
SDL_UnlockAudio();
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *
|
||||||
float yRes = float(*yResPtr);
|
float yRes = float(*yResPtr);
|
||||||
if (keepAspectRatio)
|
if (keepAspectRatio)
|
||||||
{
|
{
|
||||||
float model3Ratio = 496.0f/384.0f;
|
float model3Ratio = 496.0/384.0;
|
||||||
if (yRes < (xRes/model3Ratio))
|
if (yRes < (xRes/model3Ratio))
|
||||||
xRes = yRes*model3Ratio;
|
xRes = yRes*model3Ratio;
|
||||||
if (xRes < (yRes*model3Ratio))
|
if (xRes < (yRes*model3Ratio))
|
||||||
|
@ -154,7 +154,7 @@ static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *
|
||||||
*xResPtr = (unsigned) xRes;
|
*xResPtr = (unsigned) xRes;
|
||||||
*yResPtr = (unsigned) yRes;
|
*yResPtr = (unsigned) yRes;
|
||||||
|
|
||||||
UINT32 correction = (UINT32)(((yRes / 384.f) * 2) + 0.5f);
|
UINT32 correction = (UINT32)(((yRes / 384.f) * 2.f) + 0.5f);
|
||||||
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
|
@ -1522,7 +1522,7 @@ static void PrintGameList(const std::string &xml_file, const std::map<std::strin
|
||||||
{
|
{
|
||||||
const Game &game = v.second;
|
const Game &game = v.second;
|
||||||
printf(" %s", game.name.c_str());
|
printf(" %s", game.name.c_str());
|
||||||
for (int i = game.name.length(); i < 9; i++) // pad for alignment (no game ID should be more than 9 letters)
|
for (size_t i = game.name.length(); i < 9; i++) // pad for alignment (no game ID should be more than 9 letters)
|
||||||
printf(" ");
|
printf(" ");
|
||||||
if (!game.version.empty())
|
if (!game.version.empty())
|
||||||
printf(" %s (%s)\n", game.title.c_str(), game.version.c_str());
|
printf(" %s (%s)\n", game.title.c_str(), game.version.c_str());
|
||||||
|
@ -1563,9 +1563,9 @@ static Util::Config::Node DefaultConfig()
|
||||||
config.Set("FragmentShader2D", "");
|
config.Set("FragmentShader2D", "");
|
||||||
// CSoundBoard
|
// CSoundBoard
|
||||||
config.Set("EmulateSound", true);
|
config.Set("EmulateSound", true);
|
||||||
config.Set("Balance", "0");
|
config.Set("Balance", "0.0");
|
||||||
config.Set("BalanceLeftRight", "0");
|
config.Set("BalanceLeftRight", "0.0");
|
||||||
config.Set("BalanceFrontRear", "0");
|
config.Set("BalanceFrontRear", "0.0");
|
||||||
config.Set("NbSoundChannels", "4");
|
config.Set("NbSoundChannels", "4");
|
||||||
config.Set("SoundFreq", "57.6"); // 60.0f? 57.524160f?
|
config.Set("SoundFreq", "57.6"); // 60.0f? 57.524160f?
|
||||||
// CDSB
|
// CDSB
|
||||||
|
|
|
@ -87,23 +87,19 @@ bool legacySound; // For LegacySound (SCSP DSP) config option.
|
||||||
|
|
||||||
|
|
||||||
// These globals control the operation of the SCSP, they are no longer extern and are set through SCSP_SetBuffers(). --Bart
|
// These globals control the operation of the SCSP, they are no longer extern and are set through SCSP_SetBuffers(). --Bart
|
||||||
float SoundClock; // Originally titled SysFPS; seems to be for the sound CPU.
|
static double SoundClock; // Originally titled SysFPS; seems to be for the sound CPU.
|
||||||
const float Freq = 76;
|
static const double Freq = 76;
|
||||||
signed short* bufferfl;
|
static float* bufferfl;
|
||||||
signed short* bufferfr;
|
static float* bufferfr;
|
||||||
signed short* bufferrl;
|
static float* bufferrl;
|
||||||
signed short* bufferrr;
|
static float* bufferrr;
|
||||||
int length;
|
static int length;
|
||||||
int cnts;
|
|
||||||
|
|
||||||
signed int* buffertmpfl, * buffertmpfr; // these are allocated inside this file
|
static const double srate=44100;
|
||||||
signed int* buffertmprl, * buffertmprr; // these are allocated inside this file
|
|
||||||
|
|
||||||
unsigned int srate=44100;
|
|
||||||
|
|
||||||
|
|
||||||
#define ICLIP16(x) (x<-32768)?-32768:((x>32767)?32767:x)
|
#define ICLIP16(x) (((x)<-32768)?-32768:(((x)>32767)?32767:(x)))
|
||||||
#define ICLIP18(x) (x<-131072)?-131072:((x>131071)?131071:x)
|
#define ICLIP18(x) (((x)<-131072)?-131072:(((x)>131071)?131071:(x)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -740,7 +736,7 @@ bool SCSP_Init(const Util::Config::Node &config, int n)
|
||||||
t=ARTimes[i]; //In ms
|
t=ARTimes[i]; //In ms
|
||||||
if(t!=0.0)
|
if(t!=0.0)
|
||||||
{
|
{
|
||||||
step=(1023*1000.0)/((float) srate*t);
|
step=(1023*1000.0)/(srate*t);
|
||||||
scale=(double) (1<<EG_SHIFT);
|
scale=(double) (1<<EG_SHIFT);
|
||||||
ARTABLE[i]=(int) (step*scale);
|
ARTABLE[i]=(int) (step*scale);
|
||||||
}
|
}
|
||||||
|
@ -748,7 +744,7 @@ bool SCSP_Init(const Util::Config::Node &config, int n)
|
||||||
ARTABLE[i]=1024<<EG_SHIFT;
|
ARTABLE[i]=1024<<EG_SHIFT;
|
||||||
|
|
||||||
t=DRTimes[i]; //In ms
|
t=DRTimes[i]; //In ms
|
||||||
step=(1023*1000.0)/((float) srate*t);
|
step=(1023*1000.0)/(srate*t);
|
||||||
scale=(double) (1<<EG_SHIFT);
|
scale=(double) (1<<EG_SHIFT);
|
||||||
DRTABLE[i]=(int) (step*scale);
|
DRTABLE[i]=(int) (step*scale);
|
||||||
}
|
}
|
||||||
|
@ -762,34 +758,7 @@ bool SCSP_Init(const Util::Config::Node &config, int n)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LFO_Init();
|
LFO_Init();
|
||||||
buffertmpfl = NULL;
|
|
||||||
buffertmpfr = NULL;
|
|
||||||
buffertmprl = NULL;
|
|
||||||
buffertmprr = NULL;
|
|
||||||
buffertmpfl=(signed int*) malloc(44100*sizeof(signed int));
|
|
||||||
if (NULL == buffertmpfl)
|
|
||||||
return ErrorLog("Insufficient memory for internal SCSP buffers.");
|
|
||||||
buffertmpfr=(signed int*) malloc(44100*sizeof(signed int));
|
|
||||||
if (NULL == buffertmpfr)
|
|
||||||
{
|
|
||||||
free(buffertmpfl);
|
|
||||||
return ErrorLog("Insufficient memory for internal SCSP buffers.");
|
|
||||||
}
|
|
||||||
|
|
||||||
buffertmprl=(signed int*)malloc(44100*sizeof(signed int));
|
|
||||||
if (NULL == buffertmprl)
|
|
||||||
return ErrorLog("Insufficient memory for internal SCSP buffers.");
|
|
||||||
buffertmprr=(signed int*)malloc(44100*sizeof(signed int));
|
|
||||||
if (NULL == buffertmprr)
|
|
||||||
{
|
|
||||||
free(buffertmprl);
|
|
||||||
return ErrorLog("Insufficient memory for internal SCSP buffers.");
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(buffertmpfl, 0, 44100*sizeof(signed int));
|
|
||||||
memset(buffertmpfr, 0, 44100*sizeof(signed int));
|
|
||||||
memset(buffertmprl, 0, 44100*sizeof(signed int));
|
|
||||||
memset(buffertmprr, 0, 44100*sizeof(signed int));
|
|
||||||
SCSPs->data[0x20 / 2] = 0;
|
SCSPs->data[0x20 / 2] = 0;
|
||||||
TimCnt[0] = 0xffff;
|
TimCnt[0] = 0xffff;
|
||||||
TimCnt[1] = 0xffff;
|
TimCnt[1] = 0xffff;
|
||||||
|
@ -799,10 +768,6 @@ bool SCSP_Init(const Util::Config::Node &config, int n)
|
||||||
MIDILock = CThread::CreateMutex();
|
MIDILock = CThread::CreateMutex();
|
||||||
if (NULL == MIDILock)
|
if (NULL == MIDILock)
|
||||||
{
|
{
|
||||||
free(buffertmpfl);
|
|
||||||
free(buffertmpfr);
|
|
||||||
free(buffertmprl);
|
|
||||||
free(buffertmprr);
|
|
||||||
return ErrorLog("Unable to create MIDI mutex!");
|
return ErrorLog("Unable to create MIDI mutex!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1547,7 +1512,7 @@ void SCSP_CpuRunScanline()
|
||||||
|
|
||||||
void SCSP_DoMasterSamples(int nsamples)
|
void SCSP_DoMasterSamples(int nsamples)
|
||||||
{
|
{
|
||||||
int slice = (int)(12000000 / (SoundClock*nsamples)); // 68K cycles/sample
|
int slice = (int)(12000000. / (SoundClock*nsamples)); // 68K cycles/sample
|
||||||
static int lastdiff = 0;
|
static int lastdiff = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1556,33 +1521,25 @@ void SCSP_DoMasterSamples(int nsamples)
|
||||||
* When one SCSP is fully attenuated, the other's samples will be multiplied
|
* When one SCSP is fully attenuated, the other's samples will be multiplied
|
||||||
* by 2.
|
* by 2.
|
||||||
*/
|
*/
|
||||||
float balance = (float)s_config->Get("Balance").ValueAs<float>();
|
float balance = std::max(-100.f,std::min(100.f,s_config->Get("Balance").ValueAs<float>()));
|
||||||
if (balance < -100.0f)
|
balance *= 0.01f;
|
||||||
balance = -100.0f;
|
|
||||||
else if (balance > 100.0f)
|
|
||||||
balance = 100.0f;
|
|
||||||
balance /= 100.0f;
|
|
||||||
float masterBalance = 1.0f + balance;
|
float masterBalance = 1.0f + balance;
|
||||||
float slaveBalance = 1.0f - balance;
|
float slaveBalance = 1.0f - balance;
|
||||||
signed short* buffl, * buffr;
|
|
||||||
signed short* bufrl, * bufrr;
|
|
||||||
|
|
||||||
INT32 sl, s, i;
|
float* buffl = bufferfl;
|
||||||
|
float* buffr = bufferfr;
|
||||||
buffl = bufferfl;
|
float* bufrl = bufferrl;
|
||||||
buffr = bufferfr;
|
float* bufrr = bufferrr;
|
||||||
bufrl = bufferrl;
|
|
||||||
bufrr = bufferrr;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate samples
|
* Generate samples
|
||||||
*/
|
*/
|
||||||
for (s = 0; s < nsamples; ++s)
|
for (INT32 s = 0; s < nsamples; ++s)
|
||||||
{
|
{
|
||||||
signed int smpfl = 0, smpfr = 0;
|
signed int smpfl = 0, smpfr = 0;
|
||||||
signed int smprl = 0, smprr = 0;
|
signed int smprl = 0, smprr = 0;
|
||||||
|
|
||||||
for (sl = 0; sl < 32; ++sl)
|
for (INT32 sl = 0; sl < 32; ++sl)
|
||||||
{
|
{
|
||||||
#if FM_DELAY
|
#if FM_DELAY
|
||||||
RBUFDST = SCSPs[0].DELAYBUF + SCSPs[0].DELAYPTR;
|
RBUFDST = SCSPs[0].DELAYBUF + SCSPs[0].DELAYPTR;
|
||||||
|
@ -1596,8 +1553,6 @@ void SCSP_DoMasterSamples(int nsamples)
|
||||||
|
|
||||||
signed int sample = (int)(masterBalance*(float)SCSP_UpdateSlot(slot));
|
signed int sample = (int)(masterBalance*(float)SCSP_UpdateSlot(slot));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Enc = ((TL(slot)) << 0x0) | ((IMXL(slot)) << 0xd);
|
Enc = ((TL(slot)) << 0x0) | ((IMXL(slot)) << 0xd);
|
||||||
SCSPDSP_SetSample(&SCSPs[0].DSP, (sample*LPANTABLE[Enc]) >> (SHIFT - 2), ISEL(slot), IMXL(slot));
|
SCSPDSP_SetSample(&SCSPs[0].DSP, (sample*LPANTABLE[Enc]) >> (SHIFT - 2), ISEL(slot), IMXL(slot));
|
||||||
Enc = ((TL(slot)) << 0x0) | ((DIPAN(slot)) << 0x8) | ((DISDL(slot)) << 0xd);
|
Enc = ((TL(slot)) << 0x0) | ((DIPAN(slot)) << 0x8) | ((DISDL(slot)) << 0xd);
|
||||||
|
@ -1666,7 +1621,7 @@ void SCSP_DoMasterSamples(int nsamples)
|
||||||
|
|
||||||
// smpl=0;
|
// smpl=0;
|
||||||
// smpr=0;
|
// smpr=0;
|
||||||
for (i = 0; i < 16; ++i)
|
for (INT32 i = 0; i < 16; ++i)
|
||||||
{
|
{
|
||||||
_SLOT *slot = SCSPs[0].Slots + i;
|
_SLOT *slot = SCSPs[0].Slots + i;
|
||||||
if (legacySound == true) {
|
if (legacySound == true) {
|
||||||
|
@ -1718,8 +1673,8 @@ void SCSP_DoMasterSamples(int nsamples)
|
||||||
smpfl = ICLIP16(smpfl >> 2);
|
smpfl = ICLIP16(smpfl >> 2);
|
||||||
smpfr = ICLIP16(smpfr >> 2);
|
smpfr = ICLIP16(smpfr >> 2);
|
||||||
}
|
}
|
||||||
*buffl++ = ICLIP16(smpfl);
|
*buffl++ = (float)smpfl;
|
||||||
*buffr++ = ICLIP16(smpfr);
|
*buffr++ = (float)smpfr;
|
||||||
|
|
||||||
if (HasSlaveSCSP)
|
if (HasSlaveSCSP)
|
||||||
{
|
{
|
||||||
|
@ -1734,8 +1689,8 @@ void SCSP_DoMasterSamples(int nsamples)
|
||||||
smprr = ICLIP16(smprr >> 2);
|
smprr = ICLIP16(smprr >> 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*bufrl++ = ICLIP16(smprl);
|
*bufrl++ = (float)smprl;
|
||||||
*bufrr++ = ICLIP16(smprr);
|
*bufrr++ = (float)smprr;
|
||||||
|
|
||||||
SCSP_TimersAddTicks(1);
|
SCSP_TimersAddTicks(1);
|
||||||
CheckPendingIRQ();
|
CheckPendingIRQ();
|
||||||
|
@ -2146,16 +2101,15 @@ void SCSP_LoadState(CBlockFile *StateFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCSP_SetBuffers(INT16 *leftBufferPtr, INT16 *rightBufferPtr, INT16* leftRearBufferPtr, INT16* rightRearBufferPtr, int bufferLength)
|
void SCSP_SetBuffers(float *leftBufferPtr, float *rightBufferPtr, float* leftRearBufferPtr, float* rightRearBufferPtr, int bufferLength)
|
||||||
{
|
{
|
||||||
SoundClock = 76;
|
SoundClock = Freq;
|
||||||
bufferfl = leftBufferPtr;
|
bufferfl = leftBufferPtr;
|
||||||
bufferfr = rightBufferPtr;
|
bufferfr = rightBufferPtr;
|
||||||
bufferrl = leftRearBufferPtr;
|
bufferrl = leftRearBufferPtr;
|
||||||
bufferrr = rightRearBufferPtr;
|
bufferrr = rightRearBufferPtr;
|
||||||
|
|
||||||
length = bufferLength;
|
length = bufferLength;
|
||||||
cnts = 0; // what is this for? seems unimportant but need to find out
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCSP_Deinit(void)
|
void SCSP_Deinit(void)
|
||||||
|
@ -2163,14 +2117,6 @@ void SCSP_Deinit(void)
|
||||||
#ifdef USEDSP
|
#ifdef USEDSP
|
||||||
free(SCSP->MIXBuf);
|
free(SCSP->MIXBuf);
|
||||||
#endif
|
#endif
|
||||||
free(buffertmpfl);
|
|
||||||
free(buffertmpfr);
|
|
||||||
free(buffertmprl);
|
|
||||||
free(buffertmprr);
|
|
||||||
delete MIDILock;
|
delete MIDILock;
|
||||||
buffertmpfl = NULL;
|
|
||||||
buffertmpfr = NULL;
|
|
||||||
buffertmprl = NULL;
|
|
||||||
buffertmprr = NULL;
|
|
||||||
MIDILock = NULL;
|
MIDILock = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ UINT32 SCSP_Slave_r32(UINT32 addr);
|
||||||
// Supermodel interface functions
|
// Supermodel interface functions
|
||||||
void SCSP_SaveState(CBlockFile *StateFile);
|
void SCSP_SaveState(CBlockFile *StateFile);
|
||||||
void SCSP_LoadState(CBlockFile *StateFile);
|
void SCSP_LoadState(CBlockFile *StateFile);
|
||||||
void SCSP_SetBuffers(INT16 *leftBufferPtr, INT16 *rightBufferPtr, INT16* leftRearBufferPtr, INT16* rightRearBufferPtr, int bufferLength);
|
void SCSP_SetBuffers(float *leftBufferPtr, float *rightBufferPtr, float* leftRearBufferPtr, float* rightRearBufferPtr, int bufferLength);
|
||||||
void SCSP_Deinit(void);
|
void SCSP_Deinit(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue