move or delete effects
partial save and load for effects git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@296 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
@@ -66,7 +66,7 @@ effect::effect( const ladspa_key_t & _key, engine * _engine ) :
|
||||
m_processors = lmms_chnls / m_effectChannels;
|
||||
|
||||
// Categorize the ports, and create the buffers.
|
||||
fpab_t buffer_size = configManager::inst()->value( "mixer", "framesperaudiobuffer" ).toInt();
|
||||
m_bufferSize = configManager::inst()->value( "mixer", "framesperaudiobuffer" ).toInt();
|
||||
m_portCount = m_ladspa->getPortCount( _key );
|
||||
|
||||
for( ch_cnt_t proc = 0; proc < m_processors; proc++ )
|
||||
@@ -87,7 +87,7 @@ effect::effect( const ladspa_key_t & _key, engine * _engine ) :
|
||||
// with some prepackaged plugins that were segfaulting
|
||||
// during cleanup. It was easier to troubleshoot with the
|
||||
// memory management all taking place in one file.
|
||||
p->buffer = new LADSPA_Data[buffer_size];
|
||||
p->buffer = new LADSPA_Data[m_bufferSize];
|
||||
|
||||
if( p->name.upper().contains( "IN" ) && m_ladspa->isPortInput( _key, port ) )
|
||||
{
|
||||
@@ -240,6 +240,8 @@ effect::~effect()
|
||||
return;
|
||||
}
|
||||
|
||||
m_processLock.lock();
|
||||
|
||||
for( ch_cnt_t proc = 0; proc < m_processors; proc++ )
|
||||
{
|
||||
m_ladspa->deactivate( m_key, m_handles[proc] );
|
||||
@@ -253,6 +255,8 @@ effect::~effect()
|
||||
}
|
||||
m_ports.clear();
|
||||
m_handles.clear();
|
||||
|
||||
m_processLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -260,7 +264,7 @@ effect::~effect()
|
||||
|
||||
bool FASTCALL effect::processAudioBuffer( surroundSampleFrame * _buf, const fpab_t _frames )
|
||||
{
|
||||
if( !m_okay || m_noRun || !m_running || m_bypass )
|
||||
if( !m_okay || m_noRun || !m_running || m_bypass || !m_processLock.tryLock() )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
@@ -343,8 +347,9 @@ bool FASTCALL effect::processAudioBuffer( surroundSampleFrame * _buf, const fpab
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether we need to continue processing input.
|
||||
if( out_sum <= ( m_gate * _frames * channel ) )
|
||||
// Check whether we need to continue processing input. Restart the
|
||||
// counter if the threshold has been exceeded.
|
||||
if( out_sum <= ( m_gate ) )
|
||||
{
|
||||
m_bufferCount++;
|
||||
if( m_bufferCount > m_silenceTimeout )
|
||||
@@ -353,7 +358,12 @@ bool FASTCALL effect::processAudioBuffer( surroundSampleFrame * _buf, const fpab
|
||||
m_bufferCount = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bufferCount = 0;
|
||||
}
|
||||
|
||||
m_processLock.unlock();
|
||||
return( m_running );
|
||||
}
|
||||
|
||||
@@ -365,7 +375,9 @@ void FASTCALL effect::setControl( Uint16 _control, LADSPA_Data _value )
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_processLock.lock();
|
||||
m_controls[_control]->value = _value;
|
||||
m_processLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -373,7 +385,9 @@ void FASTCALL effect::setControl( Uint16 _control, LADSPA_Data _value )
|
||||
|
||||
void FASTCALL effect::setGate( float _level )
|
||||
{
|
||||
m_gate = _level;
|
||||
m_processLock.lock();
|
||||
m_gate = _level * _level * m_processors * m_bufferSize;
|
||||
m_processLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -40,11 +40,13 @@ effectChain::effectChain( engine * _engine ):
|
||||
|
||||
effectChain::~ effectChain()
|
||||
{
|
||||
m_processLock.lock();
|
||||
for( Uint32 eff = 0; eff < m_effects.count(); eff++ )
|
||||
{
|
||||
free( m_effects[eff] );
|
||||
}
|
||||
m_effects.clear();
|
||||
m_processLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +54,84 @@ effectChain::~ effectChain()
|
||||
|
||||
void FASTCALL effectChain::appendEffect( effect * _effect )
|
||||
{
|
||||
m_processLock.lock();
|
||||
m_effects.append( _effect );
|
||||
m_processLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FASTCALL effectChain::deleteEffect( effect * _effect )
|
||||
{
|
||||
m_processLock.lock();
|
||||
effect_list_t::iterator which = NULL;
|
||||
for( effect_list_t::iterator it = m_effects.begin(); it != m_effects.end(); it++ )
|
||||
{
|
||||
if( (*it) == _effect )
|
||||
{
|
||||
which = it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( which != NULL )
|
||||
{
|
||||
m_effects.erase( which );
|
||||
}
|
||||
|
||||
m_processLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FASTCALL effectChain::moveDown( effect * _effect )
|
||||
{
|
||||
m_processLock.lock();
|
||||
|
||||
if( _effect != m_effects.last() )
|
||||
{
|
||||
int i = 0;
|
||||
for( effect_list_t::iterator it = m_effects.begin(); it != m_effects.end(); it++, i++ )
|
||||
{
|
||||
if( (*it) == _effect )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
effect * temp = m_effects[i + 1];
|
||||
m_effects[i + 1] = _effect;
|
||||
m_effects[i] = temp;
|
||||
}
|
||||
|
||||
m_processLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FASTCALL effectChain::moveUp( effect * _effect )
|
||||
{
|
||||
m_processLock.lock();
|
||||
|
||||
if( _effect != m_effects.first() )
|
||||
{
|
||||
int i = 0;
|
||||
for( effect_list_t::iterator it = m_effects.begin(); it != m_effects.end(); it++, i++ )
|
||||
{
|
||||
if( (*it) == _effect )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
effect * temp = m_effects[i - 1];
|
||||
m_effects[i - 1] = _effect;
|
||||
m_effects[i] = temp;
|
||||
}
|
||||
|
||||
m_processLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +139,7 @@ void FASTCALL effectChain::appendEffect( effect * _effect )
|
||||
|
||||
bool FASTCALL effectChain::processAudioBuffer( surroundSampleFrame * _buf, const fpab_t _frames )
|
||||
{
|
||||
if( m_bypassed )
|
||||
if( m_bypassed || ! m_processLock.tryLock() )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
@@ -70,6 +149,7 @@ bool FASTCALL effectChain::processAudioBuffer( surroundSampleFrame * _buf, const
|
||||
{
|
||||
more_effects |= (*it)->processAudioBuffer( _buf, _frames );
|
||||
}
|
||||
m_processLock.unlock();
|
||||
return( more_effects );
|
||||
}
|
||||
|
||||
@@ -107,36 +187,8 @@ bool effectChain::isRunning( void )
|
||||
}
|
||||
return( running );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FASTCALL effectChain::swapEffects( effect * _eff1, effect * _eff2 )
|
||||
{
|
||||
Uint32 eff1_loc = m_effects.count();
|
||||
Uint32 eff2_loc = m_effects.count();
|
||||
|
||||
Uint32 count = 0;
|
||||
for( effect_list_t::iterator it = m_effects.begin(); it != m_effects.end(); it++ )
|
||||
{
|
||||
if( (*it) == _eff1 )
|
||||
{
|
||||
eff1_loc = count;
|
||||
}
|
||||
if( (*it) == _eff2 )
|
||||
{
|
||||
eff2_loc = count;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
if( eff1_loc < m_effects.count() && eff2_loc < m_effects.count() )
|
||||
{
|
||||
m_effects[eff1_loc] = _eff2;
|
||||
m_effects[eff2_loc] = _eff1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -87,6 +87,7 @@ effectTabWidget::~effectTabWidget()
|
||||
void effectTabWidget::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
{
|
||||
_this.setAttribute( "fxdisabled", !m_effectsGroupBox->isActive() );
|
||||
m_rack->saveState( _doc, _this );
|
||||
|
||||
}
|
||||
|
||||
@@ -96,6 +97,19 @@ void effectTabWidget::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
void effectTabWidget::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
m_effectsGroupBox->setState( !_this.attribute( "fxdisabled" ).toInt() );
|
||||
|
||||
QDomNode node = _this.firstChild();
|
||||
while( !node.isNull() )
|
||||
{
|
||||
if( node.isElement() )
|
||||
{
|
||||
if( m_rack->nodeName() == node.nodeName() )
|
||||
{
|
||||
m_rack->restoreState( node.toElement() );
|
||||
}
|
||||
}
|
||||
node = node.nextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -33,10 +33,12 @@
|
||||
#ifdef QT4
|
||||
|
||||
#include <QtGui/QLayout>
|
||||
#include <QtGui/QWhatsThis>
|
||||
|
||||
#else
|
||||
|
||||
#include <qlayout.h>
|
||||
#include <qwhatsthis.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -194,14 +196,16 @@ ladspaBrowser::ladspaBrowser( engine * _engine ) :
|
||||
btn_layout->setSpacing( 0 );
|
||||
btn_layout->setMargin( 0 );
|
||||
|
||||
QPushButton * cancel_btn = new QPushButton( embed::getIconPixmap(
|
||||
"cancel" ),
|
||||
tr( "Close" ),
|
||||
buttons );
|
||||
QPushButton * help_btn = new QPushButton( embed::getIconPixmap( "help" ), "", buttons );
|
||||
connect( help_btn, SIGNAL( clicked() ), this, SLOT( displayHelp() ) );
|
||||
|
||||
QPushButton * cancel_btn = new QPushButton( embed::getIconPixmap( "cancel" ), tr( "Close" ), buttons );
|
||||
connect( cancel_btn, SIGNAL( clicked() ), this, SLOT( reject() ) );
|
||||
|
||||
btn_layout->addStretch();
|
||||
btn_layout->addSpacing( 10 );
|
||||
btn_layout->addWidget( help_btn );
|
||||
btn_layout->addSpacing( 10 );
|
||||
btn_layout->addWidget( cancel_btn );
|
||||
btn_layout->addSpacing( 10 );
|
||||
|
||||
@@ -213,6 +217,37 @@ ladspaBrowser::ladspaBrowser( engine * _engine ) :
|
||||
|
||||
show();
|
||||
|
||||
#ifdef QT4
|
||||
this->setWhatsThis(
|
||||
#else
|
||||
QWhatsThis::add( this,
|
||||
#endif
|
||||
tr(
|
||||
"This dialog displays information on all of the LADSPA plugins LMMS was "
|
||||
"able to locate. The plugins are divided into five categories based "
|
||||
"upon an interpretation of the port types and names.\n\n"
|
||||
|
||||
"Available Effects are those that can be used by LMMS. In order for LMMS "
|
||||
"to be able to use an effect, it must, first and foremost, be an effect, "
|
||||
"which is to say, it has to have both input channels and output channels. "
|
||||
"LMMS identifies an input channel as an audio rate port containing 'in' in "
|
||||
"the name. Output channels are identified by the letters 'out'. Furthermore, "
|
||||
"the effect must have the same number of inputs and outputs and be real time "
|
||||
"capable.\n\n"
|
||||
|
||||
"Unavailable Effects are those that were identified as effects, but either "
|
||||
"didn't have the same number of input and output channels or weren't real "
|
||||
"time capable.\n\n"
|
||||
|
||||
"Instruments are plugins for which only output channels were identified.\n\n"
|
||||
|
||||
"Analysis Tools are plugins for which only input channels were identified.\n\n"
|
||||
|
||||
"Don't Knows are plugins for which no input or output channels were "
|
||||
"identified.\n\n"
|
||||
|
||||
"Double clicking any of the plugins will bring up information on the "
|
||||
"ports." ) );
|
||||
|
||||
}
|
||||
|
||||
@@ -255,6 +290,18 @@ void ladspaBrowser::testLADSPA( const ladspa_key_t & _key )
|
||||
|
||||
|
||||
|
||||
|
||||
void ladspaBrowser::displayHelp( void )
|
||||
{
|
||||
#ifdef QT4
|
||||
QWhatsThis::showText( mapToGlobal( rect().bottomRight() ), whatsThis() );
|
||||
#else
|
||||
QWhatsThis::display( QWhatsThis::textFor( this ), mapToGlobal( rect().bottomRight() ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "ladspa_browser.moc"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1091,6 +1091,9 @@ void instrumentTrack::saveTrackSpecificSettings( QDomDocument & _doc,
|
||||
m_envWidget->saveState( _doc, _this );
|
||||
m_arpWidget->saveState( _doc, _this );
|
||||
m_midiWidget->saveState( _doc, _this );
|
||||
#ifdef LADSPA_SUPPORT
|
||||
m_effWidget->saveState( _doc, _this );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1126,6 +1129,12 @@ void instrumentTrack::loadTrackSpecificSettings( const QDomElement & _this )
|
||||
{
|
||||
m_midiWidget->restoreState( node.toElement() );
|
||||
}
|
||||
#ifdef LADSPA_SUPPORT
|
||||
else if( m_effWidget->nodeName() == node.nodeName() )
|
||||
{
|
||||
m_effWidget->restoreState( node.toElement() );
|
||||
}
|
||||
#endif
|
||||
else if( automationPattern::classNodeName()
|
||||
!= node.nodeName() )
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
ladspaControl::ladspaControl( QWidget * _parent, port_desc_t * _port, engine * _engine, instrumentTrack * _track ) :
|
||||
QWidget( _parent, "ladspaControl" ),
|
||||
engineObject( _engine ),
|
||||
journallingObject( _engine ),
|
||||
m_port( _port ),
|
||||
m_toggle( NULL ),
|
||||
m_knob( NULL )
|
||||
@@ -112,6 +112,42 @@ LADSPA_Data ladspaControl::getValue( void )
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void ladspaControl::setValue( LADSPA_Data _value )
|
||||
{
|
||||
switch( m_port->data_type )
|
||||
{
|
||||
case TOGGLED:
|
||||
m_toggle->setChecked( static_cast<bool>( _value ) );
|
||||
break;
|
||||
case INTEGER:
|
||||
m_knob->setValue( static_cast<int>( _value ) );
|
||||
break;
|
||||
case FLOAT:
|
||||
m_knob->setValue( static_cast<float>( _value ) );
|
||||
break;
|
||||
default:
|
||||
printf("ladspaControl::setValue BAD BAD BAD\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FASTCALL ladspaControl::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FASTCALL ladspaControl::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#include "ladspa_control.moc"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -46,6 +46,9 @@
|
||||
#include <qcursor.h>
|
||||
#include <qcolor.h>
|
||||
|
||||
#define addSeparator insertSeparator
|
||||
#define addMenu insertItem
|
||||
|
||||
#endif
|
||||
|
||||
#include "rack_plugin.h"
|
||||
@@ -54,15 +57,21 @@
|
||||
#include "ladspa_2_lmms.h"
|
||||
#include "ladspa_control_dialog.h"
|
||||
#include "audio_port.h"
|
||||
#include "embed.h"
|
||||
|
||||
|
||||
rackPlugin::rackPlugin( QWidget * _parent, ladspa_key_t _key, instrumentTrack * _track, engine * _engine ) :
|
||||
QWidget( _parent, "rackPlugin" ),
|
||||
journallingObject( _engine )
|
||||
journallingObject( _engine ),
|
||||
m_track( _track ),
|
||||
m_contextMenu( NULL ),
|
||||
m_key( _key )
|
||||
{
|
||||
m_effect = new effect( _key, eng() );
|
||||
_track->getAudioPort()->getEffects()->appendEffect( m_effect );
|
||||
|
||||
m_name = m_effect->getName();
|
||||
|
||||
setFixedSize( 210, 58 );
|
||||
setPaletteBackgroundColor( QColor( 99, 99, 99 ) );
|
||||
|
||||
@@ -71,6 +80,7 @@ rackPlugin::rackPlugin( QWidget * _parent, ladspa_key_t _key, instrumentTrack *
|
||||
|
||||
m_bypass = new ledCheckBox( "", this, tr( "Turn the effect off" ), eng(), _track );
|
||||
connect( m_bypass, SIGNAL( toggled( bool ) ), this, SLOT( bypassed( bool ) ) );
|
||||
toolTip::add( m_bypass, tr( "On/Off" ) );
|
||||
m_bypass->setChecked( TRUE );
|
||||
m_bypass->move( 3, 3 );
|
||||
#ifdef QT4
|
||||
@@ -94,7 +104,7 @@ rackPlugin::rackPlugin( QWidget * _parent, ladspa_key_t _key, instrumentTrack *
|
||||
QWhatsThis::add( m_wetDry,
|
||||
#endif
|
||||
tr(
|
||||
"The wet/dry knob sets the ratio between the input signal and the effect that shows up in the output." ) );
|
||||
"The Wet/Dry knob sets the ratio between the input signal and the effect that shows up in the output." ) );
|
||||
|
||||
m_autoQuit = new knob( knobBright_26, this, tr( "Decay" ), eng(), _track );
|
||||
connect( m_autoQuit, SIGNAL( valueChanged( float ) ), this, SLOT( setAutoQuit( float ) ) );
|
||||
@@ -109,7 +119,7 @@ rackPlugin::rackPlugin( QWidget * _parent, ladspa_key_t _key, instrumentTrack *
|
||||
QWhatsThis::add( m_autoQuit,
|
||||
#endif
|
||||
tr(
|
||||
"The decay knob controls how many buffers of silence must pass before the plugin stops processing. Smaller values "
|
||||
"The Decay knob controls how many buffers of silence must pass before the plugin stops processing. Smaller values "
|
||||
"will reduce the CPU overhead but run the risk of clipping the tail on delay effects." ) );
|
||||
|
||||
m_gate = new knob( knobBright_26, this, tr( "Decay" ), eng(), _track );
|
||||
@@ -125,7 +135,7 @@ rackPlugin::rackPlugin( QWidget * _parent, ladspa_key_t _key, instrumentTrack *
|
||||
QWhatsThis::add( m_gate,
|
||||
#endif
|
||||
tr(
|
||||
"The gate knob controls the signal level that is considered to be 'silence' while deciding when to stop processing "
|
||||
"The Gate knob controls the signal level that is considered to be 'silence' while deciding when to stop processing "
|
||||
"signals." ) );
|
||||
|
||||
m_editButton = new QPushButton( this, "Controls" );
|
||||
@@ -142,12 +152,47 @@ rackPlugin::rackPlugin( QWidget * _parent, ladspa_key_t _key, instrumentTrack *
|
||||
m_label->setGeometry( 5, 38, 200, 20 );
|
||||
|
||||
m_controlView = new ladspaControlDialog( this, m_effect, eng(), _track );
|
||||
|
||||
#ifdef QT4
|
||||
this->setWhatsThis(
|
||||
#else
|
||||
QWhatsThis::add( this,
|
||||
#endif
|
||||
tr(
|
||||
"Effect plugins function as a chained series of effects where the signal will "
|
||||
"be processed from top to bottom.\n\n"
|
||||
|
||||
"The On/Off switch allows you to bypass a given plugin at any point in "
|
||||
"time.\n\n"
|
||||
|
||||
"The Wet/Dry knob controls the balance between the input signal and the "
|
||||
"effected signal that is the resulting output from the effect. The input "
|
||||
"for one stage is the output from the previous stage, so the 'dry' signal "
|
||||
"for effects lower in the chain contains all of the previous effects.\n\n"
|
||||
|
||||
"The Decay knob controls how long the signal will continue to be processed "
|
||||
"after the notes have been released. The effect will stop processing signals "
|
||||
"when the signal has dropped below a given threshold for a given length of "
|
||||
"time. This knob sets the 'given length of time'. Longer times will require "
|
||||
"more CPU, so this number should be set low for most effects. It needs to be "
|
||||
"bumped up for effects that produce lengthy periods of silence, e.g. "
|
||||
"delays.\n\n"
|
||||
|
||||
"The Gate knob controls the 'given threshold' for the effect's auto shutdown. "
|
||||
"The clock for the 'given length of time' will begin as soon as the processed "
|
||||
"signal level drops below the level specified with this knob.\n\n"
|
||||
|
||||
"The Controls button opens a dialog for editing the effect's parameters.\n\n"
|
||||
|
||||
"Right clicking will bring up a context menu where you can change the order "
|
||||
"in which the effects are processed or delete an effect altogether." ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
rackPlugin::~rackPlugin()
|
||||
{
|
||||
delete m_effect;
|
||||
}
|
||||
|
||||
|
||||
@@ -189,6 +234,109 @@ void rackPlugin::setGate( float _value )
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void rackPlugin::contextMenuEvent( QContextMenuEvent * )
|
||||
{
|
||||
m_contextMenu = new QMenu( this );
|
||||
#ifdef QT4
|
||||
m_contextMenu->setTitle( m_effect->getName() );
|
||||
#else
|
||||
QLabel * caption = new QLabel( "<font color=white><b>" + QString( m_effect->getName() ) + "</b></font>", this );
|
||||
caption->setPaletteBackgroundColor( QColor( 0, 0, 192 ) );
|
||||
caption->setAlignment( Qt::AlignCenter );
|
||||
m_contextMenu->addAction( caption );
|
||||
#endif
|
||||
m_contextMenu->addAction( embed::getIconPixmap( "arp_up_on" ), tr( "Move &up" ), this, SLOT( moveUp() ) );
|
||||
m_contextMenu->addAction( embed::getIconPixmap( "arp_down_on" ), tr( "Move &down" ), this, SLOT( moveDown() ) );
|
||||
m_contextMenu->addSeparator();
|
||||
m_contextMenu->addAction( embed::getIconPixmap( "cancel" ), tr( "&Remove this plugin" ), this, SLOT( deletePlugin() ) );
|
||||
m_contextMenu->addSeparator();
|
||||
m_contextMenu->addAction( embed::getIconPixmap( "help" ), tr( "&Help" ), this, SLOT( displayHelp() ) );
|
||||
m_contextMenu->exec( QCursor::pos() );
|
||||
if( m_contextMenu != NULL )
|
||||
{
|
||||
delete m_contextMenu;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void rackPlugin::moveUp()
|
||||
{
|
||||
if( m_contextMenu != NULL )
|
||||
{
|
||||
delete m_contextMenu;
|
||||
m_contextMenu = NULL;
|
||||
}
|
||||
emit( moveUp( this ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void rackPlugin::moveDown()
|
||||
{
|
||||
if( m_contextMenu != NULL )
|
||||
{
|
||||
delete m_contextMenu;
|
||||
m_contextMenu = NULL;
|
||||
}
|
||||
emit( moveDown( this ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void rackPlugin::deletePlugin()
|
||||
{
|
||||
if( m_contextMenu != NULL )
|
||||
{
|
||||
delete m_contextMenu;
|
||||
m_contextMenu = NULL;
|
||||
}
|
||||
emit( deletePlugin( this ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void rackPlugin::displayHelp( void )
|
||||
{
|
||||
#ifdef QT4
|
||||
QWhatsThis::showText( mapToGlobal( rect().bottomRight() ), whatsThis() );
|
||||
#else
|
||||
QWhatsThis::display( QWhatsThis::textFor( this ), mapToGlobal( rect().bottomRight() ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FASTCALL rackPlugin::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
{
|
||||
_this.setAttribute( "on", m_bypass->isChecked() );
|
||||
_this.setAttribute( "wet", m_wetDry->value() );
|
||||
_this.setAttribute( "autoquit", m_autoQuit->value() );
|
||||
_this.setAttribute( "gate", m_gate->value() );
|
||||
m_controlView->saveState( _doc, _this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FASTCALL rackPlugin::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
m_bypass->setChecked( _this.attribute( "on" ).toInt() );
|
||||
m_wetDry->setValue( _this.attribute( "wet" ).toFloat() );
|
||||
m_autoQuit->setValue( _this.attribute( "autoquit" ).toFloat() );
|
||||
m_gate->setValue( _this.attribute( "gate" ).toFloat() );
|
||||
m_controlView->loadSettings( _this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#include "rack_plugin.moc"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,13 +27,17 @@
|
||||
#include "ladspa_manager.h"
|
||||
#ifdef LADSPA_SUPPORT
|
||||
|
||||
#include <qmessagebox.h>
|
||||
|
||||
#include "rack_view.h"
|
||||
#include "audio_port.h"
|
||||
|
||||
|
||||
rackView::rackView( QWidget * _parent, engine * _engine, instrumentTrack * _track ):
|
||||
QWidget( _parent, "rackView" ),
|
||||
engineObject( _engine ),
|
||||
m_instrumentTrack( _track )
|
||||
journallingObject( _engine ),
|
||||
m_instrumentTrack( _track ),
|
||||
m_ladspa( eng()->getLADSPAManager() )
|
||||
{
|
||||
setFixedSize( 230, 180 );
|
||||
|
||||
@@ -43,25 +47,13 @@ rackView::rackView( QWidget * _parent, engine * _engine, instrumentTrack * _trac
|
||||
m_scrollView->setVScrollBarMode( QScrollView::AlwaysOn );
|
||||
m_mainLayout->addWidget( m_scrollView );
|
||||
|
||||
m_rack = new QVBox( m_scrollView->viewport() );
|
||||
m_scrollView->addChild( m_rack );
|
||||
|
||||
m_rackInserts.setAutoDelete( TRUE );
|
||||
m_lastY = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
rackView::~rackView()
|
||||
{
|
||||
m_rackInserts.setAutoDelete( TRUE );
|
||||
while( ! m_rackInserts.isEmpty() )
|
||||
{
|
||||
m_rackInserts.removeFirst();
|
||||
}
|
||||
|
||||
delete m_rack;
|
||||
delete m_scrollView;
|
||||
delete m_mainLayout;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,13 +61,173 @@ rackView::~rackView()
|
||||
|
||||
void rackView::addPlugin( ladspa_key_t _key )
|
||||
{
|
||||
rackPlugin * plugin = new rackPlugin( m_rack, _key, m_instrumentTrack, eng() );
|
||||
rackPlugin * plugin = new rackPlugin( m_scrollView->viewport(), _key, m_instrumentTrack, eng() );
|
||||
connect( plugin, SIGNAL( moveUp( rackPlugin * ) ), this, SLOT( moveUp( rackPlugin * ) ) );
|
||||
connect( plugin, SIGNAL( moveDown( rackPlugin * ) ), this, SLOT( moveDown( rackPlugin * ) ) );
|
||||
connect( plugin, SIGNAL( deletePlugin( rackPlugin * ) ), this, SLOT( deletePlugin( rackPlugin * ) ) );
|
||||
m_scrollView->addChild( plugin );
|
||||
m_scrollView->moveChild( plugin, 0, m_lastY );
|
||||
plugin->show();
|
||||
m_lastY += plugin->height();
|
||||
m_scrollView->resizeContents( 210, m_lastY );
|
||||
m_rackInserts.append( plugin );
|
||||
m_rackInserts.current()->repaint();
|
||||
m_rackInserts.current()->show();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void rackView::moveUp( rackPlugin * _plugin )
|
||||
{
|
||||
if( _plugin != m_rackInserts.first() )
|
||||
{
|
||||
int i = 0;
|
||||
for( vvector<rackPlugin *>::iterator it = m_rackInserts.begin(); it != m_rackInserts.end(); it++, i++ )
|
||||
{
|
||||
if( (*it) == _plugin )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rackPlugin * temp = m_rackInserts[ i - 1 ];
|
||||
|
||||
m_rackInserts[i - 1] = _plugin;
|
||||
m_rackInserts[i] = temp;
|
||||
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void rackView::moveDown( rackPlugin * _plugin )
|
||||
{
|
||||
m_instrumentTrack->getAudioPort()->getEffects()->moveDown( _plugin->getEffect() );
|
||||
if( _plugin != m_rackInserts.last() )
|
||||
{
|
||||
int i = 0;
|
||||
for( vvector<rackPlugin *>::iterator it = m_rackInserts.begin(); it != m_rackInserts.end(); it++, i++ )
|
||||
{
|
||||
if( (*it) == _plugin )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rackPlugin * temp = m_rackInserts.at( i + 1 );
|
||||
|
||||
m_rackInserts[i + 1] = _plugin;
|
||||
m_rackInserts[i] = temp;
|
||||
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void rackView::deletePlugin( rackPlugin * _plugin )
|
||||
{
|
||||
m_instrumentTrack->getAudioPort()->getEffects()->deleteEffect( _plugin->getEffect() );
|
||||
|
||||
m_scrollView->removeChild( _plugin );
|
||||
|
||||
vvector<rackPlugin *>::iterator loc = NULL;
|
||||
for( vvector<rackPlugin *>::iterator it = m_rackInserts.begin(); it != m_rackInserts.end(); it++ )
|
||||
{
|
||||
if( (*it) == _plugin )
|
||||
{
|
||||
loc = it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( loc != NULL )
|
||||
{
|
||||
delete _plugin;
|
||||
m_rackInserts.erase( loc );
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void rackView::redraw()
|
||||
{
|
||||
m_lastY = 0;
|
||||
for( vvector<rackPlugin *>::iterator it = m_rackInserts.begin(); it != m_rackInserts.end(); it++ )
|
||||
{
|
||||
m_scrollView->moveChild( (*it), 0, m_lastY );
|
||||
m_lastY += (*it)->height();
|
||||
}
|
||||
m_scrollView->resizeContents( 210, m_lastY );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FASTCALL rackView::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
{
|
||||
_this.setAttribute( "plugins", m_rackInserts.count() );
|
||||
for( vvector<rackPlugin *>::iterator it = m_rackInserts.begin(); it != m_rackInserts.end(); it++ )
|
||||
{
|
||||
ladspa_key_t key = (*it)->getKey();
|
||||
_this.setAttribute( "label", key.first );
|
||||
_this.setAttribute( "lib", key.second );
|
||||
_this.setAttribute( "name", m_ladspa->getName( key ) );
|
||||
_this.setAttribute( "maker", m_ladspa->getMaker( key ) );
|
||||
(*it)->saveState( _doc, _this );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FASTCALL rackView::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
int plugin_cnt = _this.attribute( "plugins" ).toInt();
|
||||
QString lib = _this.attribute( "lib" );
|
||||
QString label = _this.attribute( "label" );
|
||||
for( int i = 0; i < plugin_cnt; i++ )
|
||||
{
|
||||
printf( "%s, %s\n", lib.ascii(), label.ascii() );
|
||||
ladspa_key_t key( label, lib );
|
||||
if( m_ladspa->getDescriptor( key ) != NULL )
|
||||
{
|
||||
addPlugin( key );
|
||||
|
||||
QDomNode node = _this.firstChild();
|
||||
while( !node.isNull() )
|
||||
{
|
||||
if( node.isElement() )
|
||||
{
|
||||
if( m_rackInserts.last()->nodeName() == node.nodeName() )
|
||||
{
|
||||
m_rackInserts.last()->restoreState( node.toElement() );
|
||||
}
|
||||
}
|
||||
node = node.nextSibling();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QString name = _this.attribute( "name" );
|
||||
QString maker = _this.attribute( "maker" );
|
||||
QString message = "Couldn't find " + name + " from:\n\n";
|
||||
message += "Library: " + lib + "\n";
|
||||
message += "Label: " + label + "\n";
|
||||
message += "Maker: " + maker;
|
||||
|
||||
QMessageBox::information( 0, tr( "Uknown plugin" ), message, QMessageBox::Ok );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "rack_view.moc"
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user