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.

774 lines
23KB

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