first attempt at adding effects

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@294 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Danny McRae
2006-08-08 01:26:01 +00:00
parent 7bd0c141d4
commit 95be1a9635
49 changed files with 3198 additions and 155 deletions

View File

@@ -24,12 +24,17 @@
*
*/
#include "ladspa_manager.h"
#ifdef LADSPA_SUPPORT
#include "mixer.h"
#include "audio_device.h"
#include "config_mgr.h"
#endif
#include "audio_port.h"
#include "audio_device.h"
#include "buffer_allocator.h"
audioPort::audioPort( const QString & _name, engine * _engine ) :
engineObject( _engine ),
m_bufferUsage( NONE ),
@@ -47,6 +52,10 @@ audioPort::audioPort( const QString & _name, engine * _engine ) :
eng()->getMixer()->framesPerAudioBuffer() );
eng()->getMixer()->addAudioPort( this );
setExtOutputEnabled( TRUE );
#ifdef LADSPA_SUPPORT
m_frames = configManager::inst()->value( "mixer", "framesperaudiobuffer" ).toInt();
m_effects = new effectChain( eng() );
#endif
}

383
src/core/effect.cpp Normal file
View File

@@ -0,0 +1,383 @@
#ifndef SINGLE_SOURCE_COMPILE
/*
* effect.cpp - class for processing LADSPA effects
*
* Copyright (c) 2006 Danny McRae <khjklujn/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#include "ladspa_manager.h"
#ifdef LADSPA_SUPPORT
#include "qmessagebox.h"
#include "effect.h"
#include "mixer.h"
#include "config_mgr.h"
#include "buffer_allocator.h"
#include "audio_device.h"
#include "ladspa_control.h"
effect::effect( const ladspa_key_t & _key, engine * _engine ) :
engineObject( _engine ),
m_key( _key ),
m_ladspa( _engine->getLADSPAManager() ),
m_output( NULL ),
m_okay( TRUE ),
m_noRun( FALSE ),
m_running( TRUE ),
m_bypass( FALSE ),
m_bufferCount( 0 ),
m_silenceTimeout( 10 ),
m_wetDry( 1.0f ),
m_gate( 0.0f )
{
if( m_ladspa->getDescription( _key ) == NULL )
{
QMessageBox::warning( 0, "Effect", "Uknown LADSPA plugin requested: " + _key.first, QMessageBox::Ok, QMessageBox::NoButton );
m_okay = FALSE;
return;
}
m_name = m_ladspa->getShortName( _key );
// Calculate how many processing units are needed.
ch_cnt_t lmms_chnls = eng()->getMixer()->audioDev()->channels();
m_effectChannels = m_ladspa->getDescription( _key )->inputChannels;
m_processors = lmms_chnls / m_effectChannels;
// Categorize the ports, and create the buffers.
fpab_t buffer_size = configManager::inst()->value( "mixer", "framesperaudiobuffer" ).toInt();
m_portCount = m_ladspa->getPortCount( _key );
for( ch_cnt_t proc = 0; proc < m_processors; proc++ )
{
multi_proc_t ports;
for( Uint16 port = 0; port < m_portCount; port++ )
{
port_desc_t * p = new portDescription;
p->name = m_ladspa->getPortName( _key, port );
p->proc = proc;
p->port_id = port;
// Determine the port's category.
if( m_ladspa->isPortAudio( _key, port ) )
{
// Nasty manual memory management--was having difficulty
// 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];
if( p->name.upper().contains( "IN" ) && m_ladspa->isPortInput( _key, port ) )
{
p->rate = CHANNEL_IN;
}
else if( p->name.upper().contains( "OUT" ) && m_ladspa->isPortOutput( _key, port ) )
{
p->rate = CHANNEL_OUT;
}
else if( m_ladspa->isPortInput( _key, port ) )
{
p->rate = AUDIO_RATE_INPUT;
}
else
{
p->rate = AUDIO_RATE_OUTPUT;
}
}
else
{
p->buffer = new LADSPA_Data;
if( m_ladspa->isPortInput( _key, port ) )
{
p->rate = CONTROL_RATE_INPUT;
}
else
{
p->rate = CONTROL_RATE_OUTPUT;
}
}
if( m_ladspa->isPortToggled( _key, port ) )
{
p->data_type = TOGGLED;
}
else if( m_ladspa->isInteger( _key, port ) )
{
p->data_type = INTEGER;
}
else
{
p->data_type = FLOAT;
}
// Get the range and default values.
p->max = m_ladspa->getUpperBound( _key, port );
if( p->max == NOHINT )
{
p->max = 999999.0f;
}
else if( m_ladspa->areHintsSampleRateDependent( _key, port ) )
{
p->max *= eng()->getMixer()->sampleRate();
}
p->min = m_ladspa->getLowerBound( _key, port );
if( p->min == NOHINT )
{
p->min = -999999.0f;
}
else if( m_ladspa->areHintsSampleRateDependent( _key, port ) )
{
p->min *= eng()->getMixer()->sampleRate();
}
p->def = m_ladspa->getDefaultSetting( _key, port );
if( p->def == NOHINT )
{
if( p->data_type != TOGGLED )
{
p->def = ( p->min + p->max ) / 2.0f;
}
else
{
p->def = 1.0f;
}
}
p->value = p->def;
ports.append( p );
// For convenience, keep a separate list of the ports that are used
// to control the processors.
if( p->rate == AUDIO_RATE_INPUT || p->rate == CONTROL_RATE_INPUT )
{
p->control_id = m_controls.count();
m_controls.append( p );
}
}
m_ports.append( ports );
}
// Instantiate the processing units.
m_descriptor = m_ladspa->getDescriptor( _key );
if( m_descriptor == NULL )
{
QMessageBox::warning( 0, "Effect", "Can't get LADSPA descriptor function: " + _key.first, QMessageBox::Ok, QMessageBox::NoButton );
m_okay = FALSE;
return;
}
if( m_descriptor->run == NULL )
{
QMessageBox::warning( 0, "Effect", "Plugin has no processor: " + _key.first, QMessageBox::Ok, QMessageBox::NoButton );
m_noRun = TRUE;
}
for( ch_cnt_t proc = 0; proc < m_processors; proc++ )
{
LADSPA_Handle effect = m_ladspa->instantiate( _key, eng()->getMixer()->sampleRate() );
if( effect == NULL )
{
QMessageBox::warning( 0, "Effect", "Can't get LADSPA instance: " + _key.first, QMessageBox::Ok, QMessageBox::NoButton );
m_okay = FALSE;
return;
}
m_handles.append( effect );
}
// Connect the ports.
for( ch_cnt_t proc = 0; proc < m_processors; proc++ )
{
for( Uint16 port = 0; port < m_portCount; port++ )
{
if( !m_ladspa->connectPort( _key, m_handles[proc], port, m_ports[proc][port]->buffer ) )
{
QMessageBox::warning( 0, "Effect", "Failed to connect port: " + _key.first, QMessageBox::Ok, QMessageBox::NoButton );
m_noRun = TRUE;
}
}
}
// Activate the processing units.
for( ch_cnt_t proc = 0; proc < m_processors; proc++ )
{
m_ladspa->activate( _key, m_handles[proc] );
}
}
effect::~effect()
{
if( !m_okay )
{
return;
}
for( ch_cnt_t proc = 0; proc < m_processors; proc++ )
{
m_ladspa->deactivate( m_key, m_handles[proc] );
m_ladspa->cleanup( m_key, m_handles[proc] );
for( Uint16 port = 0; port < m_portCount; port++ )
{
free( m_ports[proc][port]->buffer );
free( m_ports[proc][port] );
}
m_ports[proc].clear();
}
m_ports.clear();
m_handles.clear();
}
bool FASTCALL effect::processAudioBuffer( surroundSampleFrame * _buf, const fpab_t _frames )
{
if( !m_okay || m_noRun || !m_running || m_bypass )
{
return( FALSE );
}
// Copy the LMMS audio buffer to the LADSPA input buffer and initialize
// the control ports. Need to change this to handle non-in-place-broken
// plugins--would speed things up to use the same buffer for both
// LMMS and LADSPA.
ch_cnt_t channel = 0;
for( ch_cnt_t proc = 0; proc < m_processors; proc++)
{
for( Uint16 port = 0; port < m_portCount; port++ )
{
switch( m_ports[proc][port]->rate )
{
case CHANNEL_IN:
for( fpab_t frame = 0; frame < _frames; frame++ )
{
m_ports[proc][port]->buffer[frame] = _buf[frame][channel];
}
channel++;
break;
case AUDIO_RATE_INPUT:
m_ports[proc][port]->value = static_cast<LADSPA_Data>( m_ports[proc][port]->control->getValue() );
// This only supports control rate ports, so the audio rates are
// treated as though they were control rate by setting the
// port buffer to all the same value.
for( fpab_t frame = 0; frame < _frames; frame++ )
{
m_ports[proc][port]->buffer[frame] = m_ports[proc][port]->value;
}
break;
case CONTROL_RATE_INPUT:
m_ports[proc][port]->value = static_cast<LADSPA_Data>( m_ports[proc][port]->control->getValue() );
m_ports[proc][port]->buffer[0] = m_ports[proc][port]->value;
break;
case CHANNEL_OUT:
case AUDIO_RATE_OUTPUT:
case CONTROL_RATE_OUTPUT:
break;
default:
break;
}
}
}
// Process the buffers.
for( ch_cnt_t proc = 0; proc < m_processors; proc++ )
{
(m_descriptor->run)(m_handles[proc], _frames);
}
// Copy the LADSPA output buffers to the LMMS buffer.
double out_sum = 0.0;
channel = 0;
for( ch_cnt_t proc = 0; proc < m_processors; proc++)
{
for( Uint16 port = 0; port < m_portCount; port++ )
{
switch( m_ports[proc][port]->rate )
{
case CHANNEL_IN:
case AUDIO_RATE_INPUT:
case CONTROL_RATE_INPUT:
break;
case CHANNEL_OUT:
for( fpab_t frame = 0; frame < _frames; frame++ )
{
_buf[frame][channel] = ( 1.0f - m_wetDry ) * _buf[frame][channel] + m_wetDry * m_ports[proc][port]->buffer[frame];
out_sum += _buf[frame][channel] * _buf[frame][channel];
}
channel++;
break;
case AUDIO_RATE_OUTPUT:
case CONTROL_RATE_OUTPUT:
break;
default:
break;
}
}
}
// Check whether we need to continue processing input.
if( out_sum <= ( m_gate * _frames * channel ) )
{
m_bufferCount++;
if( m_bufferCount > m_silenceTimeout )
{
m_running = FALSE;
m_bufferCount = 0;
}
}
return( m_running );
}
void FASTCALL effect::setControl( Uint16 _control, LADSPA_Data _value )
{
if( !m_okay )
{
return;
}
m_controls[_control]->value = _value;
}
void FASTCALL effect::setGate( float _level )
{
m_gate = _level;
}
#endif
#endif

142
src/core/effect_chain.cpp Normal file
View File

@@ -0,0 +1,142 @@
#ifndef SINGLE_SOURCE_COMPILE
/*
* effect_chain.cpp - class for processing and effects chain
*
* Copyright (c) 2006 Danny McRae <khjklujn/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#include "ladspa_manager.h"
#ifdef LADSPA_SUPPORT
#include "effect_chain.h"
effectChain::effectChain( engine * _engine ):
engineObject( _engine ),
m_bypassed( TRUE )
{
}
effectChain::~ effectChain()
{
for( Uint32 eff = 0; eff < m_effects.count(); eff++ )
{
free( m_effects[eff] );
}
m_effects.clear();
}
void FASTCALL effectChain::appendEffect( effect * _effect )
{
m_effects.append( _effect );
}
bool FASTCALL effectChain::processAudioBuffer( surroundSampleFrame * _buf, const fpab_t _frames )
{
if( m_bypassed )
{
return( FALSE );
}
bool more_effects = FALSE;
for( effect_list_t::iterator it = m_effects.begin(); it != m_effects.end(); it++ )
{
more_effects |= (*it)->processAudioBuffer( _buf, _frames );
}
return( more_effects );
}
void effectChain::setRunning( void )
{
if( m_bypassed )
{
return;
}
for( effect_list_t::iterator it = m_effects.begin(); it != m_effects.end(); it++ )
{
(*it)->setRunning();
}
}
bool effectChain::isRunning( void )
{
if( m_bypassed )
{
return( FALSE );
}
bool running = FALSE;
for( effect_list_t::iterator it = m_effects.begin(); it != m_effects.end() || !running; it++ )
{
running = (*it)->isRunning() && running;
}
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

@@ -0,0 +1,131 @@
#ifndef SINGLE_SOURCE_COMPILE
/*
* effect_tab_widget.cpp - tab-widget in channel-track-window for setting up
* effects
*
* Copyright (c) 2006 Danny McRae <khjklujn/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#include "ladspa_manager.h"
#ifdef LADSPA_SUPPORT
#include "qt3support.h"
#ifdef QT4
#include <Qt/QtXml>
#include <QtGui/QMenu>
#include <QtGui/QToolButton>
#else
#include <qdom.h>
#include <qlistbox.h>
#include <qpopupmenu.h>
#include <qtoolbutton.h>
#endif
#include "effect_tab_widget.h"
#include "instrument_track.h"
#include "group_box.h"
#include "tooltip.h"
#include "embed.h"
#include "select_ladspa_dialog.h"
#include "rack_plugin.h"
#include "audio_port.h"
effectTabWidget::effectTabWidget( instrumentTrack * _instrument_track ) :
QWidget( _instrument_track->tabWidgetParent() ),
journallingObject( _instrument_track->eng() ),
m_instrumentTrack( _instrument_track )
{
m_effectsGroupBox = new groupBox( tr( "EFFECTS CHAIN" ), this, eng(), _instrument_track );
connect( m_effectsGroupBox, SIGNAL( toggled( bool ) ), this, SLOT( setBypass( bool ) ) );
m_effectsGroupBox->setGeometry( 2, 2, 242, 244 );
m_rack = new rackView( m_effectsGroupBox, eng(), _instrument_track );
m_rack->move( 6, 22 );
m_addButton = new QPushButton( m_effectsGroupBox, "Add Effect" );
m_addButton->setText( tr( "Add" ) );
m_addButton->move( 75, 210 );
connect( m_addButton, SIGNAL( clicked( void ) ), this, SLOT( addEffect( void ) ) );
}
effectTabWidget::~effectTabWidget()
{
}
void effectTabWidget::saveSettings( QDomDocument & _doc, QDomElement & _this )
{
_this.setAttribute( "fxdisabled", !m_effectsGroupBox->isActive() );
}
void effectTabWidget::loadSettings( const QDomElement & _this )
{
m_effectsGroupBox->setState( !_this.attribute( "fxdisabled" ).toInt() );
}
void effectTabWidget::addEffect( void )
{
selectLADSPADialog sl( this, eng() );
sl.exec();
if( sl.result() == QDialog::Rejected )
{
return;
}
ladspa_key_t key = sl.getSelection();
m_rack->addPlugin( key );
}
void effectTabWidget::setBypass( bool _state )
{
m_instrumentTrack->getAudioPort()->getEffects()->setBypass( !_state );
}
#include "effect_tab_widget.moc"
#endif
#endif

View File

@@ -37,6 +37,10 @@
#include "project_notes.h"
#include "song_editor.h"
#ifdef LADSPA_SUPPORT
#include "ladspa_2_lmms.h"
#endif
engine::engine( const bool _has_gui ) :
m_hasGUI( _has_gui ),
@@ -57,6 +61,10 @@ engine::engine( const bool _has_gui ) :
m_pianoRoll = new pianoRoll( this );
m_automationEditor = new automationEditor( this );
#ifdef LADSPA_SUPPORT
m_ladspaManager = new ladspa2LMMS( this );
#endif
m_mixer->initDevices();
m_mainWindow->finalize();

262
src/core/ladspa_browser.cpp Normal file
View File

@@ -0,0 +1,262 @@
#ifndef SINGLE_SOURCE_COMPILE
/*
* ladspa_browser.h - dialog to display information about installed LADSPA
* plugins
*
* Copyright (c) 2006 Danny McRae <khjklujn/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#include "ladspa_manager.h"
#ifdef LADSPA_SUPPORT
#include "qt3support.h"
#ifdef QT4
#include <QtGui/QLayout>
#else
#include <qlayout.h>
#endif
#include "ladspa_browser.h"
#include "tab_bar.h"
#include "tab_button.h"
#include "tab_widget.h"
#include "gui_templates.h"
#include "config_mgr.h"
#include "embed.h"
#include "debug.h"
#include "tooltip.h"
#include "ladspa_description.h"
#include "ladspa_port_dialog.h"
#include "effect.h"
#include "audio_device.h"
#include "buffer_allocator.h"
#include "effect_chain.h"
inline void ladspaBrowser::labelWidget( QWidget * _w, const QString & _txt )
{
QLabel * title = new QLabel( _txt, _w );
QFont f = title->font();
f.setBold( TRUE );
title->setFont( pointSize<12>( f ) );
#ifdef LMMS_DEBUG
assert( dynamic_cast<QBoxLayout *>( _w->layout() ) != NULL );
#endif
dynamic_cast<QBoxLayout *>( _w->layout() )->addSpacing( 5 );
dynamic_cast<QBoxLayout *>( _w->layout() )->addWidget( title );
dynamic_cast<QBoxLayout *>( _w->layout() )->addSpacing( 10 );
}
ladspaBrowser::ladspaBrowser( engine * _engine ) :
QDialog(),
engineObject( _engine )
{
setWindowIcon( embed::getIconPixmap( "setup_general" ) );
setWindowTitle( tr( "LADSPA Plugin Browser" ) );
setModal( TRUE );
QVBoxLayout * vlayout = new QVBoxLayout( this );
vlayout->setSpacing( 0 );
vlayout->setMargin( 0 );
QWidget * settings = new QWidget( this );
QHBoxLayout * hlayout = new QHBoxLayout( settings );
hlayout->setSpacing( 0 );
hlayout->setMargin( 0 );
m_tabBar = new tabBar( settings, QBoxLayout::TopToBottom );
m_tabBar->setExclusive( TRUE );
m_tabBar->setFixedWidth( 72 );
QWidget * ws = new QWidget( settings );
ws->setFixedSize( 500, 400 );
QWidget * available = new QWidget( ws );
available->setFixedSize( 500, 340 );
QVBoxLayout * avl_layout = new QVBoxLayout( available );
avl_layout->setSpacing( 0 );
avl_layout->setMargin( 0 );
labelWidget( available, tr( "Available Effects" ) );
ladspaDescription * available_list = new ladspaDescription(available, _engine, VALID );
connect( available_list, SIGNAL( doubleClicked( const ladspa_key_t & ) ),
SLOT( showPorts( const ladspa_key_t & ) ) );
avl_layout->addWidget( available_list );
QWidget * unavailable = new QWidget( ws );
unavailable->setFixedSize( 500, 340 );
QVBoxLayout * unavl_layout = new QVBoxLayout( unavailable );
unavl_layout->setSpacing( 0 );
unavl_layout->setMargin( 0 );
labelWidget( unavailable, tr( "Unavailable Effects" ) );
ladspaDescription * unavailable_list = new ladspaDescription(unavailable, _engine, INVALID );
connect( unavailable_list, SIGNAL( doubleClicked( const ladspa_key_t & ) ),
SLOT( showPorts( const ladspa_key_t & ) ) );
unavl_layout->addWidget( unavailable_list );
QWidget * instruments = new QWidget( ws );
instruments->setFixedSize( 500, 340 );
QVBoxLayout * inst_layout = new QVBoxLayout( instruments );
inst_layout->setSpacing( 0 );
inst_layout->setMargin( 0 );
labelWidget( instruments, tr( "Instruments" ) );
ladspaDescription * instruments_list = new ladspaDescription(instruments, _engine, SOURCE );
connect( instruments_list, SIGNAL( doubleClicked( const ladspa_key_t & ) ),
SLOT( showPorts( const ladspa_key_t & ) ) );
inst_layout->addWidget( instruments_list );
QWidget * analysis = new QWidget( ws );
analysis->setFixedSize( 500, 340 );
QVBoxLayout * anal_layout = new QVBoxLayout( analysis );
anal_layout->setSpacing( 0 );
anal_layout->setMargin( 0 );
labelWidget( analysis, tr( "Analysis Tools" ) );
ladspaDescription * analysis_list = new ladspaDescription(analysis, _engine, SINK );
connect( analysis_list, SIGNAL( doubleClicked( const ladspa_key_t & ) ),
SLOT( showPorts( const ladspa_key_t & ) ) );
anal_layout->addWidget( analysis_list );
QWidget * other = new QWidget( ws );
other->setFixedSize( 500, 340 );
QVBoxLayout * other_layout = new QVBoxLayout( other );
other_layout->setSpacing( 0 );
other_layout->setMargin( 0 );
labelWidget( other, tr( "Don't know" ) );
ladspaDescription * other_list = new ladspaDescription(other, _engine, OTHER );
connect( other_list, SIGNAL( doubleClicked( const ladspa_key_t & ) ),
SLOT( showPorts( const ladspa_key_t & ) ) );
other_layout->addWidget( other_list );
#ifndef QT4
#define setIcon setPixmap
#endif
m_tabBar->addTab( available, tr( "Available Effects" ), 0, FALSE, TRUE
)->setIcon( embed::getIconPixmap( "setup_audio" ) );
m_tabBar->addTab( unavailable, tr( "Unavailable Effects" ), 1, FALSE, TRUE
)->setIcon( embed::getIconPixmap(
"unavailable_sound" ) );
m_tabBar->addTab( instruments, tr( "Instruments" ), 2, FALSE,
TRUE )->setIcon( embed::getIconPixmap(
"setup_midi" ) );
m_tabBar->addTab( analysis, tr( "Analysis Tools" ), 3, FALSE, TRUE
)->setIcon( embed::getIconPixmap( "analysis" ) );
m_tabBar->addTab( other, tr( "Don't know" ), 4, TRUE, TRUE
)->setIcon( embed::getIconPixmap( "uhoh" ) );
#undef setIcon
m_tabBar->setActiveTab( 0 );
hlayout->addWidget( m_tabBar );
hlayout->addSpacing( 10 );
hlayout->addWidget( ws );
hlayout->addSpacing( 10 );
hlayout->addStretch();
QWidget * buttons = new QWidget( this );
QHBoxLayout * btn_layout = new QHBoxLayout( buttons );
btn_layout->setSpacing( 0 );
btn_layout->setMargin( 0 );
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( cancel_btn );
btn_layout->addSpacing( 10 );
vlayout->addWidget( settings );
vlayout->addSpacing( 10 );
vlayout->addWidget( buttons );
vlayout->addSpacing( 10 );
vlayout->addStretch();
show();
}
ladspaBrowser::~ladspaBrowser()
{
}
void ladspaBrowser::showPorts( const ladspa_key_t & _key )
{
ladspaPortDialog ports( _key, eng() );
ports.exec();
}
void ladspaBrowser::testLADSPA( const ladspa_key_t & _key )
{
effect * eff1 = new effect( _key, eng() );
effect * eff2 = new effect( _key, eng() );
effectChain chain( eng() );
chain.appendEffect( eff1 );
chain.appendEffect( eff2 );
fpab_t buf_size = eng()->getMixer()->audioDev()->channels();
surroundSampleFrame * buffer = bufferAllocator::alloc<surroundSampleFrame>( buf_size );
for( Uint8 i = 0; i < 100; i++ )
{
chain.processAudioBuffer( buffer, buf_size );
}
bufferAllocator::free( buffer );
}
#include "ladspa_browser.moc"
#endif
#endif

View File

@@ -0,0 +1,224 @@
#ifndef SINGLE_SOURCE_COMPILE
/*
* ladspa_port_dialog.cpp - dialog to test a LADSPA plugin
*
* Copyright (c) 2006 Danny McRae <khjklujn/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#include "qt3support.h"
#include "ladspa_manager.h"
#ifdef LADSPA_SUPPORT
#ifdef QT4
#include <QtGui/QLayout>
#else
#include <qlayout.h>
#include <qtable.h>
#endif
#include "ladspa_port_dialog.h"
#include "embed.h"
#include "mixer.h"
ladspaPortDialog::ladspaPortDialog( const ladspa_key_t & _key,
engine * _engine ) :
QDialog(),
engineObject( _engine ),
m_key( _key ),
m_ladspa( _engine->getLADSPAManager() )
{
setWindowIcon( embed::getIconPixmap( "ports" ) );
setWindowTitle( "Ports" );
setModal( TRUE );
// setFixedSize( 500, 500 );
QVBoxLayout * vlayout = new QVBoxLayout( this );
vlayout->setSpacing( 0 );
vlayout->setMargin( 0 );
QWidget * settings = new QWidget( this );
Uint16 pc = m_ladspa->getPortCount( m_key );
QTable * display = new QTable( pc, 7, settings );
QStringList ports;
ports.append( tr( "Name" ) );
ports.append( tr( "Rate" ) );
ports.append( tr( "Direction" ) );
ports.append( tr( "Type" ) );
ports.append( tr( "Min < Default < Max" ) );
ports.append( tr( "Logarithmic" ) );
ports.append( tr( "SR Dependent" ) );
QStringList port_nums;
for(Uint16 row = 0; row < pc; row++)
{
port_nums.append( QString::number( row ) );
Uint8 col = 0;
display->setText( row, col, m_ladspa->getPortName( m_key, row ) );
col++;
if( m_ladspa->isPortAudio( m_key, row ) )
{
display->setText( row, col, tr( "Audio" ) );
}
else
{
display->setText( row, col, tr( "Control" ) );
}
col++;
if( m_ladspa->isPortInput( m_key, row ) )
{
display->setText( row, col, tr( "Input" ) );
}
else
{
display->setText( row, col, tr( "Output" ) );
}
col++;
if( m_ladspa->isPortToggled( m_key, row ) )
{
display->setText( row, col, tr( "Toggled" ) );
}
else if( m_ladspa->isInteger( m_key, row ) )
{
display->setText( row, col, tr( "Integer" ) );
}
else
{
display->setText( row, col, tr( "Float" ) );
}
col++;
float min = m_ladspa->getLowerBound( m_key, row );
float max = m_ladspa->getUpperBound( m_key, row );
float def = m_ladspa->getDefaultSetting( m_key, row );
QString range = "";
if( m_ladspa->areHintsSampleRateDependent( m_key, row ) )
{
if( min != NOHINT )
{
min *= eng()->getMixer()->sampleRate();
}
if( max != NOHINT )
{
max *= eng()->getMixer()->sampleRate();
}
}
if( min == NOHINT )
{
range += "-Inf < ";
}
else if( m_ladspa->isInteger( m_key, row ) )
{
range += QString::number( static_cast<int>( min ) ) + " < ";
}
else
{
range += QString::number( min ) + " < ";
}
if( def == NOHINT )
{
range += "None < ";
}
else if( m_ladspa->isInteger( m_key, row ) )
{
range += QString::number( static_cast<int>( def ) ) + " < ";
}
else
{
range += QString::number( def ) + " < ";
}
if( max == NOHINT )
{
range += "Inf";
}
else if( m_ladspa->isInteger( m_key, row ) )
{
range += QString::number( static_cast<int>( max ) );
}
else
{
range += QString::number( max );
}
if( m_ladspa->isPortOutput( m_key, row ) ||
m_ladspa->isPortToggled( m_key, row ) )
{
range = "";
}
display->setText( row, col, range );
col++;
if( m_ladspa->isLogarithmic( m_key, row ) )
{
display->setText( row, col, tr( "Yes" ) );
}
col++;
if( m_ladspa->areHintsSampleRateDependent( m_key, row ) )
{
display->setText( row, col, tr( "Yes" ) );
}
col++;
}
display->setColumnLabels( ports );
display->setRowLabels( port_nums );
display->setReadOnly( true );
for(Uint8 col = 0; col < ports.count(); col++ )
{
display->adjustColumn( col );
}
vlayout->addWidget( settings );
setFixedSize( display->width(), display->height() );
show();
}
ladspaPortDialog::~ ladspaPortDialog()
{
}
#include "ladspa_port_dialog.moc"
#endif
#endif

View File

@@ -81,6 +81,10 @@
#include "project_journal.h"
#include "automation_editor.h"
#ifdef LADSPA_SUPPORT
#include "ladspa_browser.h"
#endif
#if QT_VERSION >= 0x030100
QSplashScreen * mainWindow::s_splashScreen = NULL;
@@ -527,13 +531,26 @@ void mainWindow::finalize( void )
help_menu->addAction( embed::getIconPixmap( "whatsthis" ),
tr( "What's this?" ),
this, SLOT( enterWhatsThisMode() ) );
#ifdef LADSPA_SUPPORT
#ifdef QT4
help_menu->addSeparator();
#else
help_menu->insertSeparator();
#endif
help_menu->addAction( embed::getIconPixmap( "help" ), tr( "LADSPA Plugins..." ),
this, SLOT( ladspaPluginBrowser() ) );
#endif
#ifdef QT4
help_menu->addSeparator();
#else
help_menu->insertSeparator();
#endif
help_menu->addAction( embed::getIconPixmap( "icon" ), tr( "About" ),
this, SLOT( aboutLMMS() ) );
this, SLOT( aboutLMMS() ) );
// setup-dialog opened before?
if( !configManager::inst()->value( "app", "configured" ).toInt() )
@@ -803,12 +820,25 @@ void mainWindow::aboutLMMS( void )
void mainWindow::help( void )
{
QMessageBox::information( this, tr( "Help not available" ),
tr( "Currently there's no help "
"available in LMMS.\n"
"Please visit "
"http://wiki.mindrules.net "
"for documentation on LMMS." ),
QMessageBox::Ok );
tr( "Currently there's no help "
"available in LMMS.\n"
"Please visit "
"http://wiki.mindrules.net "
"for documentation on LMMS." ),
QMessageBox::Ok );
}
void mainWindow::ladspaPluginBrowser( void )
{
// moc for Qt 3.x doesn't recognize preprocessor directives,
// so we can't just block the whole thing out.
#ifdef LADSPA_SUPPORT
ladspaBrowser lb( eng() );
lb.exec();
#endif
}

View File

@@ -278,10 +278,18 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
eng()->getSongEditor()->processNextBuffer();
#ifdef LADSPA_SUPPORT
bool more_effects = FALSE;
#endif
for( vvector<audioPort *>::iterator it = m_audioPorts.begin();
it != m_audioPorts.end(); ++it )
{
#ifdef LADSPA_SUPPORT
more_effects |= ( *it )->processEffects();
if( ( *it )->m_bufferUsage != audioPort::NONE || more_effects )
#else
if( ( *it )->m_bufferUsage != audioPort::NONE )
#endif
{
processBuffer( ( *it )->firstBuffer(),
( *it )->nextFxChannel() );

135
src/lib/ladspa_2_lmms.cpp Normal file
View File

@@ -0,0 +1,135 @@
#ifndef SINGLE_SOURCE_COMPILE
/*
* ladspa_2_lmms.cpp - class that identifies and instantiates LADSPA effects
* for use with LMMS
*
* Copyright (c) 2005 Danny McRae <khjklujn@netscape.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#include "ladspa_manager.h"
#ifdef LADSPA_SUPPORT
#include "ladspa_2_lmms.h"
ladspa2LMMS::ladspa2LMMS( engine * _engine ):
ladspaManager( _engine )
{
l_sortable_plugin_t plugins = getSortedPlugins();
for( l_sortable_plugin_t::iterator it = plugins.begin();
it != plugins.end(); it++ )
{
ladspa_key_t key = (*it).second;
ladspaManagerDescription * desc = getDescription( key );
if( desc->type == SOURCE )
{
m_instruments.append( qMakePair( getName( key ),
key ) );
}
else if( desc->type == TRANSFER &&
( desc->inputChannels == desc->outputChannels &&
( desc->inputChannels == 1 ||
desc->inputChannels == 2 ||
desc->inputChannels == 4 ) &&
isRealTimeCapable( key ) ) )
{
m_validEffects.append( qMakePair( getName( key ),
key ) );
}
else if( desc->type == TRANSFER &&
( desc->inputChannels != desc->outputChannels ||
( desc->inputChannels != 1 &&
desc->inputChannels != 2 &&
desc->inputChannels != 4 ) ||
!isRealTimeCapable( key ) ) )
{
m_invalidEffects.append( qMakePair( getName( key ),
key ) );
}
else if( desc->type == SINK )
{
m_analysisTools.append( qMakePair( getName( key ),
key ) );
}
else if( desc->type == OTHER )
{
m_otherPlugins.append( qMakePair( getName( key ),
key ) );
}
}
}
ladspa2LMMS::~ladspa2LMMS()
{
}
QString ladspa2LMMS::getShortName( const ladspa_key_t & _key )
{
QString name = getName( _key );
if( name.find( "(" ) > 0 )
{
name = name.left( name.find( "(" ) );
}
if( name.find( " - " ) > 0 )
{
name = name.left( name.find( " - " ) );
}
if( name.find( " " ) > 0 )
{
name = name.left( name.find( " " ) );
}
if( name.find( " with ", 0, FALSE ) > 0 )
{
name = name.left( name.find( " with ", 0, FALSE ) );
}
if( name.find( ",", 0, FALSE ) > 0 )
{
name = name.left( name.find( ",", 0, FALSE ) );
}
if( name.length() > 40 )
{
Uint8 i = 40;
while( name[i] != ' ' && i != 0 )
{
i--;
}
name = name.left( i );
}
if( name.length() == 0 )
{
name = "LADSPA Plugin";
}
return( name );
}
#endif
#endif

View File

@@ -53,10 +53,7 @@
ladspaManager * ladspaManager::s_instanceOfMe = NULL;
ladspaManager::ladspaManager( void )
ladspaManager::ladspaManager( engine * _engine )
{
// TODO Need to move the search path definition to the config file to
// have more control over where it tries to find the plugins.
@@ -65,8 +62,13 @@ ladspaManager::ladspaManager( void )
split( ':' );
#else
QStringList ladspaDirectories = QStringList::split( ':',
QString( getenv( "LADSPA_PATH" ) ) );
QString( getenv( "LADSPA_PATH" ) ) );
#endif
//*********DELETE THIS*********
ladspaDirectories.push_back( "/usr/lib/ladspa" );
//*********DELETE THIS*********
// set default-directory if nothing is specified...
if( ladspaDirectories.isEmpty() )
{
@@ -91,51 +93,38 @@ ladspaManager::ladspaManager( void )
#endif
for( QFileInfoList::iterator file = list.begin();
file != list.end(); ++file )
{
{
#ifdef QT4
const QFileInfo & f = *file;
#else
const QFileInfo & f = **file;
#endif
QLibrary plugin_lib( f.absoluteFilePath() );
/* pluginHandle = dlopen( f.absoluteFilePath().
#ifdef QT4
toAscii().constData(),
#else
ascii(),
#endif
RTLD_LAZY );
if( pluginHandle )
{
dlerror();*/
if( plugin_lib.load() == TRUE )
{
LADSPA_Descriptor_Function descriptorFunction =
( LADSPA_Descriptor_Function ) plugin_lib.resolve(
( LADSPA_Descriptor_Function ) plugin_lib.resolve(
"ladspa_descriptor" );
if( /*dlerror() == NULL &&*/
descriptorFunction != NULL )
if( descriptorFunction != NULL )
{
#ifndef QT4
plugin_lib.setAutoUnload( FALSE );
#endif
addPlugins( descriptorFunction,
f.fileName() );
f.fileName() );
}
/* else
{
dlclose( ( void * )
f.absoluteFilePath().
#ifdef QT4
toAscii().constData()
#else
ascii()
#endif
);
}*/
}
}
}
l_ladspa_key_t keys = m_ladspaManagerMap.keys();
for( l_ladspa_key_t::iterator it = keys.begin();
it != keys.end(); it++ )
{
m_sortedPlugins.append( qMakePair( getName( *it ), *it ) );
}
qHeapSort( m_sortedPlugins );
}
@@ -143,20 +132,29 @@ ladspaManager::ladspaManager( void )
ladspaManager::~ladspaManager()
{
// we trust in auto-unloading-mechanisms of OS
/* for( ladspaManagerMapType::Iterator it = m_ladspaManagerMap.begin();
it != m_ladspaManagerMap.end(); ++it )
}
ladspaManagerDescription * ladspaManager::getDescription( const ladspa_key_t &
_plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
dlclose( it.value()->pluginHandle );
return( m_ladspaManagerMap[_plugin] );
}
else
{
return( NULL );
}
m_ladspaManagerMap.clear();*/
}
void FASTCALL ladspaManager::addPlugins(
LADSPA_Descriptor_Function _descriptor_func,
LADSPA_Descriptor_Function _descriptor_func,
const QString & _file )
{
const LADSPA_Descriptor * descriptor;
@@ -168,8 +166,29 @@ void FASTCALL ladspaManager::addPlugins(
new ladspaManagerDescription;
plugIn->descriptorFunction = _descriptor_func;
plugIn->index = pluginIndex;
plugIn->inputChannels = getPluginInputs( descriptor );
plugIn->outputChannels = getPluginOutputs( descriptor );
if( plugIn->inputChannels == 0 && plugIn->outputChannels > 0 )
{
plugIn->type = SOURCE;
}
else if( plugIn->inputChannels > 0 &&
plugIn->outputChannels > 0 )
{
plugIn->type = TRANSFER;
}
else if( plugIn->inputChannels > 0 &&
plugIn->outputChannels == 0 )
{
plugIn->type = SINK;
}
else
{
plugIn->type = OTHER;
}
ladspaKey key( _file, QString( descriptor->Label ) );
ladspa_key_t key( QString( descriptor->Label ), _file );
m_ladspaManagerMap[key] = plugIn;
++pluginIndex;
}
@@ -178,7 +197,63 @@ void FASTCALL ladspaManager::addPlugins(
QString FASTCALL ladspaManager::getLabel( const ladspaKey & _plugin )
Uint16 FASTCALL ladspaManager::getPluginInputs(
const LADSPA_Descriptor * _descriptor )
{
Uint16 inputs = 0;
for( Uint16 port = 0; port < _descriptor->PortCount; port++ )
{
if(
LADSPA_IS_PORT_INPUT( _descriptor->PortDescriptors[port] ) &&
LADSPA_IS_PORT_AUDIO( _descriptor->PortDescriptors[port] ) )
{
QString name = QString( _descriptor->PortNames[port] );
if( name.upper().contains( "IN" ) )
{
inputs++;
}
}
}
return inputs;
}
Uint16 FASTCALL ladspaManager::getPluginOutputs(
const LADSPA_Descriptor * _descriptor )
{
Uint16 outputs = 0;
for( Uint16 port = 0; port < _descriptor->PortCount; port++ )
{
if(
LADSPA_IS_PORT_OUTPUT( _descriptor->PortDescriptors[port] ) &&
LADSPA_IS_PORT_AUDIO( _descriptor->PortDescriptors[port] ) )
{
QString name = QString( _descriptor->PortNames[port] );
if( name.upper().contains( "OUT" ) )
{
outputs++;
}
}
}
return outputs;
}
l_sortable_plugin_t ladspaManager::getSortedPlugins()
{
return( m_sortedPlugins );
}
QString FASTCALL ladspaManager::getLabel( const ladspa_key_t & _plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
@@ -198,7 +273,7 @@ QString FASTCALL ladspaManager::getLabel( const ladspaKey & _plugin )
bool FASTCALL ladspaManager::hasRealTimeDependency( const ladspaKey & _plugin )
bool FASTCALL ladspaManager::hasRealTimeDependency( const ladspa_key_t & _plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
@@ -218,7 +293,7 @@ bool FASTCALL ladspaManager::hasRealTimeDependency( const ladspaKey & _plugin )
bool FASTCALL ladspaManager::isInplaceBroken( const ladspaKey & _plugin )
bool FASTCALL ladspaManager::isInplaceBroken( const ladspa_key_t & _plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
@@ -238,7 +313,7 @@ bool FASTCALL ladspaManager::isInplaceBroken( const ladspaKey & _plugin )
bool FASTCALL ladspaManager::isRealTimeCapable( const ladspaKey & _plugin )
bool FASTCALL ladspaManager::isRealTimeCapable( const ladspa_key_t & _plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
@@ -258,7 +333,7 @@ bool FASTCALL ladspaManager::isRealTimeCapable( const ladspaKey & _plugin )
QString FASTCALL ladspaManager::getName( const ladspaKey & _plugin )
QString FASTCALL ladspaManager::getName( const ladspa_key_t & _plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
@@ -278,7 +353,7 @@ QString FASTCALL ladspaManager::getName( const ladspaKey & _plugin )
QString FASTCALL ladspaManager::getMaker( const ladspaKey & _plugin )
QString FASTCALL ladspaManager::getMaker( const ladspa_key_t & _plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
@@ -298,7 +373,7 @@ QString FASTCALL ladspaManager::getMaker( const ladspaKey & _plugin )
QString FASTCALL ladspaManager::getCopyright( const ladspaKey & _plugin )
QString FASTCALL ladspaManager::getCopyright( const ladspa_key_t & _plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
@@ -318,7 +393,7 @@ QString FASTCALL ladspaManager::getCopyright( const ladspaKey & _plugin )
Uint32 FASTCALL ladspaManager::getPortCount( const ladspaKey & _plugin )
Uint32 FASTCALL ladspaManager::getPortCount( const ladspa_key_t & _plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
@@ -338,7 +413,7 @@ Uint32 FASTCALL ladspaManager::getPortCount( const ladspaKey & _plugin )
bool FASTCALL ladspaManager::isPortInput( const ladspaKey & _plugin,
bool FASTCALL ladspaManager::isPortInput( const ladspa_key_t & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
@@ -362,7 +437,7 @@ bool FASTCALL ladspaManager::isPortInput( const ladspaKey & _plugin,
bool FASTCALL ladspaManager::isPortOutput( const ladspaKey & _plugin,
bool FASTCALL ladspaManager::isPortOutput( const ladspa_key_t & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
@@ -386,7 +461,7 @@ bool FASTCALL ladspaManager::isPortOutput( const ladspaKey & _plugin,
bool FASTCALL ladspaManager::isPortAudio( const ladspaKey & _plugin,
bool FASTCALL ladspaManager::isPortAudio( const ladspa_key_t & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
@@ -410,7 +485,7 @@ bool FASTCALL ladspaManager::isPortAudio( const ladspaKey & _plugin,
bool FASTCALL ladspaManager::isPortControl( const ladspaKey & _plugin,
bool FASTCALL ladspaManager::isPortControl( const ladspa_key_t & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
@@ -435,7 +510,7 @@ bool FASTCALL ladspaManager::isPortControl( const ladspaKey & _plugin,
bool FASTCALL ladspaManager::areHintsSampleRateDependent(
const ladspaKey & _plugin,
const ladspa_key_t & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
@@ -459,7 +534,7 @@ bool FASTCALL ladspaManager::areHintsSampleRateDependent(
float FASTCALL ladspaManager::getLowerBound( const ladspaKey & _plugin,
float FASTCALL ladspaManager::getLowerBound( const ladspa_key_t & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
@@ -478,19 +553,19 @@ float FASTCALL ladspaManager::getLowerBound( const ladspaKey & _plugin,
}
else
{
return( -999e-99 );
return( NOHINT );
}
}
else
{
return( -999e-99 );
return( NOHINT );
}
}
float FASTCALL ladspaManager::getUpperBound( const ladspaKey & _plugin, Uint32 _port )
float FASTCALL ladspaManager::getUpperBound( const ladspa_key_t & _plugin, Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
&& _port < getPortCount( _plugin ) )
@@ -504,23 +579,23 @@ float FASTCALL ladspaManager::getUpperBound( const ladspaKey & _plugin,
descriptor->PortRangeHints[_port].HintDescriptor;
if( LADSPA_IS_HINT_BOUNDED_ABOVE( hintDescriptor ) )
{
return( descriptor->PortRangeHints[_port].LowerBound );
return( descriptor->PortRangeHints[_port].UpperBound );
}
else
{
return( -999e-99 );
return( NOHINT );
}
}
else
{
return( -999e-99 );
return( NOHINT );
}
}
bool FASTCALL ladspaManager::isPortToggled( const ladspaKey & _plugin,
bool FASTCALL ladspaManager::isPortToggled( const ladspa_key_t & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
@@ -544,7 +619,7 @@ bool FASTCALL ladspaManager::isPortToggled( const ladspaKey & _plugin,
float FASTCALL ladspaManager::getDefaultSetting( const ladspaKey & _plugin,
float FASTCALL ladspaManager::getDefaultSetting( const ladspa_key_t & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
@@ -560,7 +635,7 @@ float FASTCALL ladspaManager::getDefaultSetting( const ladspaKey & _plugin,
switch( hintDescriptor & LADSPA_HINT_DEFAULT_MASK )
{
case LADSPA_HINT_DEFAULT_NONE:
return( -999e-99 );
return( NOHINT );
case LADSPA_HINT_DEFAULT_MINIMUM:
return( descriptor->PortRangeHints[_port].
LowerBound );
@@ -619,19 +694,19 @@ float FASTCALL ladspaManager::getDefaultSetting( const ladspaKey & _plugin,
case LADSPA_HINT_DEFAULT_440:
return( 440.0 );
default:
return( -999e-99 );
return( NOHINT );
}
}
else
{
return( -999e-99 );
return( NOHINT );
}
}
bool FASTCALL ladspaManager::isLogarithmic( const ladspaKey & _plugin,
bool FASTCALL ladspaManager::isLogarithmic( const ladspa_key_t & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
@@ -655,7 +730,7 @@ bool FASTCALL ladspaManager::isLogarithmic( const ladspaKey & _plugin,
bool FASTCALL ladspaManager::isInteger( const ladspaKey & _plugin,
bool FASTCALL ladspaManager::isInteger( const ladspa_key_t & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
@@ -679,7 +754,7 @@ bool FASTCALL ladspaManager::isInteger( const ladspaKey & _plugin,
QString FASTCALL ladspaManager::getPortName( const ladspaKey & _plugin,
QString FASTCALL ladspaManager::getPortName( const ladspa_key_t & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
@@ -703,7 +778,7 @@ QString FASTCALL ladspaManager::getPortName( const ladspaKey & _plugin,
const void * FASTCALL ladspaManager::getImplementationData(
const ladspaKey & _plugin )
const ladspa_key_t & _plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
@@ -724,7 +799,7 @@ const void * FASTCALL ladspaManager::getImplementationData(
const LADSPA_Descriptor * FASTCALL ladspaManager::getDescriptor(
const ladspaKey & _plugin )
const ladspa_key_t & _plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
@@ -744,7 +819,7 @@ const LADSPA_Descriptor * FASTCALL ladspaManager::getDescriptor(
LADSPA_Handle FASTCALL ladspaManager::instantiate( const ladspaKey & _plugin,
LADSPA_Handle FASTCALL ladspaManager::instantiate( const ladspa_key_t & _plugin,
Uint32 _sample_rate )
{
if( m_ladspaManagerMap.contains( _plugin ) )
@@ -766,7 +841,7 @@ LADSPA_Handle FASTCALL ladspaManager::instantiate( const ladspaKey & _plugin,
void FASTCALL ladspaManager::connectPort( const ladspaKey & _plugin,
bool FASTCALL ladspaManager::connectPort( const ladspa_key_t & _plugin,
LADSPA_Handle _instance,
Uint32 _port,
LADSPA_Data * _data_location )
@@ -783,14 +858,16 @@ void FASTCALL ladspaManager::connectPort( const ladspaKey & _plugin,
{
( descriptor->connect_port )
( _instance, _port, _data_location );
return( TRUE );
}
}
return( FALSE );
}
void FASTCALL ladspaManager::activate( const ladspaKey & _plugin,
bool FASTCALL ladspaManager::activate( const ladspa_key_t & _plugin,
LADSPA_Handle _instance )
{
if( m_ladspaManagerMap.contains( _plugin ) )
@@ -803,14 +880,16 @@ void FASTCALL ladspaManager::activate( const ladspaKey & _plugin,
if( descriptor->activate != NULL )
{
( descriptor->activate ) ( _instance );
return( TRUE );
}
}
return( FALSE );
}
void FASTCALL ladspaManager::run( const ladspaKey & _plugin,
bool FASTCALL ladspaManager::run( const ladspa_key_t & _plugin,
LADSPA_Handle _instance,
Uint32 _sample_count )
{
@@ -824,14 +903,16 @@ void FASTCALL ladspaManager::run( const ladspaKey & _plugin,
if( descriptor->run != NULL )
{
( descriptor->run ) ( _instance, _sample_count );
return( TRUE );
}
}
return( FALSE );
}
void FASTCALL ladspaManager::runAdding( const ladspaKey & _plugin,
bool FASTCALL ladspaManager::runAdding( const ladspa_key_t & _plugin,
LADSPA_Handle _instance,
Uint32 _sample_count )
{
@@ -846,14 +927,16 @@ void FASTCALL ladspaManager::runAdding( const ladspaKey & _plugin,
descriptor->set_run_adding_gain != NULL )
{
( descriptor->run_adding ) ( _instance, _sample_count );
return( TRUE );
}
}
return( FALSE );
}
void FASTCALL ladspaManager::setRunAddingGain( const ladspaKey & _plugin,
bool FASTCALL ladspaManager::setRunAddingGain( const ladspa_key_t & _plugin,
LADSPA_Handle _instance,
LADSPA_Data _gain )
{
@@ -869,14 +952,16 @@ void FASTCALL ladspaManager::setRunAddingGain( const ladspaKey & _plugin,
{
( descriptor->set_run_adding_gain )
( _instance, _gain );
return( TRUE );
}
}
return( FALSE );
}
void FASTCALL ladspaManager::deactivate( const ladspaKey & _plugin,
bool FASTCALL ladspaManager::deactivate( const ladspa_key_t & _plugin,
LADSPA_Handle _instance )
{
if( m_ladspaManagerMap.contains( _plugin ) )
@@ -889,14 +974,16 @@ void FASTCALL ladspaManager::deactivate( const ladspaKey & _plugin,
if( descriptor->deactivate != NULL )
{
( descriptor->deactivate ) ( _instance );
return( TRUE );
}
}
return( FALSE );
}
void FASTCALL ladspaManager::cleanup( const ladspaKey & _plugin,
bool FASTCALL ladspaManager::cleanup( const ladspa_key_t & _plugin,
LADSPA_Handle _instance )
{
if( m_ladspaManagerMap.contains( _plugin ) )
@@ -909,8 +996,10 @@ void FASTCALL ladspaManager::cleanup( const ladspaKey & _plugin,
if( descriptor->cleanup != NULL )
{
( descriptor->cleanup ) ( _instance );
return( TRUE );
}
}
return( FALSE );
}

View File

@@ -1,6 +1,9 @@
#ifdef SINGLE_SOURCE_COMPILE
#undef SINGLE_SOURCE_COMPILE
#include "src/tracks/instrument_track.cpp"
#include "src/core/effect_tab_widget.cpp"
#include "src/core/ladspa_control_dialog.cpp"
#include "src/core/select_ladspa_dialog.cpp"
#include "src/core/midi_tab_widget.cpp"
#include "src/lib/string_pair_drag.cpp"
#include "src/lib/buffer_allocator.cpp"
@@ -10,9 +13,14 @@
#include "src/lib/base64.cpp"
#include "src/lib/mmp.cpp"
#include "src/lib/ladspa_manager.cpp"
#include "src/lib/ladspa_2_lmms.cpp"
#include "src/lib/oscillator.cpp"
#include "src/lib/clipboard.cpp"
#include "src/lib/sample_buffer.cpp"
#include "src/core/effect_chain.cpp"
#include "src/core/effect.cpp"
#include "src/core/ladspa_browser.cpp"
#include "src/core/ladspa_port_dialog.cpp"
#include "src/core/import_filter.cpp"
#include "src/core/config_mgr.cpp"
#include "src/core/envelope_and_lfo_widget.cpp"
@@ -65,9 +73,11 @@
#include "src/tracks/pattern.cpp"
#include "src/tracks/bb_track.cpp"
#include "src/tracks/sample_track.cpp"
#include "src/widgets/ladspa_description.cpp"
#include "src/widgets/project_notes.cpp"
#include "src/widgets/led_checkbox.cpp"
#include "src/widgets/knob.cpp"
#include "src/widgets/labeled_knob.cpp"
#include "src/widgets/pixmap_button.cpp"
#include "src/widgets/qxembed.cpp"
#include "src/widgets/group_box.cpp"
@@ -90,4 +100,8 @@
#include "src/widgets/automatable_button.cpp"
#include "src/widgets/automatable_slider.cpp"
#include "src/widgets/volume_knob.cpp"
#include "src/widgets/rack_plugin.cpp"
#include "src/widgets/rack_view.cpp"
#include "src/widgets/labeled_knob.cpp"
#include "src/widgets/ladspa_control.cpp"
#endif

View File

@@ -26,6 +26,13 @@
*/
#include "ladspa_manager.h"
#ifdef LADSPA_SUPPORT
#include "effect.h"
#include "effect_chain.h"
#include "effect_tab_widget.h"
#endif
#include "qt3support.h"
#ifdef QT4
@@ -301,9 +308,17 @@ instrumentTrack::instrumentTrack( trackContainer * _tc ) :
m_envWidget = new envelopeTabWidget( this );
m_arpWidget = new arpAndChordsTabWidget( this );
m_midiWidget = new midiTabWidget( this, m_midiPort );
#ifdef LADSPA_SUPPORT
m_effWidget = new effectTabWidget( this );
#endif
m_tabWidget->addTab( m_envWidget, tr( "ENV/LFO/FILTER" ), 1 );
m_tabWidget->addTab( m_arpWidget, tr( "ARP/CHORD" ), 2 );
#ifdef LADSPA_SUPPORT
m_tabWidget->addTab( m_effWidget, tr( "FX" ), 3 );
m_tabWidget->addTab( m_midiWidget, tr( "MIDI" ), 4 );
#else
m_tabWidget->addTab( m_midiWidget, tr( "MIDI" ), 3 );
#endif
// setup piano-widget
m_pianoWidget = new pianoWidget( this );
@@ -368,6 +383,7 @@ instrumentTrack::instrumentTrack( trackContainer * _tc ) :
setFixedWidth( CHANNEL_WIDTH );
resize( sizeHint() );
#endif
}
@@ -549,6 +565,10 @@ void instrumentTrack::processAudioBuffer( sampleFrame * _buf,
return;
}
float v_scale = (float) getVolume() / DEFAULT_VOLUME;
#ifdef LADSPA_SUPPORT
m_audioPort->getEffects()->setRunning();
#endif
// instruments using instrument-play-handles will call this method
// without any knowledge about notes, so they pass NULL for _n, which

View File

@@ -129,6 +129,9 @@ void groupBox::setState( bool _on, bool _anim )
m_animating = TRUE;
animate();
}
#ifdef LADSPA_SUPPORT
emit( toggled( _on ) );
#endif
}

View File

@@ -0,0 +1,119 @@
#ifndef SINGLE_SOURCE_COMPILE
/*
* ladspa_control.cpp - widget for controlling a LADSPA port
*
* Copyright (c) 2006 Danny McRae <khjklujn/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#include "ladspa_manager.h"
#ifdef LADSPA_SUPPORT
#include <qwhatsthis.h>
#include "ladspa_control.h"
#include "effect.h"
ladspaControl::ladspaControl( QWidget * _parent, port_desc_t * _port, engine * _engine, instrumentTrack * _track ) :
QWidget( _parent, "ladspaControl" ),
engineObject( _engine ),
m_port( _port ),
m_toggle( NULL ),
m_knob( NULL )
{
switch( m_port->data_type )
{
case TOGGLED:
m_toggle = new ledCheckBox( m_port->name, this, "", eng(), _track );
setFixedSize( m_toggle->width(), m_toggle->height() );
if( m_port->def == 1.0f )
{
m_toggle->setChecked( TRUE );
}
break;
case INTEGER:
m_knob = new knob( knobBright_26, this, m_port->name, eng(), _track);
m_knob->setLabel( m_port->name );
m_knob->setRange( m_port->max, m_port->min, 1 + static_cast<int>( m_port->max - m_port->min ) / 500 );
m_knob->setInitValue( m_port->def );
setFixedSize( m_knob->width(), m_knob->height() );
m_knob->setHintText( tr( "Value:" ) + " ", "" );
#ifdef QT4
m_knob->setWhatsThis(
#else
QWhatsThis::add( m_knob,
#endif
tr( "Sorry, no help available." ) );
break;
case FLOAT:
m_knob = new knob( knobBright_26, this, m_port->name, eng(), _track);
m_knob->setLabel( m_port->name );
if( ( m_port->max - m_port->min ) < 500.0f )
{
m_knob->setRange( m_port->min, m_port->max, 0.01 );
}
else
{
m_knob->setRange( m_port->min, m_port->max, ( m_port->max - m_port->min ) / 500.0f );
}
m_knob->setInitValue( m_port->def );
m_knob->setHintText( tr( "Value:" ) + " ", "" );
#ifdef QT4
m_knob->setWhatsThis(
#else
QWhatsThis::add( m_knob,
#endif
tr( "Sorry, no help available." ) );
setFixedSize( m_knob->width(), m_knob->height() );
break;
default:
break;
}
}
ladspaControl::~ladspaControl()
{
}
LADSPA_Data ladspaControl::getValue( void )
{
switch( m_port->data_type )
{
case TOGGLED:
return( static_cast<LADSPA_Data>( m_toggle->isChecked() ) );
default:
return( static_cast<LADSPA_Data>( m_knob->value() ) );
}
}
#include "ladspa_control.moc"
#endif
#endif

View File

@@ -0,0 +1,234 @@
#ifndef SINGLE_SOURCE_COMPILE
/*
* left_frame.cpp - presents the plugin selector portion of a ladspa rack
*
* Copyright (c) 2006 Danny McRae <khjklujn@netscape.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#include "ladspa_manager.h"
#ifdef LADSPA_SUPPORT
#include <qpair.h>
#include <qstring.h>
#include "ladspa_description.h"
#include "mixer.h"
#include "audio_device.h"
pluginDescription::pluginDescription( QWidget * _parent, engine * _engine ):
QWidget( _parent, "pluginDescription" ),
m_ladspaManager( _engine->getLADSPAManager() )
{
m_boxer = new QVBoxLayout( this );
m_grouper = new QGroupBox( 9, Qt::Vertical, tr( "Description" ), this );
m_label = new QLabel( m_grouper );
m_label->setText( tr( "Label:" ) );
m_maker = new QLabel( m_grouper );
m_maker->setText( tr( "Maker:" ) );
m_copyright = new QLabel( m_grouper );
m_copyright->setText( tr( "Copyright:" ) );
m_requiresRealTime = new QLabel( m_grouper );
m_requiresRealTime->setText( tr( "Requires Real Time:" ) );
m_realTimeCapable = new QLabel( m_grouper );
m_realTimeCapable->setText( tr( "Real Time Capable:" ) );
m_inplaceBroken = new QLabel( m_grouper );
m_inplaceBroken->setText( tr( "Inplace Broken:" ) );
m_channelsIn = new QLabel( m_grouper );
m_channelsIn->setText( tr( "Channels In:" ) );
m_channelsOut = new QLabel( m_grouper );
m_channelsOut->setText( tr( "Channels Out:" ) );
m_boxer->addWidget( m_grouper );
}
pluginDescription::~pluginDescription()
{
}
void pluginDescription::onHighlighted( const ladspa_key_t & _key )
{
m_label->setText( tr( "Name: " ) +
m_ladspaManager->getName( _key ) );
m_maker->setText( tr( "Maker: " ) +
m_ladspaManager->getMaker( _key ) );
m_copyright->setText( tr( "Copyright: " ) +
m_ladspaManager->getCopyright( _key ) );
if( m_ladspaManager->hasRealTimeDependency( _key ) )
{
m_requiresRealTime->setText( tr( "Requires Real Time: Yes" ) );
}
else
{
m_requiresRealTime->setText( tr( "Requires Real Time: No" ) );
}
if( m_ladspaManager->isRealTimeCapable( _key ) )
{
m_realTimeCapable->setText( tr( "Real Time Capable: Yes" ) );
}
else
{
m_realTimeCapable->setText( tr( "Real Time Capable: No" ) );
}
if( m_ladspaManager->isInplaceBroken( _key ) )
{
m_inplaceBroken->setText( tr( "In Place Broken: Yes" ) );
}
else
{
m_inplaceBroken->setText( tr( "In Place Broken: No" ) );
}
QString chan = QString::number( m_ladspaManager->getDescription(
_key )->inputChannels );
m_channelsIn->setText( tr( "Channels In: " ) + chan );
chan = QString::number( m_ladspaManager->getDescription(
_key )->outputChannels );
m_channelsOut->setText( tr( "Channels Out: " ) + chan );
}
ladspaDescription::ladspaDescription( QWidget * _parent, engine * _engine, pluginType _type ):
QWidget( _parent, "ladspaDescription" )
{
m_ladspaManager = _engine->getLADSPAManager();
setMinimumWidth( 200 );
m_boxer = new QVBoxLayout( this );
m_grouper = new QGroupBox( 1, Qt::Vertical, tr( "Plugins" ), this );
l_sortable_plugin_t plugins;
switch( _type )
{
case SOURCE:
plugins = m_ladspaManager->getInstruments();
break;
case TRANSFER:
plugins = m_ladspaManager->getValidEffects();
break;
case VALID:
plugins = m_ladspaManager->getValidEffects();
break;
case INVALID:
plugins = m_ladspaManager->getInvalidEffects();
break;
case SINK:
plugins = m_ladspaManager->getAnalysisTools();
break;
case OTHER:
plugins = m_ladspaManager->getOthers();
break;
default:
break;
}
for( l_sortable_plugin_t::iterator it = plugins.begin();
it != plugins.end(); it++ )
{
if( _type != VALID || m_ladspaManager->getDescription( (*it).second )->inputChannels <= _engine->getMixer()->audioDev()->channels() )
{
m_pluginNames.append( (*it).first );
m_pluginKeys.append( (*it).second );
}
}
m_pluginList = new QListBox( m_grouper );
m_pluginList->insertStringList( m_pluginNames );
connect( m_pluginList, SIGNAL( highlighted( int ) ),
SLOT( onHighlighted( int ) ) );
connect( m_pluginList, SIGNAL( doubleClicked( QListBoxItem * ) ),
SLOT( onDoubleClicked( QListBoxItem * ) ) );
m_boxer->addWidget( m_grouper );
m_pluginDescription = new pluginDescription( this, _engine );
connect( this, SIGNAL( highlighted( const ladspa_key_t & ) ),
m_pluginDescription,
SLOT( onHighlighted( const ladspa_key_t & ) ) );
m_boxer->addWidget( m_pluginDescription );
if( m_pluginList->numRows() > 0 )
{
m_pluginList->setSelected( 0, true );
m_currentSelection = m_pluginKeys[0];
emit( highlighted( m_currentSelection ) );
}
}
ladspaDescription::~ladspaDescription()
{
delete m_pluginDescription;
delete m_pluginList;
delete m_grouper;
delete m_boxer;
}
void ladspaDescription::onHighlighted( int _pluginIndex )
{
m_currentSelection = m_pluginKeys[_pluginIndex];
emit( highlighted( m_currentSelection ) );
}
void ladspaDescription::onDoubleClicked( QListBoxItem * _item )
{
// m_currentSelection = m_pluginKeys[m_pluginList->index( _item )];
emit( doubleClicked( m_currentSelection ) );
}
void ladspaDescription::onAddButtonReleased()
{
emit( addPlugin( m_currentSelection ) );
}
#include "ladspa_description.moc"
#endif
#endif

196
src/widgets/rack_plugin.cpp Normal file
View File

@@ -0,0 +1,196 @@
#ifndef SINGLE_SOURCE_COMPILE
/*
* effect_tab_widget.cpp - tab-widget in channel-track-window for setting up
* effects
*
* Copyright (c) 2006 Danny McRae <khjklujn/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#include "ladspa_manager.h"
#ifdef LADSPA_SUPPORT
#ifdef QT4
#include <Qt/QtXml>
#include <QtCore/QMap>
#include <QtGui/QLabel>
#include <QtGui/QMenu>
#include <QtGui/QWhatsThis>
#else
#include <qdom.h>
#include <qmap.h>
#include <qwhatsthis.h>
#include <qlabel.h>
#include <qpopupmenu.h>
#include <qcursor.h>
#include <qcolor.h>
#endif
#include "rack_plugin.h"
#include "knob.h"
#include "tooltip.h"
#include "ladspa_2_lmms.h"
#include "ladspa_control_dialog.h"
#include "audio_port.h"
rackPlugin::rackPlugin( QWidget * _parent, ladspa_key_t _key, instrumentTrack * _track, engine * _engine ) :
QWidget( _parent, "rackPlugin" ),
journallingObject( _engine )
{
m_effect = new effect( _key, eng() );
_track->getAudioPort()->getEffects()->appendEffect( m_effect );
setFixedSize( 210, 58 );
setPaletteBackgroundColor( QColor( 99, 99, 99 ) );
m_grouper = new QGroupBox( 1, Qt::Vertical, "", this );
m_grouper->setFixedSize( 210, 58 );
m_bypass = new ledCheckBox( "", this, tr( "Turn the effect off" ), eng(), _track );
connect( m_bypass, SIGNAL( toggled( bool ) ), this, SLOT( bypassed( bool ) ) );
m_bypass->setChecked( TRUE );
m_bypass->move( 3, 3 );
#ifdef QT4
m_bypass->setWhatsThis(
#else
QWhatsThis::add( m_bypass,
#endif
tr(
"Toggles the effect on or off." ) );
m_wetDry = new knob( knobBright_26, this, tr( "Wet/Dry mix" ), eng(), _track );
connect( m_wetDry, SIGNAL( valueChanged( float ) ), this, SLOT( setWetDry( float ) ) );
m_wetDry->setLabel( tr( "W/D" ) );
m_wetDry->setRange( 0.0f, 1.0f, 0.01f );
m_wetDry->setInitValue( 1.0f );
m_wetDry->move( 25, 3 );
m_wetDry->setHintText( tr( "Wet Level:" ) + " ", "" );
#ifdef QT4
m_wetDry->setWhatsThis(
#else
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." ) );
m_autoQuit = new knob( knobBright_26, this, tr( "Decay" ), eng(), _track );
connect( m_autoQuit, SIGNAL( valueChanged( float ) ), this, SLOT( setAutoQuit( float ) ) );
m_autoQuit->setLabel( tr( "Decay" ) );
m_autoQuit->setRange( 1, 100, 1 );
m_autoQuit->setInitValue( 1 );
m_autoQuit->move( 60, 3 );
m_autoQuit->setHintText( tr( "Buffers:" ) + " ", "" );
#ifdef QT4
m_autoQuit->setWhatsThis(
#else
QWhatsThis::add( m_autoQuit,
#endif
tr(
"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 );
connect( m_wetDry, SIGNAL( valueChanged( float ) ), this, SLOT( setGate( float ) ) );
m_gate->setLabel( tr( "Gate" ) );
m_gate->setRange( 0.0f, 1.0f, 0.01f );
m_gate->setInitValue( 0.0f );
m_gate->move( 95, 3 );
m_gate->setHintText( tr( "Gate:" ) + " ", "" );
#ifdef QT4
m_gate->setWhatsThis(
#else
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 "
"signals." ) );
m_editButton = new QPushButton( this, "Controls" );
m_editButton->setText( tr( "Controls" ) );
m_editButton->setGeometry( 140, 19, 50, 20 );
connect( m_editButton, SIGNAL( clicked() ), this, SLOT( editControls() ) );
QString name = eng()->getLADSPAManager()->getShortName( _key );
m_label = new QLabel( this );
m_label->setText( name );
QFont f = m_label->font();
f.setBold( TRUE );
m_label->setFont( pointSize<7>( f ) );
m_label->setGeometry( 5, 38, 200, 20 );
m_controlView = new ladspaControlDialog( this, m_effect, eng(), _track );
}
rackPlugin::~rackPlugin()
{
}
void rackPlugin::editControls( void )
{
m_controlView->show();
m_controlView->raise();
}
void rackPlugin::bypassed( bool _state )
{
m_effect->setBypass( !_state );
}
void rackPlugin::setWetDry( float _value )
{
m_effect->setWetDry( _value );
}
void rackPlugin::setAutoQuit( float _value )
{
m_effect->setTimeout( static_cast<Uint32>( _value ) );
}
void rackPlugin::setGate( float _value )
{
m_effect->setGate( _value );
}
#include "rack_plugin.moc"
#endif
#endif

83
src/widgets/rack_view.cpp Normal file
View File

@@ -0,0 +1,83 @@
#ifndef SINGLE_SOURCE_COMPILE
/*
* right_frame.cpp - provides the display for the rackInsert instances
*
* Copyright (c) 2006 Danny McRae <khjklujn@netscape.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#include "ladspa_manager.h"
#ifdef LADSPA_SUPPORT
#include "rack_view.h"
rackView::rackView( QWidget * _parent, engine * _engine, instrumentTrack * _track ):
QWidget( _parent, "rackView" ),
engineObject( _engine ),
m_instrumentTrack( _track )
{
setFixedSize( 230, 180 );
m_mainLayout = new QVBoxLayout( this );
m_scrollView = new QScrollView( this );
m_scrollView->setFixedSize( 230, 180 );
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 );
}
rackView::~rackView()
{
m_rackInserts.setAutoDelete( TRUE );
while( ! m_rackInserts.isEmpty() )
{
m_rackInserts.removeFirst();
}
delete m_rack;
delete m_scrollView;
delete m_mainLayout;
}
void rackView::addPlugin( ladspa_key_t _key )
{
rackPlugin * plugin = new rackPlugin( m_rack, _key, m_instrumentTrack, eng() );
m_rackInserts.append( plugin );
m_rackInserts.current()->repaint();
m_rackInserts.current()->show();
}
#include "rack_view.moc"
#endif
#endif