From c9d55d262bdb3e96768023c31ec2be9b17405d22 Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Tue, 13 May 2008 17:44:00 +0000 Subject: [PATCH] added simple way for plugins to process at lower sample-rates git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@967 0778d3d1-df1d-0410-868b-ea421aaaa00d --- include/effect.h | 31 ++++++++++++++++++++++++++++ src/core/effect.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/include/effect.h b/include/effect.h index cd5a95da7..ef6252fca 100644 --- a/include/effect.h +++ b/include/effect.h @@ -173,8 +173,36 @@ public: protected: virtual pluginView * instantiateView( QWidget * ); + // some effects might not be capable of higher sample-rates so they can + // sample it down before processing and back after processing + inline void sampleDown( const sampleFrame * _src_buf, + sampleFrame * _dst_buf, + sample_rate_t _dst_sr ) + { + resample( 0, _src_buf, + engine::getMixer()->processingSampleRate(), + _dst_buf, _dst_sr, + engine::getMixer()->framesPerPeriod() ); + } + + inline void sampleBack( const sampleFrame * _src_buf, + sampleFrame * _dst_buf, + sample_rate_t _src_sr ) + { + resample( 1, _src_buf, _src_sr, _dst_buf, + engine::getMixer()->processingSampleRate(), + engine::getMixer()->framesPerPeriod() * _src_sr / + engine::getMixer()->processingSampleRate() ); + } + void reinitSRC( void ); + private: + void resample( int _i, const sampleFrame * _src_buf, + sample_rate_t _src_sr, + sampleFrame * _dst_buf, sample_rate_t _dst_sr, + const fpp_t _frames ); + descriptor::subPluginFeatures::key m_key; ch_cnt_t m_processors; @@ -189,6 +217,9 @@ private: floatModel m_gateModel; tempoSyncKnobModel m_autoQuitModel; + SRC_DATA m_srcData[2]; + SRC_STATE * m_srcState[2]; + friend class effectView; friend class effectChain; diff --git a/src/core/effect.cpp b/src/core/effect.cpp index 3692611fd..f75f6202a 100644 --- a/src/core/effect.cpp +++ b/src/core/effect.cpp @@ -47,6 +47,8 @@ effect::effect( const plugin::descriptor * _desc, m_gateModel( 0.0f, 0.0f, 1.0f, 0.01f, this ), m_autoQuitModel( 1.0f, 1.0f, 8000.0f, 100.0f, 1.0f, this ) { + m_srcState[0] = m_srcState[1] = NULL; + reinitSRC(); } @@ -121,5 +123,53 @@ pluginView * effect::instantiateView( QWidget * _parent ) return( new effectView( this, _parent ) ); } + + + +void effect::reinitSRC( void ) +{ + for( int i = 0; i < 2; ++i ) + { + if( m_srcState[i] != NULL ) + { + src_delete( m_srcState[i] ); + } + int error; + if( ( m_srcState[i] = src_new( + engine::getMixer()->currentQualitySettings(). + libsrcInterpolation(), + DEFAULT_CHANNELS, &error ) ) == NULL ) + { + printf( "Error: src_new() failed in effect.cpp!\n" ); + } + } +} + + + + +void effect::resample( int _i, const sampleFrame * _src_buf, + sample_rate_t _src_sr, + sampleFrame * _dst_buf, sample_rate_t _dst_sr, + fpp_t _frames ) +{ + if( m_srcState[_i] == NULL ) + { + return; + } + m_srcData[_i].input_frames = _frames; + m_srcData[_i].output_frames = engine::getMixer()->framesPerPeriod(); + m_srcData[_i].data_in = (float *) _src_buf[0]; + m_srcData[_i].data_out = _dst_buf[0]; + m_srcData[_i].src_ratio = (double) _dst_sr / _src_sr; + m_srcData[_i].end_of_input = 0; + int error; + if( ( error = src_process( m_srcState[_i], &m_srcData[_i] ) ) ) + { + printf( "effect::resample(): error while resampling: %s\n", + src_strerror( error ) ); + } +} + #endif