Assists music production by grouping standalone programs into sessions. Community version of "Non Session Manager".
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.

811 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. update_tooltip();
  116. }
  117. int
  118. Plugin_Module::can_support_inputs ( int n )
  119. {
  120. /* this is the simple case */
  121. if ( plugin_ins() == n )
  122. return plugin_outs();
  123. /* e.g. MONO going into STEREO */
  124. /* we'll duplicate our inputs */
  125. else if ( n < plugin_ins() &&
  126. 1 == n )
  127. {
  128. return plugin_outs();
  129. }
  130. /* e.g. STEREO going into MONO */
  131. /* we'll run multiple instances of the plugin */
  132. else if ( n > plugin_ins() &&
  133. ( plugin_ins() == 1 && plugin_outs() == 1 ) )
  134. {
  135. return n;
  136. }
  137. return -1;
  138. }
  139. bool
  140. Plugin_Module::configure_inputs( int n )
  141. {
  142. unsigned int inst = _idata->handle.size();
  143. if ( ninputs() != n )
  144. {
  145. _crosswire = false;
  146. if ( n != ninputs() )
  147. {
  148. if ( 1 == n && plugin_ins() > 1 )
  149. {
  150. DMESSAGE( "Cross-wiring plugin inputs" );
  151. _crosswire = true;
  152. audio_input.clear();
  153. for ( int i = n; i--; )
  154. audio_input.push_back( Port( this, Port::INPUT, Port::AUDIO ) );
  155. }
  156. else if ( n >= plugin_ins() &&
  157. ( plugin_ins() == 1 && plugin_outs() == 1 ) )
  158. {
  159. DMESSAGE( "Running multiple instances of plugin" );
  160. audio_input.clear();
  161. audio_output.clear();
  162. for ( int i = n; i--; )
  163. {
  164. add_port( Port( this, Port::INPUT, Port::AUDIO ) );
  165. add_port( Port( this, Port::OUTPUT, Port::AUDIO ) );
  166. }
  167. inst = n;
  168. }
  169. else if ( n == plugin_ins() )
  170. {
  171. DMESSAGE( "Plugin input configuration is a perfect match" );
  172. }
  173. else
  174. {
  175. DMESSAGE( "Unsupported input configuration" );
  176. return false;
  177. }
  178. }
  179. }
  180. if ( loaded() )
  181. {
  182. bool b = bypass();
  183. if ( inst != _idata->handle.size() )
  184. {
  185. if ( !b )
  186. deactivate();
  187. if ( plugin_instances( inst ) )
  188. instances( inst );
  189. else
  190. return false;
  191. if ( !b )
  192. activate();
  193. }
  194. }
  195. return true;
  196. }
  197. void *
  198. Plugin_Module::discover_thread ( void * )
  199. {
  200. THREAD_ASSERT( Plugin_Discover );
  201. DMESSAGE( "Discovering plugins in the background" );
  202. ladspainfo = new LADSPAInfo();
  203. return NULL;
  204. }
  205. /* Spawn a background thread for plugin discovery */
  206. void
  207. Plugin_Module::spawn_discover_thread ( void )
  208. {
  209. if ( plugin_discover_thread )
  210. {
  211. FATAL( "Plugin discovery thread is already running or has completed" );
  212. }
  213. plugin_discover_thread = new Thread( "Plugin_Discover" );
  214. plugin_discover_thread->clone( &Plugin_Module::discover_thread, NULL );
  215. }
  216. void
  217. Plugin_Module::join_discover_thread ( void )
  218. {
  219. plugin_discover_thread->join();
  220. }
  221. /* return a list of available plugins */
  222. std::list<Plugin_Module::Plugin_Info>
  223. Plugin_Module::get_all_plugins ( void )
  224. {
  225. if ( !ladspainfo )
  226. {
  227. if ( ! plugin_discover_thread )
  228. ladspainfo = new LADSPAInfo();
  229. else
  230. plugin_discover_thread->join();
  231. }
  232. std::vector<LADSPAInfo::PluginInfo> plugins = ladspainfo->GetPluginInfo();
  233. std::list<Plugin_Module::Plugin_Info> pr;
  234. int j = 0;
  235. for (std::vector<LADSPAInfo::PluginInfo>::iterator i=plugins.begin();
  236. i!=plugins.end(); i++, j++)
  237. {
  238. Plugin_Info pi;
  239. // pi[j].path = i->Name.c_str();
  240. pi.path = NULL;
  241. pi.id = i->UniqueID;
  242. pi.author = i->Maker.c_str();
  243. pi.name = i->Name.c_str();
  244. pi.audio_inputs = i->AudioInputs;
  245. pi.audio_outputs = i->AudioOutputs;
  246. pi.category = "Unclassified";
  247. pr.push_back( pi );
  248. }
  249. pr.sort();
  250. const std::vector<LADSPAInfo::PluginEntry> pe = ladspainfo->GetMenuList();
  251. for (std::vector<LADSPAInfo::PluginEntry>::const_iterator i= pe.begin();
  252. i !=pe.end(); i++ )
  253. {
  254. for ( std::list<Plugin_Info>::iterator j = pr.begin(); j != pr.end(); j++ )
  255. {
  256. if ( j->id == i->UniqueID )
  257. {
  258. j->category = i->Category.c_str();
  259. }
  260. }
  261. }
  262. return pr;
  263. }
  264. bool
  265. Plugin_Module::plugin_instances ( unsigned int n )
  266. {
  267. if ( _idata->handle.size() > n )
  268. {
  269. for ( int i = _idata->handle.size() - n; i--; )
  270. {
  271. DMESSAGE( "Destroying plugin instance" );
  272. LADSPA_Handle h = _idata->handle.back();
  273. if ( _idata->descriptor->deactivate )
  274. _idata->descriptor->deactivate( h );
  275. if ( _idata->descriptor->cleanup )
  276. _idata->descriptor->cleanup( h );
  277. _idata->handle.pop_back();
  278. }
  279. }
  280. else if ( _idata->handle.size() < n )
  281. {
  282. for ( int i = n - _idata->handle.size(); i--; )
  283. {
  284. LADSPA_Handle h;
  285. DMESSAGE( "Instantiating plugin... with sample rate %lu", (unsigned long)sample_rate());
  286. if ( ! (h = _idata->descriptor->instantiate( _idata->descriptor, sample_rate() ) ) )
  287. {
  288. WARNING( "Failed to instantiate plugin" );
  289. return false;
  290. }
  291. DMESSAGE( "Instantiated: %p", h );
  292. _idata->handle.push_back( h );
  293. DMESSAGE( "Connecting control ports..." );
  294. int ij = 0;
  295. int oj = 0;
  296. for ( unsigned int k = 0; k < _idata->descriptor->PortCount; ++k )
  297. {
  298. if ( LADSPA_IS_PORT_CONTROL( _idata->descriptor->PortDescriptors[k] ) )
  299. {
  300. if ( LADSPA_IS_PORT_INPUT( _idata->descriptor->PortDescriptors[k] ) )
  301. _idata->descriptor->connect_port( h, k, (LADSPA_Data*)control_input[ij++].buffer() );
  302. else if ( LADSPA_IS_PORT_OUTPUT( _idata->descriptor->PortDescriptors[k] ) )
  303. _idata->descriptor->connect_port( h, k, (LADSPA_Data*)control_output[oj++].buffer() );
  304. }
  305. }
  306. // connect ports to magic bogus value to aid debugging.
  307. for ( unsigned int k = 0; k < _idata->descriptor->PortCount; ++k )
  308. if ( LADSPA_IS_PORT_AUDIO( _idata->descriptor->PortDescriptors[k] ) )
  309. _idata->descriptor->connect_port( h, k, (LADSPA_Data*)0x42 );
  310. }
  311. }
  312. return true;
  313. }
  314. void
  315. Plugin_Module::bypass ( bool v )
  316. {
  317. if ( v != bypass() )
  318. {
  319. if ( v )
  320. deactivate();
  321. else
  322. activate();
  323. }
  324. }
  325. nframes_t
  326. Plugin_Module::get_module_latency ( void ) const
  327. {
  328. for ( unsigned int i = ncontrol_outputs(); i--; )
  329. {
  330. if ( !strcasecmp( "latency", control_output[i].name() ) )
  331. {
  332. return control_output[i].control_value();
  333. }
  334. }
  335. return 0;
  336. }
  337. bool
  338. Plugin_Module::load ( unsigned long id )
  339. {
  340. if ( !ladspainfo )
  341. {
  342. if ( ! plugin_discover_thread )
  343. ladspainfo = new LADSPAInfo();
  344. else
  345. plugin_discover_thread->join();
  346. }
  347. _idata->descriptor = ladspainfo->GetDescriptorByID( id );
  348. _plugin_ins = _plugin_outs = 0;
  349. if ( ! _idata->descriptor )
  350. {
  351. /* unknown plugin ID */
  352. WARNING( "Unknown plugin ID: %lu", id );
  353. label( "----" );
  354. return false;
  355. }
  356. label( _idata->descriptor->Name );
  357. if ( _idata->descriptor )
  358. {
  359. if ( LADSPA_IS_INPLACE_BROKEN( _idata->descriptor->Properties ) )
  360. {
  361. WARNING( "Cannot use this plugin because it is incapable of processing audio in-place" );
  362. return false;
  363. }
  364. /* else if ( ! LADSPA_IS_HARD_RT_CAPABLE( _idata->descriptor->Properties ) ) */
  365. /* { */
  366. /* WARNING( "Cannot use this plugin because it is incapable of hard real-time operation" ); */
  367. /* return false; */
  368. /* } */
  369. MESSAGE( "Name: %s", _idata->descriptor->Name );
  370. for ( unsigned int i = 0; i < _idata->descriptor->PortCount; ++i )
  371. {
  372. if ( LADSPA_IS_PORT_AUDIO( _idata->descriptor->PortDescriptors[i] ) )
  373. {
  374. if ( LADSPA_IS_PORT_INPUT( _idata->descriptor->PortDescriptors[i] ) )
  375. {
  376. add_port( Port( this, Port::INPUT, Port::AUDIO, _idata->descriptor->PortNames[ i ] ) );
  377. _plugin_ins++;
  378. }
  379. else if (LADSPA_IS_PORT_OUTPUT(_idata->descriptor->PortDescriptors[i]))
  380. {
  381. _plugin_outs++;
  382. add_port( Port( this, Port::OUTPUT, Port::AUDIO, _idata->descriptor->PortNames[ i ] ) );
  383. }
  384. }
  385. }
  386. MESSAGE( "Plugin has %i inputs and %i outputs", _plugin_ins, _plugin_outs);
  387. for ( unsigned int i = 0; i < _idata->descriptor->PortCount; ++i )
  388. {
  389. if ( LADSPA_IS_PORT_CONTROL( _idata->descriptor->PortDescriptors[i] ) )
  390. {
  391. Port::Direction d = Port::INPUT;
  392. if ( LADSPA_IS_PORT_INPUT( _idata->descriptor->PortDescriptors[i] ) )
  393. {
  394. d = Port::INPUT;
  395. }
  396. else if ( LADSPA_IS_PORT_OUTPUT( _idata->descriptor->PortDescriptors[i] ) )
  397. {
  398. d = Port::OUTPUT;
  399. }
  400. Port p( this, d, Port::CONTROL, _idata->descriptor->PortNames[ i ] );
  401. p.hints.default_value = 0;
  402. LADSPA_PortRangeHintDescriptor hd = _idata->descriptor->PortRangeHints[i].HintDescriptor;
  403. if ( LADSPA_IS_HINT_BOUNDED_BELOW(hd) )
  404. {
  405. p.hints.ranged = true;
  406. p.hints.minimum = _idata->descriptor->PortRangeHints[i].LowerBound;
  407. if ( LADSPA_IS_HINT_SAMPLE_RATE(hd) )
  408. {
  409. p.hints.minimum *= sample_rate();
  410. }
  411. }
  412. if ( LADSPA_IS_HINT_BOUNDED_ABOVE(hd) )
  413. {
  414. p.hints.ranged = true;
  415. p.hints.maximum = _idata->descriptor->PortRangeHints[i].UpperBound;
  416. if ( LADSPA_IS_HINT_SAMPLE_RATE(hd) )
  417. {
  418. p.hints.maximum *= sample_rate();
  419. }
  420. }
  421. if ( LADSPA_IS_HINT_HAS_DEFAULT(hd) )
  422. {
  423. float Max=1.0f, Min=-1.0f, Default=0.0f;
  424. int Port=i;
  425. // Get the bounding hints for the port
  426. LADSPA_PortRangeHintDescriptor HintDesc=_idata->descriptor->PortRangeHints[Port].HintDescriptor;
  427. if (LADSPA_IS_HINT_BOUNDED_BELOW(HintDesc))
  428. {
  429. Min=_idata->descriptor->PortRangeHints[Port].LowerBound;
  430. if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc))
  431. {
  432. Min*=sample_rate();
  433. }
  434. }
  435. if (LADSPA_IS_HINT_BOUNDED_ABOVE(HintDesc))
  436. {
  437. Max=_idata->descriptor->PortRangeHints[Port].UpperBound;
  438. if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc))
  439. {
  440. Max*=sample_rate();
  441. }
  442. }
  443. #ifdef LADSPA_VERSION
  444. // We've got a version of the header that supports port defaults
  445. if (LADSPA_IS_HINT_HAS_DEFAULT(HintDesc)) {
  446. // LADSPA_HINT_DEFAULT_0 is assumed anyway, so we don't check for it
  447. if (LADSPA_IS_HINT_DEFAULT_1(HintDesc)) {
  448. Default = 1.0f;
  449. } else if (LADSPA_IS_HINT_DEFAULT_100(HintDesc)) {
  450. Default = 100.0f;
  451. } else if (LADSPA_IS_HINT_DEFAULT_440(HintDesc)) {
  452. Default = 440.0f;
  453. } else {
  454. // These hints may be affected by SAMPLERATE, LOGARITHMIC and INTEGER
  455. if (LADSPA_IS_HINT_DEFAULT_MINIMUM(HintDesc) &&
  456. LADSPA_IS_HINT_BOUNDED_BELOW(HintDesc)) {
  457. Default=_idata->descriptor->PortRangeHints[Port].LowerBound;
  458. } else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(HintDesc) &&
  459. LADSPA_IS_HINT_BOUNDED_ABOVE(HintDesc)) {
  460. Default=_idata->descriptor->PortRangeHints[Port].UpperBound;
  461. } else if (LADSPA_IS_HINT_BOUNDED_BELOW(HintDesc) &&
  462. LADSPA_IS_HINT_BOUNDED_ABOVE(HintDesc)) {
  463. // These hints require both upper and lower bounds
  464. float lp = 0.0f, up = 0.0f;
  465. float min = _idata->descriptor->PortRangeHints[Port].LowerBound;
  466. float max = _idata->descriptor->PortRangeHints[Port].UpperBound;
  467. if (LADSPA_IS_HINT_DEFAULT_LOW(HintDesc)) {
  468. lp = 0.75f;
  469. up = 0.25f;
  470. } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(HintDesc)) {
  471. lp = 0.5f;
  472. up = 0.5f;
  473. } else if (LADSPA_IS_HINT_DEFAULT_HIGH(HintDesc)) {
  474. lp = 0.25f;
  475. up = 0.75f;
  476. }
  477. if (LADSPA_IS_HINT_LOGARITHMIC(HintDesc)) {
  478. p.hints.type = Port::Hints::LOGARITHMIC;
  479. if (min==0.0f || max==0.0f) {
  480. // Zero at either end means zero no matter
  481. // where hint is at, since:
  482. // log(n->0) -> Infinity
  483. Default = 0.0f;
  484. } else {
  485. // Catch negatives
  486. bool neg_min = min < 0.0f ? true : false;
  487. bool neg_max = max < 0.0f ? true : false;
  488. if (!neg_min && !neg_max) {
  489. Default = exp(::log(min) * lp + ::log(max) * up);
  490. } else if (neg_min && neg_max) {
  491. Default = -exp(::log(-min) * lp + ::log(-max) * up);
  492. } else {
  493. // Logarithmic range has asymptote
  494. // so just use linear scale
  495. Default = min * lp + max * up;
  496. }
  497. }
  498. } else {
  499. Default = min * lp + max * up;
  500. }
  501. }
  502. if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc)) {
  503. Default *= sample_rate();
  504. }
  505. }
  506. if (LADSPA_IS_HINT_INTEGER(HintDesc)) {
  507. if ( p.hints.ranged &&
  508. 0 == (int)p.hints.minimum &&
  509. 1 == (int)p.hints.maximum )
  510. p.hints.type = Port::Hints::BOOLEAN;
  511. else
  512. p.hints.type = Port::Hints::INTEGER;
  513. Default = floorf(Default);
  514. }
  515. if (LADSPA_IS_HINT_TOGGLED(HintDesc)){
  516. p.hints.type = Port::Hints::BOOLEAN;
  517. }
  518. }
  519. #else
  520. Default = 0.0f;
  521. #endif
  522. p.hints.default_value = Default;
  523. }
  524. float *control_value = new float;
  525. *control_value = p.hints.default_value;
  526. p.connect_to( control_value );
  527. add_port( p );
  528. DMESSAGE( "Plugin has control port \"%s\" (default: %f)", _idata->descriptor->PortNames[ i ], p.hints.default_value );
  529. }
  530. }
  531. }
  532. else
  533. {
  534. WARNING( "Failed to load plugin" );
  535. return false;
  536. }
  537. int instances = plugin_instances( 1 );
  538. if ( instances )
  539. {
  540. bypass( false );
  541. }
  542. return instances;
  543. }
  544. void
  545. Plugin_Module::set_input_buffer ( int n, void *buf )
  546. {
  547. LADSPA_Handle h;
  548. if ( instances() > 1 )
  549. {
  550. h = _idata->handle[n];
  551. n = 0;
  552. }
  553. else
  554. h = _idata->handle[0];
  555. for ( unsigned int i = 0; i < _idata->descriptor->PortCount; ++i )
  556. if ( LADSPA_IS_PORT_INPUT( _idata->descriptor->PortDescriptors[i] ) &&
  557. LADSPA_IS_PORT_AUDIO( _idata->descriptor->PortDescriptors[i] ) )
  558. if ( n-- == 0 )
  559. _idata->descriptor->connect_port( h, i, (LADSPA_Data*)buf );
  560. }
  561. bool
  562. Plugin_Module::loaded ( void ) const
  563. {
  564. return _idata->descriptor;
  565. }
  566. void
  567. Plugin_Module::set_output_buffer ( int n, void *buf )
  568. {
  569. LADSPA_Handle h;
  570. if ( instances() > 1 )
  571. {
  572. h = _idata->handle[n];
  573. n = 0;
  574. }
  575. else
  576. h = _idata->handle[0];
  577. for ( unsigned int i = 0; i < _idata->descriptor->PortCount; ++i )
  578. if ( LADSPA_IS_PORT_OUTPUT( _idata->descriptor->PortDescriptors[i] ) &&
  579. LADSPA_IS_PORT_AUDIO( _idata->descriptor->PortDescriptors[i] ) )
  580. if ( n-- == 0 )
  581. _idata->descriptor->connect_port( h, i, (LADSPA_Data*)buf );
  582. }
  583. void
  584. Plugin_Module::activate ( void )
  585. {
  586. if ( !loaded() )
  587. return;
  588. DMESSAGE( "Activating plugin \"%s\"", label() );
  589. if ( !bypass() )
  590. FATAL( "Attempt to activate already active plugin" );
  591. if ( chain() )
  592. chain()->client()->lock();
  593. if ( _idata->descriptor->activate )
  594. for ( unsigned int i = 0; i < _idata->handle.size(); ++i )
  595. _idata->descriptor->activate( _idata->handle[i] );
  596. _bypass = false;
  597. if ( chain() )
  598. chain()->client()->unlock();
  599. }
  600. void
  601. Plugin_Module::deactivate( void )
  602. {
  603. if ( !loaded() )
  604. return;
  605. DMESSAGE( "Deactivating plugin \"%s\"", label() );
  606. if ( chain() )
  607. chain()->client()->lock();
  608. _bypass = true;
  609. if ( _idata->descriptor->deactivate )
  610. for ( unsigned int i = 0; i < _idata->handle.size(); ++i )
  611. _idata->descriptor->deactivate( _idata->handle[i] );
  612. if ( chain() )
  613. chain()->client()->unlock();
  614. }
  615. void
  616. Plugin_Module::handle_port_connection_change ( void )
  617. {
  618. // DMESSAGE( "Connecting audio ports" );
  619. if ( loaded() )
  620. {
  621. if ( _crosswire )
  622. {
  623. for ( int i = 0; i < plugin_ins(); ++i )
  624. set_input_buffer( i, audio_input[0].buffer() );
  625. }
  626. else
  627. {
  628. for ( unsigned int i = 0; i < audio_input.size(); ++i )
  629. set_input_buffer( i, audio_input[i].buffer() );
  630. }
  631. for ( unsigned int i = 0; i < audio_output.size(); ++i )
  632. set_output_buffer( i, audio_output[i].buffer() );
  633. }
  634. }
  635. /**********/
  636. /* Client */
  637. /**********/
  638. void
  639. Plugin_Module::process ( nframes_t nframes )
  640. {
  641. handle_port_connection_change();
  642. if ( unlikely( bypass() ) )
  643. {
  644. /* If this is a mono to stereo plugin, then duplicate the input channel... */
  645. /* There's not much we can do to automatically support other configurations. */
  646. if ( ninputs() == 1 && noutputs() == 2 )
  647. {
  648. buffer_copy( (sample_t*)audio_output[1].buffer(), (sample_t*)audio_input[0].buffer(), nframes );
  649. }
  650. _latency = 0;
  651. }
  652. else
  653. {
  654. for ( unsigned int i = 0; i < _idata->handle.size(); ++i )
  655. _idata->descriptor->run( _idata->handle[i], nframes );
  656. _latency = get_module_latency();
  657. }
  658. }