From 4c727abdc84e5c9eb56b3a178c2dd473d7581725 Mon Sep 17 00:00:00 2001 From: toxieainc Date: Thu, 3 Nov 2022 11:49:35 +0100 Subject: [PATCH] change all INT16 mixing/intermediate clamping to floats also fixes 3 bugs: 1) mpeg right channel volume was always using the left channel volume, too 2) too high MusicVolume setting was not clamped to 0..200 3) too high SoundVolume setting was not clamped to 0..200 --- Src/Inputs/Input.cpp | 8 +-- Src/Model3/DSB.cpp | 63 +++++++--------------- Src/Model3/DSB.h | 8 +-- Src/Model3/SoundBoard.cpp | 50 +++++++++++------ Src/Model3/SoundBoard.h | 4 +- Src/OSD/Audio.h | 2 +- Src/OSD/SDL/Audio.cpp | 110 ++++++++++++++++++++++---------------- Src/OSD/SDL/Main.cpp | 12 ++--- Src/Sound/SCSP.cpp | 110 ++++++++++---------------------------- Src/Sound/SCSP.h | 2 +- 10 files changed, 164 insertions(+), 205 deletions(-) diff --git a/Src/Inputs/Input.cpp b/Src/Inputs/Input.cpp index e9f9466..2b44556 100644 --- a/Src/Inputs/Input.cpp +++ b/Src/Inputs/Input.cpp @@ -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(); diff --git a/Src/Model3/DSB.cpp b/Src/Model3/DSB.cpp index 07ba077..9154383 100644 --- a/Src/Model3/DSB.cpp +++ b/Src/Model3/DSB.cpp @@ -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(); - musicVol = (INT32) ((float) 0x100 * (float) musicVol / 100.0f); + // Obtain program volume settings + musicVol = (float)std::max(0,std::min(200,m_config["MusicVolume"].ValueAs())); + 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()) { // 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()) { // 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) diff --git a/Src/Model3/DSB.h b/Src/Model3/DSB.h index 2c71111..411ab08 100644 --- a/Src/Model3/DSB.h +++ b/Src/Model3/DSB.h @@ -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); diff --git a/Src/Model3/SoundBoard.cpp b/Src/Model3/SoundBoard.cpp index d02eb3c..211d12b 100644 --- a/Src/Model3/SoundBoard.cpp +++ b/Src/Model3/SoundBoard.cpp @@ -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(); - soundVol = (INT32)((float)0x100 * (float)soundVol / 100.0f); + float soundVol = (float)std::max(0,std::min(200,m_config["SoundVolume"].ValueAs())); + 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); diff --git a/Src/Model3/SoundBoard.h b/Src/Model3/SoundBoard.h index a8730ec..e8d6c69 100644 --- a/Src/Model3/SoundBoard.h +++ b/Src/Model3/SoundBoard.h @@ -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) }; diff --git a/Src/OSD/Audio.h b/Src/OSD/Audio.h index c49bdd2..9653552 100755 --- a/Src/OSD/Audio.h +++ b/Src/OSD/Audio.h @@ -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() diff --git a/Src/OSD/SDL/Audio.cpp b/Src/OSD/SDL/Audio.cpp index 073dc2e..dc626d3 100755 --- a/Src/OSD/SDL/Audio.cpp +++ b/Src/OSD/SDL/Audio.cpp @@ -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(); - 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())); balancelr *= 0.01f; BalanceLeftRight = balancelr; - float balancefr = (float)s_config->Get("BalanceFrontRear").ValueAs(); - 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())); 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(); diff --git a/Src/OSD/SDL/Main.cpp b/Src/OSD/SDL/Main.cpp index e185a43..a8a470a 100644 --- a/Src/OSD/SDL/Main.cpp +++ b/Src/OSD/SDL/Main.cpp @@ -117,7 +117,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)) @@ -153,7 +153,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); @@ -1384,7 +1384,7 @@ static void PrintGameList(const std::string &xml_file, const std::map32767)?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<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(); - 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())); + 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; } diff --git a/Src/Sound/SCSP.h b/Src/Sound/SCSP.h index 137b35b..dcea202 100644 --- a/Src/Sound/SCSP.h +++ b/Src/Sound/SCSP.h @@ -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);