diff --git a/ChangeLog b/ChangeLog index af5cff1ba..4e6d24d20 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2008-06-23 Paul Giblock + + * include/lfo_controller.h: + * src/gui/lfo_controller_dialog.cpp: + * src/core/lfo_controller.cpp: + * data/themes/default/lfo_d100_active.png: + * data/themes/default/lfo_d100_inactive.png: + * data/themes/default/lfo_x100_active.png: + * data/themes/default/lfo_x100_inactive.png: + * data/themes/default/lfo_x1_active.png: + * data/themes/default/lfo_x1_inactive.png: + Add multiplier to lfo-controller and fix tempo-sync knob. Breaks old + projects that use LFO, but shouldn't matter since 0.4 hasn't been released + + * src/gui/widgets/tempo_sync_knob.cpp: + Allow tempo-sync knob to work with ranges other than [0..1] + + * src/core/envelope_and_lfo_parameters.cpp: + Remove hardcoded literal, use already defined const int instead + 2008-06-20 Tobias Doerffel * include/automatable_model_view.h: diff --git a/data/themes/default/lfo_d100_active.png b/data/themes/default/lfo_d100_active.png new file mode 100644 index 000000000..f2a05b555 Binary files /dev/null and b/data/themes/default/lfo_d100_active.png differ diff --git a/data/themes/default/lfo_d100_inactive.png b/data/themes/default/lfo_d100_inactive.png new file mode 100644 index 000000000..239be1e00 Binary files /dev/null and b/data/themes/default/lfo_d100_inactive.png differ diff --git a/data/themes/default/lfo_x100_active.png b/data/themes/default/lfo_x100_active.png new file mode 100644 index 000000000..479ff38c1 Binary files /dev/null and b/data/themes/default/lfo_x100_active.png differ diff --git a/data/themes/default/lfo_x100_inactive.png b/data/themes/default/lfo_x100_inactive.png new file mode 100644 index 000000000..e0058926e Binary files /dev/null and b/data/themes/default/lfo_x100_inactive.png differ diff --git a/data/themes/default/lfo_x1_active.png b/data/themes/default/lfo_x1_active.png new file mode 100644 index 000000000..3a44b3e28 Binary files /dev/null and b/data/themes/default/lfo_x1_active.png differ diff --git a/data/themes/default/lfo_x1_inactive.png b/data/themes/default/lfo_x1_inactive.png new file mode 100644 index 000000000..1947a4c93 Binary files /dev/null and b/data/themes/default/lfo_x1_inactive.png differ diff --git a/include/lfo_controller.h b/include/lfo_controller.h index 4f13ad696..5b8743f72 100644 --- a/include/lfo_controller.h +++ b/include/lfo_controller.h @@ -37,6 +37,7 @@ class automatableButtonGroup; class knob; +class ledCheckBox; class tempoSyncKnob; class pixmapButton; class oscillator; @@ -72,11 +73,12 @@ slots: */ - floatModel m_lfoBaseModel; - tempoSyncKnobModel m_lfoSpeedModel; - floatModel m_lfoAmountModel; - floatModel m_lfoPhaseModel; - intModel m_lfoWaveModel; + floatModel m_baseModel; + tempoSyncKnobModel m_speedModel; + floatModel m_amountModel; + floatModel m_phaseModel; + intModel m_waveModel; + intModel m_multiplierModel; int m_duration; int m_phaseCorrection; @@ -116,13 +118,13 @@ protected: lfoController * m_lfo; - knob * m_lfoBaseKnob; - tempoSyncKnob * m_lfoSpeedKnob; - knob * m_lfoAmountKnob; - knob * m_lfoPhaseKnob; - + knob * m_baseKnob; + tempoSyncKnob * m_speedKnob; + knob * m_amountKnob; + knob * m_phaseKnob; pixmapButton * m_userLfoBtn; - automatableButtonGroup * m_lfoWaveBtnGrp; + automatableButtonGroup * m_waveBtnGrp; + automatableButtonGroup * m_multiplierBtnGrp; } ; diff --git a/src/core/envelope_and_lfo_parameters.cpp b/src/core/envelope_and_lfo_parameters.cpp index 18ebcdff7..d56e0473b 100644 --- a/src/core/envelope_and_lfo_parameters.cpp +++ b/src/core/envelope_and_lfo_parameters.cpp @@ -66,7 +66,7 @@ envelopeAndLFOParameters::envelopeAndLFOParameters( m_lfoPredelayModel( 0.0, 0.0, 1.0, 0.001, this, tr( "LFO-predelay-time" ) ), m_lfoAttackModel( 0.0, 0.0, 1.0, 0.001, this, tr( "LFO-attack-time" ) ), - m_lfoSpeedModel( 0.1, 0.01, 1.0, 0.0001, 20000.0, this, + m_lfoSpeedModel( 0.1, 0.01, 1.0, 0.0001, SECS_PER_LFO_OSCILLATION * 1000.0, this, tr( "LFO-speed" ) ), m_lfoAmountModel( 0.0, -1.0, 1.0, 0.005, this, tr( "LFO-modulation-amount" ) ), diff --git a/src/core/lfo_controller.cpp b/src/core/lfo_controller.cpp index 5581fcd8d..a81a4e8a4 100644 --- a/src/core/lfo_controller.cpp +++ b/src/core/lfo_controller.cpp @@ -41,18 +41,20 @@ const float TWO_PI = 6.28318531f; lfoController::lfoController( model * _parent ) : controller( LfoController, _parent ), - m_lfoBaseModel( 0.5, 0.0, 1.0, 0.001, this, tr( "Base value" ) ), - m_lfoSpeedModel( 0.1, 0.01, 5.0, 0.0001, 20000.0, this, tr( "Oscillator speed" ) ), - m_lfoAmountModel( 1.0, -1.0, 1.0, 0.005, this, tr( "Oscillator amount" ) ), - m_lfoPhaseModel( 0.0, 0.0, 360.0, 4.0, this, tr( "Oscillator phase" ) ), - m_lfoWaveModel( oscillator::SineWave, 0, oscillator::NumWaveShapes, this, tr( "Oscillator waveform" ) ), + m_baseModel( 0.5, 0.0, 1.0, 0.001, this, tr( "Base value" ) ), + m_speedModel( 2.0, 0.01, 20.0, 0.0001, 20000.0, this, tr( "Oscillator speed" ) ), + m_amountModel( 1.0, -1.0, 1.0, 0.005, this, tr( "Oscillator amount" ) ), + m_phaseModel( 0.0, 0.0, 360.0, 4.0, this, tr( "Oscillator phase" ) ), + m_waveModel( oscillator::SineWave, 0, oscillator::NumWaveShapes, + this, tr( "Oscillator waveform" ) ), + m_multiplierModel( 0, 0, 2, this, tr( "Frequency Multiplier" ) ), m_duration( 1000 ), m_phaseCorrection( 0 ), m_phaseOffset( 0 ), m_sampleFunction( &oscillator::sinSample ) { - connect( &m_lfoWaveModel, SIGNAL( dataChanged() ), + connect( &m_waveModel, SIGNAL( dataChanged() ), this, SLOT( updateSampleFunction() ) ); } @@ -61,11 +63,12 @@ lfoController::lfoController( model * _parent ) : lfoController::~lfoController() { - m_lfoBaseModel.disconnect( this ); - m_lfoSpeedModel.disconnect( this ); - m_lfoAmountModel.disconnect( this ); - m_lfoPhaseModel.disconnect( this ); - m_lfoWaveModel.disconnect( this ); + m_baseModel.disconnect( this ); + m_speedModel.disconnect( this ); + m_amountModel.disconnect( this ); + m_phaseModel.disconnect( this ); + m_waveModel.disconnect( this ); + m_multiplierModel.disconnect( this ); } @@ -87,11 +90,25 @@ float lfoController::value( int _offset ) // The new duration in frames // (Samples/Second) / (periods/second) = (Samples/cycle) - int newDuration = static_cast( - engine::getMixer()->processingSampleRate() / - m_lfoSpeedModel.value() ); + int newDuration = static_cast( + (engine::getMixer()->processingSampleRate()) * + m_speedModel.value() ); + + switch(m_multiplierModel.value() ) + { + case 1: + newDuration /= 100.0; + break; + + case 2: + newDuration *= 100.0; + break; + + default: + break; + } - m_phaseOffset = m_lfoPhaseModel.value() * newDuration / 360.0; + m_phaseOffset = m_phaseModel.value() * newDuration / (360.0); if (newDuration != m_duration) { // frame offset @@ -114,7 +131,6 @@ float lfoController::value( int _offset ) // newFrameOffset has old phaseCorrection built-in m_phaseCorrection += newFrameOffset; - // re-run the first calculation again frame = runningFrames() + m_phaseCorrection; @@ -124,12 +140,30 @@ float lfoController::value( int _offset ) } } - float sampleFrame = float( ( frame+m_phaseOffset ) * - m_lfoSpeedModel.value() ) / - engine::getMixer()->processingSampleRate(); + // speedModel 0..1 fast..slow 0ms..20000ms + // duration m_duration + // + + // frames / (20seconds of frames) + float sampleFrame = float( frame+m_phaseOffset ) / + (engine::getMixer()->processingSampleRate() * m_speedModel.value() ); + + switch(m_multiplierModel.value() ) + { + case 1: + sampleFrame *= 100.0; + break; + + case 2: + sampleFrame /= 100.0; + break; + + default: + break; + } // 44100 frames/sec - return m_lfoBaseModel.value() + ( m_lfoAmountModel.value() * + return m_baseModel.value() + ( m_amountModel.value() * m_sampleFunction(sampleFrame) / 2.0f ); } @@ -139,7 +173,7 @@ float lfoController::value( int _offset ) void lfoController::updateSampleFunction( void ) { - switch( m_lfoWaveModel.value() ) + switch( m_waveModel.value() ) { case oscillator::SineWave: m_sampleFunction = &oscillator::sinSample; @@ -171,11 +205,12 @@ void lfoController::saveSettings( QDomDocument & _doc, QDomElement & _this ) { controller::saveSettings( _doc, _this ); - m_lfoBaseModel.saveSettings( _doc, _this, "base" ); - m_lfoSpeedModel.saveSettings( _doc, _this, "speed" ); - m_lfoAmountModel.saveSettings( _doc, _this, "amount" ); - m_lfoPhaseModel.saveSettings( _doc, _this, "phase" ); - m_lfoWaveModel.saveSettings( _doc, _this, "wave" ); + m_baseModel.saveSettings( _doc, _this, "base" ); + m_speedModel.saveSettings( _doc, _this, "speed" ); + m_amountModel.saveSettings( _doc, _this, "amount" ); + m_phaseModel.saveSettings( _doc, _this, "phase" ); + m_waveModel.saveSettings( _doc, _this, "wave" ); + m_multiplierModel.saveSettings( _doc, _this, "multiplier" ); } @@ -184,11 +219,12 @@ void lfoController::loadSettings( const QDomElement & _this ) { controller::loadSettings( _this ); - m_lfoBaseModel.loadSettings( _this, "base" ); - m_lfoSpeedModel.loadSettings( _this, "speed" ); - m_lfoAmountModel.loadSettings( _this, "amount" ); - m_lfoPhaseModel.loadSettings( _this, "phase" ); - m_lfoWaveModel.loadSettings( _this, "wave" ); + m_baseModel.loadSettings( _this, "base" ); + m_speedModel.loadSettings( _this, "speed" ); + m_amountModel.loadSettings( _this, "amount" ); + m_phaseModel.loadSettings( _this, "phase" ); + m_waveModel.loadSettings( _this, "wave" ); + m_multiplierModel.loadSettings( _this, "multiplier" ); updateSampleFunction(); } diff --git a/src/gui/lfo_controller_dialog.cpp b/src/gui/lfo_controller_dialog.cpp index 619736399..293be0d60 100644 --- a/src/gui/lfo_controller_dialog.cpp +++ b/src/gui/lfo_controller_dialog.cpp @@ -61,6 +61,7 @@ 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_MULTIPLIER_X = LFO_PHASE_KNOB_X+KNOB_X_SPACING; lfoControllerDialog::lfoControllerDialog( controller * _model, QWidget * _parent ) : controllerDialog( _model, _parent ) @@ -75,38 +76,38 @@ lfoControllerDialog::lfoControllerDialog( controller * _model, QWidget * _parent toolTip::add( this, tr( "LFO Controller" ) ); - m_lfoBaseKnob = new knob( knobBright_26, this ); - m_lfoBaseKnob->setLabel( tr( "BASE" ) ); - m_lfoBaseKnob->move( LFO_BASE_KNOB_X, LFO_KNOB_Y ); - m_lfoBaseKnob->setHintText( tr( "Base amount:" ) + " ", "" ); - m_lfoBaseKnob->setWhatsThis( tr("todo") ); + m_baseKnob = new knob( knobBright_26, this ); + m_baseKnob->setLabel( tr( "BASE" ) ); + m_baseKnob->move( LFO_BASE_KNOB_X, LFO_KNOB_Y ); + m_baseKnob->setHintText( tr( "Base amount:" ) + " ", "" ); + m_baseKnob->setWhatsThis( tr("todo") ); - m_lfoSpeedKnob = new tempoSyncKnob( knobBright_26, this ); - m_lfoSpeedKnob->setLabel( tr( "SPD" ) ); - m_lfoSpeedKnob->move( LFO_SPEED_KNOB_X, LFO_KNOB_Y ); - m_lfoSpeedKnob->setHintText( tr( "LFO-speed:" ) + " ", "" ); - m_lfoSpeedKnob->setWhatsThis( + m_speedKnob = new tempoSyncKnob( knobBright_26, this ); + m_speedKnob->setLabel( tr( "SPD" ) ); + m_speedKnob->move( LFO_SPEED_KNOB_X, LFO_KNOB_Y ); + m_speedKnob->setHintText( tr( "LFO-speed:" ) + " ", "" ); + m_speedKnob->setWhatsThis( tr( "Use this knob for setting speed of the LFO. The " "bigger this value the faster the LFO oscillates and " "the faster the effect." ) ); - m_lfoAmountKnob = new knob( knobBright_26, this ); - m_lfoAmountKnob->setLabel( tr( "AMT" ) ); - m_lfoAmountKnob->move( LFO_AMOUNT_KNOB_X, LFO_KNOB_Y ); - m_lfoAmountKnob->setHintText( tr( "Modulation amount:" ) + " ", "" ); - m_lfoAmountKnob->setWhatsThis( + m_amountKnob = new knob( knobBright_26, this ); + m_amountKnob->setLabel( tr( "AMT" ) ); + m_amountKnob->move( LFO_AMOUNT_KNOB_X, LFO_KNOB_Y ); + m_amountKnob->setHintText( tr( "Modulation amount:" ) + " ", "" ); + m_amountKnob->setWhatsThis( tr( "Use this knob for setting modulation amount of the " "current LFO. The bigger this value the more the " "selected size (e.g. volume or cutoff-frequency) will " "be influenced by this LFO." ) ); - m_lfoPhaseKnob = new knob( knobBright_26, this ); - m_lfoPhaseKnob->setLabel( tr( "PHS" ) ); - m_lfoPhaseKnob->move( LFO_PHASE_KNOB_X, LFO_KNOB_Y ); - m_lfoPhaseKnob->setHintText( tr( "Phase offset:" ) + " ", "" + tr( "degrees" ) ); - m_lfoPhaseKnob->setWhatsThis( + m_phaseKnob = new knob( knobBright_26, this ); + m_phaseKnob->setLabel( tr( "PHS" ) ); + m_phaseKnob->move( LFO_PHASE_KNOB_X, LFO_KNOB_Y ); + m_phaseKnob->setHintText( tr( "Phase offset:" ) + " ", "" + tr( "degrees" ) ); + m_phaseKnob->setWhatsThis( tr( "With this knob you can set the phase-offset of " "the LFO. That means you can move the " "point within an oscillation where the " @@ -197,17 +198,53 @@ lfoControllerDialog::lfoControllerDialog( controller * _model, QWidget * _parent uwb->setEnabled( false ); toolTip::add( uwb, tr( "Click here if you want a user-defined " "wave-shape for current oscillator." ) ); - - m_lfoWaveBtnGrp = new automatableButtonGroup( this ); - 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 ); + m_waveBtnGrp = new automatableButtonGroup( this ); + m_waveBtnGrp->addButton( sin_wave_btn ); + m_waveBtnGrp->addButton( triangle_wave_btn ); + m_waveBtnGrp->addButton( saw_wave_btn ); + m_waveBtnGrp->addButton( sqr_wave_btn ); + m_waveBtnGrp->addButton( moog_saw_wave_btn ); + m_waveBtnGrp->addButton( exp_wave_btn ); + m_waveBtnGrp->addButton( white_noise_btn ); + m_waveBtnGrp->addButton( uwb ); + + + pixmapButton * x1 = new pixmapButton( this, NULL ); + x1->move( LFO_MULTIPLIER_X, LFO_SHAPES_Y + 15 ); + x1->setActiveGraphic( embed::getIconPixmap( + "lfo_x1_active" ) ); + x1->setInactiveGraphic( embed::getIconPixmap( + "lfo_x1_inactive" ) ); + + pixmapButton * x100 = new pixmapButton( this, NULL ); + x100->move( LFO_MULTIPLIER_X, LFO_SHAPES_Y ); + x100->setActiveGraphic( embed::getIconPixmap( + "lfo_x100_active" ) ); + x100->setInactiveGraphic( embed::getIconPixmap( + "lfo_x100_inactive" ) ); + + pixmapButton * d100 = new pixmapButton( this, NULL ); + d100->move( LFO_MULTIPLIER_X, LFO_SHAPES_Y + 30 ); + d100->setActiveGraphic( embed::getIconPixmap( + "lfo_d100_active" ) ); + d100->setInactiveGraphic( embed::getIconPixmap( + "lfo_d100_inactive" ) ); + + /* + m_x100Cb = new ledCheckBox( tr( "FREQ x 100" ), this ); + m_x100Cb->setFont( pointSize<6>( m_x100Cb->font() ) ); + m_x100Cb->move( LFO_BASE_KNOB_X, LFO_KNOB_Y + 36 ); + m_x100Cb->setWhatsThis( + tr( "Click here if the frequency of this LFO should be " + "multiplied with 100." ) ); + toolTip::add( m_x100Cb, tr( "multiply LFO-frequency with 100" ) ); + */ + + m_multiplierBtnGrp = new automatableButtonGroup( this ); + m_multiplierBtnGrp->addButton( x1 ); + m_multiplierBtnGrp->addButton( x100 ); + m_multiplierBtnGrp->addButton( d100 ); setModel( _model ); @@ -279,11 +316,12 @@ void lfoControllerDialog::modelChanged( void ) { m_lfo = castModel(); - m_lfoBaseKnob->setModel( &m_lfo->m_lfoBaseModel ); - m_lfoSpeedKnob->setModel( &m_lfo->m_lfoSpeedModel ); - m_lfoAmountKnob->setModel( &m_lfo->m_lfoAmountModel ); - m_lfoPhaseKnob->setModel( &m_lfo->m_lfoPhaseModel ); - m_lfoWaveBtnGrp->setModel( &m_lfo->m_lfoWaveModel ); + m_baseKnob->setModel( &m_lfo->m_baseModel ); + m_speedKnob->setModel( &m_lfo->m_speedModel ); + m_amountKnob->setModel( &m_lfo->m_amountModel ); + m_phaseKnob->setModel( &m_lfo->m_phaseModel ); + m_waveBtnGrp->setModel( &m_lfo->m_waveModel ); + m_multiplierBtnGrp->setModel( &m_lfo->m_multiplierModel ); } diff --git a/src/gui/widgets/tempo_sync_knob.cpp b/src/gui/widgets/tempo_sync_knob.cpp index d9da4fb97..2dccbf074 100644 --- a/src/gui/widgets/tempo_sync_knob.cpp +++ b/src/gui/widgets/tempo_sync_knob.cpp @@ -117,7 +117,8 @@ void tempoSyncKnobModel::calculateTempoSyncTime( bpm_t _bpm ) default: ; } bool journalling = testAndSetJournalling( FALSE ); - setValue( 60000.0 / ( _bpm * conversionFactor * m_scale ) ); + float oneUnit = 60000.0 / ( _bpm * conversionFactor * m_scale ); + setValue( oneUnit*( maxValue() - minValue() ) + minValue() ); setJournalling( journalling ); }