From 654343f875c2dd0352f9254e98ffef1a76e40a22 Mon Sep 17 00:00:00 2001 From: gigaherz Date: Sun, 11 May 2014 16:32:01 +0200 Subject: [PATCH] Advanced (per-channel) Volume Adjustment AKA Room Correction (Windows-only, need someone to fix the linux counterpart) --- plugins/spu2-x/src/Config.h | 11 +- plugins/spu2-x/src/Mixer.h | 11 ++ plugins/spu2-x/src/SndOut.cpp | 28 +++- plugins/spu2-x/src/SndOut.h | 194 +++++++++++++++++++++- plugins/spu2-x/src/Windows/CfgHelpers.cpp | 21 +++ plugins/spu2-x/src/Windows/Config.cpp | 53 +++++- plugins/spu2-x/src/Windows/Dialogs.h | 4 +- 7 files changed, 306 insertions(+), 16 deletions(-) diff --git a/plugins/spu2-x/src/Config.h b/plugins/spu2-x/src/Config.h index 91991a7902..9a9dc82730 100644 --- a/plugins/spu2-x/src/Config.h +++ b/plugins/spu2-x/src/Config.h @@ -64,7 +64,16 @@ extern wxString RegDumpFileName; extern int Interpolation; extern int numSpeakers; extern bool EffectsDisabled; -extern float FinalVolume; +extern float FinalVolume; // Global / pre-scale +extern bool AdvancedVolumeControl; +extern float VolumeAdjustFLdb; +extern float VolumeAdjustCdb; +extern float VolumeAdjustFRdb; +extern float VolumeAdjustBLdb; +extern float VolumeAdjustBRdb; +extern float VolumeAdjustSLdb; +extern float VolumeAdjustSRdb; +extern float VolumeAdjustLFEdb; extern bool postprocess_filter_enabled; extern bool postprocess_filter_dealias; diff --git a/plugins/spu2-x/src/Mixer.h b/plugins/spu2-x/src/Mixer.h index 207e004186..fb4ebf649c 100644 --- a/plugins/spu2-x/src/Mixer.h +++ b/plugins/spu2-x/src/Mixer.h @@ -18,6 +18,10 @@ #pragma once +// Implemented in Config.cpp +extern float VolumeAdjustFL; +extern float VolumeAdjustFR; + struct StereoOut32 { static StereoOut32 Empty; @@ -76,6 +80,13 @@ struct StereoOut32 this->Right = src.Right << 2; } + void AdjustFrom(const StereoOut32& src) + { + ResampleFrom(src); + + Left = (s32) (Left * VolumeAdjustFL); + Right = (s32) (Right * VolumeAdjustFR); + } }; struct FrequencyResponseFilter diff --git a/plugins/spu2-x/src/SndOut.cpp b/plugins/spu2-x/src/SndOut.cpp index ba865cf381..abcf154b7b 100644 --- a/plugins/spu2-x/src/SndOut.cpp +++ b/plugins/spu2-x/src/SndOut.cpp @@ -270,14 +270,28 @@ template void SndBuffer::ReadSamples(T* bData) if(b1 > nSamples) b1 = nSamples; - // First part - for( int i=0; i> SndOutVolumeShift; LFE = (src.Left + src.Right) >> (SndOutVolumeShift + 1); } + + void AdjustFrom(const StereoOut32& src) + { + ResampleFrom(src); + + Left = (s16) (Left * VolumeAdjustFL); + Right = (s16) (Right * VolumeAdjustFR); + LFE = (s16) (LFE * VolumeAdjustLFE); + } }; struct Stereo40Out16 @@ -138,6 +165,16 @@ struct Stereo40Out16 LeftBack = src.Left >> SndOutVolumeShift; RightBack = src.Right >> SndOutVolumeShift; } + + void AdjustFrom(const StereoOut32& src) + { + ResampleFrom(src); + + Left = (s16) (Left * VolumeAdjustFL); + Right = (s16) (Right * VolumeAdjustFR); + LeftBack = (s16) (LeftBack * VolumeAdjustBL); + RightBack = (s16) (RightBack * VolumeAdjustBR); + } }; struct Stereo40Out32 @@ -154,6 +191,16 @@ struct Stereo40Out32 LeftBack = src.Left << SndOutVolumeShift32; RightBack = src.Right << SndOutVolumeShift32; } + + void AdjustFrom(const StereoOut32& src) + { + ResampleFrom(src); + + Left = (s32) (Left * VolumeAdjustFL); + Right = (s32) (Right * VolumeAdjustFR); + LeftBack = (s32) (LeftBack * VolumeAdjustBL); + RightBack = (s32) (RightBack * VolumeAdjustBR); + } }; struct Stereo41Out16 @@ -172,6 +219,17 @@ struct Stereo41Out16 LeftBack = src.Left >> SndOutVolumeShift; RightBack = src.Right >> SndOutVolumeShift; } + + void AdjustFrom(const StereoOut32& src) + { + ResampleFrom(src); + + Left = (s32) (Left * VolumeAdjustFL); + Right = (s32) (Right * VolumeAdjustFR); + LeftBack = (s32) (LeftBack * VolumeAdjustBL); + RightBack = (s32) (RightBack * VolumeAdjustBR); + LFE = (s32) (LFE * VolumeAdjustLFE); + } }; struct Stereo51Out16 @@ -197,6 +255,18 @@ struct Stereo51Out16 LeftBack = src.Left >> SndOutVolumeShift; RightBack = src.Right >> SndOutVolumeShift; } + + void AdjustFrom(const StereoOut32& src) + { + ResampleFrom(src); + + Left = (s16) (Left * VolumeAdjustFL); + Right = (s16) (Right * VolumeAdjustFR); + LeftBack = (s16) (LeftBack * VolumeAdjustBL); + RightBack = (s16) (RightBack * VolumeAdjustBR); + Center = (s16) (Center * VolumeAdjustC); + LFE = (s16) (LFE * VolumeAdjustLFE); + } }; struct Stereo51Out16DplII @@ -212,6 +282,18 @@ struct Stereo51Out16DplII { ProcessDplIISample16(src, this); } + + void AdjustFrom(const StereoOut32& src) + { + ResampleFrom(src); + + Left = (s32) (Left * VolumeAdjustFL); + Right = (s32) (Right * VolumeAdjustFR); + LeftBack = (s32) (LeftBack * VolumeAdjustBL); + RightBack = (s32) (RightBack * VolumeAdjustBR); + Center = (s32) (Center * VolumeAdjustC); + LFE = (s32) (LFE * VolumeAdjustLFE); + } }; struct Stereo51Out32DplII @@ -227,8 +309,19 @@ struct Stereo51Out32DplII { ProcessDplIISample32(src, this); } -}; + void AdjustFrom(const StereoOut32& src) + { + ResampleFrom(src); + + Left = (s32) (Left * VolumeAdjustFL); + Right = (s32) (Right * VolumeAdjustFR); + LeftBack = (s32) (LeftBack * VolumeAdjustBL); + RightBack = (s32) (RightBack * VolumeAdjustBR); + Center = (s32) (Center * VolumeAdjustC); + LFE = (s32) (LFE * VolumeAdjustLFE); + } +}; struct Stereo51Out16Dpl { @@ -243,6 +336,18 @@ struct Stereo51Out16Dpl { ProcessDplSample16(src, this); } + + void AdjustFrom(const StereoOut32& src) + { + ResampleFrom(src); + + Left = (s32) (Left * VolumeAdjustFL); + Right = (s32) (Right * VolumeAdjustFR); + LeftBack = (s32) (LeftBack * VolumeAdjustBL); + RightBack = (s32) (RightBack * VolumeAdjustBR); + Center = (s32) (Center * VolumeAdjustC); + LFE = (s32) (LFE * VolumeAdjustLFE); + } }; struct Stereo51Out32Dpl @@ -258,6 +363,18 @@ struct Stereo51Out32Dpl { ProcessDplSample32(src, this); } + + void AdjustFrom(const StereoOut32& src) + { + ResampleFrom(src); + + Left = (s32) (Left * VolumeAdjustFL); + Right = (s32) (Right * VolumeAdjustFR); + LeftBack = (s32) (LeftBack * VolumeAdjustBL); + RightBack = (s32) (RightBack * VolumeAdjustBR); + Center = (s32) (Center * VolumeAdjustC); + LFE = (s32) (LFE * VolumeAdjustLFE); + } }; struct Stereo71Out16 @@ -283,6 +400,20 @@ struct Stereo71Out16 LeftSide = src.Left >> (SndOutVolumeShift+1); RightSide = src.Right >> (SndOutVolumeShift+1); } + + void AdjustFrom(const StereoOut32& src) + { + ResampleFrom(src); + + Left = (s16) (Left * VolumeAdjustFL); + Right = (s16) (Right * VolumeAdjustFR); + LeftBack = (s16) (LeftBack * VolumeAdjustBL); + RightBack = (s16) (RightBack * VolumeAdjustBR); + LeftSide = (s16) (LeftBack * VolumeAdjustSL); + RightSide = (s16) (RightBack * VolumeAdjustSR); + Center = (s16) (Center * VolumeAdjustC); + LFE = (s16) (LFE * VolumeAdjustLFE); + } }; struct Stereo71Out32 @@ -308,18 +439,40 @@ struct Stereo71Out32 LeftSide = src.Left << (SndOutVolumeShift32 - 1); RightSide = src.Right << (SndOutVolumeShift32 - 1); } + + void AdjustFrom(const StereoOut32& src) + { + ResampleFrom(src); + + Left = (s32) (Left * VolumeAdjustFL); + Right = (s32) (Right * VolumeAdjustFR); + LeftBack = (s32) (LeftBack * VolumeAdjustBL); + RightBack = (s32) (RightBack * VolumeAdjustBR); + LeftSide = (s32) (LeftBack * VolumeAdjustSL); + RightSide = (s32) (RightBack * VolumeAdjustSR); + Center = (s32) (Center * VolumeAdjustC); + LFE = (s32) (LFE * VolumeAdjustLFE); + } }; struct Stereo20Out32 { s32 Left; s32 Right; - + void ResampleFrom( const StereoOut32& src ) { Left = src.Left << SndOutVolumeShift32; Right = src.Right << SndOutVolumeShift32; } + + void AdjustFrom(const StereoOut32& src) + { + ResampleFrom(src); + + Left = (s32) (Left * VolumeAdjustFL); + Right = (s32) (Right * VolumeAdjustFR); + } }; struct Stereo21Out32 @@ -327,13 +480,22 @@ struct Stereo21Out32 s32 Left; s32 Right; s32 LFE; - + void ResampleFrom( const StereoOut32& src ) { Left = src.Left << SndOutVolumeShift32; Right = src.Right << SndOutVolumeShift32; LFE = (src.Left + src.Right) << (SndOutVolumeShift32 - 1); } + + void AdjustFrom(const StereoOut32& src) + { + ResampleFrom(src); + + Left = (s32) (Left * VolumeAdjustFL); + Right = (s32) (Right * VolumeAdjustFR); + LFE = (s32) (LFE * VolumeAdjustLFE); + } }; struct Stereo41Out32 @@ -343,7 +505,7 @@ struct Stereo41Out32 s32 LFE; s32 LeftBack; s32 RightBack; - + void ResampleFrom( const StereoOut32& src ) { Left = src.Left << SndOutVolumeShift32; @@ -353,6 +515,17 @@ struct Stereo41Out32 LeftBack = src.Left << SndOutVolumeShift32; RightBack = src.Right << SndOutVolumeShift32; } + + void AdjustFrom(const StereoOut32& src) + { + ResampleFrom(src); + + Left = (s32) (Left * VolumeAdjustFL); + Right = (s32) (Right * VolumeAdjustFR); + LeftBack = (s32) (LeftBack * VolumeAdjustBL); + RightBack = (s32) (RightBack * VolumeAdjustBR); + LFE = (s32) (LFE * VolumeAdjustLFE); + } }; struct Stereo51Out32 @@ -373,6 +546,18 @@ struct Stereo51Out32 LeftBack = src.Left << SndOutVolumeShift32; RightBack = src.Right << SndOutVolumeShift32; } + + void AdjustFrom(const StereoOut32& src) + { + ResampleFrom(src); + + Left = (s32) (Left * VolumeAdjustFL); + Right = (s32) (Right * VolumeAdjustFR); + LeftBack = (s32) (LeftBack * VolumeAdjustBL); + RightBack = (s32) (RightBack * VolumeAdjustBR); + Center = (s32) (Center * VolumeAdjustC); + LFE = (s32) (LFE * VolumeAdjustLFE); + } }; // Developer Note: This is a static class only (all static members). @@ -480,7 +665,6 @@ public: virtual int GetEmptySampleCount() =0; }; - #ifdef _MSC_VER //internal extern SndOutModule* WaveOut; diff --git a/plugins/spu2-x/src/Windows/CfgHelpers.cpp b/plugins/spu2-x/src/Windows/CfgHelpers.cpp index 724b4fcff0..c35c34abc3 100644 --- a/plugins/spu2-x/src/Windows/CfgHelpers.cpp +++ b/plugins/spu2-x/src/Windows/CfgHelpers.cpp @@ -87,6 +87,13 @@ void CfgWriteInt(const TCHAR* Section, const TCHAR* Name, int Value) WritePrivateProfileString(Section,Name,Data,CfgFile); } +void CfgWriteFloat(const TCHAR* Section, const TCHAR* Name, float Value) +{ + TCHAR Data[32]; + _swprintf(Data, L"%f", Value); + WritePrivateProfileString(Section, Name, Data, CfgFile); +} + /*void CfgWriteStr(const TCHAR* Section, const TCHAR* Name, const TCHAR *Data) { WritePrivateProfileString( Section, Name, Data, CfgFile ); @@ -133,6 +140,20 @@ int CfgReadInt(const TCHAR* Section, const TCHAR* Name,int Default) return _wtoi(Data); } +int CfgReadFloat(const TCHAR* Section, const TCHAR* Name, float Default) +{ + TCHAR Data[255] = { 0 }; + GetPrivateProfileString(Section, Name, L"", Data, 255, CfgFile); + Data[254] = 0; + + if (wcslen(Data) == 0) { + CfgWriteFloat(Section, Name, Default); + return Default; + } + + return (float)_wtof(Data); +} + void CfgReadStr(const TCHAR* Section, const TCHAR* Name, TCHAR* Data, int DataSize, const TCHAR* Default) { GetPrivateProfileString(Section,Name,L"",Data,DataSize,CfgFile); diff --git a/plugins/spu2-x/src/Windows/Config.cpp b/plugins/spu2-x/src/Windows/Config.cpp index d122b5e7e2..f4efbc9402 100644 --- a/plugins/spu2-x/src/Windows/Config.cpp +++ b/plugins/spu2-x/src/Windows/Config.cpp @@ -17,6 +17,7 @@ #include "Global.h" #include "Dialogs.h" +#include #ifdef PCSX2_DEVBUILD static const int LATENCY_MAX = 3000; @@ -38,7 +39,26 @@ int Interpolation = 4; */ bool EffectsDisabled = false; -float FinalVolume; + +float FinalVolume; // Global +bool AdvancedVolumeControl; +float VolumeAdjustFLdb; // decibels settings, cos audiophiles love that +float VolumeAdjustCdb; +float VolumeAdjustFRdb; +float VolumeAdjustBLdb; +float VolumeAdjustBRdb; +float VolumeAdjustSLdb; +float VolumeAdjustSRdb; +float VolumeAdjustLFEdb; +float VolumeAdjustFL; // linear coefs calcualted from decibels, +float VolumeAdjustC; +float VolumeAdjustFR; +float VolumeAdjustBL; +float VolumeAdjustBR; +float VolumeAdjustSL; +float VolumeAdjustSR; +float VolumeAdjustLFE; + bool postprocess_filter_enabled = 1; bool postprocess_filter_dealias = false; @@ -80,11 +100,30 @@ void ReadSettings() { Interpolation = CfgReadInt( L"MIXING",L"Interpolation", 4 ); - SynchMode = CfgReadInt( L"OUTPUT", L"Synch_Mode", 0); EffectsDisabled = CfgReadBool( L"MIXING", L"Disable_Effects", false ); postprocess_filter_dealias = CfgReadBool( L"MIXING", L"DealiasFilter", false ); FinalVolume = ((float)CfgReadInt( L"MIXING", L"FinalVolume", 100 )) / 100; if ( FinalVolume > 1.0f) FinalVolume = 1.0f; + + AdvancedVolumeControl = CfgReadBool(L"MIXING", L"AdvancedVolumeControl", false); + VolumeAdjustCdb = CfgReadFloat(L"MIXING", L"VolumeAdjustC(dB)", 0); + VolumeAdjustFLdb = CfgReadFloat(L"MIXING", L"VolumeAdjustFL(dB)", 0); + VolumeAdjustFRdb = CfgReadFloat(L"MIXING", L"VolumeAdjustFR(dB)", 0); + VolumeAdjustBLdb = CfgReadFloat(L"MIXING", L"VolumeAdjustBL(dB)", 0); + VolumeAdjustBRdb = CfgReadFloat(L"MIXING", L"VolumeAdjustBR(dB)", 0); + VolumeAdjustSLdb = CfgReadFloat(L"MIXING", L"VolumeAdjustSL(dB)", 0); + VolumeAdjustSRdb = CfgReadFloat(L"MIXING", L"VolumeAdjustSR(dB)", 0); + VolumeAdjustLFEdb = CfgReadFloat(L"MIXING", L"VolumeAdjustLFE(dB)", 0); + VolumeAdjustC = powf(10, VolumeAdjustCdb / 10); + VolumeAdjustFL = powf(10, VolumeAdjustFLdb / 10); + VolumeAdjustFR = powf(10, VolumeAdjustFRdb / 10); + VolumeAdjustBL = powf(10, VolumeAdjustBLdb / 10); + VolumeAdjustBR = powf(10, VolumeAdjustBRdb / 10); + VolumeAdjustSL = powf(10, VolumeAdjustSLdb / 10); + VolumeAdjustSR = powf(10, VolumeAdjustSRdb / 10); + VolumeAdjustLFE = powf(10, VolumeAdjustLFEdb / 10); + + SynchMode = CfgReadInt( L"OUTPUT", L"Synch_Mode", 0); numSpeakers = CfgReadInt( L"OUTPUT", L"SpeakerConfiguration", 0); dplLevel = CfgReadInt( L"OUTPUT", L"DplDecodingLevel", 0); SndOutLatencyMS = CfgReadInt(L"OUTPUT",L"Latency", 100); @@ -144,6 +183,16 @@ void WriteSettings() CfgWriteBool(L"MIXING",L"DealiasFilter",postprocess_filter_dealias); CfgWriteInt(L"MIXING",L"FinalVolume",(int)(FinalVolume * 100 + 0.5f)); + CfgWriteBool(L"MIXING", L"AdvancedVolumeControl", AdvancedVolumeControl); + CfgWriteFloat(L"MIXING", L"VolumeAdjustC(dB)", VolumeAdjustCdb); + CfgWriteFloat(L"MIXING", L"VolumeAdjustFL(dB)", VolumeAdjustFLdb); + CfgWriteFloat(L"MIXING", L"VolumeAdjustFR(dB)", VolumeAdjustFRdb); + CfgWriteFloat(L"MIXING", L"VolumeAdjustBL(dB)", VolumeAdjustBLdb); + CfgWriteFloat(L"MIXING", L"VolumeAdjustBR(dB)", VolumeAdjustBRdb); + CfgWriteFloat(L"MIXING", L"VolumeAdjustSL(dB)", VolumeAdjustSLdb); + CfgWriteFloat(L"MIXING", L"VolumeAdjustSR(dB)", VolumeAdjustSRdb); + CfgWriteFloat(L"MIXING", L"VolumeAdjustLFE(dB)", VolumeAdjustLFEdb); + CfgWriteStr(L"OUTPUT",L"Output_Module", mods[OutputModule]->GetIdent() ); CfgWriteInt(L"OUTPUT",L"Latency", SndOutLatencyMS); CfgWriteInt(L"OUTPUT",L"Synch_Mode", SynchMode); diff --git a/plugins/spu2-x/src/Windows/Dialogs.h b/plugins/spu2-x/src/Windows/Dialogs.h index ea98d410ee..675b7051c0 100644 --- a/plugins/spu2-x/src/Windows/Dialogs.h +++ b/plugins/spu2-x/src/Windows/Dialogs.h @@ -54,12 +54,14 @@ extern bool CfgFindName( const TCHAR *Section, const TCHAR* Name); extern void CfgWriteBool(const TCHAR* Section, const TCHAR* Name, bool Value); extern void CfgWriteInt(const TCHAR* Section, const TCHAR* Name, int Value); +extern void CfgWriteFloat(const TCHAR* Section, const TCHAR* Name, float Value); extern void CfgWriteStr(const TCHAR* Section, const TCHAR* Name, const wxString& Data); extern bool CfgReadBool(const TCHAR *Section,const TCHAR* Name, bool Default); extern void CfgReadStr(const TCHAR* Section, const TCHAR* Name, wxString& Data, const TCHAR* Default); extern void CfgReadStr(const TCHAR* Section, const TCHAR* Name, TCHAR* Data, int DataSize, const TCHAR* Default); -extern int CfgReadInt(const TCHAR* Section, const TCHAR* Name,int Default); +extern int CfgReadInt(const TCHAR* Section, const TCHAR* Name, int Default); +extern int CfgReadFloat(const TCHAR* Section, const TCHAR* Name, float Default); // Items Specific to DirectSound #define STRFY(x) #x