diff --git a/Core/Config.cpp b/Core/Config.cpp index a36c88615303..8effa2026a14 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -579,6 +579,8 @@ static ConfigSetting soundSettings[] = { ConfigSetting("ExtraAudioBuffering", &g_Config.bExtraAudioBuffering, false, true, false), ConfigSetting("AudioResampler", &g_Config.bAudioResampler, true, true, true), ConfigSetting("GlobalVolume", &g_Config.iGlobalVolume, VOLUME_MAX, true, true), + ConfigSetting("SASVolume", &g_Config.iSASVolume, 8, true, true), + ConfigSetting("ATRACMP3Volume", &g_Config.iATRACMP3Volume, 8, true, true), ConfigSetting(false), }; diff --git a/Core/Config.h b/Core/Config.h index 48567afab3db..57bf69e1803d 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -25,6 +25,7 @@ extern const char *PPSSPP_GIT_VERSION; +const int MAX_CONFIG_VOLUME = 8; const int PSP_MODEL_FAT = 0; const int PSP_MODEL_SLIM = 1; const int PSP_DEFAULT_FIRMWARE = 150; @@ -228,7 +229,7 @@ struct Config { bool bEnableSound; int iAudioLatency; // 0 = low , 1 = medium(default) , 2 = high int iAudioBackend; - int iGlobalVolume; + int iGlobalVolume, iSASVolume, iATRACMP3Volume; bool bExtraAudioBuffering; // For bluetooth // UI diff --git a/Core/HLE/sceAtrac.cpp b/Core/HLE/sceAtrac.cpp index bef952a7e821..34e2bc5e2ddc 100644 --- a/Core/HLE/sceAtrac.cpp +++ b/Core/HLE/sceAtrac.cpp @@ -1226,6 +1226,7 @@ u32 _AtracDecodeData(int atracID, u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u3 if (avret < 0) { ERROR_LOG(ME, "swr_convert: Error while converting %d", avret); } + __AdjustATRACMP3Volume((s16 *)out, numSamples * atrac->outputChannels_); } #endif // USE_FFMPEG } @@ -2450,6 +2451,7 @@ static int sceAtracLowLevelDecode(int atracID, u32 sourceAddr, u32 sourceBytesCo if (avret < 0) { ERROR_LOG(ME, "swr_convert: Error while converting %d", avret); } + __AdjustATRACMP3Volume((s16 *)out, numSamples * atrac->outputChannels_); #endif // USE_FFMPEG } else { // TODO: Error code otherwise? diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp index 35f814ca8475..cd6887fa9931 100644 --- a/Core/HW/MediaEngine.cpp +++ b/Core/HW/MediaEngine.cpp @@ -117,6 +117,18 @@ static int getPixelFormatBytes(int pspFormat) } } + +void __AdjustATRACMP3Volume(s16 *samples, u32 count) { + if (g_Config.iATRACMP3Volume < 0 || g_Config.iATRACMP3Volume >= MAX_CONFIG_VOLUME) { + return; + } + int volumeShift = MAX_CONFIG_VOLUME - g_Config.iATRACMP3Volume; + ; + for (u32 i = 0; i < count; ++i) { + samples[i] >>= volumeShift; + } +} + MediaEngine::MediaEngine(): m_pdata(0) { #ifdef USE_FFMPEG m_pFormatCtx = 0; diff --git a/Core/HW/MediaEngine.h b/Core/HW/MediaEngine.h index 6561176b03af..9bbc3a1a2125 100644 --- a/Core/HW/MediaEngine.h +++ b/Core/HW/MediaEngine.h @@ -50,6 +50,8 @@ inline s64 getMpegTimeStamp(const u8 *buf) { bool InitFFmpeg(); #endif +void __AdjustATRACMP3Volume(s16 *samples, u32 count); + class MediaEngine { public: diff --git a/Core/HW/SasAudio.cpp b/Core/HW/SasAudio.cpp index 9bf5fd82efd0..f2fcda48ef02 100644 --- a/Core/HW/SasAudio.cpp +++ b/Core/HW/SasAudio.cpp @@ -510,7 +510,8 @@ void SasInstance::MixVoice(SasVoice &voice) { } voice.ReadSamples(&mixTemp_[2], samplesToRead); int tempPos = 2 + samplesToRead; - + int volumeShift = (12 + MAX_CONFIG_VOLUME - g_Config.iSASVolume); + if (volumeShift < 0) volumeShift = 0; for (int i = delay; i < grainSize; i++) { const int16_t *s = mixTemp_ + (sampleFrac >> PSP_SAS_PITCH_BASE_SHIFT); @@ -532,10 +533,10 @@ void SasInstance::MixVoice(SasVoice &voice) { // We mix into this 32-bit temp buffer and clip in a second loop // Ideally, the shift right should be there too but for now I'm concerned about // not overflowing. - mixBuffer[i * 2] += (sample * voice.volumeLeft) >> 12; - mixBuffer[i * 2 + 1] += (sample * voice.volumeRight) >> 12; - sendBuffer[i * 2] += sample * voice.effectLeft >> 12; - sendBuffer[i * 2 + 1] += sample * voice.effectRight >> 12; + mixBuffer[i * 2] += (sample * voice.volumeLeft) >> volumeShift; + mixBuffer[i * 2 + 1] += (sample * voice.volumeRight) >> volumeShift; + sendBuffer[i * 2] += sample * voice.effectLeft >> volumeShift; + sendBuffer[i * 2 + 1] += sample * voice.effectRight >> volumeShift; } voice.resampleHist[0] = mixTemp_[tempPos - 2]; diff --git a/Core/HW/SimpleAudioDec.cpp b/Core/HW/SimpleAudioDec.cpp index 7728b36eb85c..bd2cc9b11d7b 100644 --- a/Core/HW/SimpleAudioDec.cpp +++ b/Core/HW/SimpleAudioDec.cpp @@ -238,6 +238,8 @@ bool SimpleAudio::Decode(void *inbuf, int inbytes, uint8_t *outbuf, int *outbyte // each sample occupies 2 bytes *outbytes = outSamples * 2; + // We always convert to stereo. + __AdjustATRACMP3Volume((s16 *)outbuf, frame_->nb_samples * 2); // Save outbuf into pcm audio, you can uncomment this line to save and check the decoded audio into pcm file. // SaveAudio("dump.pcm", outbuf, *outbytes); diff --git a/README.md b/README.md index 136079346967..67486f95be06 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,8 @@ This hackish branch add's: - a few more post process shaders, - texture replacement info from ge debugger(experimental aka usually works, but it might be done badly, available from right click menu), - ultra high render resolutions and render screenshots, + - some mp3 improvements(volume clamping and removal of bad hack), + - separate sas and atrac/mp3 volume sliders, - some untested/optional hack to avoid stutter on NVidia hardware/bad drivers. To list some game compatibility improvements here: @@ -51,6 +53,8 @@ This hackish branch add's: - Resistance Retribution(some of the crashes), - Sangokushi IX with Power-Up Kit(black layer), - The Warriors(videos), + - Mighty Flip Champs DX(sound too loud), + - N+(sound too loud), - and more via included patches. Also includes a really awful hack for MOHH2 multiplayer(MOHH1 works fine without it;p). diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index b4b1900f3d19..4ed3a5437da9 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -491,6 +491,11 @@ void GameSettingsScreen::CreateViews() { CheckBox *resampling = audioSettings->Add(new CheckBox(&g_Config.bAudioResampler, a->T("Audio sync", "Audio sync (resampling)"))); resampling->SetEnabledPtr(&g_Config.bEnableSound); } + + PopupSliderChoice *sasVol = audioSettings->Add(new PopupSliderChoice(&g_Config.iSASVolume, 0, MAX_CONFIG_VOLUME, a->T("SAS volume"), screenManager())); + sasVol->SetEnabledPtr(&g_Config.bEnableSound); + PopupSliderChoice * atracmp3Vol = audioSettings->Add(new PopupSliderChoice(&g_Config.iATRACMP3Volume, 0, MAX_CONFIG_VOLUME, a->T("ATRAC / MP3 volume"), screenManager())); + atracmp3Vol->SetEnabledPtr(&g_Config.bEnableSound); } // Control ViewGroup *controlsSettingsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); diff --git a/headless/Headless.cpp b/headless/Headless.cpp index 661211d1d0d0..cf86f8f92323 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -369,6 +369,8 @@ int main(int argc, const char* argv[]) g_Config.bFrameSkipUnthrottle = false; g_Config.bEnableLogging = fullLog; g_Config.iNumWorkerThreads = 1; + g_Config.iATRACMP3Volume = MAX_CONFIG_VOLUME; + g_Config.iSASVolume = MAX_CONFIG_VOLUME; g_Config.bSoftwareSkinning = true; g_Config.bVertexDecoderJit = true; g_Config.bBlockTransferGPU = true;