From f06998808a90ec14d5daff42c8e2669f3fc8dd3a Mon Sep 17 00:00:00 2001 From: ramapcsx2 Date: Fri, 4 Sep 2009 22:15:02 +0000 Subject: [PATCH] SPU2-X: 5.1 support is back! Currently for XAudio2 only, and it's not doing much (Simple copy of the stereo source to the other speakers). Gigaherz is already working on a nice, semi - prologic II upmixer though ;) git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1738 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/spu2-x/src/Linux/Config.cpp | 2 +- plugins/spu2-x/src/Linux/Config.h | 2 +- plugins/spu2-x/src/SndOut.h | 119 ++++++++++++++++++ plugins/spu2-x/src/Windows/Config.cpp | 10 +- plugins/spu2-x/src/Windows/Config.h | 2 +- plugins/spu2-x/src/Windows/SndOut_XAudio2.cpp | 55 ++++---- plugins/spu2-x/src/Windows/SndOut_waveOut.cpp | 4 +- plugins/spu2-x/src/Windows/Spu2-X.rc | 7 +- plugins/spu2-x/src/Windows/resource.h | 2 +- 9 files changed, 167 insertions(+), 36 deletions(-) diff --git a/plugins/spu2-x/src/Linux/Config.cpp b/plugins/spu2-x/src/Linux/Config.cpp index 8853b4346f..c896779f41 100644 --- a/plugins/spu2-x/src/Linux/Config.cpp +++ b/plugins/spu2-x/src/Linux/Config.cpp @@ -83,7 +83,7 @@ bool dspPluginEnabled = false; int dspPluginModule = 0; wchar_t dspPlugin[256]; -bool StereoExpansionDisabled = true; +bool StereoExpansionEnabled = false; /*****************************************************************************/ diff --git a/plugins/spu2-x/src/Linux/Config.h b/plugins/spu2-x/src/Linux/Config.h index c7c6afe6a0..2701950a5e 100644 --- a/plugins/spu2-x/src/Linux/Config.h +++ b/plugins/spu2-x/src/Linux/Config.h @@ -78,7 +78,7 @@ extern int dspPluginModule; extern bool dspPluginEnabled; extern bool timeStretchDisabled; -extern bool StereoExpansionDisabled; +extern bool StereoExpansionEnabled; class SoundtouchCfg { diff --git a/plugins/spu2-x/src/SndOut.h b/plugins/spu2-x/src/SndOut.h index ac9a03d2cb..e4d4d1a89c 100644 --- a/plugins/spu2-x/src/SndOut.h +++ b/plugins/spu2-x/src/SndOut.h @@ -172,6 +172,125 @@ struct Stereo51Out16 } }; +struct Stereo51Out16DplII +{ + s16 Left; + s16 Right; + s16 Center; + s16 LFE; + s16 LeftBack; + s16 RightBack; + + void ResampleFrom( const StereoOut32& src ) + { + 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 s32 Gfl=0,Gfr=0; + static s32 LMax=0,RMax=0; + + static s32 LAccum; + static s32 RAccum; + static s32 ANum; + + s32 ValL = src.Left >> (SndOutVolumeShift-8); + s32 ValR = src.Right >> (SndOutVolumeShift-8); + + s32 XL = abs(ValL>>8); + s32 XR = abs(ValR>>8); + + if(XL>LMax) LMax = XL; + if(XR>RMax) RMax = XR; + + ANum++; + if(ANum>=128) + { + ANum=0; + LAccum = 1+((LAccum * 224 + LMax * 31)>>8); + RAccum = 1+((RAccum * 224 + RMax * 31)>>8); + + LMax = 0; + RMax = 0; + + s32 Tfl=(RAccum)*255/(LAccum); + s32 Tfr=(LAccum)*255/(RAccum); + + int gMax = max(Tfl,Tfr); + Tfl=Tfl*255/gMax; + Tfr=Tfr*255/gMax; + + if(Tfl>255) Tfl=255; + if(Tfr>255) Tfr=255; + if(Tfl<1) Tfl=1; + if(Tfr<1) Tfr=1; + + Gfl = (Gfl * 200 + Tfl * 56)>>8; + Gfr = (Gfr * 200 + Tfr * 56)>>8; + + } + + s32 L,R,C,SUB,SL,SR; + + C=(ValL+ValR)>>1; //16.8 + + ValL-=C;//16.8 + ValR-=C;//16.8 + + L=ValL>>8; //16.0 + R=ValR>>8; //16.0 + C=C>>8; //16.0 + SUB = C; + + { + s32 Cfl = 1+sLogTable[Gfl]; + s32 Cfr = 1+sLogTable[Gfr]; + + s32 VL=(ValL>>4) * Cfl; //16.12 + s32 VR=(ValR>>4) * Cfr; + + s32 SC = (VL-VR)>>15; + + SL = (((VR/148 - VL/209)>>4)*Cfr)>>8; + SR = (((VR/209 - VL/148)>>4)*Cfl)>>8; + + } + + // Random-ish values to get it to compile + int GainL = 200; + int GainR = 200; + int GainC = 180; + int GainSL = 230; + int GainSR = 230; + int GainLFE = 200; + int AddCLR = 55; + + int AddCX = (C * AddCLR)>>8; + + Left = (((L * GainL ))>>8) + AddCX; + Right = (((R * GainL ))>>8) + AddCX; + Center = (((C * GainC ))>>8); + LFE = (((SUB * GainLFE))>>8); + LeftBack = (((SL * GainSL ))>>8); + RightBack = (((SR * GainSR ))>>8); + } +}; + struct Stereo71Out16 { s16 Left; diff --git a/plugins/spu2-x/src/Windows/Config.cpp b/plugins/spu2-x/src/Windows/Config.cpp index 5c3e6d6f9a..b1dc43f96c 100644 --- a/plugins/spu2-x/src/Windows/Config.cpp +++ b/plugins/spu2-x/src/Windows/Config.cpp @@ -51,7 +51,7 @@ bool dspPluginEnabled = false; int dspPluginModule = 0; wchar_t dspPlugin[256]; -bool StereoExpansionDisabled = true; +bool StereoExpansionEnabled = false; /*****************************************************************************/ @@ -65,7 +65,7 @@ void ReadSettings() timeStretchDisabled = CfgReadBool( L"OUTPUT", L"Disable_Timestretch", false ); EffectsDisabled = CfgReadBool( L"MIXING", L"Disable_Effects", false ); - StereoExpansionDisabled = CfgReadBool( L"OUTPUT", L"Disable_StereoExpansion", false ); + StereoExpansionEnabled = CfgReadBool( L"OUTPUT", L"Enable_StereoExpansion", false ); SndOutLatencyMS = CfgReadInt(L"OUTPUT",L"Latency", 160); wchar_t omodid[128]; @@ -115,7 +115,7 @@ void WriteSettings() CfgWriteStr(L"OUTPUT",L"Output_Module", mods[OutputModule]->GetIdent() ); CfgWriteInt(L"OUTPUT",L"Latency", SndOutLatencyMS); CfgWriteBool(L"OUTPUT",L"Disable_Timestretch", timeStretchDisabled); - CfgWriteBool(L"OUTPUT",L"Disable_StereoExpansion", StereoExpansionDisabled); + CfgWriteBool(L"OUTPUT",L"Enable_StereoExpansion", StereoExpansionEnabled); if( Config_WaveOut.Device.empty() ) Config_WaveOut.Device = L"default"; CfgWriteStr(L"WAVEOUT",L"Device",Config_WaveOut.Device); @@ -172,7 +172,7 @@ BOOL CALLBACK ConfigProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) EnableWindow( GetDlgItem( hWnd, IDC_OPEN_CONFIG_DEBUG ), DebugEnabled ); SET_CHECK(IDC_EFFECTS_DISABLE, EffectsDisabled); - SET_CHECK(IDC_EXPANSION_DISABLE,StereoExpansionDisabled); + SET_CHECK(IDC_EXPANSION_ENABLE,StereoExpansionEnabled); SET_CHECK(IDC_TS_DISABLE, timeStretchDisabled); SET_CHECK(IDC_DEBUG_ENABLE, DebugEnabled); SET_CHECK(IDC_DSP_ENABLE, dspPluginEnabled); @@ -226,7 +226,7 @@ BOOL CALLBACK ConfigProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) HANDLE_CHECK(IDC_EFFECTS_DISABLE,EffectsDisabled); HANDLE_CHECK(IDC_DSP_ENABLE,dspPluginEnabled); - HANDLE_CHECK(IDC_EXPANSION_DISABLE,StereoExpansionDisabled); + HANDLE_CHECK(IDC_EXPANSION_ENABLE,StereoExpansionEnabled); HANDLE_CHECKNB(IDC_TS_DISABLE,timeStretchDisabled); EnableWindow( GetDlgItem( hWnd, IDC_OPEN_CONFIG_SOUNDTOUCH ), !timeStretchDisabled ); break; diff --git a/plugins/spu2-x/src/Windows/Config.h b/plugins/spu2-x/src/Windows/Config.h index 24ae24c2ba..031b287f0c 100644 --- a/plugins/spu2-x/src/Windows/Config.h +++ b/plugins/spu2-x/src/Windows/Config.h @@ -77,7 +77,7 @@ extern int dspPluginModule; extern bool dspPluginEnabled; extern bool timeStretchDisabled; -extern bool StereoExpansionDisabled; +extern bool StereoExpansionEnabled; class SoundtouchCfg { diff --git a/plugins/spu2-x/src/Windows/SndOut_XAudio2.cpp b/plugins/spu2-x/src/Windows/SndOut_XAudio2.cpp index ecfee395c4..fe286264e6 100644 --- a/plugins/spu2-x/src/Windows/SndOut_XAudio2.cpp +++ b/plugins/spu2-x/src/Windows/SndOut_XAudio2.cpp @@ -109,24 +109,26 @@ private: // virtual calls can't be made from the constructor's context. void _init( IXAudio2* pXAudio2, uint chanConfig ) { - WAVEFORMATEX wfx; + WAVEFORMATEXTENSIBLE wfx; - wfx.wFormatTag = WAVE_FORMAT_PCM; - wfx.nSamplesPerSec = SampleRate; - wfx.nChannels = m_nChannels; - wfx.wBitsPerSample = 16; - wfx.nBlockAlign = 2*m_nChannels; - wfx.nAvgBytesPerSec = SampleRate * wfx.nBlockAlign; - wfx.cbSize = 0; - - //wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; - //wfx.dwChannelMask = chanConfig; + memset(&wfx, 0, sizeof(WAVEFORMATEXTENSIBLE)); + wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + wfx.Format.nSamplesPerSec = SampleRate; + wfx.Format.nChannels = m_nChannels; + wfx.Format.wBitsPerSample = 16; + wfx.Format.nBlockAlign = wfx.Format.nChannels*wfx.Format.wBitsPerSample/8; + wfx.Format.nAvgBytesPerSec = SampleRate * wfx.Format.nBlockAlign; + wfx.Format.cbSize=22; + wfx.Samples.wValidBitsPerSample=0; + //wfx.dwChannelMask=SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT; + wfx.dwChannelMask=chanConfig; + wfx.SubFormat=KSDATAFORMAT_SUBTYPE_PCM; // // Create an XAudio2 voice to stream this wave // HRESULT hr; - if( FAILED(hr = pXAudio2->CreateSourceVoice( &pSourceVoice, &wfx, + if( FAILED(hr = pXAudio2->CreateSourceVoice( &pSourceVoice, (WAVEFORMATEX*)&wfx, XAUDIO2_VOICE_NOSRC, 1.0f, this ) ) ) { throw Exception::XAudio2Error( hr, "XAudio2 CreateSourceVoice failure." ); @@ -187,7 +189,17 @@ private: void Init( IXAudio2* pXAudio2 ) { - _init( pXAudio2, SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT ); + int chanMask = 0; + switch(m_nChannels) + { + case 1: chanMask |= SPEAKER_FRONT_CENTER; break; + case 2: chanMask |= SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; break; + case 3: chanMask |= SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY; break; + case 4: chanMask |= SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; break; + case 5: chanMask |= SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; break; + case 6: chanMask |= SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_LOW_FREQUENCY; break; + } + _init( pXAudio2, chanMask ); } protected: @@ -247,22 +259,22 @@ public: XAUDIO2_DEVICE_DETAILS deviceDetails; pXAudio2->GetDeviceDetails( 0, &deviceDetails ); + if( StereoExpansionEnabled ) + deviceDetails.OutputFormat.Format.nChannels = 6; + + // Any windows driver should support stereo at the software level, I should think! + jASSUME( deviceDetails.OutputFormat.Format.nChannels > 1 ); + // // Create a mastering voice // - if ( FAILED(hr = pXAudio2->CreateMasteringVoice( &pMasteringVoice, 0, SampleRate ) ) ) + if ( FAILED(hr = pXAudio2->CreateMasteringVoice( &pMasteringVoice, deviceDetails.OutputFormat.Format.nChannels, SampleRate ) ) ) { SysMessage( "Failed creating mastering voice: %#X\n", hr ); CoUninitialize(); return -1; } - if( StereoExpansionDisabled ) - deviceDetails.OutputFormat.Format.nChannels = 2; - - // Any windows driver should support stereo at the software level, I should think! - jASSUME( deviceDetails.OutputFormat.Format.nChannels > 1 ); - switch( deviceDetails.OutputFormat.Format.nChannels ) { case 2: @@ -288,7 +300,8 @@ public: case 6: case 7: ConLog( "* SPU2 > 5.1 speaker expansion enabled.\n" ); - voiceContext = new StreamingVoice( pXAudio2 ); + voiceContext = new StreamingVoice( pXAudio2 ); //"normal" stereo upmix + //voiceContext = new StreamingVoice( pXAudio2 ); //gigas PLII break; default: // anything 8 or more gets the 7.1 treatment! diff --git a/plugins/spu2-x/src/Windows/SndOut_waveOut.cpp b/plugins/spu2-x/src/Windows/SndOut_waveOut.cpp index 6ef8272f68..eb0f07ca1c 100644 --- a/plugins/spu2-x/src/Windows/SndOut_waveOut.cpp +++ b/plugins/spu2-x/src/Windows/SndOut_waveOut.cpp @@ -95,8 +95,8 @@ public: #if 0 int speakerConfig; - if( StereoExpansionDisabled ) - speakerConfig = 2; + if( StereoExpansionEnabled ) + speakerConfig = 2; // better not mess with this in wavout :p (rama) // Any windows driver should support stereo at the software level, I should think! jASSUME( speakerConfig > 1 ); diff --git a/plugins/spu2-x/src/Windows/Spu2-X.rc b/plugins/spu2-x/src/Windows/Spu2-X.rc index 1fca43b0df..ebd58aa1e2 100644 --- a/plugins/spu2-x/src/Windows/Spu2-X.rc +++ b/plugins/spu2-x/src/Windows/Spu2-X.rc @@ -7,8 +7,7 @@ // // Generated from the TEXTINCLUDE 2 resource. // -#include "afxresmw.h" - +#include "afxresmw.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS @@ -72,8 +71,8 @@ BEGIN PUSHBUTTON "Configure Debug Options...",IDC_OPEN_CONFIG_DEBUG,14,131,108,14 CHECKBOX "Enable Debug Options",IDC_DEBUG_ENABLE,14,117,104,10,NOT WS_TABSTOP GROUPBOX "",IDC_STATIC,6,107,129,46 - CONTROL "Disable Audio Expansion",IDC_EXPANSION_DISABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,152,135,10 - LTEXT "Audio expansion detects extended speaker setups like 5.1 and 2.1 audio, and expand the SPU2's stereo stream so that all speakers are used. Disable this if the detection causes problems on your sound system.",IDC_STATIC,162,164,146,44 + CONTROL "Enable Audio Expansion",IDC_EXPANSION_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,152,135,10 + LTEXT "Audio expansion to 5.1. Currently for XAudio2 only. WIP.",IDC_STATIC,162,164,146,44 END IDD_DEBUG DIALOGEX 0, 0, 326, 525 diff --git a/plugins/spu2-x/src/Windows/resource.h b/plugins/spu2-x/src/Windows/resource.h index a508cf2e3e..738e19d68f 100644 --- a/plugins/spu2-x/src/Windows/resource.h +++ b/plugins/spu2-x/src/Windows/resource.h @@ -43,7 +43,7 @@ #define IDC_OVERLAP_SLIDER 1045 #define IDC_MSG_PUBLIC_BUILD 1048 #define IDC_XA2_TRIBLE_BUFFER 1050 -#define IDC_EXPANSION_DISABLE 1051 +#define IDC_EXPANSION_ENABLE 1051 #define IDC_LABEL_VERSION_INFO 1054 #define IDC_LINK_WEBSITE 1055 #define IDC_LINK_GOOGLECODE 1056