added LADSPA-support and some fixed lockup-bugs

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@17 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Tobias Doerffel
2005-10-14 11:37:16 +00:00
parent 2d0bcc7140
commit 58fe360793
8 changed files with 1259 additions and 33 deletions

View File

@@ -1,3 +1,30 @@
2005-10-13 Tobias Doerffel <tobydox@users.sourceforge.net>
* src/audio/audio_jack.cpp:
do not fill up buffers if JACK-transport is not rolling but at the same
time always handle frame-syncing-var in JACK-callback, even if JACK-
transport is not rolling - fixes several bugs like lockups when
removing tracks while JACK-server is pausing...
* src/widgets/knob.cpp:
fixed bug which caused hidden mouse-cursor forever when pressing right
mouse-button while left one is pressed
* src/lib/ladspa_manager.cpp:
use /usr/lib/ladspa as default-directory if env-var LADSPA_PATH is not
set
* src/soundgenerators/*.cpp:
removed obsolete defaultSettings()-method from each soundgenerator
2005-10-13 Dany McRae <khjklujn@yahoo.com>
* include/ladspa_manager.h
* include/ladspa_sine_1063.h
* src/lib/ladspa_manager.cpp:
* src/soundgenerators/ladspa_sine_1063.cpp:
added LADSPA-support and a simple soundgenerator for testing-purposes
2005-10-12 Dany McRae <khjklujn@yahoo.com>
* Makefile.am:

View File

@@ -58,6 +58,7 @@ lmms_MOC = \
./kmultitabbar.moc \
./group_box.moc \
./knob.moc \
./ladspa_sine_1063.moc \
./lcd_spinbox.moc \
./led_checkbox.moc \
./lmms_main_win.moc \
@@ -137,6 +138,7 @@ lmms_SOURCES = \
$(srcdir)/src/lib/buffer_allocator.cpp \
$(srcdir)/src/lib/clipboard.cpp \
$(srcdir)/src/lib/embed.cpp \
$(srcdir)/src/lib/ladspa_manager.cpp \
$(srcdir)/src/lib/mmp.cpp \
$(srcdir)/src/lib/oscillator.cpp \
$(srcdir)/src/lib/sample_buffer.cpp \
@@ -257,7 +259,8 @@ lmms_SOURCES = \
$(srcdir)/include/text_float.h \
$(srcdir)/include/tempo_sync_knob.h \
$(srcdir)/include/setup_dialog.h \
$(srcdir)/include/empty_sg_plugin.h
$(srcdir)/include/empty_sg_plugin.h \
$(srcdir)/include/ladspa_manager.h
EXTRA_DIST = $(lmms_EMBEDDED_RESOURCES)
@@ -300,10 +303,11 @@ SUBDIRS = artwork locale midi-maps presets projects samples
pkglib_LTLIBRARIES= libaudiofileprocessor.la libmidiout.la libpluckedstringsynth.la libtripleoscillator.la
pkglib_LTLIBRARIES= libaudiofileprocessor.la libsine1063oscillator.la libmidiout.la libpluckedstringsynth.la libtripleoscillator.la
libaudiofileprocessor_la_SOURCES = src/soundgenerators/audio_file_processor.cpp
libsine1063oscillator_la_SOURCES = src/soundgenerators/ladspa_sine_1063.cpp
libmidiout_la_SOURCES = src/soundgenerators/midi_out.cpp
libpluckedstringsynth_la_SOURCES = src/soundgenerators/plucked_string_synth.cpp
libtripleoscillator_la_SOURCES = src/soundgenerators/triple_oscillator.cpp

15
TODO
View File

@@ -1,10 +1,12 @@
- toolbar-redesign in song-editor, bb-editor and piano-roll!!!
- addchannel-toolbutton -> popup-menu with available soundgenerator-plugins
- solve problem with knob-control-precision
- built-in VST-support
- proper dlclos()ing of sg-plugins
- use own scrollview for capturing wheel-events
- add note-len- and note-alignment-selectbox to piano-roll
- only redraw region given by paint-event in pattern, bbTCO, sampleTCO etc.
- make usable with Qt4
- make LMMS an ALSA-sequencer-client
- adchannel-toolbutton -> popup-menu with available soundgenerator-plugins
- pre-listen when opening sample with QFileDialog
- level-meters in output-graph and channel-track
- panning-editing in piano-roll
@@ -13,7 +15,7 @@
- setup MIDI-channel and -program in MIDI-Out
- speed up painting of sampleTCO
- save window-positions, -states and -sizes in files
- solve problems with different keyboard-layouts when playing channel-track with pc-keyboard
- solve problems with different keyboard-layouts when playing channel-track with pc-keyboard -> use tr()
- balance env+lfo
- autosave every 1 minute
- audioDummy: always wait until the stuff normally would have been written (=simulate blocking IO)
@@ -23,9 +25,11 @@
- dynamic pitch-change
- make piano-roll use the global clipboard??
- add languages:
- Dutch
- Italian
- ...any other welcome
- Swedish
- Norwegian
- Greece
- ...
@@ -37,7 +41,6 @@ Things to be done anytime in the future
- FLP-Import
- classical note-edit-window -> also ability of printing and maybe later scanning & recognition of notes
- add FLAC as export-format?
- support of LADSPA for all plugins
- better commented source...
- optimize, optimize, optimize.....

View File

@@ -2,8 +2,8 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.50)
AC_INIT(lmms, 0.1.1-cvs20051012, tobydox@users.sourceforge.net)
AM_INIT_AUTOMAKE(lmms, 0.1.1-cvs20051012)
AC_INIT(lmms, 0.1.1-cvs20051013, tobydox@users.sourceforge.net)
AM_INIT_AUTOMAKE(lmms, 0.1.1-cvs20051013)
AM_CONFIG_HEADER(config.h)
@@ -355,6 +355,7 @@ AC_CONFIG_FILES([Makefile
presets/AudioFileProcessor/Makefile
presets/MIDI-Out/Makefile
presets/PluckedStringSynth/Makefile
presets/Sine1063Oscillator/Makefile
presets/TripleOscillator/Makefile
projects/Makefile
projects/cool_songs/Makefile

330
include/ladspa_manager.h Normal file
View File

@@ -0,0 +1,330 @@
/*
* ladspa_manager.h - declaration of class ladspaManager
* a class to manage loading and instantiation
* of ladspa plugins
*
* Linux MultiMedia Studio
* Copyright (c) 2004-2005 Danny McRae <khjklujn@netscape.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.
*
*/
#ifndef _LADSPA_MANAGER_H
#define _LADSPA_MANAGER_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "qt3support.h"
#ifdef QT4
#include <QString>
#include <QStringList>
#include <QMap>
#include <QPair>
#else
#include <qstring.h>
#include <qstringlist.h>
#include <qmap.h>
#include <qpair.h>
#endif
#include <ladspa.h>
#include "types.h"
typedef QPair<QString, QString> ladspaKey;
/* ladspaManager provides a database of LADSPA plug-ins. Upon instantiation,
it loads all of the plug-ins found in the LADSPA_PATH environmental variable
and stores their access descriptors according in a dictionary keyed on
the filename the plug-in was loaded from and the label of the plug-in.
The can be retrieved by using ladspaKey. For example, to get the
"Phase Modulated Voice" plug-in from the cmt library, you would perform the
calls using:
ladspaKey( "cmt.so", "phasemod" )
as the plug-in key. */
class ladspaManager
{
public:
/* Provides access to the single instance of the class. */
static inline ladspaManager * inst( void )
{
if( s_instanceOfMe == NULL )
{
s_instanceOfMe = new ladspaManager();
}
return( s_instanceOfMe );
}
/* This identifier can be used as a unique, case-sensitive
identifier for the plugin type within the plugin file. Plugin
types should be identified by file and label rather than by index
or plugin name, which may be changed in new plugin
versions. Labels must not contain white-space characters. */
QString FASTCALL getLabel( const ladspaKey & _plugin );
/* Indicates that the plugin has a real-time dependency
(e.g. listens to a MIDI device) and so its output must not
be cached or subject to significant latency. */
bool FASTCALL hasRealTimeDependency( const ladspaKey & _plugin );
/* Indicates that the plugin may cease to work correctly if the
host elects to use the same data location for both input and output
(see connectPort). */
bool FASTCALL isInplaceBroken( const ladspaKey & _plugin );
/* Indicates that the plugin is capable of running not only in a
conventional host but also in a 'hard real-time' environment. */
bool FASTCALL isRealTimeCapable( const ladspaKey & _plugin );
/* Returns the name of the plug-in */
QString FASTCALL getName( const ladspaKey & _plugin );
/* Returns the the plug-in's author */
QString FASTCALL getMaker( const ladspaKey & _plugin );
/* Returns the copyright for the plug-in */
QString FASTCALL getCopyright( const ladspaKey & _plugin );
/* This indicates the number of ports (input AND output) present on
the plugin. */
Uint32 FASTCALL getPortCount( const ladspaKey & _plugin );
/* Indicates that the port is an input. */
bool FASTCALL isPortInput( const ladspaKey & _plugin, Uint32 _port );
/* Indicates that the port is an output. */
bool FASTCALL isPortOutput( const ladspaKey & _plugin, Uint32 _port );
/* Indicates that the port is an audio. */
bool FASTCALL isPortAudio( const ladspaKey & _plugin, Uint32 _port );
/* Indicates that the port is an control. */
bool FASTCALL isPortControl( const ladspaKey & _plugin, Uint32 _port );
/* Indicates that any bounds specified should be interpreted as
multiples of the sample rate. For instance, a frequency range from
0Hz to the Nyquist frequency (half the sample rate) could be requested
by this hint in conjunction with LowerBound = 0 and UpperBound = 0.5.
Hosts that support bounds at all must support this hint to retain meaning. */
bool FASTCALL areHintsSampleRateDependent( const ladspaKey & _plugin,
Uint32 _port );
/* Returns the lower boundary value for the given port. If
no lower bound is provided by the plug-in, returns -999e-99. When
areHintsSampleRateDependent() is also true then this value should be
multiplied by the relevant sample rate. */
float FASTCALL getLowerBound( const ladspaKey & _plugin, Uint32 _port );
/* Returns the upper boundary value for the given port. If
no upper bound is provided by the plug-in, returns -999e-99. When
areHintsSampleRateDependent() is also true then this value should be
multiplied by the relevant sample rate. */
float FASTCALL getUpperBound( const ladspaKey & _plugin, Uint32 _port );
/* Indicates whether the given port should be considered 0 or 1
boolean switch. */
bool FASTCALL isPortToggled( const ladspaKey & _plugin, Uint32 _port );
/* Retrieves any default setting hints offered by the plug-in for
the given port. */
float FASTCALL getDefaultSetting( const ladspaKey & _plugin,
Uint32 _port );
/* Indicates that it is likely that the user will find it more
intuitive to view values using a logarithmic scale. This is
particularly useful for frequencies and gains. */
bool FASTCALL isLogarithmic( const ladspaKey & _plugin, Uint32 _port );
/* Indicates that a user interface would probably wish to provide a
stepped control taking only integer values. Any bounds set should be
slightly wider than the actual integer range required to avoid floating
point rounding errors. For instance, the integer set {0,1,2,3} might
be described as [-0.1, 3.1]. */
bool FASTCALL isInteger( const ladspaKey & _plugin, Uint32 _port );
/* Returns the name of the port. */
QString FASTCALL getPortName( const ladspaKey & _plugin, Uint32 _port );
/* This may be used by the plugin developer to pass any custom
implementation data into an instantiate call. It must not be used
or interpreted by the host. It is expected that most plugin
writers will not use this facility as LADSPA_Handle should be
used to hold instance data. */
const void * FASTCALL getImplementationData( const ladspaKey & _plugin );
/* Returns a pointer to the plug-in's descriptor from which control
of the plug-in is accessible */
const LADSPA_Descriptor * FASTCALL getDescriptor( const ladspaKey & _plugin );
/* The following methods are convenience functions for use during
development. A real soundGenerator should use the getDescriptor()
method and implement the plug-in manipulations internally to avoid
the overhead associated with QMap lookups. */
/* Returns a handle to an instantiation of the given plug-in. */
LADSPA_Handle FASTCALL instantiate( const ladspaKey & _plugin,
Uint32 _sample_rate );
/* This method calls a function pointer that connects a port on an
instantiated plugin to a memory location at which a block of data
for the port will be read/written. The data location is expected
to be an array of LADSPA_Data for audio ports or a single
LADSPA_Data value for control ports. Memory issues will be
managed by the host. The plugin must read/write the data at these
locations every time run() or runAdding() is called and the data
present at the time of this connection call should not be
considered meaningful.
connectPort() may be called more than once for a plugin instance
to allow the host to change the buffers that the plugin is
reading or writing. These calls may be made before or after
activate() or deactivate() calls.
connectPort() must be called at least once for each port before
run() or runAdding() is called. */
void FASTCALL connectPort( const ladspaKey & _plugin,
LADSPA_Handle _instance,
Uint32 _port,
LADSPA_Data * _data_location );
/* This method calls a function pointer that initialises a plugin
instance and activates it for use. This is separated from
instantiate() to aid real-time support and so that hosts can
reinitialise a plugin instance by calling deactivate() and then
activate(). In this case the plugin instance must reset all state
information dependent on the history of the plugin instance
except for any data locations provided by connectPort() and any
gain set by setRunAddingGain(). If there is nothing for
activate() to do then the plugin writer may provide a NULL rather
than an empty function.
When present, hosts must call this function once before run() (or
runAdding()) is called for the first time. This call should be
made as close to the run() call as possible and indicates to
real-time plugins that they are now live. Plugins should not rely
on a prompt call to run() after activate(). activate() may not be
called again unless deactivate() is called first. Note that
connectPort() may be called before or after a call to
activate(). */
void FASTCALL activate( const ladspaKey & _plugin, LADSPA_Handle _instance );
/* This method calls a function pointer that runs an instance of a
plugin for a block. Two parameters are required: the first is a
handle to the particular instance to be run and the second
indicates the block size (in samples) for which the plugin
instance may run.
Note that if an activate() function exists then it must be called
before run() or run_adding(). If deactivate() is called for a
plugin instance then the plugin instance may not be reused until
activate() has been called again. */
void FASTCALL run( const ladspaKey & _plugin, LADSPA_Handle _instance,
Uint32 _sample_count );
/* This method calls a function pointer that runs an instance of a
plugin for a block. This has identical behaviour to run() except
in the way data is output from the plugin. When run() is used,
values are written directly to the memory areas associated with
the output ports. However when runAdding() is called, values
must be added to the values already present in the memory
areas. Furthermore, output values written must be scaled by the
current gain set by setRunAddingGain() (see below) before
addition.
runAdding() is optional. When it is not provided by a plugin,
this function pointer must be set to NULL. When it is provided,
the function setRunAddingGain() must be provided also. */
void FASTCALL runAdding( const ladspaKey & _plugin, LADSPA_Handle _instance,
Uint32 _sample_count );
/* This method calls a function pointer that sets the output gain for
use when runAdding() is called (see above). If this function is
never called the gain is assumed to default to 1. Gain
information should be retained when activate() or deactivate()
are called.
This function should be provided by the plugin if and only if the
runAdding() function is provided. When it is absent this
function pointer must be set to NULL. */
void FASTCALL setRunAddingGain( const ladspaKey & _plugin, LADSPA_Handle _instance,
LADSPA_Data _gain );
/* This is the counterpart to activate() (see above). If there is
nothing for deactivate() to do then the plugin writer may provide
a NULL rather than an empty function.
Hosts must deactivate all activated units after they have been
run() (or run_adding()) for the last time. This call should be
made as close to the last run() call as possible and indicates to
real-time plugins that they are no longer live. Plugins should
not rely on prompt deactivation. Note that connect_port() may be
called before or after a call to deactivate().
Deactivation is not similar to pausing as the plugin instance
will be reinitialised when activate() is called to reuse it. */
void FASTCALL deactivate( const ladspaKey & _plugin, LADSPA_Handle _instance );
/* Once an instance of a plugin has been finished with it can be
deleted using the following function. The instance handle passed
ceases to be valid after this call.
If activate() was called for a plugin instance then a
corresponding call to deactivate() must be made before cleanup()
is called. */
void FASTCALL cleanup( const ladspaKey & _plugin, LADSPA_Handle _instance );
private:
void FASTCALL addPlugins( void * _plugin_handle,
LADSPA_Descriptor_Function _descriptor_func,
const QString & _file );
ladspaManager( void );
~ladspaManager();
static ladspaManager * s_instanceOfMe;
typedef struct ladspaManagerStorage
{
void * pluginHandle;
LADSPA_Descriptor_Function descriptorFunction;
Uint32 index;
} ladspaManagerDescription;
typedef QMap<ladspaKey, ladspaManagerDescription *> ladspaManagerMapType;
ladspaManagerMapType m_ladspaManagerMap;
};
#endif

View File

@@ -218,24 +218,29 @@ void audioJACK::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
{
m_bufMutex.lock();
vvector<bufset> bufs;
for( Uint8 chnl = 0; chnl < channels(); ++chnl )
jack_transport_state_t ts = jack_transport_query( m_client, NULL );
if( ts == JackTransportRolling )
{
sampleType * buf = bufferAllocator::alloc<sampleType>(
_frames );
for( Uint32 frame = 0; frame < _frames; ++frame )
vvector<bufset> bufs;
for( Uint8 chnl = 0; chnl < channels(); ++chnl )
{
buf[frame] = _ab[frame][chnl] * _master_output;
sampleType * buf = bufferAllocator::alloc<sampleType>(
_frames );
for( Uint32 frame = 0; frame < _frames; ++frame )
{
buf[frame] = _ab[frame][chnl] * _master_output;
}
bufset b = { buf, _frames } ;
bufs.push_back( b );
}
bufset b = { buf, _frames } ;
bufs.push_back( b );
m_bufferSets.push_back( bufs );
}
m_bufferSets.push_back( bufs );
m_frameSync += _frames;
m_bufMutex.unlock();
// now wait until data has been collected by processCallback()
// now wait until data has been collected/skipped by processCallback()
while( m_frameSync > m_jackBufSize )
{
#ifdef HAVE_UNISTD_H
@@ -261,6 +266,16 @@ int audioJACK::processCallback( jack_nframes_t _nframes, void * _udata )
NULL );
if( ts != JackTransportRolling )
{
// always decrease frame-sync-var as we would do it if running
// in normal mode, so that the mixer-thread does up
if( _nframes < _this->m_frameSync )
{
_this->m_frameSync -= _nframes;
}
else
{
_this->m_frameSync = 0;
}
return( 0 );
}

844
src/lib/ladspa_manager.cpp Normal file
View File

@@ -0,0 +1,844 @@
/*
* ladspa_manager.cpp - a class to manage loading and instantiation
* of ladspa plugins
*
* Linux MultiMedia Studio
* Copyright (c) 2004-2005 Danny McRae <khjklujn@netscape.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.
*
*/
#ifdef QT4
#include <QDir>
#include <QFileInfo>
#include <QPair>
#else
#include <qdir.h>
#include <qfileinfo.h>
#include <qpair.h>
#endif
#include <ladspa.h>
#include <dlfcn.h>
#include <math.h>
#include "ladspa_manager.h"
ladspaManager * ladspaManager::s_instanceOfMe = NULL;
ladspaManager::ladspaManager( void )
{
LADSPA_Descriptor_Function descriptorFunction;
void * pluginHandle;
// TODO Need to move the search path definition to the config file to have
// more control over where it tries to find the plugins.
QStringList ladspaDirectories = QStringList::split( QString( ":" ),
QString( getenv( "LADSPA_PATH" ) ) );
// set default-directory if nothing is specified...
if( ladspaDirectories.isEmpty() )
{
ladspaDirectories.push_back( "/usr/lib/ladspa" );
}
for( QStringList::iterator it = ladspaDirectories.begin();
it != ladspaDirectories.end(); ++it )
{
QDir directory( ( *it ) );
const QFileInfoList * list = directory.entryInfoList();
for( QFileInfoList::iterator file = list->begin();
file != list->end(); ++file )
{
pluginHandle = dlopen( ( *file )->absFilePath().latin1(),
RTLD_LAZY );
if( pluginHandle )
{
dlerror();
descriptorFunction
= ( LADSPA_Descriptor_Function )
dlsym( pluginHandle,
"ladspa_descriptor" );
if( dlerror() == NULL && descriptorFunction )
{
addPlugins( pluginHandle,
descriptorFunction,
( *file )->fileName() );
}
else
{
dlclose( ( void * )
( *file )->absFilePath().latin1()
);
}
}
}
}
}
ladspaManager::~ladspaManager()
{
for( ladspaManagerMapType::Iterator it = m_ladspaManagerMap.begin();
it != m_ladspaManagerMap.end(); ++it )
{
dlclose( it.data()->pluginHandle );
}
m_ladspaManagerMap.clear();
}
void FASTCALL ladspaManager::addPlugins( void * _plugin_handle,
LADSPA_Descriptor_Function _descriptor_func,
const QString & _file )
{
const LADSPA_Descriptor * descriptor;
long pluginIndex = 0;
while( ( descriptor = _descriptor_func( pluginIndex ) ) != NULL )
{
ladspaManagerDescription * plugIn =
new ladspaManagerDescription;
plugIn->pluginHandle = _plugin_handle;
plugIn->descriptorFunction = _descriptor_func;
plugIn->index = pluginIndex;
ladspaKey key( _file, QString( descriptor->Label ) );
m_ladspaManagerMap[key] = plugIn;
++pluginIndex;
}
}
QString FASTCALL ladspaManager::getLabel( const ladspaKey & _plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
return( QString( descriptor->Label ) );
}
else
{
return( QString( "" ) );
}
}
bool FASTCALL ladspaManager::hasRealTimeDependency( const ladspaKey & _plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
return( LADSPA_IS_REALTIME( descriptor->Properties ) );
}
else
{
return( FALSE );
}
}
bool FASTCALL ladspaManager::isInplaceBroken( const ladspaKey & _plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
return( LADSPA_IS_INPLACE_BROKEN( descriptor->Properties ) );
}
else
{
return( FALSE );
}
}
bool FASTCALL ladspaManager::isRealTimeCapable( const ladspaKey & _plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
return( LADSPA_IS_HARD_RT_CAPABLE( descriptor->Properties ) );
}
else
{
return( FALSE );
}
}
QString FASTCALL ladspaManager::getName( const ladspaKey & _plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
return( QString( descriptor->Name ) );
}
else
{
return( QString( "" ) );
}
}
QString FASTCALL ladspaManager::getMaker( const ladspaKey & _plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
return( QString( descriptor->Maker ) );
}
else
{
return( QString( "" ) );
}
}
QString FASTCALL ladspaManager::getCopyright( const ladspaKey & _plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
return( QString( descriptor->Copyright ) );
}
else
{
return( QString( "" ) );
}
}
Uint32 FASTCALL ladspaManager::getPortCount( const ladspaKey & _plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
return( descriptor->PortCount );
}
else
{
return( 0 );
}
}
bool FASTCALL ladspaManager::isPortInput( const ladspaKey & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
&& _port < getPortCount( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
return( LADSPA_IS_PORT_INPUT
( descriptor->PortDescriptors[_port] ) );
}
else
{
return( FALSE );
}
}
bool FASTCALL ladspaManager::isPortOutput( const ladspaKey & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
&& _port < getPortCount( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
return( LADSPA_IS_PORT_OUTPUT
( descriptor->PortDescriptors[_port] ) );
}
else
{
return( FALSE );
}
}
bool FASTCALL ladspaManager::isPortAudio( const ladspaKey & _plugin, Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
&& _port < getPortCount( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
return( LADSPA_IS_PORT_AUDIO
( descriptor->PortDescriptors[_port] ) );
}
else
{
return( FALSE );
}
}
bool FASTCALL ladspaManager::isPortControl( const ladspaKey & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
&& _port < getPortCount( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
return( LADSPA_IS_PORT_CONTROL
( descriptor->PortDescriptors[_port] ) );
}
else
{
return( FALSE );
}
}
bool FASTCALL ladspaManager::areHintsSampleRateDependent(
const ladspaKey & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
&& _port < getPortCount( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
LADSPA_PortRangeHintDescriptor hintDescriptor
= descriptor->PortRangeHints[_port].HintDescriptor;
return( LADSPA_IS_HINT_SAMPLE_RATE
( hintDescriptor ) );
}
else
{
return( FALSE );
}
}
float FASTCALL ladspaManager::getLowerBound( const ladspaKey & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
&& _port < getPortCount( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
LADSPA_PortRangeHintDescriptor hintDescriptor
= descriptor->PortRangeHints[_port].HintDescriptor;
if( LADSPA_IS_HINT_BOUNDED_BELOW
( hintDescriptor ) )
{
return( descriptor->PortRangeHints[_port].LowerBound );
}
else
{
return( -999e-99 );
}
}
else
{
return( -999e-99 );
}
}
float FASTCALL ladspaManager::getUpperBound( const ladspaKey & _plugin, Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
&& _port < getPortCount( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
LADSPA_PortRangeHintDescriptor hintDescriptor
= descriptor->PortRangeHints[_port].HintDescriptor;
if( LADSPA_IS_HINT_BOUNDED_ABOVE
( hintDescriptor ) )
{
return( descriptor->PortRangeHints[_port].LowerBound );
}
else
{
return( -999e-99 );
}
}
else
{
return( -999e-99 );
}
}
bool FASTCALL ladspaManager::isPortToggled( const ladspaKey & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
&& _port < getPortCount( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
LADSPA_PortRangeHintDescriptor hintDescriptor
= descriptor->PortRangeHints[_port].HintDescriptor;
return( LADSPA_IS_HINT_TOGGLED
( hintDescriptor ) );
}
else
{
return( FALSE );
}
}
float FASTCALL ladspaManager::getDefaultSetting( const ladspaKey & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
&& _port < getPortCount( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
LADSPA_PortRangeHintDescriptor hintDescriptor
= descriptor->PortRangeHints[_port].HintDescriptor;
switch( hintDescriptor & LADSPA_HINT_DEFAULT_MASK )
{
case LADSPA_HINT_DEFAULT_NONE:
return( -999e-99 );
case LADSPA_HINT_DEFAULT_MINIMUM:
return( descriptor->PortRangeHints[_port].LowerBound );
case LADSPA_HINT_DEFAULT_LOW:
if( LADSPA_IS_HINT_LOGARITHMIC
( hintDescriptor ))
{
return( exp( log( descriptor->PortRangeHints[_port].LowerBound )
* 0.75
+ log( descriptor->PortRangeHints[_port].UpperBound )
* 0.25 ) );
}
else
{
return( descriptor->PortRangeHints[_port].LowerBound
* 0.75
+ descriptor->PortRangeHints[_port].UpperBound
* 0.25 );
}
case LADSPA_HINT_DEFAULT_MIDDLE:
if( LADSPA_IS_HINT_LOGARITHMIC
( hintDescriptor ) )
{
return( sqrt( descriptor->PortRangeHints[_port].LowerBound
* descriptor->PortRangeHints[_port].UpperBound ) );
}
else
{
return( 0.5 * ( descriptor->PortRangeHints[_port].LowerBound
+ descriptor->PortRangeHints[_port].UpperBound ) );
}
case LADSPA_HINT_DEFAULT_HIGH:
if( LADSPA_IS_HINT_LOGARITHMIC
( hintDescriptor ) )
{
return( exp( log( descriptor->PortRangeHints[_port].LowerBound )
* 0.25
+ log( descriptor->PortRangeHints[_port].UpperBound )
* 0.75 ) );
}
else
{
return( descriptor->PortRangeHints[_port].LowerBound
* 0.25
+ descriptor->PortRangeHints[_port].UpperBound
* 0.75 );
}
case LADSPA_HINT_DEFAULT_MAXIMUM:
return( descriptor->PortRangeHints[_port].UpperBound );
case LADSPA_HINT_DEFAULT_0:
return( 0.0 );
case LADSPA_HINT_DEFAULT_1:
return( 1.0 );
case LADSPA_HINT_DEFAULT_100:
return( 100.0 );
case LADSPA_HINT_DEFAULT_440:
return( 440.0 );
default:
return( -999e-99 );
}
}
else
{
return( -999e-99 );
}
}
bool FASTCALL ladspaManager::isLogarithmic( const ladspaKey & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
&& _port < getPortCount( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
LADSPA_PortRangeHintDescriptor hintDescriptor
= descriptor->PortRangeHints[_port].HintDescriptor;
return( LADSPA_IS_HINT_LOGARITHMIC
( hintDescriptor ) );
}
else
{
return( FALSE );
}
}
bool FASTCALL ladspaManager::isInteger( const ladspaKey & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
&& _port < getPortCount( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
LADSPA_PortRangeHintDescriptor hintDescriptor
= descriptor->PortRangeHints[_port].HintDescriptor;
return( LADSPA_IS_HINT_INTEGER
( hintDescriptor ) );
}
else
{
return( FALSE );
}
}
QString FASTCALL ladspaManager::getPortName( const ladspaKey & _plugin,
Uint32 _port )
{
if( m_ladspaManagerMap.contains( _plugin )
&& _port < getPortCount( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
return( QString( descriptor->PortNames[_port] ) );
}
else
{
return( QString( "" ) );
}
}
const void * FASTCALL ladspaManager::getImplementationData( const ladspaKey &
_plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
return( descriptor->ImplementationData );
}
else
{
return( NULL );
}
}
const LADSPA_Descriptor * FASTCALL ladspaManager::getDescriptor(
const ladspaKey & _plugin )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
return( descriptor );
}
else
{
return( NULL );
}
}
LADSPA_Handle FASTCALL ladspaManager::instantiate( const ladspaKey & _plugin,
Uint32 _sample_rate )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
return( ( descriptor->instantiate ) ( descriptor, _sample_rate ) );
}
else
{
return( NULL );
}
}
void FASTCALL ladspaManager::connectPort( const ladspaKey & _plugin,
LADSPA_Handle _instance,
Uint32 _port,
LADSPA_Data * _data_location )
{
if( m_ladspaManagerMap.contains( _plugin )
&& _port < getPortCount( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
if( descriptor->connect_port != NULL )
{
( descriptor->connect_port ) ( _instance, _port, _data_location );
}
}
}
void FASTCALL ladspaManager::activate( const ladspaKey & _plugin,
LADSPA_Handle _instance )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
if( descriptor->activate != NULL )
{
( descriptor->activate ) ( _instance );
}
}
}
void FASTCALL ladspaManager::run( const ladspaKey & _plugin, LADSPA_Handle _instance,
Uint32 _sample_count )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
if( descriptor->run != NULL )
{
( descriptor->run ) ( _instance, _sample_count );
}
}
}
void FASTCALL ladspaManager::runAdding( const ladspaKey & _plugin,
LADSPA_Handle _instance,
Uint32 _sample_count )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
if( descriptor->run_adding!=NULL
&& descriptor->set_run_adding_gain!=NULL )
{
( descriptor->run_adding ) ( _instance, _sample_count );
}
}
}
void FASTCALL ladspaManager::setRunAddingGain( const ladspaKey & _plugin,
LADSPA_Handle _instance,
LADSPA_Data _gain )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
if( descriptor->run_adding!=NULL
&& descriptor->set_run_adding_gain!=NULL )
{
( descriptor->set_run_adding_gain ) ( _instance, _gain );
}
}
}
void FASTCALL ladspaManager::deactivate( const ladspaKey & _plugin,
LADSPA_Handle _instance )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
if( descriptor->deactivate != NULL )
{
( descriptor->deactivate ) ( _instance );
}
}
}
void FASTCALL ladspaManager::cleanup( const ladspaKey & _plugin,
LADSPA_Handle _instance )
{
if( m_ladspaManagerMap.contains( _plugin ) )
{
LADSPA_Descriptor_Function descriptorFunction
= m_ladspaManagerMap[_plugin]->descriptorFunction;
const LADSPA_Descriptor * descriptor
= descriptorFunction( m_ladspaManagerMap[_plugin]->index );
if( descriptor->cleanup != NULL )
{
( descriptor->cleanup ) ( _instance );
}
}
}

View File

@@ -162,8 +162,6 @@ void knob::setHintText( const QString & _txt_before,
{
m_hintTextBeforeValue = _txt_before;
m_hintTextAfterValue = _txt_after;
/* toolTip::add( this, m_hintTextBeforeValue + QString::number( value() ) +
m_hintTextAfterValue );*/
}
@@ -253,8 +251,6 @@ void knob::valueChange( void )
{
recalcAngle();
update();
/* toolTip::add( this, m_hintTextBeforeValue + QString::number( value() ) +
m_hintTextAfterValue );*/
if( m_tracking )
{
emit valueChanged( value() );
@@ -474,22 +470,25 @@ void knob::mouseMoveEvent( QMouseEvent * _me )
//! Mouse Release Event handler
void knob::mouseReleaseEvent( QMouseEvent * _me )
void knob::mouseReleaseEvent( QMouseEvent * /* _me*/ )
{
m_scrollMode = ScrNone;
buttonReleased();
if( m_scrollMode != ScrNone )
{
m_scrollMode = ScrNone;
buttonReleased();
}
switch( m_scrollMode )
{
case ScrMouse:
setPosition( _me->pos() );
//setPosition( _me->pos() );
m_direction = 0;
m_mouseOffset = 0;
emit sliderReleased ();
emit sliderReleased();
break;
case ScrDirect:
setPosition( _me->pos() );
//setPosition( _me->pos() );
m_direction = 0;
m_mouseOffset = 0;
break;
@@ -527,9 +526,6 @@ void knob::wheelEvent( QWheelEvent * _me )
QPoint( m_knobPixmap->width() + 2, 0 ) );
s_textFloat->setVisibilityTimeOut( 1000 );
/* toolTip::add( this, m_hintTextBeforeValue+QString::number( value() ) +
m_hintTextAfterValue );*/
if( value() != m_prevValue )
{
emit sliderMoved( value() );
@@ -727,6 +723,12 @@ void knob::setStep( float _vstep )
void knob::contextMenuEvent( QContextMenuEvent * )
{
// for the case, the user clicked right while pressing left mouse-
// button, the context-menu appears while mouse-cursor is still hidden
// and it isn't shown again until user does something which causes
// an QApplication::restoreOverrideCursor()-call...
mouseReleaseEvent( NULL );
QMenu contextMenu( this );
#ifdef QT4
contextMenu.setTitle( accessibleName() );