From 49d05f466db3d2d2c2773a3bed7cc46c809ad1d1 Mon Sep 17 00:00:00 2001 From: Vesa Date: Mon, 14 Apr 2014 14:15:08 +0300 Subject: [PATCH] Watsyn: use fast sinc instead of medium quality (not much diff in this case), increase oversampling to 32 because why not Graph: optimize graph widget codepaths so that we don't send redundant samplesChanged signals, which in watsyn cause recalculation of the wavetable --- include/graph.h | 3 ++- plugins/watsyn/Watsyn.cpp | 25 +++++++++++-------------- plugins/watsyn/Watsyn.h | 4 ++-- src/gui/widgets/graph.cpp | 35 +++++++++++++++++++++++------------ 4 files changed, 38 insertions(+), 29 deletions(-) diff --git a/include/graph.h b/include/graph.h index b2041c6e9..bd2254d9b 100644 --- a/include/graph.h +++ b/include/graph.h @@ -150,7 +150,7 @@ public slots: void setLength( int _size ); - void setSampleAt( int _samplePos, float _value ); + void setSampleAt( int x, float val ); void setSamples( const float * _value ); void setWaveToSine(); @@ -172,6 +172,7 @@ signals: void rangeChanged(); private: + void drawSampleAt( int x, float val ); QVector m_samples; float m_minValue; diff --git a/plugins/watsyn/Watsyn.cpp b/plugins/watsyn/Watsyn.cpp index 9d7be21b2..de0bc178f 100644 --- a/plugins/watsyn/Watsyn.cpp +++ b/plugins/watsyn/Watsyn.cpp @@ -116,14 +116,13 @@ void WatsynObject::renderOutput( fpp_t _frames ) ///////////// A-series ///////////////// // A2 - sample_t A2_L = m_A2wave[ static_cast( m_lphase[A2_OSC] ) ] * m_parent->m_lvol[A2_OSC]; - /*interpolate( m_A2wave[ static_cast( m_lphase[A2_OSC] ) % WAVELEN ], + sample_t A2_L = linearInterpolate( m_A2wave[ static_cast( m_lphase[A2_OSC] ) ], m_A2wave[ static_cast( m_lphase[A2_OSC] + 1 ) % WAVELEN ], - fraction( m_lphase[A2_OSC] ) ) * m_parent->m_lvol[A2_OSC];*/ - sample_t A2_R = m_A2wave[ static_cast( m_rphase[A2_OSC] ) ] * m_parent->m_rvol[A2_OSC]; - /*interpolate( m_A2wave[ static_cast( m_rphase[A2_OSC] ) % WAVELEN ], + fraction( m_lphase[A2_OSC] ) ) * m_parent->m_lvol[A2_OSC]; + sample_t A2_R = linearInterpolate( m_A2wave[ static_cast( m_rphase[A2_OSC] ) ], m_A2wave[ static_cast( m_rphase[A2_OSC] + 1 ) % WAVELEN ], - fraction( m_rphase[A2_OSC] ) ) * m_parent->m_rvol[A2_OSC];*/ + fraction( m_rphase[A2_OSC] ) ) * m_parent->m_rvol[A2_OSC]; + // if phase mod, add to phases if( m_amod == MOD_PM ) { @@ -143,14 +142,12 @@ void WatsynObject::renderOutput( fpp_t _frames ) ///////////// B-series ///////////////// // B2 - sample_t B2_L = m_B2wave[ static_cast( m_lphase[B2_OSC] ) ] * m_parent->m_lvol[B2_OSC]; - /*interpolate( m_B2wave[ static_cast( m_lphase[B2_OSC] ) % WAVELEN ], - m_B2wave[ static_cast( m_lphase[B2_OSC] + 1 ) % WAVELEN ], - fraction( m_lphase[B2_OSC] ) ) * m_parent->m_lvol[B2_OSC];*/ - sample_t B2_R = m_B2wave[ static_cast( m_rphase[B2_OSC] ) ] * m_parent->m_rvol[B2_OSC]; - /*interpolate( m_B2wave[ static_cast( m_rphase[B2_OSC] ) % WAVELEN ], - m_B2wave[ static_cast( m_rphase[B2_OSC] + 1 ) % WAVELEN ], - fraction( m_rphase[B2_OSC] ) ) * m_parent->m_rvol[B2_OSC];*/ + sample_t B2_L = linearInterpolate( m_B2wave[ static_cast( m_lphase[B2_OSC] ) ], + m_B2wave[ static_cast( m_lphase[B2_OSC] + 1 ) % WAVELEN ], + fraction( m_lphase[B2_OSC] ) ) * m_parent->m_lvol[B2_OSC]; + sample_t B2_R = linearInterpolate( m_B2wave[ static_cast( m_rphase[B2_OSC] ) ], + m_B2wave[ static_cast( m_rphase[B2_OSC] + 1 ) % WAVELEN ], + fraction( m_rphase[B2_OSC] ) ) * m_parent->m_rvol[B2_OSC]; // if crosstalk active, add a1 const float xt = m_parent->m_xtalk.value(); diff --git a/plugins/watsyn/Watsyn.h b/plugins/watsyn/Watsyn.h index 2590d287c..0369aee72 100644 --- a/plugins/watsyn/Watsyn.h +++ b/plugins/watsyn/Watsyn.h @@ -59,7 +59,7 @@ const int GRAPHLEN = 220; // don't change - must be same as the size of the widget -const int WAVERATIO = 25; // oversampling ratio +const int WAVERATIO = 32; // oversampling ratio const int WAVELEN = GRAPHLEN * WAVERATIO; const int PMOD_AMT = WAVELEN / 2; @@ -177,7 +177,7 @@ private: inline void srccpy( float * _dst, float * _src ) { int err; - SRC_STATE * src_state = src_new( SRC_SINC_MEDIUM_QUALITY, 1, &err ); + SRC_STATE * src_state = src_new( SRC_SINC_FASTEST, 1, &err ); SRC_DATA src_data; src_data.data_in = _src; src_data.input_frames = GRAPHLEN; diff --git a/src/gui/widgets/graph.cpp b/src/gui/widgets/graph.cpp index fbf3b5a43..2345bf422 100644 --- a/src/gui/widgets/graph.cpp +++ b/src/gui/widgets/graph.cpp @@ -221,8 +221,11 @@ void graph::drawLineAt( int _x, int _y, int _lastx ) for ( int i = 0; i < linelen; i++ ) { int x = (_x + (i * xstep)); // get x value - model()->setSampleAt( (int)( x * xscale ), val + (i * ystep)); + model()->drawSampleAt( (int)( x * xscale ), val + (i * ystep)); } + int start = qMin( _x, _x + ( ( linelen - 1 ) * xstep ) ); + int end = qMax( _x, _x + ( ( linelen - 1 ) * xstep ) ); + model()->samplesChanged( start, end ); } void graph::changeSampleAt( int _x, int _y ) @@ -488,18 +491,10 @@ void graphModel::setLength( int _length ) -void graphModel::setSampleAt( int _x, float _val ) +void graphModel::setSampleAt( int x, float val ) { - //snap to the grid - _val -= ( m_step != 0.0 ) ? fmod( _val, m_step ) * m_step : 0; - - // boundary crop - _x = qMax( 0, qMin( length()-1, _x ) ); - _val = qMax( minValue(), qMin( maxValue(), _val ) ); - - // change sample shape - m_samples[_x] = _val; - emit samplesChanged( _x, _x ); + drawSampleAt( x, val ); + emit samplesChanged( x, x ); } @@ -690,4 +685,20 @@ void graphModel::shiftPhase( int _deg ) +void graphModel::drawSampleAt( int x, float val ) +{ + //snap to the grid + val -= ( m_step != 0.0 ) ? fmod( val, m_step ) * m_step : 0; + + // boundary crop + x = qMax( 0, qMin( length()-1, x ) ); + val = qMax( minValue(), qMin( maxValue(), val ) ); + + // change sample shape + m_samples[x] = val; +} + + + + #include "moc_graph.cxx"