diff --git a/stepmania/src/RageSoundReader_PitchChange.cpp b/stepmania/src/RageSoundReader_PitchChange.cpp new file mode 100644 index 0000000000..d5c40f6bf4 --- /dev/null +++ b/stepmania/src/RageSoundReader_PitchChange.cpp @@ -0,0 +1,96 @@ +/* + * Pitch changing is implemented by combining speed changing and rate changing + * (via resampling). The resampler needs to be changed later than the speed + * changer; this class just controls parameters on the other two real filters. + */ + +#include "global.h" +#include "RageSoundReader_PitchChange.h" +#include "RageSoundReader_SpeedChange.h" +#include "RageSoundReader_Resample_Good.h" +#include "RageLog.h" + +RageSoundReader_PitchChange::RageSoundReader_PitchChange( RageSoundReader *pSource ): + RageSoundReader_Filter( NULL ) +{ + m_pSpeedChange = new RageSoundReader_SpeedChange( pSource ); + m_pResample = new RageSoundReader_Resample_Good( m_pSpeedChange, m_pSpeedChange->GetSampleRate() ); + m_pSource = m_pResample; + m_fSpeedRatio = 1.0f; + m_fPitchRatio = 1.0f; +} + +RageSoundReader_PitchChange::RageSoundReader_PitchChange( const RageSoundReader_PitchChange &cpy ): + RageSoundReader_Filter( cpy ) +{ + /* The source tree has already been copied. Our source is m_pResample; its source + * is m_pSpeedChange (and its source is a copy of the pSource we were initialized + * with). */ + m_pResample = dynamic_cast( &*m_pSource ); + m_pSpeedChange = dynamic_cast( m_pResample->GetSource() ); + m_fSpeedRatio = cpy.m_fSpeedRatio; + m_fPitchRatio = cpy.m_fPitchRatio; +} + +int RageSoundReader_PitchChange::Read( char *pBuf, unsigned iLen ) +{ + /* Changing the ratios will tell the speed changer to change ratios, but it + * can't change immediately; it'll change on the next slice. The resampler + * puts rate changes into effect immediately. If this read will cause the + * speed changer new ratio to put a new ratio into effect, tell the resampler + * to do the same. This way, changes to the ratios will take effect in both + * the resampler and speed changer as closely together as possible. */ + m_pSpeedChange->SetSpeedRatio( m_fSpeedRatio / m_fPitchRatio ); + if( m_pSpeedChange->NextReadWillStep() ) + m_pResample->SetRate( m_fPitchRatio ); + + return RageSoundReader_Filter::Read( pBuf, iLen ); +} + +bool RageSoundReader_PitchChange::SetProperty( const RString &sProperty, float fValue ) +{ + if( sProperty == "Rate" ) + { + /* Don't propagate this. m_pResample will take it, but it's under + * our control. */ + return false; + } + if( sProperty == "Speed" ) + { + SetSpeedRatio( fValue ); + return true; + } + + if( sProperty == "Pitch" ) + { + SetPitchRatio( fValue ); + return true; + } + + return RageSoundReader_Filter::SetProperty( sProperty, fValue ); +} + +/* + * Copyright (c) 2006 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/RageSoundReader_PitchChange.h b/stepmania/src/RageSoundReader_PitchChange.h new file mode 100644 index 0000000000..237d2ed038 --- /dev/null +++ b/stepmania/src/RageSoundReader_PitchChange.h @@ -0,0 +1,57 @@ +/* RageSoundReader_PitchChange - change the pitch and speed of an audio stream independently. */ + +#ifndef RAGE_SOUND_READER_PITCH_CHANGE_H +#define RAGE_SOUND_READER_PITCH_CHANGE_H + +#include "RageSoundReader_Filter.h" +class RageSoundReader_SpeedChange; +class RageSoundReader_Resample_Good; + +class RageSoundReader_PitchChange: public RageSoundReader_Filter +{ +public: + RageSoundReader_PitchChange( RageSoundReader *pSource ); + RageSoundReader_PitchChange( const RageSoundReader_PitchChange &cpy ); + + virtual int Read( char *pBuf, unsigned iLen ); + virtual bool SetProperty( const RString &sProperty, float fValue ); + + void SetSpeedRatio( float fRatio ) { m_fSpeedRatio = fRatio; } + void SetPitchRatio( float fRatio ) { m_fPitchRatio = fRatio; } + + virtual RageSoundReader_PitchChange *Copy() const { return new RageSoundReader_PitchChange(*this); } + +private: + RageSoundReader_SpeedChange *m_pSpeedChange; // freed by RageSoundReader_Filter + RageSoundReader_Resample_Good *m_pResample; // freed by RageSoundReader_Filter + + float m_fSpeedRatio; + float m_fPitchRatio; +}; + +#endif + +/* + * Copyright (c) 2006 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */