diff --git a/plugins/spu2-x/src/Global.h b/plugins/spu2-x/src/Global.h index 48c6aedb8f..18a493544a 100644 --- a/plugins/spu2-x/src/Global.h +++ b/plugins/spu2-x/src/Global.h @@ -1,114 +1,114 @@ -/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2 - * Developed and maintained by the Pcsx2 Development Team. - * - * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] - * - * SPU2-X 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. - * - * SPU2-X 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with SPU2-X. If not, see . - */ - -#ifndef _SPU2X_GLOBAL_H_ -#define _SPU2X_GLOBAL_H_ - -#define NOMINMAX - -struct StereoOut16; -struct StereoOut32; -struct StereoOutFloat; - -struct V_Core; - -namespace soundtouch -{ - class SoundTouch; -} - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using std::string; -using std::wstring; +/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2 + * Developed and maintained by the Pcsx2 Development Team. + * + * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] + * + * SPU2-X 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. + * + * SPU2-X 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SPU2-X. If not, see . + */ + +#ifndef _SPU2X_GLOBAL_H_ +#define _SPU2X_GLOBAL_H_ + +#define NOMINMAX + +struct StereoOut16; +struct StereoOut32; +struct StereoOutFloat; + +struct V_Core; + +namespace soundtouch +{ + class SoundTouch; +} + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using std::string; +using std::wstring; + +#include "Pcsx2Defs.h" +#include "Pcsx2Types.h" + +namespace VersionInfo +{ + static const u8 Release = 1; + static const u8 Revision = 4; // increase that with each version +} + +////////////////////////////////////////////////////////////////////////// +// Override Win32 min/max macros with the STL's type safe and macro +// free varieties (much safer!) + +#undef min +#undef max + +template< typename T > +static __forceinline void Clampify( T& src, T min, T max ) +{ + src = std::min( std::max( src, min ), max ); +} + +template< typename T > +static __forceinline T GetClamped( T src, T min, T max ) +{ + return std::min( std::max( src, min ), max ); +} + +extern void SysMessage(const char *fmt, ...); +extern void SysMessage(const wchar_t *fmt, ...); + +////////////////////////////////////////////////////////////// +// Dev / Debug conditionals -- +// Consts for using if() statements instead of uglier #ifdef macros. +// Abbreviated macros for dev/debug only consoles and msgboxes. + +#ifdef PCSX2_DEVBUILD +# define DevCon Console +# define DevMsg MsgBox +#else +# define DevCon 0&&Console +# define DevMsg +#endif + +#ifdef PCSX2_DEBUG +# define DbgCon Console +#else +# define DbgCon 0&&Console +#endif + +#ifdef PCSX2_DEVBUILD +# define SPU2_LOG +#endif + +#include "Utilities/Exceptions.h" +#include "Utilities/SafeArray.h" + +#include "ConvertUTF.h" + +#include "defs.h" +#include "regs.h" + +#include "Config.h" +#include "Debug.h" +#include "SndOut.h" -#include "Pcsx2Defs.h" -#include "Pcsx2Types.h" - -namespace VersionInfo -{ - static const u8 Release = 1; - static const u8 Revision = 4; // increase that with each version -} - -////////////////////////////////////////////////////////////////////////// -// Override Win32 min/max macros with the STL's type safe and macro -// free varieties (much safer!) - -#undef min -#undef max - -template< typename T > -static __forceinline void Clampify( T& src, T min, T max ) -{ - src = std::min( std::max( src, min ), max ); -} - -template< typename T > -static __forceinline T GetClamped( T src, T min, T max ) -{ - return std::min( std::max( src, min ), max ); -} - -extern void SysMessage(const char *fmt, ...); -extern void SysMessage(const wchar_t *fmt, ...); - -////////////////////////////////////////////////////////////// -// Dev / Debug conditionals -- -// Consts for using if() statements instead of uglier #ifdef macros. -// Abbreviated macros for dev/debug only consoles and msgboxes. - -#ifdef PCSX2_DEVBUILD -# define DevCon Console -# define DevMsg MsgBox -#else -# define DevCon 0&&Console -# define DevMsg -#endif - -#ifdef PCSX2_DEBUG -# define DbgCon Console -#else -# define DbgCon 0&&Console -#endif - -#ifdef PCSX2_DEVBUILD -# define SPU2_LOG -#endif - -#include "Utilities/Exceptions.h" -#include "Utilities/SafeArray.h" - -#include "ConvertUTF.h" - -#include "defs.h" -#include "regs.h" - -#include "Config.h" -#include "Debug.h" -#include "SndOut.h" - #endif diff --git a/plugins/spu2-x/src/Mixer.cpp b/plugins/spu2-x/src/Mixer.cpp index 30cf005779..b8b039dd32 100644 --- a/plugins/spu2-x/src/Mixer.cpp +++ b/plugins/spu2-x/src/Mixer.cpp @@ -31,6 +31,22 @@ static const s32 tbl_XA_Factor[5][2] = { 122, -60 } }; +static double K0[4] = +{ + 0.0, + 0.9375, + 1.796875, + 1.53125 +}; + +static double K1[4] = +{ + 0.0, + 0.0, + -0.8125, + -0.859375 +}; + // Performs a 64-bit multiplication between two values and returns the // high 32 bits as a result (discarding the fractional 32 bits). @@ -77,59 +93,42 @@ StereoOut32 clamp_mix( const StereoOut32& sample, u8 bitshift ) static void __forceinline XA_decode_block(s16* buffer, const s16* block, s32& prev1, s32& prev2) { const s32 header = *block; - const s32 shift = ((header>> 0)&0xF)+16; + const s32 shift = (header&0xF)+16; const s32 pred1 = tbl_XA_Factor[(header>> 4)&0xF][0]; const s32 pred2 = tbl_XA_Factor[(header>> 4)&0xF][1]; - const s8* blockbytes = (s8*)&block[1]; + const s8* blockbytes = (s8*)&block[1]; + const s8* blockend = &blockbytes[13]; - for(int i=0; i<14; i++, blockbytes++) + for(; blockbytes<=blockend; ++blockbytes) { - s32 pcm, pcm2; - { - s32 data = ((*blockbytes)<<28) & 0xF0000000; - pcm = data>>shift; - pcm+=((pred1*prev1)+(pred2*prev2))>>6; + s32 data = ((*blockbytes)<<28) & 0xF0000000; + s32 pcm = (data >> shift) + (((pred1*prev1)+(pred2*prev2)) >> 6); - if(pcm> 32767) ConLog("pcm too high, is %d\n",pcm); - else if(pcm<-32768) ConLog("pcm too low, is %d\n",pcm); + Clampify( pcm, -0x8000, 0x7fff ); + *(buffer++) = pcm; - if(pcm> 32767) pcm= 32767; - else if(pcm<-32768) pcm=-32768; - *(buffer++) = pcm; - } + data = ((*blockbytes)<<24) & 0xF0000000; + s32 pcm2 = (data >> shift) + (((pred1*pcm)+(pred2*prev1)) >> 6); - //prev2=prev1; - //prev1=pcm; + Clampify( pcm2, -0x8000, 0x7fff ); + *(buffer++) = pcm2; - { - s32 data = ((*blockbytes)<<24) & 0xF0000000; - pcm2 = data>>shift; - pcm2+=((pred1*pcm)+(pred2*prev1))>>6; - - if(pcm2> 32767) ConLog("pcm2 too high, is %d\n",pcm2); - else if(pcm2<-32768) ConLog("pcm2 too low, is %d\n",pcm2); - - if(pcm2> 32767) pcm2= 32767; - else if(pcm2<-32768) pcm2=-32768; - *(buffer++) = pcm2; - } - - prev2=pcm; - prev1=pcm2; + prev2 = pcm; + prev1 = pcm2; } } static void __forceinline XA_decode_block_unsaturated(s16* buffer, const s16* block, s32& prev1, s32& prev2) { const u8 header = *(u8*)block; - s32 shift = (header&0xF) + 16; - s32 pred1 = tbl_XA_Factor[header>>4][0]; - s32 pred2 = tbl_XA_Factor[header>>4][1]; + const s32 shift = (header&0xF) + 16; + const s32 pred1 = tbl_XA_Factor[header>>4][0]; + const s32 pred2 = tbl_XA_Factor[header>>4][1]; const s8* blockbytes = (s8*)&block[1]; - for(int i=0; i<14; i++, blockbytes++) + for(uint i=0; i<14; i++, blockbytes++) { s32 pcm, pcm2; { @@ -151,6 +150,7 @@ static void __forceinline XA_decode_block_unsaturated(s16* buffer, const s16* bl } } + static void __forceinline IncrementNextA( const V_Core& thiscore, V_Voice& vc ) { // Important! Both cores signal IRQ when an address is read, regardless of @@ -451,28 +451,36 @@ static s32 __forceinline GetVoiceValues_Cubic( V_Core& thiscore, uint voiceidx ) vc.PV2 = vc.PV1; vc.PV1 = GetNextDataBuffered( thiscore, voiceidx ); - vc.PV1 <<= 2; - vc.SPc = vc.SP&4095; // just the fractional part, please! + //vc.PV1 <<= 2; + //vc.SPc = vc.SP&4095; // just the fractional part, please! vc.SP -= 4096; } CalculateADSR( thiscore, voiceidx ); - s32 z0 = vc.PV3 - vc.PV4 + vc.PV1 - vc.PV2; - s32 z1 = (vc.PV4 - vc.PV3 - z0); - s32 z2 = (vc.PV2 - vc.PV4); + /*mu2 = mu*mu; + a0 = y3 - y2 - y0 + y1; //p + a1 = y0 - y1 - a0; + a2 = y2 - y0; + a3 = y1; - s32 mu = vc.SPc; + return ( a0*mu*mu2 + a1*mu2 + a2*mu + a3 );*/ + + const s32 z0 = vc.PV4 - vc.PV3 - vc.PV1 + vc.PV2; + const s32 z1 = vc.PV1 - vc.PV2 - z0; + const s32 z2 = vc.PV3 - vc.PV1; + + const s32 mu = vc.SP; s32 val = (z0 * mu) >> 12; val = ((val + z1) * mu) >> 12; val = ((val + z2) * mu) >> 12; - val += vc.PV3; + val += vc.PV2; // Note! It's very important that ADSR stay as accurate as possible. By the way // it is used, various sound effects can end prematurely if we truncate more than // one or two bits. (or maybe it's better with no truncation at all?) - return MulShr32( val>>1, vc.ADSR.Value ); + return MulShr32( val, vc.ADSR.Value ); } // Noise values need to be mixed without going through interpolation, since it