Non reinvents the DAW. Powerful enough to form a complete studio, fast and light enough to run on low-end hardware like the eeePC or Raspberry Pi, and so reliable that it can be used live https://non.tuxfamily.org/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

817 lines
24KB

  1. /*******************************************************************************/
  2. /* Copyright (C) 2009 Jonathan Moore Liles */
  3. /* */
  4. /* This program is free software; you can redistribute it and/or modify it */
  5. /* under the terms of the GNU General Public License as published by the */
  6. /* Free Software Foundation; either version 2 of the License, or (at your */
  7. /* option) any later version. */
  8. /* */
  9. /* This program is distributed in the hope that it will be useful, but WITHOUT */
  10. /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
  11. /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
  12. /* more details. */
  13. /* */
  14. /* You should have received a copy of the GNU General Public License along */
  15. /* with This program; see the file COPYING. If not,write to the Free Software */
  16. /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  17. /*******************************************************************************/
  18. /* Filter module. Can host LADPSA Plugins, or can be inherited from to make internal
  19. modules with special features and appearance. */
  20. #include "const.h"
  21. #include <string.h>
  22. #include <vector>
  23. #include <string>
  24. #include <ladspa.h>
  25. #include <stdlib.h>
  26. #include <math.h>
  27. #include <FL/fl_draw.H>
  28. #include <FL/Fl_Group.H>
  29. #include <FL/Fl_Menu_Button.H>
  30. #include "Plugin_Module.H"
  31. #include "debug.h"
  32. #define HAVE_LIBLRDF 1
  33. #include "LADSPAInfo.h"
  34. #include "Chain.H"
  35. //#include "Client/Client.H"
  36. #include <dsp.h>
  37. #include <algorithm>
  38. static LADSPAInfo *ladspainfo;
  39. Thread* Plugin_Module::plugin_discover_thread;
  40. /* keep this out of the header to avoid spreading ladspa.h dependency */
  41. struct Plugin_Module::ImplementationData
  42. {
  43. const LADSPA_Descriptor *descriptor;
  44. // std::vector<LADSPA_Data*> m_LADSPABufVec;
  45. std::vector<LADSPA_Handle> handle;
  46. };
  47. Plugin_Module::Plugin_Module ( ) : Module( 50, 35, name() )
  48. {
  49. init();
  50. end();
  51. log_create();
  52. }
  53. Plugin_Module::~Plugin_Module ( )
  54. {
  55. log_destroy();
  56. plugin_instances( 0 );
  57. }
  58. void
  59. Plugin_Module::get ( Log_Entry &e ) const
  60. {
  61. // char s[512];
  62. // snprintf( s, sizeof( s ), "ladspa:%lu", _idata->descriptor->UniqueID );
  63. e.add( ":plugin_id", _idata->descriptor->UniqueID );
  64. /* these help us display the module on systems which are missing this plugin */
  65. e.add( ":plugin_ins", _plugin_ins );
  66. e.add( ":plugin_outs", _plugin_outs );
  67. Module::get( e );
  68. }
  69. void
  70. Plugin_Module::set ( Log_Entry &e )
  71. {
  72. for ( int i = 0; i < e.size(); ++i )
  73. {
  74. const char *s, *v;
  75. e.get( i, &s, &v );
  76. if ( ! strcmp( s, ":plugin_id" ) )
  77. {
  78. load( (unsigned long) atoll ( v ) );
  79. }
  80. else if ( ! strcmp( s, ":plugin_ins" ) )
  81. {
  82. _plugin_ins = atoi( v );
  83. }
  84. else if ( ! strcmp( s, ":plugin_outs" ) )
  85. {
  86. _plugin_outs = atoi( v );
  87. }
  88. }
  89. Module::set( e );
  90. }
  91. void
  92. Plugin_Module::init ( void )
  93. {
  94. _latency = 0;
  95. _last_latency = 0;
  96. _idata = new Plugin_Module::ImplementationData();
  97. _idata->handle.clear();
  98. /* module will be bypassed until plugin is loaded */
  99. _bypass = true;
  100. _crosswire = false;
  101. align( (Fl_Align)FL_ALIGN_CENTER | FL_ALIGN_INSIDE );
  102. // color( (Fl_Color)fl_color_average( FL_MAGENTA, FL_WHITE, 0.5f ) );
  103. int tw, th, tx, ty;
  104. bbox( tx, ty, tw, th );
  105. }
  106. void
  107. Plugin_Module::update ( void )
  108. {
  109. if ( _last_latency != _latency )
  110. {
  111. DMESSAGE( "Plugin latency changed to %lu", (unsigned long)_latency );
  112. chain()->client()->recompute_latencies();
  113. }
  114. _last_latency = _latency;
  115. }
  116. int
  117. Plugin_Module::can_support_inputs ( int n )
  118. {
  119. /* this is the simple case */
  120. if ( plugin_ins() == n )
  121. return plugin_outs();
  122. /* e.g. MONO going into STEREO */
  123. /* we'll duplicate our inputs */
  124. else if ( n < plugin_ins() &&
  125. 1 == n )
  126. {
  127. return plugin_outs();
  128. }
  129. /* e.g. STEREO going into MONO */
  130. /* we'll run multiple instances of the plugin */
  131. else if ( n > plugin_ins() &&
  132. ( plugin_ins() == 1 && plugin_outs() == 1 ) )
  133. {
  134. return n;
  135. }
  136. return -1;
  137. }
  138. bool
  139. Plugin_Module::configure_inputs( int n )
  140. {
  141. unsigned int inst = _idata->handle.size();
  142. if ( ninputs() != n )
  143. {
  144. _crosswire = false;
  145. if ( n != ninputs() )
  146. {
  147. if ( 1 == n && plugin_ins() > 1 )
  148. {
  149. DMESSAGE( "Cross-wiring plugin inputs" );
  150. _crosswire = true;
  151. audio_input.clear();
  152. for ( int i = n; i--; )
  153. audio_input.push_back( Port( this, Port::INPUT, Port::AUDIO ) );
  154. }
  155. else if ( n >= plugin_ins() &&
  156. ( plugin_ins() == 1 && plugin_outs() == 1 ) )
  157. {
  158. DMESSAGE( "Running multiple instances of plugin" );
  159. audio_input.clear();
  160. audio_output.clear();
  161. for ( int i = n; i--; )
  162. {
  163. add_port( Port( this, Port::INPUT, Port::AUDIO ) );
  164. add_port( Port( this, Port::OUTPUT, Port::AUDIO ) );
  165. }
  166. inst = n;
  167. }
  168. else if ( n == plugin_ins() )
  169. {
  170. DMESSAGE( "Plugin input configuration is a perfect match" );
  171. }
  172. else
  173. {
  174. DMESSAGE( "Unsupported input configuration" );
  175. return false;
  176. }
  177. }
  178. }
  179. if ( loaded() )
  180. {
  181. bool b = bypass();
  182. if ( inst != _idata->handle.size() )
  183. {
  184. if ( !b )
  185. deactivate();
  186. if ( plugin_instances( inst ) )
  187. instances( inst );
  188. else
  189. return false;
  190. if ( !b )
  191. activate();
  192. }
  193. }
  194. return true;
  195. }
  196. void *
  197. Plugin_Module::discover_thread ( void * )
  198. {
  199. THREAD_ASSERT( Plugin_Discover );
  200. DMESSAGE( "Discovering plugins in the background" );
  201. ladspainfo = new LADSPAInfo();
  202. return NULL;
  203. }
  204. /* Spawn a background thread for plugin discovery */
  205. void
  206. Plugin_Module::spawn_discover_thread ( void )
  207. {
  208. if ( plugin_discover_thread )
  209. {
  210. FATAL( "Plugin discovery thread is already running or has completed" );
  211. }
  212. plugin_discover_thread = new Thread( "Plugin_Discover" );
  213. plugin_discover_thread->clone( &Plugin_Module::discover_thread, NULL );
  214. }
  215. void
  216. Plugin_Module::join_discover_thread ( void )
  217. {
  218. plugin_discover_thread->join();
  219. }
  220. /* return a list of available plugins */
  221. std::list<Plugin_Module::Plugin_Info>
  222. Plugin_Module::get_all_plugins ( void )
  223. {
  224. if ( !ladspainfo )
  225. {
  226. if ( ! plugin_discover_thread )
  227. ladspainfo = new LADSPAInfo();
  228. else
  229. plugin_discover_thread->join();
  230. }
  231. std::vector<LADSPAInfo::PluginInfo> plugins = ladspainfo->GetPluginInfo();
  232. std::list<Plugin_Module::Plugin_Info> pr;
  233. int j = 0;
  234. for (std::vector<LADSPAInfo::PluginInfo>::iterator i=plugins.begin();
  235. i!=plugins.end(); i++, j++)
  236. {
  237. Plugin_Info pi;
  238. // pi[j].path = i->Name.c_str();
  239. pi.path = NULL;
  240. pi.id = i->UniqueID;
  241. pi.author = i->Maker.c_str();
  242. pi.name = i->Name.c_str();
  243. pi.audio_inputs = i->AudioInputs;
  244. pi.audio_outputs = i->AudioOutputs;
  245. pi.category = "Unclassified";
  246. pr.push_back( pi );
  247. }
  248. pr.sort();
  249. const std::vector<LADSPAInfo::PluginEntry> pe = ladspainfo->GetMenuList();
  250. for (std::vector<LADSPAInfo::PluginEntry>::const_iterator i= pe.begin();
  251. i !=pe.end(); i++ )
  252. {
  253. for ( std::list<Plugin_Info>::iterator j = pr.begin(); j != pr.end(); j++ )
  254. {
  255. if ( j->id == i->UniqueID )
  256. {
  257. j->category = i->Category.c_str();
  258. }
  259. }
  260. }
  261. return pr;
  262. }
  263. bool
  264. Plugin_Module::plugin_instances ( unsigned int n )
  265. {
  266. if ( _idata->handle.size() > n )
  267. {
  268. for ( int i = _idata->handle.size() - n; i--; )
  269. {
  270. DMESSAGE( "Destroying plugin instance" );
  271. LADSPA_Handle h = _idata->handle.back();
  272. if ( _idata->descriptor->deactivate )
  273. _idata->descriptor->deactivate( h );
  274. if ( _idata->descriptor->cleanup )
  275. _idata->descriptor->cleanup( h );
  276. _idata->handle.pop_back();
  277. }
  278. }
  279. else if ( _idata->handle.size() < n )
  280. {
  281. for ( int i = n - _idata->handle.size(); i--; )
  282. {
  283. LADSPA_Handle h;
  284. DMESSAGE( "Instantiating plugin... with sample rate %lu", (unsigned long)sample_rate());
  285. if ( ! (h = _idata->descriptor->instantiate( _idata->descriptor, sample_rate() ) ) )
  286. {
  287. WARNING( "Failed to instantiate plugin" );
  288. return false;
  289. }
  290. DMESSAGE( "Instantiated: %p", h );
  291. _idata->handle.push_back( h );
  292. DMESSAGE( "Connecting control ports..." );
  293. int ij = 0;
  294. int oj = 0;
  295. for ( unsigned int k = 0; k < _idata->descriptor->PortCount; ++k )
  296. {
  297. if ( LADSPA_IS_PORT_CONTROL( _idata->descriptor->PortDescriptors[k] ) )
  298. {
  299. if ( LADSPA_IS_PORT_INPUT( _idata->descriptor->PortDescriptors[k] ) )
  300. _idata->descriptor->connect_port( h, k, (LADSPA_Data*)control_input[ij++].buffer() );
  301. else if ( LADSPA_IS_PORT_OUTPUT( _idata->descriptor->PortDescriptors[k] ) )
  302. _idata->descriptor->connect_port( h, k, (LADSPA_Data*)control_output[oj++].buffer() );
  303. }
  304. }
  305. // connect ports to magic bogus value to aid debugging.
  306. for ( unsigned int k = 0; k < _idata->descriptor->PortCount; ++k )
  307. if ( LADSPA_IS_PORT_AUDIO( _idata->descriptor->PortDescriptors[k] ) )
  308. _idata->descriptor->connect_port( h, k, (LADSPA_Data*)0x42 );
  309. }
  310. }
  311. return true;
  312. }
  313. void
  314. Plugin_Module::bypass ( bool v )
  315. {
  316. if ( v != bypass() )
  317. {
  318. if ( v )
  319. deactivate();
  320. else
  321. activate();
  322. }
  323. }
  324. nframes_t
  325. Plugin_Module::get_plugin_latency ( void ) const
  326. {
  327. for ( unsigned int i = ncontrol_outputs(); i--; )
  328. {
  329. if ( !strcasecmp( "latency", control_output[i].name() ) )
  330. {
  331. return control_output[i].control_value();
  332. }
  333. }
  334. return 0;
  335. }
  336. nframes_t
  337. Plugin_Module::get_latency ( JACK::Port::direction_e dir ) const
  338. {
  339. nframes_t latency = Module::get_latency( dir );
  340. latency += get_plugin_latency();
  341. return latency;
  342. }
  343. bool
  344. Plugin_Module::load ( unsigned long id )
  345. {
  346. if ( !ladspainfo )
  347. {
  348. if ( ! plugin_discover_thread )
  349. ladspainfo = new LADSPAInfo();
  350. else
  351. plugin_discover_thread->join();
  352. }
  353. _idata->descriptor = ladspainfo->GetDescriptorByID( id );
  354. _plugin_ins = _plugin_outs = 0;
  355. if ( ! _idata->descriptor )
  356. {
  357. /* unknown plugin ID */
  358. WARNING( "Unknown plugin ID: %lu", id );
  359. label( "----" );
  360. return false;
  361. }
  362. label( _idata->descriptor->Name );
  363. if ( _idata->descriptor )
  364. {
  365. if ( LADSPA_IS_INPLACE_BROKEN( _idata->descriptor->Properties ) )
  366. {
  367. WARNING( "Cannot use this plugin because it is incapable of processing audio in-place" );
  368. return false;
  369. }
  370. else if ( ! LADSPA_IS_HARD_RT_CAPABLE( _idata->descriptor->Properties ) )
  371. {
  372. WARNING( "Cannot use this plugin because it is incapable of hard real-time operation" );
  373. return false;
  374. }
  375. MESSAGE( "Name: %s", _idata->descriptor->Name );
  376. for ( unsigned int i = 0; i < _idata->descriptor->PortCount; ++i )
  377. {
  378. if ( LADSPA_IS_PORT_AUDIO( _idata->descriptor->PortDescriptors[i] ) )
  379. {
  380. if ( LADSPA_IS_PORT_INPUT( _idata->descriptor->PortDescriptors[i] ) )
  381. {
  382. add_port( Port( this, Port::INPUT, Port::AUDIO, _idata->descriptor->PortNames[ i ] ) );
  383. _plugin_ins++;
  384. }
  385. else if (LADSPA_IS_PORT_OUTPUT(_idata->descriptor->PortDescriptors[i]))
  386. {
  387. _plugin_outs++;
  388. add_port( Port( this, Port::OUTPUT, Port::AUDIO, _idata->descriptor->PortNames[ i ] ) );
  389. }
  390. }
  391. }
  392. MESSAGE( "Plugin has %i inputs and %i outputs", _plugin_ins, _plugin_outs);
  393. for ( unsigned int i = 0; i < _idata->descriptor->PortCount; ++i )
  394. {
  395. if ( LADSPA_IS_PORT_CONTROL( _idata->descriptor->PortDescriptors[i] ) )
  396. {
  397. Port::Direction d = Port::INPUT;
  398. if ( LADSPA_IS_PORT_INPUT( _idata->descriptor->PortDescriptors[i] ) )
  399. {
  400. d = Port::INPUT;
  401. }
  402. else if ( LADSPA_IS_PORT_OUTPUT( _idata->descriptor->PortDescriptors[i] ) )
  403. {
  404. d = Port::OUTPUT;
  405. }
  406. Port p( this, d, Port::CONTROL, _idata->descriptor->PortNames[ i ] );
  407. p.hints.default_value = 0;
  408. LADSPA_PortRangeHintDescriptor hd = _idata->descriptor->PortRangeHints[i].HintDescriptor;
  409. if ( LADSPA_IS_HINT_BOUNDED_BELOW(hd) )
  410. {
  411. p.hints.ranged = true;
  412. p.hints.minimum = _idata->descriptor->PortRangeHints[i].LowerBound;
  413. if ( LADSPA_IS_HINT_SAMPLE_RATE(hd) )
  414. {
  415. p.hints.minimum *= sample_rate();
  416. }
  417. }
  418. if ( LADSPA_IS_HINT_BOUNDED_ABOVE(hd) )
  419. {
  420. p.hints.ranged = true;
  421. p.hints.maximum = _idata->descriptor->PortRangeHints[i].UpperBound;
  422. if ( LADSPA_IS_HINT_SAMPLE_RATE(hd) )
  423. {
  424. p.hints.maximum *= sample_rate();
  425. }
  426. }
  427. if ( LADSPA_IS_HINT_HAS_DEFAULT(hd) )
  428. {
  429. float Max=1.0f, Min=-1.0f, Default=0.0f;
  430. int Port=i;
  431. // Get the bounding hints for the port
  432. LADSPA_PortRangeHintDescriptor HintDesc=_idata->descriptor->PortRangeHints[Port].HintDescriptor;
  433. if (LADSPA_IS_HINT_BOUNDED_BELOW(HintDesc))
  434. {
  435. Min=_idata->descriptor->PortRangeHints[Port].LowerBound;
  436. if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc))
  437. {
  438. Min*=sample_rate();
  439. }
  440. }
  441. if (LADSPA_IS_HINT_BOUNDED_ABOVE(HintDesc))
  442. {
  443. Max=_idata->descriptor->PortRangeHints[Port].UpperBound;
  444. if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc))
  445. {
  446. Max*=sample_rate();
  447. }
  448. }
  449. #ifdef LADSPA_VERSION
  450. // We've got a version of the header that supports port defaults
  451. if (LADSPA_IS_HINT_HAS_DEFAULT(HintDesc)) {
  452. // LADSPA_HINT_DEFAULT_0 is assumed anyway, so we don't check for it
  453. if (LADSPA_IS_HINT_DEFAULT_1(HintDesc)) {
  454. Default = 1.0f;
  455. } else if (LADSPA_IS_HINT_DEFAULT_100(HintDesc)) {
  456. Default = 100.0f;
  457. } else if (LADSPA_IS_HINT_DEFAULT_440(HintDesc)) {
  458. Default = 440.0f;
  459. } else {
  460. // These hints may be affected by SAMPLERATE, LOGARITHMIC and INTEGER
  461. if (LADSPA_IS_HINT_DEFAULT_MINIMUM(HintDesc) &&
  462. LADSPA_IS_HINT_BOUNDED_BELOW(HintDesc)) {
  463. Default=_idata->descriptor->PortRangeHints[Port].LowerBound;
  464. } else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(HintDesc) &&
  465. LADSPA_IS_HINT_BOUNDED_ABOVE(HintDesc)) {
  466. Default=_idata->descriptor->PortRangeHints[Port].UpperBound;
  467. } else if (LADSPA_IS_HINT_BOUNDED_BELOW(HintDesc) &&
  468. LADSPA_IS_HINT_BOUNDED_ABOVE(HintDesc)) {
  469. // These hints require both upper and lower bounds
  470. float lp = 0.0f, up = 0.0f;
  471. float min = _idata->descriptor->PortRangeHints[Port].LowerBound;
  472. float max = _idata->descriptor->PortRangeHints[Port].UpperBound;
  473. if (LADSPA_IS_HINT_DEFAULT_LOW(HintDesc)) {
  474. lp = 0.75f;
  475. up = 0.25f;
  476. } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(HintDesc)) {
  477. lp = 0.5f;
  478. up = 0.5f;
  479. } else if (LADSPA_IS_HINT_DEFAULT_HIGH(HintDesc)) {
  480. lp = 0.25f;
  481. up = 0.75f;
  482. }
  483. if (LADSPA_IS_HINT_LOGARITHMIC(HintDesc)) {
  484. p.hints.type = Port::Hints::LOGARITHMIC;
  485. if (min==0.0f || max==0.0f) {
  486. // Zero at either end means zero no matter
  487. // where hint is at, since:
  488. // log(n->0) -> Infinity
  489. Default = 0.0f;
  490. } else {
  491. // Catch negatives
  492. bool neg_min = min < 0.0f ? true : false;
  493. bool neg_max = max < 0.0f ? true : false;
  494. if (!neg_min && !neg_max) {
  495. Default = exp(::log(min) * lp + ::log(max) * up);
  496. } else if (neg_min && neg_max) {
  497. Default = -exp(::log(-min) * lp + ::log(-max) * up);
  498. } else {
  499. // Logarithmic range has asymptote
  500. // so just use linear scale
  501. Default = min * lp + max * up;
  502. }
  503. }
  504. } else {
  505. Default = min * lp + max * up;
  506. }
  507. }
  508. if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc)) {
  509. Default *= sample_rate();
  510. }
  511. }
  512. if (LADSPA_IS_HINT_INTEGER(HintDesc)) {
  513. if ( p.hints.ranged &&
  514. 0 == (int)p.hints.minimum &&
  515. 1 == (int)p.hints.maximum )
  516. p.hints.type = Port::Hints::BOOLEAN;
  517. else
  518. p.hints.type = Port::Hints::INTEGER;
  519. Default = floorf(Default);
  520. }
  521. if (LADSPA_IS_HINT_TOGGLED(HintDesc)){
  522. p.hints.type = Port::Hints::BOOLEAN;
  523. }
  524. }
  525. #else
  526. Default = 0.0f;
  527. #endif
  528. p.hints.default_value = Default;
  529. }
  530. float *control_value = new float;
  531. *control_value = p.hints.default_value;
  532. p.connect_to( control_value );
  533. add_port( p );
  534. DMESSAGE( "Plugin has control port \"%s\" (default: %f)", _idata->descriptor->PortNames[ i ], p.hints.default_value );
  535. }
  536. }
  537. }
  538. else
  539. {
  540. WARNING( "Failed to load plugin" );
  541. return false;
  542. }
  543. int instances = plugin_instances( 1 );
  544. if ( instances )
  545. {
  546. bypass( false );
  547. }
  548. return instances;
  549. }
  550. void
  551. Plugin_Module::set_input_buffer ( int n, void *buf )
  552. {
  553. LADSPA_Handle h;
  554. if ( instances() > 1 )
  555. {
  556. h = _idata->handle[n];
  557. n = 0;
  558. }
  559. else
  560. h = _idata->handle[0];
  561. for ( unsigned int i = 0; i < _idata->descriptor->PortCount; ++i )
  562. if ( LADSPA_IS_PORT_INPUT( _idata->descriptor->PortDescriptors[i] ) &&
  563. LADSPA_IS_PORT_AUDIO( _idata->descriptor->PortDescriptors[i] ) )
  564. if ( n-- == 0 )
  565. _idata->descriptor->connect_port( h, i, (LADSPA_Data*)buf );
  566. }
  567. bool
  568. Plugin_Module::loaded ( void ) const
  569. {
  570. return _idata->descriptor;
  571. }
  572. void
  573. Plugin_Module::set_output_buffer ( int n, void *buf )
  574. {
  575. LADSPA_Handle h;
  576. if ( instances() > 1 )
  577. {
  578. h = _idata->handle[n];
  579. n = 0;
  580. }
  581. else
  582. h = _idata->handle[0];
  583. for ( unsigned int i = 0; i < _idata->descriptor->PortCount; ++i )
  584. if ( LADSPA_IS_PORT_OUTPUT( _idata->descriptor->PortDescriptors[i] ) &&
  585. LADSPA_IS_PORT_AUDIO( _idata->descriptor->PortDescriptors[i] ) )
  586. if ( n-- == 0 )
  587. _idata->descriptor->connect_port( h, i, (LADSPA_Data*)buf );
  588. }
  589. void
  590. Plugin_Module::activate ( void )
  591. {
  592. if ( !loaded() )
  593. return;
  594. DMESSAGE( "Activating plugin \"%s\"", label() );
  595. if ( !bypass() )
  596. FATAL( "Attempt to activate already active plugin" );
  597. if ( chain() )
  598. chain()->client()->lock();
  599. if ( _idata->descriptor->activate )
  600. for ( unsigned int i = 0; i < _idata->handle.size(); ++i )
  601. _idata->descriptor->activate( _idata->handle[i] );
  602. _bypass = false;
  603. if ( chain() )
  604. chain()->client()->unlock();
  605. }
  606. void
  607. Plugin_Module::deactivate( void )
  608. {
  609. if ( !loaded() )
  610. return;
  611. DMESSAGE( "Deactivating plugin \"%s\"", label() );
  612. if ( chain() )
  613. chain()->client()->lock();
  614. _bypass = true;
  615. if ( _idata->descriptor->deactivate )
  616. for ( unsigned int i = 0; i < _idata->handle.size(); ++i )
  617. _idata->descriptor->deactivate( _idata->handle[i] );
  618. if ( chain() )
  619. chain()->client()->unlock();
  620. }
  621. void
  622. Plugin_Module::handle_port_connection_change ( void )
  623. {
  624. // DMESSAGE( "Connecting audio ports" );
  625. if ( loaded() )
  626. {
  627. if ( _crosswire )
  628. {
  629. for ( int i = 0; i < plugin_ins(); ++i )
  630. set_input_buffer( i, audio_input[0].buffer() );
  631. }
  632. else
  633. {
  634. for ( unsigned int i = 0; i < audio_input.size(); ++i )
  635. set_input_buffer( i, audio_input[i].buffer() );
  636. }
  637. for ( unsigned int i = 0; i < audio_output.size(); ++i )
  638. set_output_buffer( i, audio_output[i].buffer() );
  639. }
  640. }
  641. /**********/
  642. /* Client */
  643. /**********/
  644. void
  645. Plugin_Module::process ( nframes_t nframes )
  646. {
  647. handle_port_connection_change();
  648. if ( !bypass() )
  649. {
  650. for ( unsigned int i = 0; i < _idata->handle.size(); ++i )
  651. _idata->descriptor->run( _idata->handle[i], nframes );
  652. }
  653. else
  654. {
  655. /* If this is a mono to stereo plugin, then duplicate the input channel... */
  656. /* There's not much we can do to automatically support other configurations. */
  657. if ( ninputs() == 1 && noutputs() == 2 )
  658. {
  659. buffer_copy( (sample_t*)audio_output[1].buffer(), (sample_t*)audio_input[0].buffer(), nframes );
  660. }
  661. }
  662. _latency = get_plugin_latency();
  663. }