mirror of
https://github.com/ARMSX2/ARMSX2.git
synced 2026-08-24 16:50:16 -07:00
172 lines
6.0 KiB
C++
172 lines
6.0 KiB
C++
/* PCSX2 - PS2 Emulator for PCs
|
|
* Copyright (C) 2002-2020 PCSX2 Dev Team
|
|
*
|
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
|
*
|
|
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with PCSX2.
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "PrecompiledHeader.h"
|
|
#include "Global.h"
|
|
|
|
// FIXME Not yet used so let's comment it out.
|
|
/*static const u8 sLogTable[256] = {
|
|
0x00, 0x3C, 0x60, 0x78, 0x8C, 0x9C, 0xA8, 0xB4, 0xBE, 0xC8, 0xD0, 0xD8, 0xDE, 0xE4, 0xEA, 0xF0,
|
|
0xF6, 0xFA, 0xFE, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x16, 0x1A, 0x1E, 0x20, 0x24, 0x26, 0x2A, 0x2C,
|
|
0x2E, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3E, 0x40, 0x42, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x50,
|
|
0x50, 0x52, 0x54, 0x56, 0x58, 0x5A, 0x5A, 0x5C, 0x5E, 0x60, 0x60, 0x62, 0x64, 0x66, 0x66, 0x68,
|
|
0x6A, 0x6A, 0x6C, 0x6E, 0x6E, 0x70, 0x70, 0x72, 0x74, 0x74, 0x76, 0x76, 0x78, 0x7A, 0x7A, 0x7C,
|
|
0x7C, 0x7E, 0x7E, 0x80, 0x80, 0x82, 0x82, 0x84, 0x84, 0x86, 0x86, 0x88, 0x88, 0x8A, 0x8A, 0x8C,
|
|
0x8C, 0x8C, 0x8E, 0x8E, 0x90, 0x90, 0x92, 0x92, 0x92, 0x94, 0x94, 0x96, 0x96, 0x96, 0x98, 0x98,
|
|
0x9A, 0x9A, 0x9A, 0x9C, 0x9C, 0x9C, 0x9E, 0x9E, 0xA0, 0xA0, 0xA0, 0xA2, 0xA2, 0xA2, 0xA4, 0xA4,
|
|
0xA4, 0xA6, 0xA6, 0xA6, 0xA8, 0xA8, 0xA8, 0xAA, 0xAA, 0xAA, 0xAC, 0xAC, 0xAC, 0xAC, 0xAE, 0xAE,
|
|
0xAE, 0xB0, 0xB0, 0xB0, 0xB2, 0xB2, 0xB2, 0xB2, 0xB4, 0xB4, 0xB4, 0xB6, 0xB6, 0xB6, 0xB6, 0xB8,
|
|
0xB8, 0xB8, 0xB8, 0xBA, 0xBA, 0xBA, 0xBC, 0xBC, 0xBC, 0xBC, 0xBE, 0xBE, 0xBE, 0xBE, 0xC0, 0xC0,
|
|
0xC0, 0xC0, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC4, 0xC4, 0xC4, 0xC4, 0xC6, 0xC6, 0xC6, 0xC6, 0xC8,
|
|
0xC8, 0xC8, 0xC8, 0xC8, 0xCA, 0xCA, 0xCA, 0xCA, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCE, 0xCE, 0xCE,
|
|
0xCE, 0xCE, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD4, 0xD4, 0xD4, 0xD4,
|
|
0xD4, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xDA, 0xDA, 0xDA, 0xDA,
|
|
0xDA, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xE0, 0xE0, 0xE0,
|
|
};*/
|
|
|
|
static float Gfl = 0, Gfr = 0;
|
|
static float LMax = 0, RMax = 0;
|
|
|
|
static float AccL = 0;
|
|
static float AccR = 0;
|
|
|
|
const float Scale = 4294967296.0f; // tweak this value to change the overall output volume
|
|
|
|
const float GainL = 0.80f * Scale;
|
|
const float GainR = 0.80f * Scale;
|
|
|
|
const float GainC = 0.75f * Scale;
|
|
|
|
const float GainSL = 0.90f * Scale;
|
|
const float GainSR = 0.90f * Scale;
|
|
|
|
const float GainLFE = 0.90f * Scale;
|
|
|
|
const float AddCLR = 0.20f * Scale; // Stereo expansion
|
|
|
|
extern void ResetDplIIDecoder()
|
|
{
|
|
Gfl = 0;
|
|
Gfr = 0;
|
|
LMax = 0;
|
|
RMax = 0;
|
|
AccL = 0;
|
|
AccR = 0;
|
|
}
|
|
|
|
void ProcessDplIISample32(const StereoOut32& src, Stereo51Out32DplII* s)
|
|
{
|
|
float IL = src.Left / (float)(1 << (SndOutVolumeShift + 16));
|
|
float IR = src.Right / (float)(1 << (SndOutVolumeShift + 16));
|
|
|
|
// Calculate center channel and LFE
|
|
float C = (IL + IR) * 0.5f;
|
|
float SUB = C; // no need to lowpass, the speaker amplifier should take care of it
|
|
|
|
float L = IL - C; // Effective L/R data
|
|
float R = IR - C;
|
|
|
|
// Peak L/R
|
|
float PL = std::abs(L);
|
|
float PR = std::abs(R);
|
|
|
|
AccL += (PL - AccL) * 0.1f;
|
|
AccR += (PR - AccR) * 0.1f;
|
|
|
|
// Calculate power balance
|
|
float Balance = (AccR - AccL); // -1 .. 1
|
|
|
|
// If the power levels are different, then the audio is meant for the front speakers
|
|
float Frontness = std::abs(Balance);
|
|
float Rearness = 1 - Frontness; // And the other way around
|
|
|
|
// Equalize the power levels for L/R
|
|
float B = std::min(0.9f, std::max(-0.9f, Balance));
|
|
|
|
float VL = L / (1 - B); // if B>0, it means R>L, so increase L, else decrease L
|
|
float VR = R / (1 + B); // vice-versa
|
|
|
|
// 1.73+1.22 = 2.94; 2.94 = 0.34 = 0.9996; Close enough.
|
|
// The range for VL/VR is approximately 0..1,
|
|
// But in the cases where VL/VR are > 0.5, Rearness is 0 so it should never overflow.
|
|
const float RearScale = 0.34f * 2;
|
|
|
|
float SL = (VR * 1.73f - VL * 1.22f) * RearScale * Rearness;
|
|
float SR = (VR * 1.22f - VL * 1.73f) * RearScale * Rearness;
|
|
// Possible experiment: Play with stereo expension levels on rear
|
|
|
|
// Adjust the volume of the front speakers based on what we calculated above
|
|
L *= Frontness;
|
|
R *= Frontness;
|
|
|
|
s32 CX = (s32)(C * AddCLR);
|
|
|
|
s->Left = (s32)(L * GainL) + CX;
|
|
s->Right = (s32)(R * GainR) + CX;
|
|
s->Center = (s32)(C * GainC);
|
|
s->LFE = (s32)(SUB * GainLFE);
|
|
s->LeftBack = (s32)(SL * GainSL);
|
|
s->RightBack = (s32)(SR * GainSR);
|
|
}
|
|
|
|
void ProcessDplIISample16(const StereoOut32& src, Stereo51Out16DplII* s)
|
|
{
|
|
Stereo51Out32DplII ss;
|
|
ProcessDplIISample32(src, &ss);
|
|
|
|
s->Left = ss.Left >> 16;
|
|
s->Right = ss.Right >> 16;
|
|
s->Center = ss.Center >> 16;
|
|
s->LFE = ss.LFE >> 16;
|
|
s->LeftBack = ss.LeftBack >> 16;
|
|
s->RightBack = ss.RightBack >> 16;
|
|
}
|
|
|
|
void ProcessDplSample32(const StereoOut32& src, Stereo51Out32Dpl* s)
|
|
{
|
|
float ValL = src.Left / (float)(1 << (SndOutVolumeShift + 16));
|
|
float ValR = src.Right / (float)(1 << (SndOutVolumeShift + 16));
|
|
|
|
float C = (ValL + ValR) * 0.5f; //+15.8
|
|
float S = (ValL - ValR) * 0.5f;
|
|
|
|
float L = ValL - C; //+15.8
|
|
float R = ValR - C;
|
|
|
|
float SUB = C;
|
|
|
|
s32 CX = (s32)(C * AddCLR); // +15.16
|
|
|
|
s->Left = (s32)(L * GainL) + CX; // +15.16 = +31, can grow to +32 if (GainL + AddCLR)>255
|
|
s->Right = (s32)(R * GainR) + CX;
|
|
s->Center = (s32)(C * GainC); // +15.16 = +31
|
|
s->LFE = (s32)(SUB * GainLFE);
|
|
s->LeftBack = (s32)(S * GainSL);
|
|
s->RightBack = (s32)(S * GainSR);
|
|
}
|
|
|
|
void ProcessDplSample16(const StereoOut32& src, Stereo51Out16Dpl* s)
|
|
{
|
|
Stereo51Out32Dpl ss;
|
|
ProcessDplSample32(src, &ss);
|
|
|
|
s->Left = ss.Left >> 16;
|
|
s->Right = ss.Right >> 16;
|
|
s->Center = ss.Center >> 16;
|
|
s->LFE = ss.LFE >> 16;
|
|
s->LeftBack = ss.LeftBack >> 16;
|
|
s->RightBack = ss.RightBack >> 16;
|
|
}
|