mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-22 13:55:38 +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_JOYSTICK2: return "4-Way Joysticks";
|
||||
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_VEHICLE: return "Racing Game Steering Controls";
|
||||
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_SKI: return "Ski Controls";
|
||||
case Game::INPUT_MAGTRUCK: return "Magical Truck Controls";
|
||||
case Game::INPUT_FISHING: return "Fishing Controls";
|
||||
default: return "Misc";
|
||||
case Game::INPUT_FISHING: return "Fishing Controls";
|
||||
default: return "Misc";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,7 +138,7 @@ void CInput::AppendMapping(const char *mapping)
|
|||
else
|
||||
{
|
||||
// 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, mapping, size);
|
||||
CreateSource();
|
||||
|
|
|
@ -125,52 +125,31 @@ void CDSBResampler::Reset(void)
|
|||
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)
|
||||
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 outIdx = 0;
|
||||
int inIdx = 0;
|
||||
INT32 leftSample, rightSample, leftSoundSample, rightSoundSample;
|
||||
INT32 v[2], musicVol;
|
||||
float v[2], musicVol;
|
||||
|
||||
// Obtain program volume settings and convert to 24.8 fixed point (0-200 -> 0x00-0x200)
|
||||
musicVol = m_config["MusicVolume"].ValueAs<int>();
|
||||
musicVol = (INT32) ((float) 0x100 * (float) musicVol / 100.0f);
|
||||
// Obtain program volume settings
|
||||
musicVol = (float)std::max(0,std::min(200,m_config["MusicVolume"].ValueAs<int>()));
|
||||
musicVol = musicVol * (float) (1.0 / 100.0);
|
||||
|
||||
// Scale volume from 0x00-0xFF -> 0x00-0x100 (24.8 fixed point)
|
||||
v[0] = (INT16) ((float) 0x100 * (float) volumeL / 255.0f);
|
||||
v[1] = (INT16) ((float) 0x100 * (float) volumeR / 255.0f);
|
||||
v[0] = musicVol * (float) volumeL * (float) (1.0 / (255.0*256.0)); // 256 is there to correct for fixed point interpolation below
|
||||
v[1] = musicVol * (float) volumeR * (float) (1.0 / (255.0*256.0));
|
||||
|
||||
// Up-sample and mix!
|
||||
while (outIdx < sizeOut)
|
||||
{
|
||||
// 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
|
||||
rightSample = ((int)inR[inIdx]*pFrac+(int)inR[inIdx+1]*nFrac) >> 8; // right channel
|
||||
INT32 leftSample = (int)inL[inIdx]*pFrac+(int)inL[inIdx+1]*nFrac; // left channel
|
||||
INT32 rightSample = (int)inR[inIdx]*pFrac+(int)inR[inIdx+1]*nFrac; // right channel
|
||||
|
||||
// Apply DSB volume and then overall music volume setting
|
||||
leftSample = (leftSample*v[0]*musicVol) >> 16; // multiplied by two 24.8 numbers, shift back by 16
|
||||
rightSample = (rightSample*v[0]*musicVol) >> 16;
|
||||
|
||||
// Apply sound volume setting
|
||||
leftSoundSample = outL[outIdx];
|
||||
rightSoundSample = outR[outIdx];
|
||||
|
||||
// Mix and output
|
||||
outL[outIdx] = MixAndClip(leftSoundSample, leftSample);
|
||||
outR[outIdx] = MixAndClip(rightSoundSample, rightSample);
|
||||
// Apply DSB volume+overall music volume setting, and mix into output
|
||||
outL[outIdx] += (float)leftSample * v[0];
|
||||
outR[outIdx] += (float)rightSample * v[1];
|
||||
outIdx++;
|
||||
|
||||
// Time step
|
||||
|
@ -422,11 +401,8 @@ void CDSB1::SendCommand(UINT8 data)
|
|||
#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>())
|
||||
{
|
||||
// DSB code applies SCSP volume, too, so we must still mix
|
||||
|
@ -436,6 +412,7 @@ void CDSB1::RunFrame(INT16 *audioL, INT16 *audioR)
|
|||
return;
|
||||
}
|
||||
|
||||
int cycles;
|
||||
// While FIFO not empty, fire interrupts, run for up to one frame
|
||||
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);
|
||||
|
||||
// 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
|
||||
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>())
|
||||
{
|
||||
// DSB code applies SCSP volume, too, so we must still mix
|
||||
memset(mpegL, 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);
|
||||
memset(mpegL, 0, (32000/60+2) * sizeof(INT16));
|
||||
memset(mpegR, 0, (32000/60+2) * sizeof(INT16));
|
||||
retainedSamples = Resampler.UpSampleAndMix(audioL, audioR, mpegL, mpegR, 0, 0, NUM_SAMPLES_PER_FRAME, 32000/60+2, 44100, 32000);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1069,7 +1046,7 @@ void CDSB2::RunFrame(INT16 *audioL, INT16 *audioR)
|
|||
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)
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
class CDSBResampler
|
||||
{
|
||||
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);
|
||||
CDSBResampler(const Util::Config::Node &config)
|
||||
: m_config(config)
|
||||
|
@ -114,7 +114,7 @@ public:
|
|||
* audioL Left audio channel, one frame (44 KHz, 1/60th second).
|
||||
* audioR Right audio channel.
|
||||
*/
|
||||
virtual void RunFrame(INT16 *audioL, INT16 *audioR) = 0;
|
||||
virtual void RunFrame(float *audioL, float *audioR) = 0;
|
||||
|
||||
/*
|
||||
* Reset(void):
|
||||
|
@ -187,7 +187,7 @@ public:
|
|||
|
||||
// DSB interface (see CDSB definition)
|
||||
void SendCommand(UINT8 data);
|
||||
void RunFrame(INT16 *audioL, INT16 *audioR);
|
||||
void RunFrame(float *audioL, float *audioR);
|
||||
void Reset(void);
|
||||
void SaveState(CBlockFile *StateFile);
|
||||
void LoadState(CBlockFile *StateFile);
|
||||
|
@ -264,7 +264,7 @@ public:
|
|||
|
||||
// DSB interface (see definition of CDSB)
|
||||
void SendCommand(UINT8 data);
|
||||
void RunFrame(INT16 *audioL, INT16 *audioR);
|
||||
void RunFrame(float *audioL, float *audioR);
|
||||
void Reset(void);
|
||||
void SaveState(CBlockFile *StateFile);
|
||||
void LoadState(CBlockFile *StateFile);
|
||||
|
|
|
@ -70,11 +70,11 @@ static FILE *soundFP;
|
|||
// Offsets of memory regions within sound board's pool
|
||||
#define OFFSET_RAM1 0 // 1 MB SCSP1 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 OFFSET_AUDIO_FRONTLEFT 0x200000 // 1470 bytes (16 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_REARLEFT (OFFSET_AUDIO_FRONTRIGHT + LENGTH_CHANNEL_BUFFER) // 1470 bytes (16 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 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 // 2940 bytes (32 bits, 44.1 KHz, 1/60th second) left 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) // 2940 bytes (32 bits, 44.1 KHz, 1/60th second) left 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)
|
||||
|
||||
|
@ -351,6 +351,18 @@ void CSoundBoard::WriteMIDIPort(UINT8 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)
|
||||
{
|
||||
// Run sound board first to generate SCSP audio
|
||||
|
@ -369,15 +381,15 @@ bool CSoundBoard::RunFrame(void)
|
|||
}
|
||||
|
||||
// Compute sound volume as
|
||||
INT32 soundVol = m_config["SoundVolume"].ValueAs<int>();
|
||||
soundVol = (INT32)((float)0x100 * (float)soundVol / 100.0f);
|
||||
float soundVol = (float)std::max(0,std::min(200,m_config["SoundVolume"].ValueAs<int>()));
|
||||
soundVol = soundVol * (float)(1.0 / 100.0);
|
||||
|
||||
// Apply sound volume setting to SCSP channels only
|
||||
for (int i = 0; i < NUM_SAMPLES_PER_FRAME; i++) {
|
||||
audioFL[i] = (audioFL[i]*soundVol) >> 8;
|
||||
audioFR[i] = (audioFR[i]*soundVol) >> 8;
|
||||
audioRL[i] = (audioRL[i]*soundVol) >> 8;
|
||||
audioRR[i] = (audioRR[i]*soundVol) >> 8;
|
||||
audioFL[i] *= soundVol;
|
||||
audioFR[i] *= soundVol;
|
||||
audioRL[i] *= soundVol;
|
||||
audioRR[i] *= soundVol;
|
||||
}
|
||||
|
||||
// Run DSB and mix with existing audio, apply music volume
|
||||
|
@ -399,9 +411,13 @@ bool CSoundBoard::RunFrame(void)
|
|||
INT16 s;
|
||||
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
|
||||
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
|
||||
}
|
||||
#endif // SUPERMODEL_LOG_AUDIO
|
||||
|
@ -496,10 +512,10 @@ bool CSoundBoard::Init(const UINT8 *soundROMPtr, const UINT8 *sampleROMPtr)
|
|||
// Set up memory pointers
|
||||
ram1 = &memoryPool[OFFSET_RAM1];
|
||||
ram2 = &memoryPool[OFFSET_RAM2];
|
||||
audioFL = (INT16*)&memoryPool[OFFSET_AUDIO_FRONTLEFT];
|
||||
audioFR = (INT16*)&memoryPool[OFFSET_AUDIO_FRONTRIGHT];
|
||||
audioRL = (INT16*)&memoryPool[OFFSET_AUDIO_REARLEFT];
|
||||
audioRR = (INT16*)&memoryPool[OFFSET_AUDIO_REARRIGHT];
|
||||
audioFL = (float*)&memoryPool[OFFSET_AUDIO_FRONTLEFT];
|
||||
audioFR = (float*)&memoryPool[OFFSET_AUDIO_FRONTRIGHT];
|
||||
audioRL = (float*)&memoryPool[OFFSET_AUDIO_REARLEFT];
|
||||
audioRR = (float*)&memoryPool[OFFSET_AUDIO_REARRIGHT];
|
||||
|
||||
// Initialize 68K core
|
||||
M68KSetContext(&M68K);
|
||||
|
|
|
@ -203,8 +203,8 @@ private:
|
|||
UINT8 ctrlReg; // control register: ROM banking
|
||||
|
||||
// Audio
|
||||
INT16* 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* audioFL, * audioFR; // left and right front 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.
|
||||
*/
|
||||
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()
|
||||
|
|
|
@ -166,6 +166,35 @@ static INT16 MixINT16(INT32 x, INT32 y)
|
|||
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)
|
||||
{
|
||||
//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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (nbHostAudioChannels == 1) {
|
||||
for (unsigned i = 0; i < numSamples; i++) {
|
||||
INT16 monovalue = MixINT16(
|
||||
MixINT16((INT32)(leftFrontBuffer[i] * balanceFactorFrontLeft), (INT32)(rightFrontBuffer[i] * balanceFactorFrontRight)),
|
||||
MixINT16((INT32)(leftRearBuffer[i] * balanceFactorRearLeft), (INT32)(rightRearBuffer[i] * balanceFactorRearRight)));
|
||||
MixFloat(leftFrontBuffer[i] * balanceFactorFrontLeft,rightFrontBuffer[i] * balanceFactorFrontRight),
|
||||
MixFloat(leftRearBuffer[i] * balanceFactorRearLeft, rightRearBuffer[i] * balanceFactorRearRight));
|
||||
*p++ = monovalue;
|
||||
}
|
||||
} else {
|
||||
|
@ -295,8 +324,8 @@ static void MixChannels(unsigned numSamples, INT16* leftFrontBuffer, INT16* righ
|
|||
// Now order channels according to audio type
|
||||
if (nbHostAudioChannels == 2) {
|
||||
for (unsigned i = 0; i < numSamples; i++) {
|
||||
INT16 leftvalue = MixINT16((INT32)(leftFrontBuffer[i] * balanceFactorFrontLeft), (INT32)(leftRearBuffer[i] * balanceFactorRearLeft));
|
||||
INT16 rightvalue = MixINT16((INT32)(rightFrontBuffer[i]*balanceFactorFrontRight), (INT32)(rightRearBuffer[i]*balanceFactorRearRight));
|
||||
INT16 leftvalue = MixINT16(leftFrontBuffer[i] * balanceFactorFrontLeft, leftRearBuffer[i] * balanceFactorRearLeft);
|
||||
INT16 rightvalue = MixINT16(rightFrontBuffer[i]*balanceFactorFrontRight, rightRearBuffer[i]*balanceFactorRearRight);
|
||||
if (flipStereo) // swap left and right channels
|
||||
{
|
||||
*p++ = rightvalue;
|
||||
|
@ -308,15 +337,15 @@ static void MixChannels(unsigned numSamples, INT16* leftFrontBuffer, INT16* righ
|
|||
}
|
||||
} else if (nbHostAudioChannels == 4) {
|
||||
for (unsigned i = 0; i < numSamples; i++) {
|
||||
INT16 frontLeftValue = (INT16)(leftFrontBuffer[i]*balanceFactorFrontLeft);
|
||||
INT16 frontRightValue = (INT16)(rightFrontBuffer[i]*balanceFactorFrontRight);
|
||||
INT16 rearLeftValue = (INT16)(leftRearBuffer[i]*balanceFactorRearLeft);
|
||||
INT16 rearRightValue = (INT16)(rightRearBuffer[i]*balanceFactorRearRight);
|
||||
float frontLeftValue = leftFrontBuffer[i]*balanceFactorFrontLeft;
|
||||
float frontRightValue = rightFrontBuffer[i]*balanceFactorFrontRight;
|
||||
float rearLeftValue = leftRearBuffer[i]*balanceFactorRearLeft;
|
||||
float rearRightValue = rightRearBuffer[i]*balanceFactorRearRight;
|
||||
|
||||
// Check game audio type
|
||||
switch (AudioType) {
|
||||
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;
|
||||
|
@ -346,15 +375,15 @@ static void MixChannels(unsigned numSamples, INT16* leftFrontBuffer, INT16* righ
|
|||
// Normal channels Front Left/Right then Rear Left/Right
|
||||
if (flipStereo) // swap left and right channels
|
||||
{
|
||||
*p++ = frontRightValue;
|
||||
*p++ = frontLeftValue;
|
||||
*p++ = rearRightValue;
|
||||
*p++ = rearLeftValue;
|
||||
*p++ = ClampINT16(frontRightValue);
|
||||
*p++ = ClampINT16(frontLeftValue);
|
||||
*p++ = ClampINT16(rearRightValue);
|
||||
*p++ = ClampINT16(rearLeftValue);
|
||||
} else {
|
||||
*p++ = frontLeftValue;
|
||||
*p++ = frontRightValue;
|
||||
*p++ = rearLeftValue;
|
||||
*p++ = rearRightValue;
|
||||
*p++ = ClampINT16(frontLeftValue);
|
||||
*p++ = ClampINT16(frontRightValue);
|
||||
*p++ = ClampINT16(rearLeftValue);
|
||||
*p++ = ClampINT16(rearRightValue);
|
||||
}
|
||||
} break;
|
||||
|
||||
|
@ -363,15 +392,15 @@ static void MixChannels(unsigned numSamples, INT16* leftFrontBuffer, INT16* righ
|
|||
// Reversed channels Front/Rear Left then Front/Rear Right
|
||||
if (flipStereo) // swap left and right channels
|
||||
{
|
||||
*p++ = rearRightValue;
|
||||
*p++ = rearLeftValue;
|
||||
*p++ = frontRightValue;
|
||||
*p++ = frontLeftValue;
|
||||
*p++ = ClampINT16(rearRightValue);
|
||||
*p++ = ClampINT16(rearLeftValue);
|
||||
*p++ = ClampINT16(frontRightValue);
|
||||
*p++ = ClampINT16(frontLeftValue);
|
||||
} else {
|
||||
*p++ = rearLeftValue;
|
||||
*p++ = rearRightValue;
|
||||
*p++ = frontLeftValue;
|
||||
*p++ = frontRightValue;
|
||||
*p++ = ClampINT16(rearLeftValue);
|
||||
*p++ = ClampINT16(rearRightValue);
|
||||
*p++ = ClampINT16(frontLeftValue);
|
||||
*p++ = ClampINT16(frontRightValue);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -440,19 +469,11 @@ bool OpenAudio(const Util::Config::Node& config)
|
|||
break;
|
||||
}
|
||||
// Mixer Balance
|
||||
float balancelr = (float)s_config->Get("BalanceLeftRight").ValueAs<float>();
|
||||
if (balancelr < -100.0f)
|
||||
balancelr = -100.0f;
|
||||
else if (balancelr > 100.0f)
|
||||
balancelr = 100.0f;
|
||||
float balancelr = std::max(-100.f, std::min(100.f, s_config->Get("BalanceLeftRight").ValueAs<float>()));
|
||||
balancelr *= 0.01f;
|
||||
BalanceLeftRight = balancelr;
|
||||
|
||||
float balancefr = (float)s_config->Get("BalanceFrontRear").ValueAs<float>();
|
||||
if (balancefr < -100.0f)
|
||||
balancefr = -100.0f;
|
||||
else if (balancefr > 100.0f)
|
||||
balancefr = 100.0f;
|
||||
float balancefr = std::max(-100.f, std::min(100.f, s_config->Get("BalanceFrontRear").ValueAs<float>()));
|
||||
balancefr *= 0.01f;
|
||||
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);
|
||||
|
||||
// Set up audio specification
|
||||
SDL_AudioSpec desired;
|
||||
memset(&desired, 0, sizeof(SDL_AudioSpec));
|
||||
SDL_AudioSpec desired{};
|
||||
desired.freq = SAMPLE_RATE_M3;
|
||||
// Number of host channels to use (choice limited to 1,2,4)
|
||||
desired.channels = nbHostAudioChannels;
|
||||
|
@ -533,7 +553,7 @@ bool OpenAudio(const Util::Config::Node& config)
|
|||
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",
|
||||
// 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)
|
||||
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)
|
||||
writePos += audioBufferSize;
|
||||
|
||||
|
@ -619,9 +639,9 @@ bool OutputAudio(unsigned numSamples, INT16* leftFrontBuffer, INT16* rightFrontB
|
|||
bufferFull = true;
|
||||
|
||||
// Discard current chunk of data
|
||||
goto Finish;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
src = mixBuffer;
|
||||
INT8* dst1;
|
||||
INT8* dst2;
|
||||
|
@ -641,9 +661,9 @@ bool OutputAudio(unsigned numSamples, INT16* leftFrontBuffer, INT16* rightFrontB
|
|||
{
|
||||
// Otherwise, just copy whole region
|
||||
dst1 = audioBuffer + writePos;
|
||||
dst2 = 0;
|
||||
dst2 = NULL;
|
||||
len1 = numBytes;
|
||||
len2 = 0;
|
||||
len2 = NULL;
|
||||
}
|
||||
|
||||
// Copy chunk to write position in buffer
|
||||
|
@ -672,8 +692,8 @@ bool OutputAudio(unsigned numSamples, INT16* leftFrontBuffer, INT16* rightFrontB
|
|||
writePos -= audioBufferSize;
|
||||
writeWrapped = true;
|
||||
}
|
||||
}
|
||||
|
||||
Finish:
|
||||
// Unlock SDL audio callback
|
||||
SDL_UnlockAudio();
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *
|
|||
float yRes = float(*yResPtr);
|
||||
if (keepAspectRatio)
|
||||
{
|
||||
float model3Ratio = 496.0f/384.0f;
|
||||
float model3Ratio = 496.0/384.0;
|
||||
if (yRes < (xRes/model3Ratio))
|
||||
xRes = yRes*model3Ratio;
|
||||
if (xRes < (yRes*model3Ratio))
|
||||
|
@ -154,7 +154,7 @@ static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *
|
|||
*xResPtr = (unsigned) xRes;
|
||||
*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);
|
||||
|
||||
|
@ -1522,7 +1522,7 @@ static void PrintGameList(const std::string &xml_file, const std::map<std::strin
|
|||
{
|
||||
const Game &game = v.second;
|
||||
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(" ");
|
||||
if (!game.version.empty())
|
||||
printf(" %s (%s)\n", game.title.c_str(), game.version.c_str());
|
||||
|
@ -1563,9 +1563,9 @@ static Util::Config::Node DefaultConfig()
|
|||
config.Set("FragmentShader2D", "");
|
||||
// CSoundBoard
|
||||
config.Set("EmulateSound", true);
|
||||
config.Set("Balance", "0");
|
||||
config.Set("BalanceLeftRight", "0");
|
||||
config.Set("BalanceFrontRear", "0");
|
||||
config.Set("Balance", "0.0");
|
||||
config.Set("BalanceLeftRight", "0.0");
|
||||
config.Set("BalanceFrontRear", "0.0");
|
||||
config.Set("NbSoundChannels", "4");
|
||||
config.Set("SoundFreq", "57.6"); // 60.0f? 57.524160f?
|
||||
// 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
|
||||
float SoundClock; // Originally titled SysFPS; seems to be for the sound CPU.
|
||||
const float Freq = 76;
|
||||
signed short* bufferfl;
|
||||
signed short* bufferfr;
|
||||
signed short* bufferrl;
|
||||
signed short* bufferrr;
|
||||
int length;
|
||||
int cnts;
|
||||
static double SoundClock; // Originally titled SysFPS; seems to be for the sound CPU.
|
||||
static const double Freq = 76;
|
||||
static float* bufferfl;
|
||||
static float* bufferfr;
|
||||
static float* bufferrl;
|
||||
static float* bufferrr;
|
||||
static int length;
|
||||
|
||||
signed int* buffertmpfl, * buffertmpfr; // these are allocated inside this file
|
||||
signed int* buffertmprl, * buffertmprr; // these are allocated inside this file
|
||||
|
||||
unsigned int srate=44100;
|
||||
static const double srate=44100;
|
||||
|
||||
|
||||
#define ICLIP16(x) (x<-32768)?-32768:((x>32767)?32767:x)
|
||||
#define ICLIP18(x) (x<-131072)?-131072:((x>131071)?131071:x)
|
||||
#define ICLIP16(x) (((x)<-32768)?-32768:(((x)>32767)?32767:(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
|
||||
if(t!=0.0)
|
||||
{
|
||||
step=(1023*1000.0)/((float) srate*t);
|
||||
step=(1023*1000.0)/(srate*t);
|
||||
scale=(double) (1<<EG_SHIFT);
|
||||
ARTABLE[i]=(int) (step*scale);
|
||||
}
|
||||
|
@ -748,7 +744,7 @@ bool SCSP_Init(const Util::Config::Node &config, int n)
|
|||
ARTABLE[i]=1024<<EG_SHIFT;
|
||||
|
||||
t=DRTimes[i]; //In ms
|
||||
step=(1023*1000.0)/((float) srate*t);
|
||||
step=(1023*1000.0)/(srate*t);
|
||||
scale=(double) (1<<EG_SHIFT);
|
||||
DRTABLE[i]=(int) (step*scale);
|
||||
}
|
||||
|
@ -762,34 +758,7 @@ bool SCSP_Init(const Util::Config::Node &config, int n)
|
|||
#endif
|
||||
|
||||
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;
|
||||
TimCnt[0] = 0xffff;
|
||||
TimCnt[1] = 0xffff;
|
||||
|
@ -799,10 +768,6 @@ bool SCSP_Init(const Util::Config::Node &config, int n)
|
|||
MIDILock = CThread::CreateMutex();
|
||||
if (NULL == MIDILock)
|
||||
{
|
||||
free(buffertmpfl);
|
||||
free(buffertmpfr);
|
||||
free(buffertmprl);
|
||||
free(buffertmprr);
|
||||
return ErrorLog("Unable to create MIDI mutex!");
|
||||
}
|
||||
|
||||
|
@ -1547,7 +1512,7 @@ void SCSP_CpuRunScanline()
|
|||
|
||||
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;
|
||||
|
||||
/*
|
||||
|
@ -1556,33 +1521,25 @@ void SCSP_DoMasterSamples(int nsamples)
|
|||
* When one SCSP is fully attenuated, the other's samples will be multiplied
|
||||
* by 2.
|
||||
*/
|
||||
float balance = (float)s_config->Get("Balance").ValueAs<float>();
|
||||
if (balance < -100.0f)
|
||||
balance = -100.0f;
|
||||
else if (balance > 100.0f)
|
||||
balance = 100.0f;
|
||||
balance /= 100.0f;
|
||||
float balance = std::max(-100.f,std::min(100.f,s_config->Get("Balance").ValueAs<float>()));
|
||||
balance *= 0.01f;
|
||||
float masterBalance = 1.0f + balance;
|
||||
float slaveBalance = 1.0f - balance;
|
||||
signed short* buffl, * buffr;
|
||||
signed short* bufrl, * bufrr;
|
||||
|
||||
INT32 sl, s, i;
|
||||
|
||||
buffl = bufferfl;
|
||||
buffr = bufferfr;
|
||||
bufrl = bufferrl;
|
||||
bufrr = bufferrr;
|
||||
float* buffl = bufferfl;
|
||||
float* buffr = bufferfr;
|
||||
float* bufrl = bufferrl;
|
||||
float* bufrr = bufferrr;
|
||||
|
||||
/*
|
||||
* Generate samples
|
||||
*/
|
||||
for (s = 0; s < nsamples; ++s)
|
||||
for (INT32 s = 0; s < nsamples; ++s)
|
||||
{
|
||||
signed int smpfl = 0, smpfr = 0;
|
||||
signed int smprl = 0, smprr = 0;
|
||||
|
||||
for (sl = 0; sl < 32; ++sl)
|
||||
for (INT32 sl = 0; sl < 32; ++sl)
|
||||
{
|
||||
#if FM_DELAY
|
||||
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));
|
||||
|
||||
|
||||
|
||||
Enc = ((TL(slot)) << 0x0) | ((IMXL(slot)) << 0xd);
|
||||
SCSPDSP_SetSample(&SCSPs[0].DSP, (sample*LPANTABLE[Enc]) >> (SHIFT - 2), ISEL(slot), IMXL(slot));
|
||||
Enc = ((TL(slot)) << 0x0) | ((DIPAN(slot)) << 0x8) | ((DISDL(slot)) << 0xd);
|
||||
|
@ -1666,7 +1621,7 @@ void SCSP_DoMasterSamples(int nsamples)
|
|||
|
||||
// smpl=0;
|
||||
// smpr=0;
|
||||
for (i = 0; i < 16; ++i)
|
||||
for (INT32 i = 0; i < 16; ++i)
|
||||
{
|
||||
_SLOT *slot = SCSPs[0].Slots + i;
|
||||
if (legacySound == true) {
|
||||
|
@ -1718,8 +1673,8 @@ void SCSP_DoMasterSamples(int nsamples)
|
|||
smpfl = ICLIP16(smpfl >> 2);
|
||||
smpfr = ICLIP16(smpfr >> 2);
|
||||
}
|
||||
*buffl++ = ICLIP16(smpfl);
|
||||
*buffr++ = ICLIP16(smpfr);
|
||||
*buffl++ = (float)smpfl;
|
||||
*buffr++ = (float)smpfr;
|
||||
|
||||
if (HasSlaveSCSP)
|
||||
{
|
||||
|
@ -1734,8 +1689,8 @@ void SCSP_DoMasterSamples(int nsamples)
|
|||
smprr = ICLIP16(smprr >> 2);
|
||||
}
|
||||
}
|
||||
*bufrl++ = ICLIP16(smprl);
|
||||
*bufrr++ = ICLIP16(smprr);
|
||||
*bufrl++ = (float)smprl;
|
||||
*bufrr++ = (float)smprr;
|
||||
|
||||
SCSP_TimersAddTicks(1);
|
||||
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;
|
||||
bufferfr = rightBufferPtr;
|
||||
bufferrl = leftRearBufferPtr;
|
||||
bufferrr = rightRearBufferPtr;
|
||||
|
||||
length = bufferLength;
|
||||
cnts = 0; // what is this for? seems unimportant but need to find out
|
||||
}
|
||||
|
||||
void SCSP_Deinit(void)
|
||||
|
@ -2163,14 +2117,6 @@ void SCSP_Deinit(void)
|
|||
#ifdef USEDSP
|
||||
free(SCSP->MIXBuf);
|
||||
#endif
|
||||
free(buffertmpfl);
|
||||
free(buffertmpfr);
|
||||
free(buffertmprl);
|
||||
free(buffertmprr);
|
||||
delete MIDILock;
|
||||
buffertmpfl = NULL;
|
||||
buffertmpfr = NULL;
|
||||
buffertmprl = NULL;
|
||||
buffertmprr = NULL;
|
||||
MIDILock = NULL;
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ UINT32 SCSP_Slave_r32(UINT32 addr);
|
|||
// Supermodel interface functions
|
||||
void SCSP_SaveState(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);
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue