Skip to content

Commit

Permalink
Probably fix sound and music volume settings by removing code from DS…
Browse files Browse the repository at this point in the history
…B and moving it to SoundBoard.cpp
  • Loading branch information
njz3 committed Jun 17, 2022
1 parent b284713 commit 95968f3
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 89 deletions.
15 changes: 6 additions & 9 deletions Src/Model3/DSB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,7 @@ int CDSBResampler::UpSampleAndMix(INT16 *outL, INT16 *outR, INT16 *inL, INT16 *i

// Obtain program volume settings and convert to 24.8 fixed point (0-200 -> 0x00-0x200)
musicVol = m_config["MusicVolume"].ValueAs<int>();
soundVol = m_config["SoundVolume"].ValueAs<int>();
musicVol = (INT32) ((float) 0x100 * (float) musicVol / 100.0f);
soundVol = (INT32) ((float) 0x100 * (float) soundVol / 100.0f);

// Scale volume from 0x00-0xFF -> 0x00-0x100 (24.8 fixed point)
v[0] = (INT16) ((float) 0x100 * (float) volumeL / 255.0f);
Expand All @@ -167,8 +165,8 @@ int CDSBResampler::UpSampleAndMix(INT16 *outL, INT16 *outR, INT16 *inL, INT16 *i
rightSample = (rightSample*v[0]*musicVol) >> 16;

// Apply sound volume setting
leftSoundSample = (outL[outIdx]*soundVol) >> 8;
rightSoundSample = (outR[outIdx]*soundVol) >> 8;
leftSoundSample = outL[outIdx];
rightSoundSample = outR[outIdx];

// Mix and output
outL[outIdx] = MixAndClip(leftSoundSample, leftSample);
Expand All @@ -185,7 +183,6 @@ int CDSBResampler::UpSampleAndMix(INT16 *outL, INT16 *outR, INT16 *inL, INT16 *i
pFrac += (1<<8);
nFrac -= (1<<8);
inIdx++; // advance samples (for upsampling only; downsampling may advance by more than one -- add delta every loop iteration)

}
}

Expand Down Expand Up @@ -435,7 +432,7 @@ void CDSB1::RunFrame(INT16 *audioL, INT16 *audioR)
// 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, 0, 0, 44100/60, 32000/60+2, 44100, 32000);
retainedSamples = Resampler.UpSampleAndMix(audioL, audioR, mpegL, mpegR, 0, 0, NUM_SAMPLES_PER_FRAME, 32000/60+2, 44100, 32000);
return;
}

Expand All @@ -457,7 +454,7 @@ void CDSB1::RunFrame(INT16 *audioL, INT16 *audioR)

// Decode MPEG for this frame
MpegDec::DecodeAudio(&mpegL[retainedSamples], &mpegR[retainedSamples], 32000 / 60 - retainedSamples + 2);
retainedSamples = Resampler.UpSampleAndMix(audioL, audioR, mpegL, mpegR, v, v, 44100/60, 32000/60+2, 44100, 32000);
retainedSamples = Resampler.UpSampleAndMix(audioL, audioR, mpegL, mpegR, v, v, NUM_SAMPLES_PER_FRAME, 32000/60+2, 44100, 32000);
}

void CDSB1::Reset(void)
Expand Down Expand Up @@ -1001,7 +998,7 @@ void CDSB2::RunFrame(INT16 *audioL, INT16 *audioR)
// 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], 44100 / 60, 32000 / 60 + 2, 44100, 32000);
retainedSamples = Resampler.UpSampleAndMix(audioL, audioR, mpegL, mpegR, volume[0], volume[1], NUM_SAMPLES_PER_FRAME, 32000 / 60 + 2, 44100, 32000);
return;
}

Expand Down Expand Up @@ -1072,7 +1069,7 @@ void CDSB2::RunFrame(INT16 *audioL, INT16 *audioR)
break;
}

retainedSamples = Resampler.UpSampleAndMix(audioL, audioR, leftChannelSource, rightChannelSource, volL, volR, 44100 / 60, 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)
Expand Down
2 changes: 2 additions & 0 deletions Src/Model3/DSB.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
#define FIFO_STACK_SIZE 0x100
#define FIFO_STACK_SIZE_MASK (FIFO_STACK_SIZE - 1)

#define NUM_SAMPLES_PER_FRAME (44100/60)

/******************************************************************************
Resampling
Expand Down
50 changes: 32 additions & 18 deletions Src/Model3/SoundBoard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ static FILE *soundFP;
#endif


// 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 MEMORY_POOL_SIZE (0x100000 + 0x100000 + 4*LENGTH_CHANNEL_BUFFER)


/******************************************************************************
68K Address Space Handlers
******************************************************************************/
Expand Down Expand Up @@ -350,13 +362,25 @@ bool CSoundBoard::RunFrame(void)
}
else
{
memset(audioFL, 0, 44100/60*sizeof(INT16));
memset(audioFR, 0, 44100/60*sizeof(INT16));
memset(audioRL, 0, 44100/60*sizeof(INT16));
memset(audioRR, 0, 44100/60*sizeof(INT16));
memset(audioFL, 0, LENGTH_CHANNEL_BUFFER);
memset(audioFR, 0, LENGTH_CHANNEL_BUFFER);
memset(audioRL, 0, LENGTH_CHANNEL_BUFFER);
memset(audioRR, 0, LENGTH_CHANNEL_BUFFER);
}

// Run DSB and mix with existing audio
// Compute sound volume as
INT32 soundVol = m_config["SoundVolume"].ValueAs<int>();
soundVol = (INT32)((float)0x100 * (float)soundVol / 100.0f);

// 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;
}

// Run DSB and mix with existing audio, apply music volume
if (NULL != DSB) {
// Will need to mix with proper front, rear channels or both (game specific)
bool mixDSBWithFront = true; // Everything to front channels for now
Expand All @@ -368,12 +392,12 @@ bool CSoundBoard::RunFrame(void)
}

// Output the audio buffers
bool bufferFull = OutputAudio(44100/60, audioFL, audioFR, audioRL, audioRR, m_config["FlipStereo"].ValueAs<bool>());
bool bufferFull = OutputAudio(NUM_SAMPLES_PER_FRAME, audioFL, audioFR, audioRL, audioRR, m_config["FlipStereo"].ValueAs<bool>());

#ifdef SUPERMODEL_LOG_AUDIO
// Output to binary file
INT16 s;
for (int i = 0; i < 44100/60; i++)
for (int i = 0; i < NUM_SAMPLES_PER_FRAME; i++)
{
s = audioL[i];
fwrite(&s, sizeof(INT16), 1, soundFP); // left channel
Expand Down Expand Up @@ -452,16 +476,6 @@ void CSoundBoard::AttachDSB(CDSB *DSBPtr)
DebugLog("Sound Board connected to DSB\n");
}

// 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 0x5BE
#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 MEMORY_POOL_SIZE (0x100000 + 0x100000 + 4*LENGTH_CHANNEL_BUFFER)

bool CSoundBoard::Init(const UINT8 *soundROMPtr, const UINT8 *sampleROMPtr)
{
Expand Down Expand Up @@ -495,7 +509,7 @@ bool CSoundBoard::Init(const UINT8 *soundROMPtr, const UINT8 *sampleROMPtr)
M68KGetContext(&M68K);

// Initialize SCSPs
SCSP_SetBuffers(audioFL, audioFR, audioRL, audioRR, 44100/60);
SCSP_SetBuffers(audioFL, audioFR, audioRL, audioRR, NUM_SAMPLES_PER_FRAME);
SCSP_SetCB(SCSP68KRunCallback, SCSP68KIRQCallback);
if (OKAY != SCSP_Init(m_config, 2))
return FAIL;
Expand Down
61 changes: 37 additions & 24 deletions Src/OSD/SDL/Audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ static int bytes_per_frame_host = BYTES_PER_FRAME_M3;
float BalanceLeftRight = 0; // 0 mid balance, 100: left only, -100:right only
float BalanceFrontRear = 0; // 0 mid balance, 100: front only, -100:right only
// Mixer factor (depends on values above)
float balanceFactorFrontLeft = 1.0;
float balanceFactorFrontRight = 1.0;
float balanceFactorRearLeft = 1.0;
float balanceFactorRearRight = 1.0;
float balanceFactorFrontLeft = 1.0f;
float balanceFactorFrontRight = 1.0f;
float balanceFactorRearLeft = 1.0f;
float balanceFactorRearRight = 1.0f;

static bool enabled = true; // True if sound output is enabled
static constexpr unsigned latency = 20; // Audio latency to use (ie size of audio buffer) as percentage of max buffer size
Expand Down Expand Up @@ -145,10 +145,24 @@ void SetAudioType(Game::AudioTypes type)
static INT16 AddAndClampINT16(INT32 x, INT32 y)
{
INT32 sum = x+y;
if (sum>INT16_MAX)
if (sum > INT16_MAX) {
sum = INT16_MAX;
if (sum<INT16_MIN)
}
if (sum < INT16_MIN) {
sum = INT16_MIN;
}
return (INT16)sum;
}

static INT16 MixINT16(INT32 x, INT32 y)
{
INT32 sum = (x + y)>>1;
if (sum > INT16_MAX) {
sum = INT16_MAX;
}
if (sum < INT16_MIN) {
sum = INT16_MIN;
}
return (INT16)sum;
}

Expand Down Expand Up @@ -263,10 +277,9 @@ static void MixChannels(unsigned numSamples, INT16* leftFrontBuffer, INT16* righ

if (nbHostAudioChannels == 1) {
for (unsigned i = 0; i < numSamples; i++) {
// TODO: these should probably be clipped!
//INT16 monovalue = (INT16)(((INT32)leftFrontBuffer[i] + (INT32)rightFrontBuffer[i] + (INT32)leftRearBuffer[i] + (INT32)rightRearBuffer[i]));
INT16 monovalue = AddAndClampINT16(((INT32)leftFrontBuffer[i])*balanceFactorFrontLeft + ((INT32)rightFrontBuffer[i])*balanceFactorFrontRight,
((INT32)leftRearBuffer[i])*balanceFactorRearLeft + ((INT32)rightRearBuffer[i])*balanceFactorRearRight);
INT16 monovalue = MixINT16(
MixINT16((INT32)(leftFrontBuffer[i] * balanceFactorFrontLeft), (INT32)(rightFrontBuffer[i] * balanceFactorFrontRight)),
MixINT16((INT32)(leftRearBuffer[i] * balanceFactorRearLeft), (INT32)(rightRearBuffer[i] * balanceFactorRearRight)));
*p++ = monovalue;
}
} else {
Expand All @@ -282,8 +295,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 = AddAndClampINT16(leftFrontBuffer[i]*balanceFactorFrontLeft, leftRearBuffer[i]*balanceFactorRearLeft);
INT16 rightvalue = AddAndClampINT16(rightFrontBuffer[i]*balanceFactorFrontRight, rightRearBuffer[i]*balanceFactorRearRight);
INT16 leftvalue = MixINT16((INT32)(leftFrontBuffer[i] * balanceFactorFrontLeft), (INT32)(leftRearBuffer[i] * balanceFactorRearLeft));
INT16 rightvalue = MixINT16((INT32)(rightFrontBuffer[i]*balanceFactorFrontRight), (INT32)(rightRearBuffer[i]*balanceFactorRearRight));
if (flipStereo) // swap left and right channels
{
*p++ = rightvalue;
Expand All @@ -303,7 +316,7 @@ static void MixChannels(unsigned numSamples, INT16* leftFrontBuffer, INT16* righ
// Check game audio type
switch (AudioType) {
case Game::MONO: {
INT16 monovalue = AddAndClampINT16(AddAndClampINT16(frontLeftValue, frontRightValue), AddAndClampINT16(rearLeftValue, rearRightValue));
INT16 monovalue = MixINT16(MixINT16(frontLeftValue, frontRightValue), MixINT16(rearLeftValue, rearRightValue));
*p++ = monovalue;
*p++ = monovalue;
*p++ = monovalue;
Expand All @@ -312,8 +325,8 @@ static void MixChannels(unsigned numSamples, INT16* leftFrontBuffer, INT16* righ

case Game::STEREO_LR:
case Game::STEREO_RL: {
INT16 leftvalue = AddAndClampINT16(frontLeftValue, frontRightValue);
INT16 rightvalue = AddAndClampINT16(rearLeftValue, rearRightValue);
INT16 leftvalue = MixINT16(frontLeftValue, frontRightValue);
INT16 rightvalue = MixINT16(rearLeftValue, rearRightValue);
if (flipStereo) // swap left and right channels
{
*p++ = rightvalue;
Expand Down Expand Up @@ -365,10 +378,10 @@ static void MixChannels(unsigned numSamples, INT16* leftFrontBuffer, INT16* righ
case Game::QUAD_1_LR_2_FR_MIX:
// Split mix: one goes to left/right, other front/rear (mono)
// =>Remix all!
INT16 newfrontLeftValue = AddAndClampINT16(frontLeftValue, rearLeftValue);
INT16 newfrontRightValue = AddAndClampINT16(frontLeftValue, rearRightValue);
INT16 newrearLeftValue = AddAndClampINT16(frontRightValue, rearLeftValue);
INT16 newrearRightValue = AddAndClampINT16(frontRightValue, rearRightValue);
INT16 newfrontLeftValue = MixINT16(frontLeftValue, rearLeftValue);
INT16 newfrontRightValue = MixINT16(frontLeftValue, rearRightValue);
INT16 newrearLeftValue = MixINT16(frontRightValue, rearLeftValue);
INT16 newrearRightValue = MixINT16(frontRightValue, rearRightValue);

if (flipStereo) // swap left and right channels
{
Expand Down Expand Up @@ -443,10 +456,10 @@ bool OpenAudio(const Util::Config::Node& config)
balancefr *= 0.01f;
BalanceFrontRear = balancefr;

balanceFactorFrontLeft = (BalanceLeftRight<0.0?1.0+BalanceLeftRight:1.0)*(BalanceFrontRear<0?1.0+BalanceFrontRear:1.0);
balanceFactorFrontRight = (BalanceLeftRight>0.0?1.0-BalanceLeftRight:1.0)*(BalanceFrontRear<0?1.0+BalanceFrontRear:1.0);
balanceFactorRearLeft = (BalanceLeftRight<0.0?1.0+BalanceLeftRight:1.0)*(BalanceFrontRear>0?1.0-BalanceFrontRear:1.0);
balanceFactorRearRight = (BalanceLeftRight>0.0?1.0-BalanceLeftRight:1.0)*(BalanceFrontRear>0?1.0-BalanceFrontRear:1.0);
balanceFactorFrontLeft = (BalanceLeftRight < 0.f ? 1.f + BalanceLeftRight : 1.f) * (BalanceFrontRear < 0 ? 1.f + BalanceFrontRear : 1.f);
balanceFactorFrontRight = (BalanceLeftRight > 0.f ? 1.f - BalanceLeftRight : 1.f) * (BalanceFrontRear < 0 ? 1.f + BalanceFrontRear : 1.f);
balanceFactorRearLeft = (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
SDL_AudioSpec desired;
Expand Down Expand Up @@ -530,7 +543,7 @@ bool OutputAudio(unsigned numSamples, INT16* leftFrontBuffer, INT16* rightFrontB
INT16* src;

// Number of samples should never be more than max number of samples per frame
if (numSamples > samples_per_frame_host)
if (numSamples > (unsigned)samples_per_frame_host)
numSamples = samples_per_frame_host;

// Mix together left and right channels into single chunk of data
Expand Down
Loading

0 comments on commit 95968f3

Please sign in to comment.