From ea467f92b762a021db36b36b2de266da87c3923e Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Thu, 3 Jan 2008 00:57:51 +0000 Subject: [PATCH] M/V-split for instrument-tracks git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms-mv@638 0778d3d1-df1d-0410-868b-ea421aaaa00d --- ChangeLog | 13 +++ include/dummy_instrument.h | 10 +- include/instrument.h | 52 ++++++++-- include/mv_base.h | 16 ++-- plugins/kicker/kicker.cpp | 162 ++++++++++++++++++-------------- plugins/kicker/kicker.h | 32 ++++++- src/core/instrument.cpp | 55 ++++++++++- src/tracks/instrument_track.cpp | 8 +- 8 files changed, 254 insertions(+), 94 deletions(-) diff --git a/ChangeLog b/ChangeLog index e54b56753..293c38528 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2008-01-02 Tobias Doerffel + + * plugins/kicker/kicker.cpp: + * plugins/kicker/kicker.h: + make plugin work with M/V-architecture + + * include/instrument.h: + * include/dummy_instrument.h: + * include/mv_base.h: + * src/tracks/instrument_track.cpp: + * src/core/instrument.cpp: + M/V-split for instrument-tracks + 2008-01-02 Tobias Doerffel * include/dummy_effect.h: diff --git a/include/dummy_instrument.h b/include/dummy_instrument.h index dd9fa4212..736d4ee56 100644 --- a/include/dummy_instrument.h +++ b/include/dummy_instrument.h @@ -2,7 +2,7 @@ * dummy_instrument.h - instrument used as fallback if an instrument couldn't * be loaded * - * Copyright (c) 2005-2006 Tobias Doerffel + * Copyright (c) 2005-2008 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -33,8 +33,8 @@ class dummyInstrument : public instrument { public: - inline dummyInstrument( instrumentTrack * _channel_track ) : - instrument( _channel_track, NULL ) + inline dummyInstrument( instrumentTrack * _instrument_track ) : + instrument( _instrument_track, NULL ) { } @@ -56,6 +56,10 @@ public: return( "dummyinstrument" ); } + virtual instrumentView * createView( QWidget * _parent ) + { + return( new instrumentView( this, _parent ) ); + } } ; diff --git a/include/instrument.h b/include/instrument.h index a9a8035c5..55f823cbc 100644 --- a/include/instrument.h +++ b/include/instrument.h @@ -2,7 +2,7 @@ * instrument.h - declaration of class instrument, which provides a * standard interface for all instrument plugins * - * Copyright (c) 2005-2007 Tobias Doerffel + * Copyright (c) 2005-2008 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -27,29 +27,33 @@ #ifndef _INSTRUMENT_H #define _INSTRUMENT_H - #include -#include #include "plugin.h" #include "mixer.h" +#include "mv_base.h" // forward-declarations class instrumentTrack; -class notePlayHandle; +class instrumentView; class midiEvent; class midiTime; +class notePlayHandle; class track; -class instrument : public QWidget, public plugin +class instrument : public plugin, public model { public: - instrument( instrumentTrack * _channel_track, + instrument( instrumentTrack * _instrument_track, const descriptor * _descriptor ); virtual ~instrument(); + // -------------------------------------------------------------------- + // functions that can/should be re-implemented: + // -------------------------------------------------------------------- + // if the plugin doesn't play each note, it can create an instrument- // play-handle and re-implement this method, so that it mixes it's // output buffer only once per mixer-period @@ -101,13 +105,20 @@ public: return( FALSE ); } + + // -------------------------------------------------------------------- + // provided functions: + // -------------------------------------------------------------------- + // instantiate instrument-plugin with given name or return NULL // on failure static instrument * FASTCALL instantiate( const QString & _plugin_name, - instrumentTrack * _channel_track ); + instrumentTrack * _instrument_track ); virtual bool isFromTrack( const track * _track ) const; + instrumentView * createEditor( QWidget * _parent ); + protected: inline instrumentTrack * getInstrumentTrack( void ) const @@ -120,6 +131,10 @@ protected: // desiredReleaseFrames() frames are left void applyRelease( sampleFrame * buf, const notePlayHandle * _n ); + // instruments have to implement this to create an according view for + // themselves + virtual instrumentView * createView( QWidget * _parent ) = 0; + private: instrumentTrack * m_instrumentTrack; @@ -127,4 +142,27 @@ private: } ; + +class instrumentView : public QWidget, public modelView +{ +public: + instrumentView( instrument * _instrument, QWidget * _parent ); + virtual ~instrumentView(); + + instrument * model( void ) + { + return( castModel() ); + } + + const instrument * model( void ) const + { + return( castModel() ); + } + + virtual void setModel( ::model * _model, bool = FALSE ); + +} ; + + + #endif diff --git a/include/mv_base.h b/include/mv_base.h index d0c990c5d..dab64b2c0 100644 --- a/include/mv_base.h +++ b/include/mv_base.h @@ -1,7 +1,7 @@ /* * mv_base.h - base for M/V-architecture of LMMS * - * Copyright (c) 2007 Tobias Doerffel + * Copyright (c) 2007-2008 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -77,12 +77,7 @@ public: { } - void setModel( model * _model, bool _old_model_valid = TRUE ); - - // sub-classes can re-implement this to track model-changes - virtual void modelChanged( void ) - { - } + virtual void setModel( model * _model, bool _old_model_valid = TRUE ); template T * castModel( void ) @@ -97,6 +92,13 @@ public: } +protected: + // sub-classes can re-implement this to track model-changes + virtual void modelChanged( void ) + { + } + + private: model * m_model; diff --git a/plugins/kicker/kicker.cpp b/plugins/kicker/kicker.cpp index d2e738a8c..1e2a498b5 100644 --- a/plugins/kicker/kicker.cpp +++ b/plugins/kicker/kicker.cpp @@ -1,7 +1,7 @@ /* * kicker.cpp - bassdrum-synthesizer * - * Copyright (c) 2006-2007 Tobias Doerffel + * Copyright (c) 2006-2008 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -32,6 +32,7 @@ #include "knob.h" #include "note_play_handle.h" #include "sweep_oscillator.h" +#include "automatable_model_templates.h" #undef SINGLE_SOURCE_COMPILE #include "embed.cpp" @@ -57,58 +58,13 @@ plugin::descriptor kicker_plugin_descriptor = kickerInstrument::kickerInstrument( instrumentTrack * _instrument_track ) : - instrument( _instrument_track, &kicker_plugin_descriptor ) + instrument( _instrument_track, &kicker_plugin_descriptor ), + m_startFreqModel( 150.0f, 5.0f, 1000.0f, 1.0f, this ), + m_endFreqModel( 40.0f, 5.0f, 1000.0f, 1.0f, this ), + m_decayModel( 120.0f, 5.0f, 1000.0f, 1.0f, this ), + m_distModel( 0.8f, 0.0f, 100.0f, 0.1f, this ), + m_gainModel( 1.0f, 0.1f, 5.0f, 0.05f, this ) { - QVBoxLayout * vl = new QVBoxLayout( this ); - QHBoxLayout * hl = new QHBoxLayout; - m_startFreqKnob = new knob( knobDark_28, this, tr( "Start frequency" ), - _instrument_track ); - m_startFreqKnob->setRange( 5.0f, 1000.0f, 1.0f ); - m_startFreqKnob->setInitValue( 150.0f ); - m_startFreqKnob->setLabel( tr( "START" ) ); - m_startFreqKnob->setHintText( tr( "Start frequency:" ) + " ", "Hz" ); - - m_endFreqKnob = new knob( knobDark_28, this, tr( "End frequency" ), - _instrument_track ); - m_endFreqKnob->setRange( 5.0f, 1000.0f, 1.0f ); - m_endFreqKnob->setInitValue( 40.0f ); - m_endFreqKnob->setLabel( tr( "END" ) ); - m_endFreqKnob->setHintText( tr( "End frequency:" ) + " ", "Hz" ); - - m_decayKnob = new knob( knobDark_28, this, tr( "Decay" ), - _instrument_track ); - m_decayKnob->setRange( 5.0f, 1000.0f, 1.0f ); - m_decayKnob->setInitValue( 120.0f ); - m_decayKnob->setLabel( tr( "DECAY" ) ); - m_decayKnob->setHintText( tr( "Decay:" ) + " ", "ms" ); - - m_distKnob = new knob( knobDark_28, this, tr( "Distortion" ), - _instrument_track ); - m_distKnob->setRange( 0.0f, 100.0f, 0.1f ); - m_distKnob->setInitValue( 0.8f ); - m_distKnob->setLabel( tr( "DIST" ) ); - m_distKnob->setHintText( tr( "Distortion:" ) + " ", "" ); - - m_gainKnob = new knob( knobDark_28, this, tr( "Gain" ), - _instrument_track ); - m_gainKnob->setRange( 0.1f, 5.0f, 0.05f ); - m_gainKnob->setInitValue( 1.0f ); - m_gainKnob->setLabel( tr( "GAIN" ) ); - m_gainKnob->setHintText( tr( "Gain:" ) + " ", "" ); - - hl->addWidget( m_startFreqKnob ); - hl->addWidget( m_endFreqKnob ); - hl->addWidget( m_decayKnob ); - hl->addWidget( m_distKnob ); - hl->addWidget( m_gainKnob ); - - vl->addLayout( hl ); - - setAutoFillBackground( TRUE ); - QPalette pal; - pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( - "artwork" ) ); - setPalette( pal ); } @@ -124,11 +80,11 @@ kickerInstrument::~kickerInstrument() void kickerInstrument::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - m_startFreqKnob->saveSettings( _doc, _this, "startfreq" ); - m_endFreqKnob->saveSettings( _doc, _this, "endfreq" ); - m_decayKnob->saveSettings( _doc, _this, "decay" ); - m_distKnob->saveSettings( _doc, _this, "dist" ); - m_gainKnob->saveSettings( _doc, _this, "gain" ); + m_startFreqModel.saveSettings( _doc, _this, "startfreq" ); + m_endFreqModel.saveSettings( _doc, _this, "endfreq" ); + m_decayModel.saveSettings( _doc, _this, "decay" ); + m_distModel.saveSettings( _doc, _this, "dist" ); + m_gainModel.saveSettings( _doc, _this, "gain" ); } @@ -136,11 +92,11 @@ void kickerInstrument::saveSettings( QDomDocument & _doc, void kickerInstrument::loadSettings( const QDomElement & _this ) { - m_startFreqKnob->loadSettings( _this, "startfreq" ); - m_endFreqKnob->loadSettings( _this, "endfreq" ); - m_decayKnob->loadSettings( _this, "decay" ); - m_distKnob->loadSettings( _this, "dist" ); - m_gainKnob->loadSettings( _this, "gain" ); + m_startFreqModel.loadSettings( _this, "startfreq" ); + m_endFreqModel.loadSettings( _this, "endfreq" ); + m_decayModel.loadSettings( _this, "decay" ); + m_distModel.loadSettings( _this, "dist" ); + m_gainModel.loadSettings( _this, "gain" ); } @@ -160,15 +116,15 @@ typedef sweepOscillator > sweepOsc; void kickerInstrument::playNote( notePlayHandle * _n, bool ) { - const float decfr = m_decayKnob->value() * + const float decfr = m_decayModel.value() * engine::getMixer()->sampleRate() / 1000.0f; const f_cnt_t tfp = _n->totalFramesPlayed(); if ( tfp == 0 ) { _n->m_pluginData = new sweepOsc( - distFX( m_distKnob->value(), - m_gainKnob->value() ) ); + distFX( m_distModel.value(), + m_gainModel.value() ) ); } else if( tfp > decfr && !_n->released() ) { @@ -176,7 +132,7 @@ void kickerInstrument::playNote( notePlayHandle * _n, bool ) } //const float freq = getInstrumentTrack()->frequency( _n ) / 2; - const float fdiff = m_endFreqKnob->value() - m_startFreqKnob->value(); + const float fdiff = m_endFreqModel.value() - m_startFreqModel.value(); /* const fpp_t frames = _n->released() ? tMax( tMin( desiredReleaseFrames() - _n->releaseFramesDone(), @@ -184,8 +140,8 @@ void kickerInstrument::playNote( notePlayHandle * _n, bool ) : engine::getMixer()->framesPerAudioBuffer();*/ const fpp_t frames = _n->framesLeftForCurrentPeriod(); - const float f1 = m_startFreqKnob->value() + tfp * fdiff / decfr; - const float f2 = m_startFreqKnob->value() + (frames+tfp-1)*fdiff/decfr; + const float f1 = m_startFreqModel.value() + tfp * fdiff / decfr; + const float f2 = m_startFreqModel.value() + (frames+tfp-1)*fdiff/decfr; sampleFrame * buf = new sampleFrame[frames]; @@ -222,6 +178,76 @@ void kickerInstrument::deleteNotePluginData( notePlayHandle * _n ) +instrumentView * kickerInstrument::createView( QWidget * _parent ) +{ + return( new kickerInstrumentView( this, _parent ) ); +} + + + + +kickerInstrumentView::kickerInstrumentView( instrument * _instrument, + QWidget * _parent ) : + instrumentView( _instrument, _parent ) +{ + QVBoxLayout * vl = new QVBoxLayout( this ); + QHBoxLayout * hl = new QHBoxLayout; + m_startFreqKnob = new knob( knobDark_28, this, tr( "Start frequency" ) ); + m_startFreqKnob->setLabel( tr( "START" ) ); + m_startFreqKnob->setHintText( tr( "Start frequency:" ) + " ", "Hz" ); + + m_endFreqKnob = new knob( knobDark_28, this, tr( "End frequency" ) ); + m_endFreqKnob->setLabel( tr( "END" ) ); + m_endFreqKnob->setHintText( tr( "End frequency:" ) + " ", "Hz" ); + + m_decayKnob = new knob( knobDark_28, this, tr( "Decay" ) ); + m_decayKnob->setLabel( tr( "DECAY" ) ); + m_decayKnob->setHintText( tr( "Decay:" ) + " ", "ms" ); + + m_distKnob = new knob( knobDark_28, this, tr( "Distortion" ) ); + m_distKnob->setLabel( tr( "DIST" ) ); + m_distKnob->setHintText( tr( "Distortion:" ) + " ", "" ); + + m_gainKnob = new knob( knobDark_28, this, tr( "Gain" ) ); + m_gainKnob->setLabel( tr( "GAIN" ) ); + m_gainKnob->setHintText( tr( "Gain:" ) + " ", "" ); + + hl->addWidget( m_startFreqKnob ); + hl->addWidget( m_endFreqKnob ); + hl->addWidget( m_decayKnob ); + hl->addWidget( m_distKnob ); + hl->addWidget( m_gainKnob ); + + vl->addLayout( hl ); + + setAutoFillBackground( TRUE ); + QPalette pal; + pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( + "artwork" ) ); + setPalette( pal ); +} + + + + +kickerInstrumentView::~kickerInstrumentView() +{ +} + + + + +void kickerInstrumentView::modelChanged( void ) +{ + kickerInstrument * k = castModel(); + m_startFreqKnob->setModel( &k->m_startFreqModel ); + m_endFreqKnob->setModel( &k->m_endFreqModel ); + m_decayKnob->setModel( &k->m_decayModel ); + m_distKnob->setModel( &k->m_distModel ); + m_gainKnob->setModel( &k->m_gainModel ); +} + + diff --git a/plugins/kicker/kicker.h b/plugins/kicker/kicker.h index 2d9782f2d..152a5c746 100644 --- a/plugins/kicker/kicker.h +++ b/plugins/kicker/kicker.h @@ -1,7 +1,7 @@ /* * kicker.h - bassdrum-synthesizer * - * Copyright (c) 2006 Tobias Doerffel + * Copyright (c) 2006-2008 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -27,10 +27,11 @@ #define _KICKER_H #include "instrument.h" +#include "knob.h" +class kickerInstrumentView; class notePlayHandle; -class knob; class kickerInstrument : public instrument @@ -55,13 +56,40 @@ public: return( 512 ); } + virtual instrumentView * createView( QWidget * _parent ); + + private: + knobModel m_startFreqModel; + knobModel m_endFreqModel; + knobModel m_decayModel; + knobModel m_distModel; + knobModel m_gainModel; + + friend class kickerInstrumentView; + +} ; + + + +class kickerInstrumentView : public instrumentView +{ +public: + kickerInstrumentView( instrument * _instrument, + QWidget * _parent ); + virtual ~kickerInstrumentView(); + +private: + virtual void modelChanged( void ); + knob * m_startFreqKnob; knob * m_endFreqKnob; knob * m_decayKnob; knob * m_distKnob; knob * m_gainKnob; + } ; + #endif diff --git a/src/core/instrument.cpp b/src/core/instrument.cpp index a26cd4c8e..48c0312eb 100644 --- a/src/core/instrument.cpp +++ b/src/core/instrument.cpp @@ -3,7 +3,7 @@ /* * instrument.cpp - base-class for all instrument-plugins (synths, samplers etc) * - * Copyright (c) 2005-2007 Tobias Doerffel + * Copyright (c) 2005-2008 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -34,12 +34,10 @@ instrument::instrument( instrumentTrack * _instrument_track, const descriptor * _descriptor ) : - QWidget( _instrument_track->tabWidgetParent() ), plugin( _descriptor ), + model( /* _instrument_track */ NULL ), m_instrumentTrack( _instrument_track ) { - setFixedSize( 250, 250 ); - m_instrumentTrack->setWindowIcon( *getDescriptor()->logo ); } @@ -107,6 +105,16 @@ bool instrument::isFromTrack( const track * _track ) const +instrumentView * instrument::createEditor( QWidget * _parent ) +{ + instrumentView * i = createView( _parent ); + i->setModel( this ); + return( i ); +} + + + + void instrument::applyRelease( sampleFrame * buf, const notePlayHandle * _n ) { const fpp_t frames = _n->framesLeftForCurrentPeriod(); @@ -128,4 +136,43 @@ void instrument::applyRelease( sampleFrame * buf, const notePlayHandle * _n ) } } + + + + + + + +instrumentView::instrumentView( instrument * _instrument, QWidget * _parent ) : + QWidget( _parent ), + modelView() +{ + setModel( _instrument ); + setFixedSize( 250, 250 ); +} + + + + +instrumentView::~instrumentView() +{ +} + + + +void instrumentView::setModel( ::model * _model, bool ) +{ + if( dynamic_cast( _model ) != NULL ) + { + modelView::setModel( _model ); + if( dynamic_cast( parentWidget() ) != NULL ) + { + dynamic_cast( parentWidget() )-> + setWindowIcon( *( model()-> + getDescriptor()->logo ) ); + } + } +} + + #endif diff --git a/src/tracks/instrument_track.cpp b/src/tracks/instrument_track.cpp index f9296a4c2..ca5a1344e 100644 --- a/src/tracks/instrument_track.cpp +++ b/src/tracks/instrument_track.cpp @@ -4,7 +4,7 @@ * instrument_track.cpp - implementation of instrument-track-class * (window + data-structures) * - * Copyright (c) 2004-2007 Tobias Doerffel + * Copyright (c) 2004-2008 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -1040,7 +1040,8 @@ void instrumentTrack::loadTrackSpecificSettings( const QDomElement & _this ) m_instrument->restoreState( node.toElement() ); } - m_tabWidget->addTab( m_instrument, + m_tabWidget->addTab( m_instrument-> + createEditor( m_tabWidget ), tr( "PLUGIN" ), 0 ); } } @@ -1075,7 +1076,8 @@ instrument * instrumentTrack::loadInstrument( const QString & _plugin_name ) m_instrument = instrument::instantiate( _plugin_name, this ); engine::getMixer()->unlock(); - m_tabWidget->addTab( m_instrument, tr( "PLUGIN" ), 0 ); + m_tabWidget->addTab( m_instrument->createEditor( m_tabWidget ), + tr( "PLUGIN" ), 0 ); m_tabWidget->setActiveTab( 0 ); m_tswInstrumentTrackButton->update();