diff --git a/src/RageSoundReader_PitchChange.cpp b/src/RageSoundReader_PitchChange.cpp index 11d77fc286..4d63d01aed 100644 --- a/src/RageSoundReader_PitchChange.cpp +++ b/src/RageSoundReader_PitchChange.cpp @@ -9,16 +9,28 @@ */ #include "global.h" +#include "Preference.h" #include "RageSoundReader_PitchChange.h" #include "RageSoundReader_SpeedChange.h" #include "RageSoundReader_Resample_Good.h" #include "RageLog.h" +static Preference g_bRateModPreservesPitch( "RateModPreservesPitch", true ); + RageSoundReader_PitchChange::RageSoundReader_PitchChange( RageSoundReader *pSource ): RageSoundReader_Filter(nullptr) { + bool bPreservePitch = g_bRateModPreservesPitch.Get(); + m_pSpeedChange = new RageSoundReader_SpeedChange( pSource ); - m_pResample = new RageSoundReader_Resample_Good( m_pSpeedChange, m_pSpeedChange->GetSampleRate() ); + if (bPreservePitch) + { + m_pResample = new RageSoundReader_Resample_Good( m_pSpeedChange, m_pSpeedChange->GetSampleRate() ); + } + else + { + m_pResample = new RageSoundReader_Resample_Good( pSource, pSource->GetSampleRate() ); + } m_pSource = m_pResample; m_fSpeedRatio = 1.0f; m_fPitchRatio = 1.0f; @@ -46,8 +58,10 @@ int RageSoundReader_PitchChange::Read( float *pBuf, int iFrames ) * immediately on the next Read(). When this is true, apply the ratio to the * resampler and the speed changer simultaneously, so they take effect as * closely together as possible. */ - if( (m_fLastSetSpeedRatio != m_fSpeedRatio || m_fLastSetPitchRatio != m_fPitchRatio) && - m_pSpeedChange->NextReadWillStep() ) + bool bPreservePitch = g_bRateModPreservesPitch.Get(); + if( (!bPreservePitch) || + ((m_fLastSetSpeedRatio != m_fSpeedRatio || m_fLastSetPitchRatio != m_fPitchRatio) && + m_pSpeedChange->NextReadWillStep()) ) { float fRate = GetStreamToSourceRatio(); @@ -58,13 +72,22 @@ int RageSoundReader_PitchChange::Read( float *pBuf, int iFrames ) /* However, the resampler has a limited granularity due to internal fixed- * point math, and the actual ratio will be slightly different than what * we tell it to use. The actual ratio used is fActualPitchRatio. */ - m_pResample->SetRate( m_fPitchRatio ); - float fActualPitchRatio = m_pResample->GetRate(); - float fRequestedSpeedRatio = m_fSpeedRatio / fActualPitchRatio; - m_pSpeedChange->SetSpeedRatio( fRequestedSpeedRatio ); - m_fLastSetSpeedRatio = m_fSpeedRatio; - m_fLastSetPitchRatio = m_fPitchRatio; + if (bPreservePitch) + { + m_pResample->SetRate( m_fPitchRatio ); + float fActualPitchRatio = m_pResample->GetRate(); + float fRequestedSpeedRatio = m_fSpeedRatio / fActualPitchRatio; + m_pSpeedChange->SetSpeedRatio( fRequestedSpeedRatio ); + m_fLastSetPitchRatio = m_fPitchRatio; + m_fLastSetSpeedRatio = m_fSpeedRatio; + } + else + { + m_pResample->SetRate(m_fSpeedRatio); + m_fLastSetSpeedRatio = m_fSpeedRatio; + } + /* If we just applied a new speed and it caused the ratio to change, return * no data, so the caller can see the new ratio. */