~ubuntu-branches/ubuntu/hardy/lmms/hardy

« back to all changes in this revision

Viewing changes to plugins/ladspa_effect/ladspa_effect.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Tobias Doerffel
  • Date: 2007-09-17 15:00:24 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070917150024-mo0zk4ks81jawqii
Tags: 0.3.0-1ubuntu1
* Resynchronized with Debian (LP: #139759, LP: #90806, LP: #102639,
  LP: #113447, LP: #121172, LP: #124890)
* reverted changes from 0.2.1-1.1ubuntu1 as upstream merged/included them

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * ladspa_effect.cpp - class for processing LADSPA effects
 
3
 *
 
4
 * Copyright (c) 2006-2007 Danny McRae <khjklujn/at/users.sourceforge.net>
 
5
 * 
 
6
 * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or
 
9
 * modify it under the terms of the GNU General Public
 
10
 * License as published by the Free Software Foundation; either
 
11
 * version 2 of the License, or (at your option) any later version.
 
12
 *
 
13
 * This program is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
16
 * General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU General Public
 
19
 * License along with this program (see COPYING); if not, write to the
 
20
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
21
 * Boston, MA 02110-1301 USA.
 
22
 *
 
23
 */
 
24
 
 
25
 
 
26
#include "qt3support.h"
 
27
 
 
28
#ifdef QT4
 
29
 
 
30
#include <QtGui/QMessageBox>
 
31
 
 
32
#else
 
33
 
 
34
#include "qmessagebox.h"
 
35
#define indexOf find
 
36
 
 
37
#endif
 
38
 
 
39
 
 
40
#include "ladspa_effect.h"
 
41
#include "mixer.h"
 
42
#include "config_mgr.h"
 
43
#include "audio_device.h"
 
44
#include "ladspa_control.h"
 
45
#include "ladspa_subplugin_features.h"
 
46
 
 
47
 
 
48
#undef SINGLE_SOURCE_COMPILE
 
49
#include "embed.cpp"
 
50
 
 
51
 
 
52
extern "C"
 
53
{
 
54
 
 
55
plugin::descriptor ladspaeffect_plugin_descriptor =
 
56
{
 
57
        STRINGIFY_PLUGIN_NAME( PLUGIN_NAME ),
 
58
        "LADSPA Effect",
 
59
        QT_TRANSLATE_NOOP( "pluginBrowser",
 
60
                                "plugin for using arbitrary LADSPA-effects "
 
61
                                "inside LMMS." ),
 
62
        "Danny McRae <khjklujn/at/users.sourceforge.net>",
 
63
        0x0100,
 
64
        plugin::Effect,
 
65
        new QPixmap( PLUGIN_NAME::getIconPixmap( "logo" ) ),
 
66
        new ladspaSubPluginFeatures( plugin::Effect )
 
67
} ;
 
68
 
 
69
}
 
70
 
 
71
 
 
72
ladspaEffect::ladspaEffect( const descriptor::subPluginFeatures::key * _key ) :
 
73
        effect( &ladspaeffect_plugin_descriptor, _key ),
 
74
        m_effName( "none" ),
 
75
        m_key( subPluginKeyToLadspaKey( _key )
 
76
                /* ladspa_key_t( _cdata->settings.attribute( "label" ),
 
77
                                _cdata->settings.attribute( "lib" ) )*/ ),
 
78
        m_ladspa( engine::getLADSPAManager() )
 
79
{
 
80
        if( m_ladspa->getDescription( m_key ) == NULL )
 
81
        {
 
82
                QMessageBox::warning( 0, "Effect", 
 
83
                        "Unknown LADSPA plugin requested: " + m_key.first, 
 
84
                        QMessageBox::Ok, QMessageBox::NoButton );
 
85
                setOkay( FALSE );
 
86
                return;
 
87
        }
 
88
        
 
89
        setPublicName( m_ladspa->getShortName( m_key ) );
 
90
        
 
91
        // Calculate how many processing units are needed.
 
92
        const ch_cnt_t lmms_chnls = engine::getMixer()->audioDev()->channels();
 
93
        m_effectChannels = m_ladspa->getDescription( m_key )->inputChannels;
 
94
        setProcessorCount( lmms_chnls / m_effectChannels );
 
95
        
 
96
        // Categorize the ports, and create the buffers.
 
97
        m_portCount = m_ladspa->getPortCount( m_key );
 
98
        
 
99
        for( ch_cnt_t proc = 0; proc < getProcessorCount(); proc++ )
 
100
        {
 
101
                multi_proc_t ports;
 
102
                for( Uint16 port = 0; port < m_portCount; port++ )
 
103
                {
 
104
                        port_desc_t * p = new portDescription;
 
105
                        
 
106
                        p->name = m_ladspa->getPortName( m_key, port );
 
107
                        p->proc = proc;
 
108
                        p->port_id = port;
 
109
                        p->control = NULL;
 
110
                        
 
111
                        // Determine the port's category.
 
112
                        if( m_ladspa->isPortAudio( m_key, port ) )
 
113
                        {
 
114
                // Nasty manual memory management--was having difficulty
 
115
                // with some prepackaged plugins that were segfaulting
 
116
                // during cleanup.  It was easier to troubleshoot with the
 
117
                // memory management all taking place in one file.
 
118
                                p->buffer = 
 
119
                new LADSPA_Data[engine::getMixer()->framesPerPeriod()];
 
120
                                
 
121
                                if( p->name.toUpper().contains( "IN" ) && 
 
122
                                        m_ladspa->isPortInput( m_key, port ) )
 
123
                                {
 
124
                                        p->rate = CHANNEL_IN;
 
125
                                }
 
126
                                else if( p->name.toUpper().contains( "OUT" ) && 
 
127
                                        m_ladspa->isPortOutput( m_key, port ) )
 
128
                                {
 
129
                                        p->rate = CHANNEL_OUT;
 
130
                                }
 
131
                                else if( m_ladspa->isPortInput( m_key, port ) )
 
132
                                {
 
133
                                        p->rate = AUDIO_RATE_INPUT;
 
134
                                }
 
135
                                else
 
136
                                {
 
137
                                        p->rate = AUDIO_RATE_OUTPUT;
 
138
                                }
 
139
                        }
 
140
                        else
 
141
                        {
 
142
                                p->buffer = new LADSPA_Data;
 
143
                                
 
144
                                if( m_ladspa->isPortInput( m_key, port ) )
 
145
                                {
 
146
                                        p->rate = CONTROL_RATE_INPUT;
 
147
                                }
 
148
                                else
 
149
                                {
 
150
                                        p->rate = CONTROL_RATE_OUTPUT;
 
151
                                }
 
152
                        }
 
153
                        
 
154
                        p->scale = 1.0f;
 
155
                        if( m_ladspa->isPortToggled( m_key, port ) )
 
156
                        {
 
157
                                p->data_type = TOGGLED;
 
158
                        }
 
159
                        else if( m_ladspa->isInteger( m_key, port ) )
 
160
                        {
 
161
                                p->data_type = INTEGER;
 
162
                        }
 
163
                        else if( p->name.toUpper().contains( "(SECONDS)" ) )
 
164
                        {
 
165
                                p->data_type = TIME;
 
166
                                p->scale = 1000.0f;
 
167
                                int loc = p->name.toUpper().indexOf(
 
168
                                                                "(SECONDS)" );
 
169
                                p->name.replace( loc, 9, "(ms)" );
 
170
                        }
 
171
                        else if( p->name.toUpper().contains( "(S)" ) )
 
172
                        {
 
173
                                p->data_type = TIME;
 
174
                                p->scale = 1000.0f;
 
175
                                int loc = p->name.toUpper().indexOf( "(S)" );
 
176
                                p->name.replace( loc, 3, "(ms)" );
 
177
                        }
 
178
                        else if( p->name.toUpper().contains( "(MS)" ) )
 
179
                        {
 
180
                                p->data_type = TIME;
 
181
                                int loc = p->name.toUpper().indexOf( "(MS)" );
 
182
                                p->name.replace( loc, 4, "(ms)" );
 
183
                        }
 
184
                        else
 
185
                        {
 
186
                                p->data_type = FLOAT;
 
187
                        }
 
188
                        
 
189
                        // Get the range and default values.
 
190
                        p->max = m_ladspa->getUpperBound( m_key, port );
 
191
                        if( p->max == NOHINT )
 
192
                        {
 
193
                                p->max = p->name.toUpper() == "GAIN" ? 10.0f :
 
194
                                        1.0f;
 
195
                        }
 
196
                        
 
197
                        if( m_ladspa->areHintsSampleRateDependent( 
 
198
                                                                m_key, port ) )
 
199
                        {
 
200
                                p->max *= engine::getMixer()->sampleRate();
 
201
                        }
 
202
                        
 
203
                        p->min = m_ladspa->getLowerBound( m_key, port );
 
204
                        if( p->min == NOHINT )
 
205
                        {
 
206
                                p->min = 0.0f;
 
207
                        }
 
208
                        
 
209
                        if( m_ladspa->areHintsSampleRateDependent( 
 
210
                                                                m_key, port ) )
 
211
                        {
 
212
                                p->min *= engine::getMixer()->sampleRate();
 
213
                        }
 
214
                                
 
215
                        p->def = m_ladspa->getDefaultSetting( m_key, port );
 
216
                        if( p->def == NOHINT )
 
217
                        {
 
218
                                if( p->data_type != TOGGLED )
 
219
                                {
 
220
                                        p->def = ( p->min + p->max ) / 2.0f;
 
221
                                }
 
222
                                else
 
223
                                {
 
224
                                        p->def = 1.0f;
 
225
                                }
 
226
                        }
 
227
                        
 
228
                        p->max *= p->scale;
 
229
                        p->min *= p->scale;
 
230
                        p->def *= p->scale;
 
231
                        
 
232
                        p->value = p->def;
 
233
                        
 
234
                        
 
235
                        ports.append( p );
 
236
                        
 
237
        // For convenience, keep a separate list of the ports that are used 
 
238
        // to control the processors.
 
239
                        if( p->rate == AUDIO_RATE_INPUT || 
 
240
                                        p->rate == CONTROL_RATE_INPUT )
 
241
                        {
 
242
                                p->control_id = m_controls.count();
 
243
                                m_controls.append( p );
 
244
                        }
 
245
                }
 
246
                m_ports.append( ports );
 
247
        }
 
248
        
 
249
        // Instantiate the processing units.
 
250
        m_descriptor = m_ladspa->getDescriptor( m_key );
 
251
        if( m_descriptor == NULL )
 
252
        {
 
253
                QMessageBox::warning( 0, "Effect", 
 
254
                        "Can't get LADSPA descriptor function: " + m_key.first,
 
255
                        QMessageBox::Ok, QMessageBox::NoButton );
 
256
                setOkay( FALSE );
 
257
                return;
 
258
        }
 
259
        if( m_descriptor->run == NULL )
 
260
        {
 
261
                QMessageBox::warning( 0, "Effect", 
 
262
                        "Plugin has no processor: " + m_key.first,
 
263
                        QMessageBox::Ok, QMessageBox::NoButton );
 
264
                setDontRun( TRUE );
 
265
        }
 
266
        for( ch_cnt_t proc = 0; proc < getProcessorCount(); proc++ )
 
267
        {
 
268
                LADSPA_Handle effect = m_ladspa->instantiate( m_key,
 
269
                                        engine::getMixer()->sampleRate() );
 
270
                if( effect == NULL )
 
271
                {
 
272
                        QMessageBox::warning( 0, "Effect", 
 
273
                                "Can't get LADSPA instance: " + m_key.first,
 
274
                                QMessageBox::Ok, QMessageBox::NoButton );
 
275
                        setOkay( FALSE );
 
276
                        return;
 
277
                }
 
278
                m_handles.append( effect );
 
279
                
 
280
        }
 
281
        
 
282
        // Connect the ports.
 
283
        for( ch_cnt_t proc = 0; proc < getProcessorCount(); proc++ )
 
284
        {
 
285
                for( Uint16 port = 0; port < m_portCount; port++ )
 
286
                {
 
287
                        if( !m_ladspa->connectPort( m_key, 
 
288
                                                m_handles[proc], 
 
289
                                                port, 
 
290
                                                m_ports[proc][port]->buffer ) )
 
291
                        {
 
292
                                QMessageBox::warning( 0, "Effect", 
 
293
                                "Failed to connect port: " + m_key.first, 
 
294
                                QMessageBox::Ok, QMessageBox::NoButton );
 
295
                                setDontRun( TRUE );
 
296
                                return;
 
297
                        }
 
298
                }
 
299
        }
 
300
        
 
301
        // Activate the processing units.
 
302
        for( ch_cnt_t proc = 0; proc < getProcessorCount(); proc++ )
 
303
        {
 
304
                m_ladspa->activate( m_key, m_handles[proc] );
 
305
        }
 
306
}
 
307
 
 
308
 
 
309
 
 
310
 
 
311
ladspaEffect::~ladspaEffect()
 
312
{
 
313
        if( !isOkay() )
 
314
        {
 
315
                return;
 
316
        }
 
317
        
 
318
        for( ch_cnt_t proc = 0; proc < getProcessorCount(); proc++ )
 
319
        {
 
320
                m_ladspa->deactivate( m_key, m_handles[proc] );
 
321
                m_ladspa->cleanup( m_key, m_handles[proc] );
 
322
                for( Uint16 port = 0; port < m_portCount; port++ )
 
323
                {
 
324
                        free( m_ports[proc][port]->buffer );
 
325
                        free( m_ports[proc][port] );
 
326
                }
 
327
                m_ports[proc].clear();
 
328
        }
 
329
        m_ports.clear();
 
330
        m_handles.clear();
 
331
}
 
332
 
 
333
 
 
334
 
 
335
 
 
336
bool FASTCALL ladspaEffect::processAudioBuffer( surroundSampleFrame * _buf, 
 
337
                                                        const fpp_t _frames )
 
338
{
 
339
        if( !isOkay() || dontRun() || !isRunning() || isBypassed() )
 
340
        {
 
341
                return( FALSE );
 
342
        }
 
343
        
 
344
        // Copy the LMMS audio buffer to the LADSPA input buffer and initialize
 
345
        // the control ports.  Need to change this to handle non-in-place-broken
 
346
        // plugins--would speed things up to use the same buffer for both
 
347
        // LMMS and LADSPA.
 
348
        ch_cnt_t channel = 0;
 
349
        for( ch_cnt_t proc = 0; proc < getProcessorCount(); proc++)
 
350
        {
 
351
                for( Uint16 port = 0; port < m_portCount; port++ )
 
352
                {
 
353
                        switch( m_ports[proc][port]->rate )
 
354
                        {
 
355
                                case CHANNEL_IN:
 
356
                                        for( fpp_t frame = 0; 
 
357
                                                frame < _frames; frame++ )
 
358
                                        {
 
359
                                                m_ports[proc][port]->buffer[frame] = 
 
360
                                                        _buf[frame][channel];
 
361
                                        }
 
362
                                        channel++;
 
363
                                        break;
 
364
                                case AUDIO_RATE_INPUT:
 
365
                                        m_ports[proc][port]->value = 
 
366
                                                static_cast<LADSPA_Data>( 
 
367
                                                        m_ports[proc][port]->control->getValue() /
 
368
                                                                m_ports[proc][port]->scale );
 
369
                                        // This only supports control rate ports, so the audio rates are
 
370
                                        // treated as though they were control rate by setting the
 
371
                                        // port buffer to all the same value.
 
372
                                        for( fpp_t frame = 0; 
 
373
                                                frame < _frames; frame++ )
 
374
                                        {
 
375
                                                m_ports[proc][port]->buffer[frame] = 
 
376
                                                        m_ports[proc][port]->value;
 
377
                                        }
 
378
                                        break;
 
379
                                case CONTROL_RATE_INPUT:
 
380
                                        if( m_ports[proc][port]->control ==
 
381
                                                                        NULL )
 
382
                                        {
 
383
                                                break;
 
384
                                        }
 
385
                                        m_ports[proc][port]->value = 
 
386
                                                static_cast<LADSPA_Data>( 
 
387
                                                        m_ports[proc][port]->control->getValue() /
 
388
                                                                m_ports[proc][port]->scale );
 
389
                                        m_ports[proc][port]->buffer[0] = 
 
390
                                                m_ports[proc][port]->value;
 
391
                                        break;
 
392
                                case CHANNEL_OUT:
 
393
                                case AUDIO_RATE_OUTPUT:
 
394
                                case CONTROL_RATE_OUTPUT:
 
395
                                        break;
 
396
                                default:
 
397
                                        break;
 
398
                        }
 
399
                }
 
400
        }
 
401
        
 
402
        // Process the buffers.
 
403
        for( ch_cnt_t proc = 0; proc < getProcessorCount(); proc++ )
 
404
        {
 
405
                (m_descriptor->run)(m_handles[proc], _frames);
 
406
        }
 
407
        
 
408
        // Copy the LADSPA output buffers to the LMMS buffer.
 
409
        double out_sum = 0.0;
 
410
        channel = 0;
 
411
        for( ch_cnt_t proc = 0; proc < getProcessorCount(); proc++)
 
412
        {
 
413
                for( Uint16 port = 0; port < m_portCount; port++ )
 
414
                {
 
415
                        switch( m_ports[proc][port]->rate )
 
416
                        {
 
417
                                case CHANNEL_IN:
 
418
                                case AUDIO_RATE_INPUT:
 
419
                                case CONTROL_RATE_INPUT:
 
420
                                        break;
 
421
                                case CHANNEL_OUT:
 
422
                                        for( fpp_t frame = 0; 
 
423
                                                frame < _frames; frame++ )
 
424
                                        {
 
425
                                                _buf[frame][channel] = 
 
426
                                                        getDryLevel() * 
 
427
                                                        _buf[frame][channel] +
 
428
                                                        getWetLevel() *
 
429
                                                        m_ports[proc][port]->buffer[frame];
 
430
                                                out_sum += 
 
431
                                                        _buf[frame][channel] *
 
432
                                                        _buf[frame][channel];
 
433
                                        }
 
434
                                        channel++;
 
435
                                        break;
 
436
                                case AUDIO_RATE_OUTPUT:
 
437
                                case CONTROL_RATE_OUTPUT:
 
438
                                        break;
 
439
                                default:
 
440
                                        break;
 
441
                        }
 
442
                }
 
443
        }
 
444
        
 
445
        // Check whether we need to continue processing input.  Restart the
 
446
        // counter if the threshold has been exceeded.
 
447
        if( out_sum <= getGate() )
 
448
        {
 
449
                incrementBufferCount();
 
450
                if( getBufferCount() > getTimeout() )
 
451
                {
 
452
                        stopRunning();
 
453
                        resetBufferCount();
 
454
                }
 
455
        }
 
456
        else
 
457
        {
 
458
                resetBufferCount();
 
459
        }
 
460
        
 
461
        return( isRunning() );
 
462
}
 
463
 
 
464
 
 
465
 
 
466
 
 
467
void FASTCALL ladspaEffect::setControl( Uint16 _control, LADSPA_Data _value )
 
468
{
 
469
        if( !isOkay() )
 
470
        {
 
471
                return;
 
472
        }
 
473
        m_controls[_control]->value = _value;
 
474
}
 
475
 
 
476
 
 
477
#undef indexOf
 
478
 
 
479
extern "C"
 
480
{
 
481
 
 
482
// neccessary for getting instance out of shared lib
 
483
plugin * lmms_plugin_main( void * _data )
 
484
{
 
485
        return( new ladspaEffect(
 
486
                static_cast<const plugin::descriptor::subPluginFeatures::key *>(
 
487
                                                                _data ) ) );
 
488
}
 
489
 
 
490
}
 
491