Update NTK.
[nondaw.git] / mixer / src / Plugin_Module.C
blobaff05d83a679a34e5bb92d92ec2b8116dc510117
2 /*******************************************************************************/
3 /* Copyright (C) 2009 Jonathan Moore Liles                                     */
4 /*                                                                             */
5 /* This program is free software; you can redistribute it and/or modify it     */
6 /* under the terms of the GNU General Public License as published by the       */
7 /* Free Software Foundation; either version 2 of the License, or (at your      */
8 /* option) any later version.                                                  */
9 /*                                                                             */
10 /* This program is distributed in the hope that it will be useful, but WITHOUT */
11 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       */
12 /* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for   */
13 /* more details.                                                               */
14 /*                                                                             */
15 /* You should have received a copy of the GNU General Public License along     */
16 /* with This program; see the file COPYING.  If not,write to the Free Software */
17 /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
18 /*******************************************************************************/
20 /* Filter module. Can host LADPSA Plugins, or can be inherited from to make internal
21    modules with special features and appearance. */
23 #include "const.h"
25 #include <string.h>
26 #include <vector>
27 #include <string>
28 #include <ladspa.h>
29 #include <stdlib.h>
30 #include <math.h>
32 #include <FL/fl_draw.H>
33 #include <FL/Fl_Group.H>
34 #include <FL/Fl_Menu_Button.H>
36 #include "Plugin_Module.H"
38 #include "debug.h"
40 #define HAVE_LIBLRDF 1
41 #include "LADSPAInfo.h"
43 #include "Engine/Engine.H"
47 static LADSPAInfo *ladspainfo;
48 Thread* Plugin_Module::plugin_discover_thread;
50 /* keep this out of the header to avoid spreading ladspa.h dependency */
51 struct Plugin_Module::ImplementationData
53     const LADSPA_Descriptor     *descriptor;
54 //    std::vector<LADSPA_Data*>    m_LADSPABufVec;
55     std::vector<LADSPA_Handle>   handle;
60 Plugin_Module::Plugin_Module ( ) : Module( 50, 35, name() )
62     init();
64     end();
66     log_create();
69 Plugin_Module::~Plugin_Module ( )
71     log_destroy();
72     plugin_instances( 0 );
77 void
78 Plugin_Module::get ( Log_Entry &e ) const
80 //    char s[512];
81 //    snprintf( s, sizeof( s ), "ladspa:%lu", _idata->descriptor->UniqueID );
82     e.add( ":plugin_id", _idata->descriptor->UniqueID );
84     Module::get( e );
87 void
88 Plugin_Module::set ( Log_Entry &e )
90     for ( int i = 0; i < e.size(); ++i )
91     {
92         const char *s, *v;
94         e.get( i, &s, &v );
96         if ( ! strcmp( s, ":plugin_id" ) )
97         {
98             load( (unsigned long) atoll ( v ) );
99         }
100     }
102     Module::set( e );
107 void
108 Plugin_Module::add_plugins_to_menu ( Fl_Menu_Button *menu )
110     Plugin_Module::Plugin_Info *pia = Plugin_Module::get_all_plugins();
112     char path[1024];
113     for ( Plugin_Module::Plugin_Info *pi = pia; pi->path; ++pi )
114     {
115         snprintf( path, sizeof( path ), "Plugin/%s", pi->path );
117         menu->add(path, 0, NULL, new unsigned long( pi->id ), 0 );
118     }
120     delete[] pia;
123 /* allow the user to pick a plugin */
124 Plugin_Module *
125 Plugin_Module::pick_plugin ( void )
127     /**************/
128     /* build menu */
129     /**************/
131     Fl_Menu_Button *menu = new Fl_Menu_Button( 0, 0, 400, 400 );
132     menu->type( Fl_Menu_Button::POPUP3 );
134     Plugin_Module::Plugin_Info *pia = Plugin_Module::get_all_plugins();
136     for ( Plugin_Module::Plugin_Info *pi = pia; pi->path; ++pi )
137     {
138         menu->add(pi->path, 0, NULL, pi, 0 );
139     }
141     menu->popup();
143     if ( menu->value() <= 0 )
144         return NULL;
146     /************************/
147     /* load selected plugin */
148     /************************/
150     Plugin_Module::Plugin_Info *pi = (Plugin_Module::Plugin_Info*)menu->menu()[ menu->value() ].user_data();
152     if ( ! pi )
153         return NULL;
155     Plugin_Module *m = new Plugin_Module();
157     m->load( pi->id );
159     delete[] pia;
161     return m;
165 void
166 Plugin_Module::init ( void )
168     _idata = new Plugin_Module::ImplementationData();
169     _idata->handle.clear();
170     _active = false;
171     _crosswire = false;
173     align( (Fl_Align)FL_ALIGN_CENTER | FL_ALIGN_INSIDE );
174     color( (Fl_Color)fl_color_average( FL_BLUE, FL_GREEN, 0.5f ) );
175     int tw, th, tx, ty;
177     bbox( tx, ty, tw, th );
181 Plugin_Module::can_support_inputs ( int n )
183     /* this is the simple case */
184     if ( plugin_ins() == n )
185         return plugin_outs();
186     /* e.g. MONO going into STEREO */
187     /* we'll duplicate our inputs */
188     else if ( n < plugin_ins() &&
189               1 == n  )
190     {
191         return plugin_outs();
192     }
193     /* e.g. STEREO going into MONO */
194     /* we'll run multiple instances of the plugin */
195     else if ( n > plugin_ins() &&
196               ( plugin_ins() == 1 && plugin_outs() == 1 ) )
197     {
198         return n;
199     }
201     return -1;
204 bool
205 Plugin_Module::configure_inputs( int n )
207     int inst = _idata->handle.size();
209     if ( ninputs() != n )
210     {
211         _crosswire = false;
213         if ( n != ninputs() )
214         {
215             if ( 1 == n && plugin_ins() > 1 )
216             {
217                 DMESSAGE( "Cross-wiring plugin inputs" );
218                 _crosswire = true;
220                 audio_input.clear();
222                 for ( int i = n; i--; )
223                     audio_input.push_back( Port( this, Port::INPUT, Port::AUDIO ) );
224             }
225             else if ( n >= plugin_ins() &&
226                       ( plugin_ins() == 1 && plugin_outs() == 1 ) )
227             {
228                 DMESSAGE( "Running multiple instances of plugin" );
230                 audio_input.clear();
231                 audio_output.clear();
233                 for ( int i = n; i--; )
234                 {
235                     add_port( Port( this, Port::INPUT, Port::AUDIO ) );
236                     add_port( Port( this, Port::OUTPUT, Port::AUDIO ) );
237                 }
239                 inst = n;
240             }
241             else if ( n == plugin_ins() )
242             {
243                 DMESSAGE( "Plugin input configuration is a perfect match" );
244             }
245             else
246             {
247                 DMESSAGE( "Unsupported input configuration" );
248                 return false;
249             }
250         }
251     }
253     if ( _active )
254         deactivate();
256     if ( plugin_instances( inst ) )
257         instances( inst );
258     else
259         return false;
261     if ( ! _active )
262         activate();
264     return true;
267 void *
268 Plugin_Module::discover_thread ( void * )
270     THREAD_ASSERT( Plugin_Discover );
272     DMESSAGE( "Discovering plugins in the background" );
274     ladspainfo = new LADSPAInfo();
276     return NULL;
279 /* Spawn a background thread for plugin discovery */
280 void
281 Plugin_Module::spawn_discover_thread ( void )
283     if ( plugin_discover_thread )
284     {
285         FATAL( "Plugin discovery thread is already running or has completed" );
286     }
288     plugin_discover_thread = new Thread( "Plugin_Discover" );
290     plugin_discover_thread->clone( &Plugin_Module::discover_thread, NULL );
293 void
294 Plugin_Module::join_discover_thread ( void )
296     plugin_discover_thread->join();
299 /* return a list of available plugins */
300 Plugin_Module::Plugin_Info *
301 Plugin_Module::get_all_plugins ( void )
303     if ( !ladspainfo )
304     {
305         if ( ! plugin_discover_thread )
306             ladspainfo = new LADSPAInfo();
307         else
308             plugin_discover_thread->join();
309     }
311     std::vector<LADSPAInfo::PluginEntry> plugins = ladspainfo->GetMenuList();
313     Plugin_Info* pi = new Plugin_Info[plugins.size() + 1];
315     int j = 0;
316     for (std::vector<LADSPAInfo::PluginEntry>::iterator i=plugins.begin();
317          i!=plugins.end(); i++, j++)
318     {
319         pi[j].path = i->Name.c_str();
320         pi[j].id = i->UniqueID;
321     }
323     return pi;
326 bool
327 Plugin_Module::plugin_instances ( unsigned int n )
329     if ( _idata->handle.size() > n )
330     {
331         for ( int i = _idata->handle.size() - n; i--; )
332         {
333             DMESSAGE( "Destroying plugin instance" );
335             LADSPA_Handle h = _idata->handle.back();
337             if ( _idata->descriptor->deactivate )
338                 _idata->descriptor->deactivate( h );
339             if ( _idata->descriptor->cleanup )
340                 _idata->descriptor->cleanup( h );
342             _idata->handle.pop_back();
343         }
344     }
345     else if ( _idata->handle.size() < n )
346     {
347         for ( int i = n - _idata->handle.size(); i--; )
348         {
349             LADSPA_Handle h;
351             DMESSAGE( "Instantiating plugin..." );
353             if ( ! (h = _idata->descriptor->instantiate( _idata->descriptor, Engine::sample_rate() ) ) )
354             {
355                 WARNING( "Failed to instantiate plugin" );
356                 return false;
357             }
359             DMESSAGE( "Instantiated: %p", h );
361             _idata->handle.push_back( h );
363             DMESSAGE( "Connecting control ports..." );
365             int ij = 0;
366             int oj = 0;
367             for ( unsigned int k = 0; k < _idata->descriptor->PortCount; ++k )
368             {
369                 if ( LADSPA_IS_PORT_CONTROL( _idata->descriptor->PortDescriptors[k] ) )
370                 {
371                     if ( LADSPA_IS_PORT_INPUT( _idata->descriptor->PortDescriptors[k] ) )
372                         _idata->descriptor->connect_port( h, k, (LADSPA_Data*)control_input[ij++].buffer() );
373                     else if ( LADSPA_IS_PORT_OUTPUT( _idata->descriptor->PortDescriptors[k] ) )
374                         _idata->descriptor->connect_port( h, k, (LADSPA_Data*)control_output[oj++].buffer() );
375                 }
376             }
378             // connect ports to magic bogus value to aid debugging.
379             for ( unsigned int k = 0; k < _idata->descriptor->PortCount; ++k )
380                 if ( LADSPA_IS_PORT_AUDIO( _idata->descriptor->PortDescriptors[k] ) )
381                     _idata->descriptor->connect_port( h, k, (LADSPA_Data*)0x42 );
383         }
384     }
386     return true;
389 bool
390 Plugin_Module::load ( unsigned long id )
392     if ( !ladspainfo )
393     {
394         if ( ! plugin_discover_thread )
395             ladspainfo = new LADSPAInfo();
396         else
397             plugin_discover_thread->join();
398     }
400     _idata->descriptor = ladspainfo->GetDescriptorByID( id );
402     label( _idata->descriptor->Name );
404     _plugin_ins = _plugin_outs = 0;
406     if ( _idata->descriptor )
407     {
408         if ( LADSPA_IS_INPLACE_BROKEN( _idata->descriptor->Properties ) )
409         {
410             WARNING( "Cannot use this plugin because it is incapable of processing audio in-place" );
411             return false;
412         }
413         else if ( ! LADSPA_IS_HARD_RT_CAPABLE( _idata->descriptor->Properties ) )
414         {
415             WARNING( "Cannot use this plugin because it is incapable of hard real-time operation" );
416             return false;
417         }
419         MESSAGE( "Name: %s", _idata->descriptor->Name );
421         for ( unsigned int i = 0; i < _idata->descriptor->PortCount; ++i )
422         {
423             if ( LADSPA_IS_PORT_AUDIO( _idata->descriptor->PortDescriptors[i] ) )
424             {
425                 if ( LADSPA_IS_PORT_INPUT( _idata->descriptor->PortDescriptors[i] ) )
426                 {
427                     add_port( Port( this, Port::INPUT, Port::AUDIO, _idata->descriptor->PortNames[ i ] ) );
428                     _plugin_ins++;
429                 }
430                 else if (LADSPA_IS_PORT_OUTPUT(_idata->descriptor->PortDescriptors[i]))
431                 {
432                     _plugin_outs++;
433                     add_port( Port( this, Port::OUTPUT, Port::AUDIO, _idata->descriptor->PortNames[ i ] ) );
434                 }
435             }
436         }
438         MESSAGE( "Plugin has %i inputs and %i outputs", _plugin_ins, _plugin_outs);
440         for ( unsigned int i = 0; i < _idata->descriptor->PortCount; ++i )
441         {
442             if ( LADSPA_IS_PORT_CONTROL( _idata->descriptor->PortDescriptors[i] ) )
443             {
444                 Port::Direction d = Port::INPUT;
446                 if ( LADSPA_IS_PORT_INPUT( _idata->descriptor->PortDescriptors[i] ) )
447                 {
448                     d = Port::INPUT;
449                 }
450                 else if ( LADSPA_IS_PORT_OUTPUT( _idata->descriptor->PortDescriptors[i] ) )
451                 {
452                     d = Port::OUTPUT;
453                 }
455                 Port p( this, d, Port::CONTROL, _idata->descriptor->PortNames[ i ] );
458                 LADSPA_PortRangeHintDescriptor hd = _idata->descriptor->PortRangeHints[i].HintDescriptor;
460                 if ( LADSPA_IS_HINT_BOUNDED_BELOW(hd) )
461                 {
462                     p.hints.ranged = true;
463                     p.hints.minimum = _idata->descriptor->PortRangeHints[i].LowerBound;
464                     if ( LADSPA_IS_HINT_SAMPLE_RATE(hd) )
465                     {
466                         p.hints.minimum *= Engine::sample_rate();
467                     }
468                 }
469                 if ( LADSPA_IS_HINT_BOUNDED_ABOVE(hd) )
470                 {
471                     p.hints.ranged = true;
472                     p.hints.maximum = _idata->descriptor->PortRangeHints[i].UpperBound;
473                     if ( LADSPA_IS_HINT_SAMPLE_RATE(hd) )
474                     {
475                         p.hints.maximum *= Engine::sample_rate();
476                     }
477                 }
479                 if ( LADSPA_IS_HINT_HAS_DEFAULT(hd) )
480                 {
482                     float Max=1.0f, Min=-1.0f, Default=0.0f;
483                     int Port=i;
485                     // Get the bounding hints for the port
486                     LADSPA_PortRangeHintDescriptor HintDesc=_idata->descriptor->PortRangeHints[Port].HintDescriptor;
487                     if (LADSPA_IS_HINT_BOUNDED_BELOW(HintDesc))
488                     {
489                         Min=_idata->descriptor->PortRangeHints[Port].LowerBound;
490                         if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc))
491                         {
492                             Min*=Engine::sample_rate();
493                         }
494                     }
495                     if (LADSPA_IS_HINT_BOUNDED_ABOVE(HintDesc))
496                     {
497                         Max=_idata->descriptor->PortRangeHints[Port].UpperBound;
498                         if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc))
499                         {
500                             Max*=Engine::sample_rate();
501                         }
502                     }
504 #ifdef LADSPA_VERSION
505 // We've got a version of the header that supports port defaults
506                     if (LADSPA_IS_HINT_HAS_DEFAULT(HintDesc)) {
507                         // LADSPA_HINT_DEFAULT_0 is assumed anyway, so we don't check for it
508                         if (LADSPA_IS_HINT_DEFAULT_1(HintDesc)) {
509                             Default = 1.0f;
510                         } else if (LADSPA_IS_HINT_DEFAULT_100(HintDesc)) {
511                             Default = 100.0f;
512                         } else if (LADSPA_IS_HINT_DEFAULT_440(HintDesc)) {
513                             Default = 440.0f;
514                         } else {
515                             // These hints may be affected by SAMPLERATE, LOGARITHMIC and INTEGER
516                             if (LADSPA_IS_HINT_DEFAULT_MINIMUM(HintDesc) &&
517                                 LADSPA_IS_HINT_BOUNDED_BELOW(HintDesc)) {
518                                 Default=_idata->descriptor->PortRangeHints[Port].LowerBound;
519                             } else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(HintDesc) &&
520                                        LADSPA_IS_HINT_BOUNDED_ABOVE(HintDesc)) {
521                                 Default=_idata->descriptor->PortRangeHints[Port].UpperBound;
522                             } else if (LADSPA_IS_HINT_BOUNDED_BELOW(HintDesc) &&
523                                        LADSPA_IS_HINT_BOUNDED_ABOVE(HintDesc)) {
524                                 // These hints require both upper and lower bounds
525                                 float lp = 0.0f, up = 0.0f;
526                                 float min = _idata->descriptor->PortRangeHints[Port].LowerBound;
527                                 float max = _idata->descriptor->PortRangeHints[Port].UpperBound;
528                                 if (LADSPA_IS_HINT_DEFAULT_LOW(HintDesc)) {
529                                     lp = 0.75f;
530                                     up = 0.25f;
531                                 } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(HintDesc)) {
532                                     lp = 0.5f;
533                                     up = 0.5f;
534                                 } else if (LADSPA_IS_HINT_DEFAULT_HIGH(HintDesc)) {
535                                     lp = 0.25f;
536                                     up = 0.75f;
537                                 }
539                                 if (LADSPA_IS_HINT_LOGARITHMIC(HintDesc)) {
541                                     p.hints.type = Port::Hints::LOGARITHMIC;
543                                     if (min==0.0f || max==0.0f) {
544                                         // Zero at either end means zero no matter
545                                         // where hint is at, since:
546                                         //  log(n->0) -> Infinity
547                                         Default = 0.0f;
548                                     } else {
549                                         // Catch negatives
550                                         bool neg_min = min < 0.0f ? true : false;
551                                         bool neg_max = max < 0.0f ? true : false;
553                                         if (!neg_min && !neg_max) {
554                                             Default = exp(::log(min) * lp + ::log(max) * up);
555                                         } else if (neg_min && neg_max) {
556                                             Default = -exp(::log(-min) * lp + ::log(-max) * up);
557                                         } else {
558                                             // Logarithmic range has asymptote
559                                             // so just use linear scale
560                                             Default = min * lp + max * up;
561                                         }
562                                     }
563                                 } else {
564                                     Default = min * lp + max * up;
565                                 }
566                             }
567                             if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc)) {
568                                 Default *= Engine::sample_rate();
569                             }
570                             if (LADSPA_IS_HINT_INTEGER(HintDesc)) {
571                                 if ( p.hints.ranged &&
572                                      0 == p.hints.minimum &&
573                                      1 == p.hints.maximum )
574                                     p.hints.type = Port::Hints::BOOLEAN;
575                                 else
576                                     p.hints.type = Port::Hints::INTEGER;
577                                 Default = floorf(Default);
578                             }
579                             if (LADSPA_IS_HINT_TOGGLED(HintDesc)){
580                                 p.hints.type = Port::Hints::BOOLEAN;
581                             }
582                         }
583                     }
584 #else
585                     Default = 0.0f;
586 #endif
587                     p.hints.default_value = Default;
588                 }
590                 float *control_value = new float;
592                 *control_value = p.hints.default_value;
594                 p.connect_to( control_value );
596                 add_port( p );
598                 DMESSAGE( "Plugin has control port \"%s\" (default: %f)", _idata->descriptor->PortNames[ i ], p.hints.default_value );
599             }
600         }
601     }
602     else
603     {
604         WARNING( "Failed to load plugin" );
605         return false;
606     }
608     return plugin_instances( 1 );
611 void
612 Plugin_Module::set_input_buffer ( int n, void *buf )
614     LADSPA_Handle h;
616     if ( instances() > 1 )
617     {
618         h = _idata->handle[n];
619         n = 0;
620     }
621     else
622         h = _idata->handle[0];
624     for ( unsigned int i = 0; i < _idata->descriptor->PortCount; ++i )
625         if ( LADSPA_IS_PORT_INPUT( _idata->descriptor->PortDescriptors[i] ) &&
626              LADSPA_IS_PORT_AUDIO( _idata->descriptor->PortDescriptors[i] ) )
627             if ( n-- == 0 )
628                 _idata->descriptor->connect_port( h, i, (LADSPA_Data*)buf );
631 void
632 Plugin_Module::set_output_buffer ( int n, void *buf )
634     LADSPA_Handle h;
636     if ( instances() > 1 )
637     {
638         h = _idata->handle[n];
639         n = 0;
640     }
641     else
642         h = _idata->handle[0];
644     for ( unsigned int i = 0; i < _idata->descriptor->PortCount; ++i )
645         if ( LADSPA_IS_PORT_OUTPUT( _idata->descriptor->PortDescriptors[i] ) &&
646              LADSPA_IS_PORT_AUDIO( _idata->descriptor->PortDescriptors[i] ) )
647             if ( n-- == 0 )
648                 _idata->descriptor->connect_port( h, i, (LADSPA_Data*)buf );
651 void
652 Plugin_Module::activate ( void )
654     if ( _active )
655         FATAL( "Attempt to activate already active plugin" );
657     if ( _idata->descriptor->activate )
658         for ( unsigned int i = 0; i < _idata->handle.size(); ++i )
659             _idata->descriptor->activate( _idata->handle[i] );
661     _active = true;
664 void
665 Plugin_Module::deactivate( void )
667     if ( _idata->descriptor->deactivate )
668         for ( unsigned int i = 0; i < _idata->handle.size(); ++i )
669             _idata->descriptor->activate( _idata->handle[i] );
671     _active = false;
674 void
675 Plugin_Module::handle_port_connection_change ( void )
677 //    DMESSAGE( "Connecting audio ports" );
679     if ( _crosswire )
680     {
681         for ( int i = 0; i < plugin_ins(); ++i )
682             set_input_buffer( i, audio_input[0].buffer() );
683     }
684     else
685     {
686         for ( unsigned int i = 0; i < audio_input.size(); ++i )
687             set_input_buffer( i, audio_input[i].buffer() );
688     }
690     for ( unsigned int i = 0; i < audio_output.size(); ++i )
691         set_output_buffer( i, audio_output[i].buffer() );
696 /**********/
697 /* Engine */
698 /**********/
700 void
701 Plugin_Module::process ( nframes_t nframes )
703     handle_port_connection_change();
705     if ( _active )
706         for ( unsigned int i = 0; i < _idata->handle.size(); ++i )
707             _idata->descriptor->run( _idata->handle[i], nframes );