Advanced (per-channel) Volume Adjustment AKA Room Correction (Windows-only, need someone to fix the linux counterpart)

This commit is contained in:
gigaherz 2014-05-11 16:32:01 +02:00
parent 0bf7a35a53
commit 654343f875
7 changed files with 306 additions and 16 deletions

View File

@ -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;

View File

@ -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

View File

@ -270,6 +270,19 @@ template<typename T> void SndBuffer::ReadSamples(T* bData)
if(b1 > nSamples)
b1 = nSamples;
if (AdvancedVolumeControl)
{
// First part
for (int i = 0; i < b1; i++)
bData[i].AdjustFrom(m_buffer[i + m_rpos]);
// Second part
int b2 = nSamples - b1;
for (int i = 0; i < b2; i++)
bData[i + b1].AdjustFrom(m_buffer[i]);
}
else
{
// First part
for (int i = 0; i < b1; i++)
bData[i].ResampleFrom(m_buffer[i + m_rpos]);
@ -278,6 +291,7 @@ template<typename T> void SndBuffer::ReadSamples(T* bData)
int b2 = nSamples - b1;
for (int i = 0; i < b2; i++)
bData[i + b1].ResampleFrom(m_buffer[i]);
}
_DropSamples_Internal(nSamples);
}

View File

@ -36,6 +36,16 @@ static const int SampleRate = 48000;
extern int FindOutputModuleById( const wchar_t* omodid );
// Implemented in Config.cpp
extern float VolumeAdjustFL;
extern float VolumeAdjustC;
extern float VolumeAdjustFR;
extern float VolumeAdjustBL;
extern float VolumeAdjustBR;
extern float VolumeAdjustSL;
extern float VolumeAdjustSR;
extern float VolumeAdjustLFE;
struct Stereo51Out16DplII;
struct Stereo51Out32DplII;
@ -78,6 +88,14 @@ struct StereoOut16
// Use StereoOut32's built in conversion
*this = src.DownSample();
}
void AdjustFrom(const StereoOut32& src)
{
ResampleFrom(src);
Left = (s16) (Left * VolumeAdjustFL);
Right = (s16) (Right * VolumeAdjustFR);
}
};
struct StereoOutFloat
@ -122,6 +140,15 @@ struct Stereo21Out16
Right = src.Right >> 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,6 +439,20 @@ 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
@ -320,6 +465,14 @@ struct Stereo20Out32
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
@ -334,6 +487,15 @@ struct Stereo21Out32
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
@ -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;

View File

@ -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);

View File

@ -17,6 +17,7 @@
#include "Global.h"
#include "Dialogs.h"
#include <math.h>
#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);

View File

@ -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 CfgReadFloat(const TCHAR* Section, const TCHAR* Name, float Default);
// Items Specific to DirectSound
#define STRFY(x) #x