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:
Danny McRae
2006-08-09 00:49:22 +00:00
parent 08c166b4d9
commit ccb5a4ea77
16 changed files with 635 additions and 76 deletions

View File

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

View File

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

View File

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

View File

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

View File

@@ -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() )
{

View File

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

View File

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

View File

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