add multiplier to LFO controller and fix temposync

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1162 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Paul Giblock
2008-06-23 17:15:48 +00:00
parent 66f98a3017
commit 053feaba8f
12 changed files with 176 additions and 79 deletions

View File

@@ -1,3 +1,23 @@
2008-06-23 Paul Giblock <drfaygo/at/gmail/dot/com>
* 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 <tobydox/at/users/dot/sourceforge/dot/net>
* include/automatable_model_view.h:

Binary file not shown.

After

Width:  |  Height:  |  Size: 706 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 738 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 770 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 801 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

View File

@@ -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;
} ;

View File

@@ -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" ) ),

View File

@@ -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<int>(
engine::getMixer()->processingSampleRate() /
m_lfoSpeedModel.value() );
int newDuration = static_cast<int>(
(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();
}

View File

@@ -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<lfoController>();
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 );
}

View File

@@ -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 );
}