From 1781974657a0452c7414f8fc76eda2d71d03797e Mon Sep 17 00:00:00 2001 From: Paul Giblock Date: Thu, 22 May 2008 04:03:30 +0000 Subject: [PATCH] Add more wave shapes to LFO controller git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1011 0778d3d1-df1d-0410-868b-ea421aaaa00d --- ChangeLog | 7 ++ include/lfo_controller.h | 15 ++-- src/core/lfo_controller.cpp | 55 ++++++++++-- src/gui/lfo_controller_dialog.cpp | 144 ++++++++++++++++++------------ 4 files changed, 147 insertions(+), 74 deletions(-) diff --git a/ChangeLog b/ChangeLog index db7c7ee91..a63ce5cfa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-05-22 Paul Giblock + + * include/lfo_controller.h: + * src/gui/lfo_controller_dialog.cpp: + * src/core/lfo_controller.cpp: + Add more wave shapes to LFO controller + 2008-05-21 Paul Giblock * plugins/sf2_player/Makefile.am: diff --git a/include/lfo_controller.h b/include/lfo_controller.h index b715d0c2d..33e85b337 100644 --- a/include/lfo_controller.h +++ b/include/lfo_controller.h @@ -32,6 +32,7 @@ #include "controller.h" #include "controller_dialog.h" #include "tempo_sync_knob.h" +#include "oscillator.h" class automatableButtonGroup; @@ -53,16 +54,6 @@ public: return "LFO Controller"; } - enum LfoShapes - { - SineWave, - TriangleWave, - SawWave, - SquareWave, - UserDefinedWave, - NumLfoShapes - } ; - public slots: virtual controllerDialog * createDialog( QWidget * _parent ); @@ -88,6 +79,10 @@ slots: int m_phaseCorrection; int m_phaseOffset; + sample_t (*m_sampleFunction)( const float ); + +protected slots: + void updateSampleFunction( void ); friend class lfoControllerDialog; }; diff --git a/src/core/lfo_controller.cpp b/src/core/lfo_controller.cpp index b820bf279..13bcd72b9 100644 --- a/src/core/lfo_controller.cpp +++ b/src/core/lfo_controller.cpp @@ -45,14 +45,20 @@ lfoController::lfoController( model * _parent ) : m_lfoSpeedModel( 0.1, 0.01, 5.0, 0.0001, 20000.0, this ), m_lfoAmountModel( 1.0, -1.0, 1.0, 0.005, this ), m_lfoPhaseModel( 0.0, 0.0, 360.0, 4.0, this ), - m_lfoWaveModel( SineWave, 0, NumLfoShapes, 1, this ), + m_lfoWaveModel( oscillator::SineWave, 0, oscillator::NumWaveShapes, 1, this ), + m_sampleFunction( &oscillator::sinSample ), m_duration( 1000 ), m_phaseCorrection( 0 ), m_phaseOffset( 0 ) { + + connect( &m_lfoWaveModel, SIGNAL( dataChanged() ), + this, SLOT( updateSampleFunction() ) ); } + + lfoController::~lfoController() { m_lfoBaseModel.disconnect( this ); @@ -63,6 +69,8 @@ lfoController::~lfoController() } + + // This code took forever to get right. It can // definately be optimized. // The code should probably be integrated with the oscillator class. But I @@ -115,21 +123,53 @@ float lfoController::value( int _offset ) } } + float sampleFrame = float( ( frame+m_phaseOffset ) * + m_lfoSpeedModel.value() ) / + engine::getMixer()->processingSampleRate(); // 44100 frames/sec return m_lfoBaseModel.value() + ( m_lfoAmountModel.value() * - sinf( TWO_PI * float( ( frame+m_phaseOffset ) * - m_lfoSpeedModel.value() ) / - engine::getMixer()->processingSampleRate() ) / 2.0f ); + m_sampleFunction(sampleFrame) + / 2.0f ); } + + +void lfoController::updateSampleFunction( void ) +{ + switch( m_lfoWaveModel.value() ) + { + case oscillator::SineWave: + m_sampleFunction = &oscillator::sinSample; + break; + case oscillator::TriangleWave: + m_sampleFunction = &oscillator::triangleSample; + break; + case oscillator::SawWave: + m_sampleFunction = &oscillator::sawSample; + break; + case oscillator::SquareWave: + m_sampleFunction = &oscillator::squareSample; + break; + case oscillator::MoogSawWave: + m_sampleFunction = &oscillator::moogSawSample; + break; + case oscillator::ExponentialWave: + m_sampleFunction = &oscillator::expSample; + break; + case oscillator::WhiteNoise: + m_sampleFunction = &oscillator::noiseSample; + break; + } +} + + + + controllerDialog * lfoController::createDialog( QWidget * _parent ) { controllerDialog * d = new lfoControllerDialog( this, _parent ); - - - return d; } @@ -138,3 +178,4 @@ controllerDialog * lfoController::createDialog( QWidget * _parent ) #endif + diff --git a/src/gui/lfo_controller_dialog.cpp b/src/gui/lfo_controller_dialog.cpp index 2ba7bb580..bdf97d780 100644 --- a/src/gui/lfo_controller_dialog.cpp +++ b/src/gui/lfo_controller_dialog.cpp @@ -51,17 +51,17 @@ const int ENV_KNOBS_LBL_Y = 0; const int KNOB_X_SPACING = 32; +const int LFO_SHAPES_X = 6; +const int LFO_SHAPES_Y = 16; + const int LFO_GRAPH_X = 6; const int LFO_GRAPH_Y = ENV_KNOBS_LBL_Y+14; const int LFO_KNOB_Y = LFO_GRAPH_Y-2; -const int LFO_BASE_KNOB_X = LFO_GRAPH_X + 10; +const int LFO_BASE_KNOB_X = LFO_SHAPES_X + 64; const int LFO_SPEED_KNOB_X = LFO_BASE_KNOB_X+KNOB_X_SPACING; const int LFO_AMOUNT_KNOB_X = LFO_SPEED_KNOB_X+KNOB_X_SPACING; const int LFO_PHASE_KNOB_X = LFO_AMOUNT_KNOB_X+KNOB_X_SPACING; -const int LFO_SHAPES_X = LFO_GRAPH_X;//PREDELAY_KNOB_X; -const int LFO_SHAPES_Y = LFO_GRAPH_Y + 50; - lfoControllerDialog::lfoControllerDialog( controller * _model, QWidget * _parent ) : controllerDialog( _model, _parent ) { @@ -114,68 +114,98 @@ lfoControllerDialog::lfoControllerDialog( controller * _model, QWidget * _parent "down. It's the same with a square-wave." ) ); + pixmapButton * sin_wave_btn = new pixmapButton( this, NULL ); + sin_wave_btn->move( LFO_SHAPES_X, LFO_SHAPES_Y ); + sin_wave_btn->setActiveGraphic( embed::getIconPixmap( + "sin_wave_active" ) ); + sin_wave_btn->setInactiveGraphic( embed::getIconPixmap( + "sin_wave_inactive" ) ); + toolTip::add( sin_wave_btn, + tr( "Click here if you want a sine-wave for " + "current oscillator." ) ); - pixmapButton * sin_lfo_btn = new pixmapButton( this, NULL ); - sin_lfo_btn->move( LFO_SHAPES_X, LFO_SHAPES_Y ); - sin_lfo_btn->setActiveGraphic( embed::getIconPixmap( - "sin_wave_active" ) ); - sin_lfo_btn->setInactiveGraphic( embed::getIconPixmap( - "sin_wave_inactive" ) ); - sin_lfo_btn->setWhatsThis( - tr( "Click here if you want a sine-wave for current " - "oscillator." ) ); + pixmapButton * triangle_wave_btn = + new pixmapButton( this, NULL ); + triangle_wave_btn->move( LFO_SHAPES_X + 14, LFO_SHAPES_Y ); + triangle_wave_btn->setActiveGraphic( + embed::getIconPixmap( "triangle_wave_active" ) ); + triangle_wave_btn->setInactiveGraphic( + embed::getIconPixmap( "triangle_wave_inactive" ) ); + toolTip::add( triangle_wave_btn, + tr( "Click here if you want a triangle-wave " + "for current oscillator." ) ); - pixmapButton * triangle_lfo_btn = new pixmapButton( this, NULL ); - triangle_lfo_btn->move( LFO_SHAPES_X+15, LFO_SHAPES_Y ); - triangle_lfo_btn->setActiveGraphic( embed::getIconPixmap( - "triangle_wave_active" ) ); - triangle_lfo_btn->setInactiveGraphic( embed::getIconPixmap( - "triangle_wave_inactive" ) ); - triangle_lfo_btn->setWhatsThis( - tr( "Click here if you want a triangle-wave for current " - "oscillator." ) ); + pixmapButton * saw_wave_btn = new pixmapButton( this, NULL ); + saw_wave_btn->move( LFO_SHAPES_X + 28, LFO_SHAPES_Y ); + saw_wave_btn->setActiveGraphic( embed::getIconPixmap( + "saw_wave_active" ) ); + saw_wave_btn->setInactiveGraphic( embed::getIconPixmap( + "saw_wave_inactive" ) ); + toolTip::add( saw_wave_btn, + tr( "Click here if you want a saw-wave for " + "current oscillator." ) ); - pixmapButton * saw_lfo_btn = new pixmapButton( this, NULL ); - saw_lfo_btn->move( LFO_SHAPES_X+30, LFO_SHAPES_Y ); - saw_lfo_btn->setActiveGraphic( embed::getIconPixmap( - "saw_wave_active" ) ); - saw_lfo_btn->setInactiveGraphic( embed::getIconPixmap( - "saw_wave_inactive" ) ); - saw_lfo_btn->setWhatsThis( - tr( "Click here if you want a saw-wave for current " - "oscillator." ) ); + pixmapButton * sqr_wave_btn = new pixmapButton( this, NULL ); + sqr_wave_btn->move( LFO_SHAPES_X + 42, LFO_SHAPES_Y ); + sqr_wave_btn->setActiveGraphic( embed::getIconPixmap( + "square_wave_active" ) ); + sqr_wave_btn->setInactiveGraphic( embed::getIconPixmap( + "square_wave_inactive" ) ); + toolTip::add( sqr_wave_btn, + tr( "Click here if you want a square-wave for " + "current oscillator." ) ); - pixmapButton * sqr_lfo_btn = new pixmapButton( this, NULL ); - sqr_lfo_btn->move( LFO_SHAPES_X+45, LFO_SHAPES_Y ); - sqr_lfo_btn->setActiveGraphic( embed::getIconPixmap( - "square_wave_active" ) ); - sqr_lfo_btn->setInactiveGraphic( embed::getIconPixmap( - "square_wave_inactive" ) ); - sqr_lfo_btn->setWhatsThis( - tr( "Click here if you want a square-wave for current " - "oscillator." ) ); + pixmapButton * moog_saw_wave_btn = + new pixmapButton( this, NULL ); + moog_saw_wave_btn->move( LFO_SHAPES_X, LFO_SHAPES_Y + 14 ); + moog_saw_wave_btn->setActiveGraphic( + embed::getIconPixmap( "moog_saw_wave_active" ) ); + moog_saw_wave_btn->setInactiveGraphic( + embed::getIconPixmap( "moog_saw_wave_inactive" ) ); + toolTip::add( moog_saw_wave_btn, + tr( "Click here if you want a moog-saw-wave " + "for current oscillator." ) ); - m_userLfoBtn = new pixmapButton( this, NULL ); - m_userLfoBtn->move( LFO_SHAPES_X+60, LFO_SHAPES_Y ); - m_userLfoBtn->setActiveGraphic( embed::getIconPixmap( - "usr_wave_active" ) ); - m_userLfoBtn->setInactiveGraphic( embed::getIconPixmap( - "usr_wave_inactive" ) ); - m_userLfoBtn->setWhatsThis( - tr( "Click here if you want a user-defined wave for current " - "oscillator. Afterwards drag an according sample-" - "file into LFO-graph." ) ); + pixmapButton * exp_wave_btn = new pixmapButton( this, NULL ); + exp_wave_btn->move( LFO_SHAPES_X + 14, LFO_SHAPES_Y + 14 ); + exp_wave_btn->setActiveGraphic( embed::getIconPixmap( + "exp_wave_active" ) ); + exp_wave_btn->setInactiveGraphic( embed::getIconPixmap( + "exp_wave_inactive" ) ); + toolTip::add( exp_wave_btn, + tr( "Click here if you want an exponential " + "wave for current oscillator." ) ); - connect( m_userLfoBtn, SIGNAL( toggled( bool ) ), - this, SLOT( lfoUserWaveChanged() ) ); + pixmapButton * white_noise_btn = new pixmapButton( this, NULL ); + white_noise_btn->move( LFO_SHAPES_X + 28, LFO_SHAPES_Y + 14 ); + white_noise_btn->setActiveGraphic( + embed::getIconPixmap( "white_noise_wave_active" ) ); + white_noise_btn->setInactiveGraphic( + embed::getIconPixmap( "white_noise_wave_inactive" ) ); + toolTip::add( white_noise_btn, + tr( "Click here if you want a white-noise for " + "current oscillator." ) ); + pixmapButton * uwb = new pixmapButton( this, NULL ); + uwb->move( LFO_SHAPES_X + 42, LFO_SHAPES_Y + 14 ); + uwb->setActiveGraphic( embed::getIconPixmap( + "usr_shape_active" ) ); + uwb->setInactiveGraphic( embed::getIconPixmap( + "usr_shape_inactive" ) ); + toolTip::add( uwb, tr( "Click here if you want a user-defined " + "wave-shape for current oscillator." ) ); + + m_lfoWaveBtnGrp = new automatableButtonGroup( this, tr( "LFO wave shape" ) ); - m_lfoWaveBtnGrp->addButton( sin_lfo_btn ); - m_lfoWaveBtnGrp->addButton( triangle_lfo_btn ); - m_lfoWaveBtnGrp->addButton( saw_lfo_btn ); - m_lfoWaveBtnGrp->addButton( sqr_lfo_btn ); - m_lfoWaveBtnGrp->addButton( m_userLfoBtn ); + m_lfoWaveBtnGrp->addButton( sin_wave_btn ); + m_lfoWaveBtnGrp->addButton( triangle_wave_btn ); + m_lfoWaveBtnGrp->addButton( saw_wave_btn ); + m_lfoWaveBtnGrp->addButton( sqr_wave_btn ); + m_lfoWaveBtnGrp->addButton( moog_saw_wave_btn ); + m_lfoWaveBtnGrp->addButton( exp_wave_btn ); + m_lfoWaveBtnGrp->addButton( white_noise_btn ); + m_lfoWaveBtnGrp->addButton( uwb ); /*