diff --git a/pcsx2/MMI.cpp b/pcsx2/MMI.cpp index 96379e5406..f4948bc151 100644 --- a/pcsx2/MMI.cpp +++ b/pcsx2/MMI.cpp @@ -694,10 +694,10 @@ void PPACB() { __forceinline void _PEXT5(int n) { - cpuRegs.GPR.r[_Rd_].UL[n] = \ - ((cpuRegs.GPR.r[_Rt_].UL[n] & 0x0000001F) << 3) | \ - ((cpuRegs.GPR.r[_Rt_].UL[n] & 0x000003E0) << 6) | \ - ((cpuRegs.GPR.r[_Rt_].UL[n] & 0x00007C00) << 9) | \ + cpuRegs.GPR.r[_Rd_].UL[n] = + ((cpuRegs.GPR.r[_Rt_].UL[n] & 0x0000001F) << 3) | + ((cpuRegs.GPR.r[_Rt_].UL[n] & 0x000003E0) << 6) | + ((cpuRegs.GPR.r[_Rt_].UL[n] & 0x00007C00) << 9) | ((cpuRegs.GPR.r[_Rt_].UL[n] & 0x00008000) << 16); } @@ -709,10 +709,10 @@ void PEXT5() { __forceinline void _PPAC5(int n) { - cpuRegs.GPR.r[_Rd_].UL[n] = \ - ((cpuRegs.GPR.r[_Rt_].UL[n] >> 3) & 0x0000001F) | \ - ((cpuRegs.GPR.r[_Rt_].UL[n] >> 6) & 0x000003E0) | \ - ((cpuRegs.GPR.r[_Rt_].UL[n] >> 9) & 0x00007C00) | \ + cpuRegs.GPR.r[_Rd_].UL[n] = + ((cpuRegs.GPR.r[_Rt_].UL[n] >> 3) & 0x0000001F) | + ((cpuRegs.GPR.r[_Rt_].UL[n] >> 6) & 0x000003E0) | + ((cpuRegs.GPR.r[_Rt_].UL[n] >> 9) & 0x00007C00) | ((cpuRegs.GPR.r[_Rt_].UL[n] >> 16) & 0x00008000); } diff --git a/plugins/spu2-x/src/Linux/Alsa.cpp b/plugins/spu2-x/src/Linux/Alsa.cpp index e5d5de3ab9..018250f92a 100644 --- a/plugins/spu2-x/src/Linux/Alsa.cpp +++ b/plugins/spu2-x/src/Linux/Alsa.cpp @@ -25,138 +25,212 @@ #define ALSA_MEM_DEF #include "Alsa.h" -static snd_pcm_t *handle = NULL; -static snd_pcm_uframes_t buffer_size; +class AlsaMod: public SndOutModule +{ +protected: + static const int PacketsPerBuffer = 1; // increase this if ALSA can't keep up with 512-sample packets + static const int MAX_BUFFER_COUNT = 4; + static const int NumBuffers = 4; // TODO: this should be configurable someday -- lower values reduce latency. -int AlsaSetupSound() -{ - snd_pcm_hw_params_t *hwparams; - snd_pcm_sw_params_t *swparams; - snd_pcm_status_t *status; - unsigned int pspeed = SAMPLE_RATE; - int pchannels = 2; - snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE; - unsigned int buffer_time = SOUNDSIZE; - unsigned int period_time= buffer_time / 4; - int err; + snd_pcm_t *handle = NULL; + snd_pcm_uframes_t buffer_size; + snd_async_handler_t *pcm_callback = NULL; - err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); - if(err < 0) + uint period_time; + uint buffer_time; + +protected: + // Invoked by the static ExternalCallback method below. + void _InternalCallback() + { + snd_pcm_sframes_t avail; + int err; + + avail = snd_pcm_avail_update( handle ); + while (avail >= period_time ) + { + StereoOut16 buff[PacketsPerBuffer * SndOutPacketSize]; + StereoOut16* p1 = buff; + + for( int p=0; phandle == snd_async_handler_get_pcm(pcm_callback) ); + + // Not sure if we just need an assert, or something like this: + //if( data->handle != snd_async_handler_get_pcm(pcm_callback) ) return; + + data->_InternalCallback(); } - err = snd_pcm_hw_params_set_format(handle, hwparams, format); - if (err < 0) - { - ERROR_LOG("Sample format not available: %s\n", snd_strerror(err)); - return -1; - } - - err = snd_pcm_hw_params_set_channels(handle, hwparams, pchannels); - if (err < 0) - { - ERROR_LOG("Channels count not available: %s\n", snd_strerror(err)); - return -1; - } - err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &pspeed, 0); - if (err < 0) - { - ERROR_LOG("Rate not available: %s\n", snd_strerror(err)); - return -1; - } - - err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, 0); - if(err < 0) { - ERROR_LOG("Buffer time error: %s\n", snd_strerror(err)); - return -1; - } - - err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, 0); - if (err < 0) - { - ERROR_LOG("Period time error: %s\n", snd_strerror(err)); - return -1; - } - - err = snd_pcm_hw_params(handle, hwparams); - if (err < 0) - { - ERROR_LOG("Unable to install hw params: %s\n", snd_strerror(err)); - return -1; - } - - snd_pcm_status_alloca(&status); - err = snd_pcm_status(handle, status); - if(err < 0) - { - ERROR_LOG("Unable to get status: %s\n", snd_strerror(err)); - return -1; - } - - buffer_size=snd_pcm_status_get_avail(status); +public: - return 0; -} + s32 Init() + { + snd_pcm_hw_params_t *hwparams; + snd_pcm_sw_params_t *swparams; + snd_pcm_status_t *status; + int pchannels = 2; + snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE; + + // buffer time and period time are in microseconds... + // (don't simplify the equation below -- it'll just cause integer rounding errors. + period_time = (SndOutPacketSize*1000) / (SampleRate / 1000); + buffer_time = period_time * NumBuffers; + + int err; + + err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); + if(err < 0) + { + ERROR_LOG("Audio open error: %s\n", snd_strerror(err)); + return -1; + } + + err = snd_pcm_nonblock(handle, 0); + if(err < 0) + { + ERROR_LOG("Can't set blocking mode: %s\n", snd_strerror(err)); + return -1; + } + + snd_pcm_hw_params_alloca(&hwparams); + snd_pcm_sw_params_alloca(&swparams); + + err = snd_pcm_hw_params_any(handle, hwparams); + if (err < 0) + { + ERROR_LOG("Broken configuration for this PCM: %s\n", snd_strerror(err)); + return -1; + } + + err = snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED); + if (err < 0) + { + ERROR_LOG("Access type not available: %s\n", snd_strerror(err)); + return -1; + } + + err = snd_pcm_hw_params_set_format(handle, hwparams, format); + if (err < 0) + { + ERROR_LOG("Sample format not available: %s\n", snd_strerror(err)); + return -1; + } + + err = snd_pcm_hw_params_set_channels(handle, hwparams, pchannels); + if (err < 0) + { + ERROR_LOG("Channels count not available: %s\n", snd_strerror(err)); + return -1; + } + err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &pspeed, 0); + if (err < 0) + { + ERROR_LOG("Rate not available: %s\n", snd_strerror(err)); + return -1; + } + + err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, 0); + if(err < 0) { + ERROR_LOG("Buffer time error: %s\n", snd_strerror(err)); + return -1; + } + + err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, 0); + if (err < 0) + { + ERROR_LOG("Period time error: %s\n", snd_strerror(err)); + return -1; + } + + err = snd_pcm_hw_params(handle, hwparams); + if (err < 0) + { + ERROR_LOG("Unable to install hw params: %s\n", snd_strerror(err)); + return -1; + } + + snd_pcm_status_alloca(&status); + err = snd_pcm_status(handle, status); + if(err < 0) + { + ERROR_LOG("Unable to get status: %s\n", snd_strerror(err)); + return -1; + } + + // Bind our asynchronous callback magic: + + snd_async_add_pcm_handler( &pcm_callback, handle, ExternalCallback, this ); + + snd_pcm_start( handle ); + // Diagnostic code: + //buffer_size = snd_pcm_status_get_avail(status); + + return 0; + } + + void Close() + { + if(handle == NULL) return; -void AlsaRemoveSound() -{ - if(handle != NULL) { snd_pcm_drop(handle); snd_pcm_close(handle); handle = NULL; } -} -int AlsaSoundGetBytesBuffered() -{ - int l; + virtual void Configure(HWND parent) + { + } + + virtual bool Is51Out() const { return false; } + { + } - // failed to open? - if(handle == NULL) return SOUNDSIZE; - - l = snd_pcm_avail_update(handle); - - if (l<0) - return 0; - else if (l no? wait - else - l=0; // -> else go on - - return l; -} + s32 Test() const + { + return 0; + } + + int GetEmptySampleCount() const + { + if(handle == NULL) return 0; -void AlsaSoundFeedVoiceData(unsigned char* pSound,long lBytes) -{ - if (handle == NULL) return; - - if (snd_pcm_state(handle) == SND_PCM_STATE_XRUN) - snd_pcm_prepare(handle); - snd_pcm_writei(handle,pSound, lBytes/4); -} + // Returns the amount of free buffer space, in samples. + uint l = snd_pcm_avail_update(handle); + if( l < 0 ) return 0; + return (l / 1000) * (SampleRate / 1000); + } + + const wchar_t* GetIdent() const + { + return L"Alsa"; + } + + const wchar_t* GetLongName() const + { + return L"Alsa ('tis all ya get)"; + } + + void ReadSettings() + { + } + + void WriteSettings() const + { + } +} static Alsa; + +SndOutModule *AlsaOut = &Alsa; diff --git a/plugins/spu2-x/src/Win32/SndOut_DSound.cpp b/plugins/spu2-x/src/Win32/SndOut_DSound.cpp index b18d987346..f30b6fb0a0 100644 --- a/plugins/spu2-x/src/Win32/SndOut_DSound.cpp +++ b/plugins/spu2-x/src/Win32/SndOut_DSound.cpp @@ -474,7 +474,7 @@ public: CfgWriteBool( L"DSOUNDOUT", L"Use_Hardware", m_UseHardware ); } -} DS; +} static DS; BOOL CALLBACK DSound::ConfigProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { diff --git a/plugins/spu2-x/src/Win32/SndOut_XAudio2.cpp b/plugins/spu2-x/src/Win32/SndOut_XAudio2.cpp index 8b7cefaf33..d6a2e4089b 100644 --- a/plugins/spu2-x/src/Win32/SndOut_XAudio2.cpp +++ b/plugins/spu2-x/src/Win32/SndOut_XAudio2.cpp @@ -22,7 +22,6 @@ #define _WIN32_DCOM #include "Dialogs.h" -#include #include @@ -35,11 +34,11 @@ namespace Exception { switch( hr ) { - case XAUDIO2_E_INVALID_CALL: - return "Invalid call for the XA2 object state."; + case XAUDIO2_E_INVALID_CALL: + return "Invalid call for the XA2 object state."; - case XAUDIO2_E_DEVICE_INVALIDATED: - return "Device is unavailable, unplugged, unsupported, or has been consumed by The Nothing."; + case XAUDIO2_E_DEVICE_INVALIDATED: + return "Device is unavailable, unplugged, unsupported, or has been consumed by The Nothing."; } return "Unknown error code!"; } @@ -375,6 +374,6 @@ public: { } -} XA2; +} static XA2; SndOutModule *XAudio2Out = &XA2; diff --git a/plugins/spu2-x/src/Win32/SndOut_waveOut.cpp b/plugins/spu2-x/src/Win32/SndOut_waveOut.cpp index 1394f6a275..ed93c09520 100644 --- a/plugins/spu2-x/src/Win32/SndOut_waveOut.cpp +++ b/plugins/spu2-x/src/Win32/SndOut_waveOut.cpp @@ -324,6 +324,6 @@ public: { } -} WO; +} static WO; SndOutModule *WaveOut = &WO; diff --git a/plugins/spu2-x/src/Win32/Spu2-X_vs2008.vcproj b/plugins/spu2-x/src/Win32/Spu2-X_vs2008.vcproj index e562c033a3..59cf6634dc 100644 --- a/plugins/spu2-x/src/Win32/Spu2-X_vs2008.vcproj +++ b/plugins/spu2-x/src/Win32/Spu2-X_vs2008.vcproj @@ -957,19 +957,179 @@ RelativePath="..\DllInterface.cpp" > - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +