123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737 |
- /*
- * TripleOscillator.cpp - powerful instrument with three oscillators
- *
- * Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
- *
- * This file is part of LMMS - https://lmms.io
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program (see COPYING); if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- */
-
- #include <QDomDocument>
- #include <QBitmap>
- #include <QPainter>
- #include "TripleOscillator.h"
- #include "AutomatableButton.h"
- #include "debug.h"
- #include "Engine.h"
- #include "InstrumentTrack.h"
- #include "Knob.h"
- #include "Mixer.h"
- #include "NotePlayHandle.h"
- #include "PixmapButton.h"
- #include "SampleBuffer.h"
- #include "ToolTip.h"
- #include "embed.h"
- #include "plugin_export.h"
- extern "C"
- {
- Plugin::Descriptor PLUGIN_EXPORT tripleoscillator_plugin_descriptor =
- {
- STRINGIFY( PLUGIN_NAME ),
- "TripleOscillator",
- QT_TRANSLATE_NOOP( "PluginBrowser",
- "Three powerful oscillators you can modulate "
- "in several ways" ),
- "Tobias Doerffel <tobydox/at/users.sf.net>",
- 0x0110,
- Plugin::Instrument,
- new PluginPixmapLoader( "logo" ),
- NULL,
- NULL
- } ;
- }
- OscillatorObject::OscillatorObject( Model * _parent, int _idx ) :
- Model( _parent ),
- m_volumeModel( DefaultVolume / NUM_OF_OSCILLATORS, MinVolume,
- MaxVolume, 1.0f, this, tr( "Osc %1 volume" ).arg( _idx+1 ) ),
- m_panModel( DefaultPanning, PanningLeft, PanningRight, 1.0f, this,
- tr( "Osc %1 panning" ).arg( _idx+1 ) ),
- m_coarseModel( -_idx*KeysPerOctave,
- -2 * KeysPerOctave, 2 * KeysPerOctave, 1.0f, this,
- tr( "Osc %1 coarse detuning" ).arg( _idx+1 ) ),
- m_fineLeftModel( 0.0f, -100.0f, 100.0f, 1.0f, this,
- tr( "Osc %1 fine detuning left" ).arg( _idx+1 ) ),
- m_fineRightModel( 0.0f, -100.0f, 100.0f, 1.0f, this,
- tr( "Osc %1 fine detuning right" ).arg( _idx + 1 ) ),
- m_phaseOffsetModel( 0.0f, 0.0f, 360.0f, 1.0f, this,
- tr( "Osc %1 phase-offset" ).arg( _idx+1 ) ),
- m_stereoPhaseDetuningModel( 0.0f, 0.0f, 360.0f, 1.0f, this,
- tr( "Osc %1 stereo phase-detuning" ).arg( _idx+1 ) ),
- m_waveShapeModel( Oscillator::SineWave, 0,
- Oscillator::NumWaveShapes-1, this,
- tr( "Osc %1 wave shape" ).arg( _idx+1 ) ),
- m_modulationAlgoModel( Oscillator::SignalMix, 0,
- Oscillator::NumModulationAlgos-1, this,
- tr( "Modulation type %1" ).arg( _idx+1 ) ),
- m_sampleBuffer( new SampleBuffer ),
- m_volumeLeft( 0.0f ),
- m_volumeRight( 0.0f ),
- m_detuningLeft( 0.0f ),
- m_detuningRight( 0.0f ),
- m_phaseOffsetLeft( 0.0f ),
- m_phaseOffsetRight( 0.0f )
- {
- // Connect knobs with Oscillators' inputs
- connect( &m_volumeModel, SIGNAL( dataChanged() ),
- this, SLOT( updateVolume() ), Qt::DirectConnection );
- connect( &m_panModel, SIGNAL( dataChanged() ),
- this, SLOT( updateVolume() ), Qt::DirectConnection );
- updateVolume();
- connect( &m_coarseModel, SIGNAL( dataChanged() ),
- this, SLOT( updateDetuningLeft() ), Qt::DirectConnection );
- connect( &m_coarseModel, SIGNAL( dataChanged() ),
- this, SLOT( updateDetuningRight() ), Qt::DirectConnection );
- connect( &m_fineLeftModel, SIGNAL( dataChanged() ),
- this, SLOT( updateDetuningLeft() ), Qt::DirectConnection );
- connect( &m_fineRightModel, SIGNAL( dataChanged() ),
- this, SLOT( updateDetuningRight() ), Qt::DirectConnection );
- updateDetuningLeft();
- updateDetuningRight();
- connect( &m_phaseOffsetModel, SIGNAL( dataChanged() ),
- this, SLOT( updatePhaseOffsetLeft() ), Qt::DirectConnection );
- connect( &m_phaseOffsetModel, SIGNAL( dataChanged() ),
- this, SLOT( updatePhaseOffsetRight() ), Qt::DirectConnection );
- connect( &m_stereoPhaseDetuningModel, SIGNAL( dataChanged() ),
- this, SLOT( updatePhaseOffsetLeft() ), Qt::DirectConnection );
- updatePhaseOffsetLeft();
- updatePhaseOffsetRight();
- }
- OscillatorObject::~OscillatorObject()
- {
- sharedObject::unref( m_sampleBuffer );
- }
- void OscillatorObject::oscUserDefWaveDblClick()
- {
- QString af = m_sampleBuffer->openAndSetWaveformFile();
- if( af != "" )
- {
- // TODO:
- //ToolTip::add( m_usrWaveBtn, m_sampleBuffer->audioFile() );
- }
- }
- void OscillatorObject::updateVolume()
- {
- if( m_panModel.value() >= 0.0f )
- {
- const float panningFactorLeft = 1.0f - m_panModel.value()
- / (float)PanningRight;
- m_volumeLeft = panningFactorLeft * m_volumeModel.value() /
- 100.0f;
- m_volumeRight = m_volumeModel.value() / 100.0f;
- }
- else
- {
- m_volumeLeft = m_volumeModel.value() / 100.0f;
- const float panningFactorRight = 1.0f + m_panModel.value()
- / (float)PanningRight;
- m_volumeRight = panningFactorRight * m_volumeModel.value() /
- 100.0f;
- }
- }
- void OscillatorObject::updateDetuningLeft()
- {
- m_detuningLeft = powf( 2.0f, ( (float)m_coarseModel.value() * 100.0f
- + (float)m_fineLeftModel.value() ) / 1200.0f )
- / Engine::mixer()->processingSampleRate();
- }
- void OscillatorObject::updateDetuningRight()
- {
- m_detuningRight = powf( 2.0f, ( (float)m_coarseModel.value() * 100.0f
- + (float)m_fineRightModel.value() ) / 1200.0f )
- / Engine::mixer()->processingSampleRate();
- }
- void OscillatorObject::updatePhaseOffsetLeft()
- {
- m_phaseOffsetLeft = ( m_phaseOffsetModel.value() +
- m_stereoPhaseDetuningModel.value() ) / 360.0f;
- }
- void OscillatorObject::updatePhaseOffsetRight()
- {
- m_phaseOffsetRight = m_phaseOffsetModel.value() / 360.0f;
- }
-
- TripleOscillator::TripleOscillator( InstrumentTrack * _instrument_track ) :
- Instrument( _instrument_track, &tripleoscillator_plugin_descriptor )
- {
- for( int i = 0; i < NUM_OF_OSCILLATORS; ++i )
- {
- m_osc[i] = new OscillatorObject( this, i );
- }
- connect( Engine::mixer(), SIGNAL( sampleRateChanged() ),
- this, SLOT( updateAllDetuning() ) );
- }
- TripleOscillator::~TripleOscillator()
- {
- }
- void TripleOscillator::saveSettings( QDomDocument & _doc, QDomElement & _this )
- {
- for( int i = 0; i < NUM_OF_OSCILLATORS; ++i )
- {
- QString is = QString::number( i );
- m_osc[i]->m_volumeModel.saveSettings( _doc, _this, "vol" + is );
- m_osc[i]->m_panModel.saveSettings( _doc, _this, "pan" + is );
- m_osc[i]->m_coarseModel.saveSettings( _doc, _this, "coarse"
- + is );
- m_osc[i]->m_fineLeftModel.saveSettings( _doc, _this, "finel" +
- is );
- m_osc[i]->m_fineRightModel.saveSettings( _doc, _this, "finer" +
- is );
- m_osc[i]->m_phaseOffsetModel.saveSettings( _doc, _this,
- "phoffset" + is );
- m_osc[i]->m_stereoPhaseDetuningModel.saveSettings( _doc, _this,
- "stphdetun" + is );
- m_osc[i]->m_waveShapeModel.saveSettings( _doc, _this,
- "wavetype" + is );
- m_osc[i]->m_modulationAlgoModel.saveSettings( _doc, _this,
- "modalgo" + QString::number( i+1 ) );
- _this.setAttribute( "userwavefile" + is,
- m_osc[i]->m_sampleBuffer->audioFile() );
- }
- }
- void TripleOscillator::loadSettings( const QDomElement & _this )
- {
- for( int i = 0; i < NUM_OF_OSCILLATORS; ++i )
- {
- const QString is = QString::number( i );
- m_osc[i]->m_volumeModel.loadSettings( _this, "vol" + is );
- m_osc[i]->m_panModel.loadSettings( _this, "pan" + is );
- m_osc[i]->m_coarseModel.loadSettings( _this, "coarse" + is );
- m_osc[i]->m_fineLeftModel.loadSettings( _this, "finel" + is );
- m_osc[i]->m_fineRightModel.loadSettings( _this, "finer" + is );
- m_osc[i]->m_phaseOffsetModel.loadSettings( _this,
- "phoffset" + is );
- m_osc[i]->m_stereoPhaseDetuningModel.loadSettings( _this,
- "stphdetun" + is );
- m_osc[i]->m_waveShapeModel.loadSettings( _this, "wavetype" +
- is );
- m_osc[i]->m_modulationAlgoModel.loadSettings( _this,
- "modalgo" + QString::number( i+1 ) );
- m_osc[i]->m_sampleBuffer->setAudioFile( _this.attribute(
- "userwavefile" + is ) );
- }
- }
- QString TripleOscillator::nodeName() const
- {
- return( tripleoscillator_plugin_descriptor.name );
- }
- void TripleOscillator::playNote( NotePlayHandle * _n,
- sampleFrame * _working_buffer )
- {
- if( _n->totalFramesPlayed() == 0 || _n->m_pluginData == NULL )
- {
- Oscillator * oscs_l[NUM_OF_OSCILLATORS];
- Oscillator * oscs_r[NUM_OF_OSCILLATORS];
- for( int i = NUM_OF_OSCILLATORS - 1; i >= 0; --i )
- {
- // the last oscs needs no sub-oscs...
- if( i == NUM_OF_OSCILLATORS - 1 )
- {
- oscs_l[i] = new Oscillator(
- &m_osc[i]->m_waveShapeModel,
- &m_osc[i]->m_modulationAlgoModel,
- _n->frequency(),
- m_osc[i]->m_detuningLeft,
- m_osc[i]->m_phaseOffsetLeft,
- m_osc[i]->m_volumeLeft );
- oscs_r[i] = new Oscillator(
- &m_osc[i]->m_waveShapeModel,
- &m_osc[i]->m_modulationAlgoModel,
- _n->frequency(),
- m_osc[i]->m_detuningRight,
- m_osc[i]->m_phaseOffsetRight,
- m_osc[i]->m_volumeRight );
- }
- else
- {
- oscs_l[i] = new Oscillator(
- &m_osc[i]->m_waveShapeModel,
- &m_osc[i]->m_modulationAlgoModel,
- _n->frequency(),
- m_osc[i]->m_detuningLeft,
- m_osc[i]->m_phaseOffsetLeft,
- m_osc[i]->m_volumeLeft,
- oscs_l[i + 1] );
- oscs_r[i] = new Oscillator(
- &m_osc[i]->m_waveShapeModel,
- &m_osc[i]->m_modulationAlgoModel,
- _n->frequency(),
- m_osc[i]->m_detuningRight,
- m_osc[i]->m_phaseOffsetRight,
- m_osc[i]->m_volumeRight,
- oscs_r[i + 1] );
- }
- oscs_l[i]->setUserWave( m_osc[i]->m_sampleBuffer );
- oscs_r[i]->setUserWave( m_osc[i]->m_sampleBuffer );
- }
- _n->m_pluginData = new oscPtr;
- static_cast<oscPtr *>( _n->m_pluginData )->oscLeft = oscs_l[0];
- static_cast< oscPtr *>( _n->m_pluginData )->oscRight =
- oscs_r[0];
- }
- Oscillator * osc_l = static_cast<oscPtr *>( _n->m_pluginData )->oscLeft;
- Oscillator * osc_r = static_cast<oscPtr *>( _n->m_pluginData )->oscRight;
- const fpp_t frames = _n->framesLeftForCurrentPeriod();
- const f_cnt_t offset = _n->noteOffset();
- osc_l->update( _working_buffer + offset, frames, 0 );
- osc_r->update( _working_buffer + offset, frames, 1 );
- applyFadeIn(_working_buffer, _n);
- applyRelease( _working_buffer, _n );
- instrumentTrack()->processAudioBuffer( _working_buffer, frames + offset, _n );
- }
- void TripleOscillator::deleteNotePluginData( NotePlayHandle * _n )
- {
- delete static_cast<Oscillator *>( static_cast<oscPtr *>(
- _n->m_pluginData )->oscLeft );
- delete static_cast<Oscillator *>( static_cast<oscPtr *>(
- _n->m_pluginData )->oscRight );
- delete static_cast<oscPtr *>( _n->m_pluginData );
- }
- PluginView * TripleOscillator::instantiateView( QWidget * _parent )
- {
- return new TripleOscillatorView( this, _parent );
- }
- void TripleOscillator::updateAllDetuning()
- {
- for( int i = 0; i < NUM_OF_OSCILLATORS; ++i )
- {
- m_osc[i]->updateDetuningLeft();
- m_osc[i]->updateDetuningRight();
- }
- }
- class TripleOscKnob : public Knob
- {
- public:
- TripleOscKnob( QWidget * _parent ) :
- Knob( knobStyled, _parent )
- {
- setFixedSize( 28, 35 );
- }
- };
- // 82, 109
- TripleOscillatorView::TripleOscillatorView( Instrument * _instrument,
- QWidget * _parent ) :
- InstrumentViewFixedSize( _instrument, _parent )
- {
- setAutoFillBackground( true );
- QPalette pal;
- pal.setBrush( backgroundRole(),
- PLUGIN_NAME::getIconPixmap( "artwork" ) );
- setPalette( pal );
- const int mod_x = 66;
- const int mod1_y = 58;
- const int mod2_y = 75;
- const int osc_y = 109;
- const int osc_h = 52;
- // TODO: clean rewrite using layouts and all that...
- PixmapButton * pm_osc1_btn = new PixmapButton( this, NULL );
- pm_osc1_btn->move( mod_x, mod1_y );
- pm_osc1_btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
- "pm_active" ) );
- pm_osc1_btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
- "pm_inactive" ) );
- ToolTip::add( pm_osc1_btn, tr( "Modulate phase of oscillator 1 by oscillator 2" ) );
- PixmapButton * am_osc1_btn = new PixmapButton( this, NULL );
- am_osc1_btn->move( mod_x + 35, mod1_y );
- am_osc1_btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
- "am_active" ) );
- am_osc1_btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
- "am_inactive" ) );
- ToolTip::add( am_osc1_btn, tr( "Modulate amplitude of oscillator 1 by oscillator 2" ) );
- PixmapButton * mix_osc1_btn = new PixmapButton( this, NULL );
- mix_osc1_btn->move( mod_x + 70, mod1_y );
- mix_osc1_btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
- "mix_active" ) );
- mix_osc1_btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
- "mix_inactive" ) );
- ToolTip::add( mix_osc1_btn, tr( "Mix output of oscillators 1 & 2" ) );
- PixmapButton * sync_osc1_btn = new PixmapButton( this, NULL );
- sync_osc1_btn->move( mod_x + 105, mod1_y );
- sync_osc1_btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
- "sync_active" ) );
- sync_osc1_btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
- "sync_inactive" ) );
- ToolTip::add( sync_osc1_btn, tr( "Synchronize oscillator 1 with "
- "oscillator 2" ) );
- PixmapButton * fm_osc1_btn = new PixmapButton( this, NULL );
- fm_osc1_btn->move( mod_x + 140, mod1_y );
- fm_osc1_btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
- "fm_active" ) );
- fm_osc1_btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
- "fm_inactive" ) );
- ToolTip::add( fm_osc1_btn, tr( "Modulate frequency of oscillator 1 by oscillator 2" ) );
- m_mod1BtnGrp = new automatableButtonGroup( this );
- m_mod1BtnGrp->addButton( pm_osc1_btn );
- m_mod1BtnGrp->addButton( am_osc1_btn );
- m_mod1BtnGrp->addButton( mix_osc1_btn );
- m_mod1BtnGrp->addButton( sync_osc1_btn );
- m_mod1BtnGrp->addButton( fm_osc1_btn );
- PixmapButton * pm_osc2_btn = new PixmapButton( this, NULL );
- pm_osc2_btn->move( mod_x, mod2_y );
- pm_osc2_btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
- "pm_active" ) );
- pm_osc2_btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
- "pm_inactive" ) );
- ToolTip::add( pm_osc2_btn, tr( "Modulate phase of oscillator 2 by oscillator 3" ) );
- PixmapButton * am_osc2_btn = new PixmapButton( this, NULL );
- am_osc2_btn->move( mod_x + 35, mod2_y );
- am_osc2_btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
- "am_active" ) );
- am_osc2_btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
- "am_inactive" ) );
- ToolTip::add( am_osc2_btn, tr( "Modulate amplitude of oscillator 2 by oscillator 3" ) );
- PixmapButton * mix_osc2_btn = new PixmapButton( this, NULL );
- mix_osc2_btn->move( mod_x + 70, mod2_y );
- mix_osc2_btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
- "mix_active" ) );
- mix_osc2_btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
- "mix_inactive" ) );
- ToolTip::add( mix_osc2_btn, tr("Mix output of oscillators 2 & 3" ) );
- PixmapButton * sync_osc2_btn = new PixmapButton( this, NULL );
- sync_osc2_btn->move( mod_x + 105, mod2_y );
- sync_osc2_btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
- "sync_active" ) );
- sync_osc2_btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
- "sync_inactive" ) );
- ToolTip::add( sync_osc2_btn, tr( "Synchronize oscillator 2 with oscillator 3" ) );
- PixmapButton * fm_osc2_btn = new PixmapButton( this, NULL );
- fm_osc2_btn->move( mod_x + 140, mod2_y );
- fm_osc2_btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
- "fm_active" ) );
- fm_osc2_btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
- "fm_inactive" ) );
- ToolTip::add( fm_osc2_btn, tr( "Modulate frequency of oscillator 2 by oscillator 3" ) );
- m_mod2BtnGrp = new automatableButtonGroup( this );
- m_mod2BtnGrp->addButton( pm_osc2_btn );
- m_mod2BtnGrp->addButton( am_osc2_btn );
- m_mod2BtnGrp->addButton( mix_osc2_btn );
- m_mod2BtnGrp->addButton( sync_osc2_btn );
- m_mod2BtnGrp->addButton( fm_osc2_btn );
- for( int i = 0; i < NUM_OF_OSCILLATORS; ++i )
- {
- int knob_y = osc_y + i * osc_h;
- // setup volume-knob
- Knob * vk = new Knob( knobStyled, this );
- vk->setVolumeKnob( true );
- vk->setFixedSize( 28, 35 );
- vk->move( 6, knob_y );
- vk->setHintText( tr( "Osc %1 volume:" ).arg(
- i+1 ), "%" );
- // setup panning-knob
- Knob * pk = new TripleOscKnob( this );
- pk->move( 35, knob_y );
- pk->setHintText( tr("Osc %1 panning:").arg( i + 1 ), "" );
- // setup coarse-knob
- Knob * ck = new TripleOscKnob( this );
- ck->move( 82, knob_y );
- ck->setHintText( tr( "Osc %1 coarse detuning:" ).arg( i + 1 )
- , " " + tr( "semitones" ) );
- // setup knob for left fine-detuning
- Knob * flk = new TripleOscKnob( this );
- flk->move( 111, knob_y );
- flk->setHintText( tr( "Osc %1 fine detuning left:" ).
- arg( i + 1 ),
- " " + tr( "cents" ) );
- // setup knob for right fine-detuning
- Knob * frk = new TripleOscKnob( this );
- frk->move( 140, knob_y );
- frk->setHintText( tr( "Osc %1 fine detuning right:" ).
- arg( i + 1 ),
- " " + tr( "cents" ) );
- // setup phase-offset-knob
- Knob * pok = new TripleOscKnob( this );
- pok->move( 188, knob_y );
- pok->setHintText( tr( "Osc %1 phase-offset:" ).
- arg( i + 1 ),
- " " + tr( "degrees" ) );
- // setup stereo-phase-detuning-knob
- Knob * spdk = new TripleOscKnob( this );
- spdk->move( 217, knob_y );
- spdk->setHintText( tr("Osc %1 stereo phase-detuning:" ).
- arg( i + 1 ),
- " " + tr( "degrees" ) );
- int btn_y = 96 + i * osc_h;
- PixmapButton * sin_wave_btn = new PixmapButton( this, NULL );
- sin_wave_btn->move( 128, btn_y );
- sin_wave_btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
- "sin_shape_active" ) );
- sin_wave_btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
- "sin_shape_inactive" ) );
- ToolTip::add( sin_wave_btn,
- tr( "Sine wave" ) );
- PixmapButton * triangle_wave_btn =
- new PixmapButton( this, NULL );
- triangle_wave_btn->move( 143, btn_y );
- triangle_wave_btn->setActiveGraphic(
- PLUGIN_NAME::getIconPixmap( "triangle_shape_active" ) );
- triangle_wave_btn->setInactiveGraphic(
- PLUGIN_NAME::getIconPixmap( "triangle_shape_inactive" ) );
- ToolTip::add( triangle_wave_btn,
- tr( "Triangle wave") );
- PixmapButton * saw_wave_btn = new PixmapButton( this, NULL );
- saw_wave_btn->move( 158, btn_y );
- saw_wave_btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
- "saw_shape_active" ) );
- saw_wave_btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
- "saw_shape_inactive" ) );
- ToolTip::add( saw_wave_btn,
- tr( "Saw wave" ) );
- PixmapButton * sqr_wave_btn = new PixmapButton( this, NULL );
- sqr_wave_btn->move( 173, btn_y );
- sqr_wave_btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
- "square_shape_active" ) );
- sqr_wave_btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
- "square_shape_inactive" ) );
- ToolTip::add( sqr_wave_btn,
- tr( "Square wave" ) );
- PixmapButton * moog_saw_wave_btn =
- new PixmapButton( this, NULL );
- moog_saw_wave_btn->move( 188, btn_y );
- moog_saw_wave_btn->setActiveGraphic(
- PLUGIN_NAME::getIconPixmap( "moog_saw_shape_active" ) );
- moog_saw_wave_btn->setInactiveGraphic(
- PLUGIN_NAME::getIconPixmap( "moog_saw_shape_inactive" ) );
- ToolTip::add( moog_saw_wave_btn,
- tr( "Moog-like saw wave" ) );
- PixmapButton * exp_wave_btn = new PixmapButton( this, NULL );
- exp_wave_btn->move( 203, btn_y );
- exp_wave_btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
- "exp_shape_active" ) );
- exp_wave_btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
- "exp_shape_inactive" ) );
- ToolTip::add( exp_wave_btn,
- tr( "Exponential wave" ) );
- PixmapButton * white_noise_btn = new PixmapButton( this, NULL );
- white_noise_btn->move( 218, btn_y );
- white_noise_btn->setActiveGraphic(
- PLUGIN_NAME::getIconPixmap( "white_noise_shape_active" ) );
- white_noise_btn->setInactiveGraphic(
- PLUGIN_NAME::getIconPixmap( "white_noise_shape_inactive" ) );
- ToolTip::add( white_noise_btn,
- tr( "White noise" ) );
- PixmapButton * uwb = new PixmapButton( this, NULL );
- uwb->move( 233, btn_y );
- uwb->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
- "usr_shape_active" ) );
- uwb->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
- "usr_shape_inactive" ) );
- ToolTip::add( uwb, tr( "User-defined wave" ) );
- automatableButtonGroup * wsbg =
- new automatableButtonGroup( this );
- wsbg->addButton( sin_wave_btn );
- wsbg->addButton( triangle_wave_btn );
- wsbg->addButton( saw_wave_btn );
- wsbg->addButton( sqr_wave_btn );
- wsbg->addButton( moog_saw_wave_btn );
- wsbg->addButton( exp_wave_btn );
- wsbg->addButton( white_noise_btn );
- wsbg->addButton( uwb );
- m_oscKnobs[i] = OscillatorKnobs( vk, pk, ck, flk, frk, pok,
- spdk, uwb, wsbg );
- }
- }
- TripleOscillatorView::~TripleOscillatorView()
- {
- }
- void TripleOscillatorView::modelChanged()
- {
- TripleOscillator * t = castModel<TripleOscillator>();
- m_mod1BtnGrp->setModel( &t->m_osc[0]->m_modulationAlgoModel );
- m_mod2BtnGrp->setModel( &t->m_osc[1]->m_modulationAlgoModel );
- for( int i = 0; i < NUM_OF_OSCILLATORS; ++i )
- {
- m_oscKnobs[i].m_volKnob->setModel(
- &t->m_osc[i]->m_volumeModel );
- m_oscKnobs[i].m_panKnob->setModel(
- &t->m_osc[i]->m_panModel );
- m_oscKnobs[i].m_coarseKnob->setModel(
- &t->m_osc[i]->m_coarseModel );
- m_oscKnobs[i].m_fineLeftKnob->setModel(
- &t->m_osc[i]->m_fineLeftModel );
- m_oscKnobs[i].m_fineRightKnob->setModel(
- &t->m_osc[i]->m_fineRightModel );
- m_oscKnobs[i].m_phaseOffsetKnob->setModel(
- &t->m_osc[i]->m_phaseOffsetModel );
- m_oscKnobs[i].m_stereoPhaseDetuningKnob->setModel(
- &t->m_osc[i]->m_stereoPhaseDetuningModel );
- m_oscKnobs[i].m_waveShapeBtnGrp->setModel(
- &t->m_osc[i]->m_waveShapeModel );
- connect( m_oscKnobs[i].m_userWaveButton,
- SIGNAL( doubleClicked() ),
- t->m_osc[i], SLOT( oscUserDefWaveDblClick() ) );
- }
- }
- extern "C"
- {
- // necessary for getting instance out of shared lib
- PLUGIN_EXPORT Plugin * lmms_plugin_main( Model* model, void * )
- {
- return new TripleOscillator( static_cast<InstrumentTrack *>( model ) );
- }
- }
|