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.

650 lines
17KB

  1. /* SpiralSound
  2. * Copyleft (C) 2001 David Griffiths <dave@pawfal.org>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. #include "LADSPAPlugin.h"
  19. #include "LADSPAPluginGUI.h"
  20. #include <cstdio>
  21. #include <cstdlib>
  22. #include <cstring>
  23. #include "SpiralIcon.xpm"
  24. #include "utils.h"
  25. #include <algorithm>
  26. ////////////////////////////////////////////
  27. /* FIXME: No matter what, I can't let this as it!! */
  28. static LADSPAPlugin * lg = NULL;
  29. void describePluginLibrary(const char * pcFullFilename,
  30. void * pvPluginHandle,
  31. LADSPA_Descriptor_Function pfDescriptorFunction)
  32. {
  33. const LADSPA_Descriptor * psDescriptor;
  34. long lIndex;
  35. unsigned long lPluginIndex;
  36. unsigned long lPortIndex;
  37. unsigned long lLength;
  38. LADSPA_PortRangeHintDescriptor iHintDescriptor;
  39. LADSPA_Data fBound;
  40. #define testcond(c,s) { \
  41. if (!(c)) { \
  42. cerr << (s); \
  43. failure = 1; \
  44. } \
  45. }
  46. for (lIndex = 0; (psDescriptor = pfDescriptorFunction(lIndex)) != NULL; lIndex++) {
  47. int failure = 0;
  48. testcond(!LADSPA_IS_REALTIME(psDescriptor->Properties), "ERROR: PLUGIN MUST RUN REAL TIME.\n");
  49. testcond(psDescriptor->instantiate, "ERROR: PLUGIN HAS NO INSTANTIATE FUNCTION.\n");
  50. testcond(psDescriptor->connect_port, "ERROR: PLUGIN HAS NO CONNECT_PORT FUNCTION.\n");
  51. testcond(psDescriptor->run, "ERROR: PLUGIN HAS NO RUN FUNCTION.\n");
  52. testcond(!(psDescriptor->run_adding != 0 && psDescriptor->set_run_adding_gain == 0),
  53. "ERROR: PLUGIN HAS RUN_ADDING FUNCTION BUT NOT SET_RUN_ADDING_GAIN.\n");
  54. testcond(!(psDescriptor->run_adding == 0 && psDescriptor->set_run_adding_gain != 0),
  55. "ERROR: PLUGIN HAS SET_RUN_ADDING_GAIN FUNCTION BUT NOT RUN_ADDING.\n");
  56. testcond(psDescriptor->cleanup, "ERROR: PLUGIN HAS NO CLEANUP FUNCTION.\n");
  57. testcond(!LADSPA_IS_INPLACE_BROKEN(psDescriptor->Properties),
  58. "ERROR: THIS PLUGIN CANNOT USE IN-PLACE PROCESSING.\n");
  59. testcond(psDescriptor->PortCount, "ERROR: PLUGIN HAS NO PORTS.\n");
  60. if (!failure) {
  61. LPluginInfo pi;
  62. pi.Filename = pcFullFilename;
  63. pi.Label = psDescriptor->Label;
  64. pi.Name = psDescriptor->Name;
  65. pi.InputPortCount = getPortCountByType(psDescriptor, LADSPA_PORT_INPUT);
  66. // ARGH! I really can't stand this ugly hack
  67. lg->m_LADSPAList.push_back(pi);
  68. } else {
  69. cerr << "Plugin ignored...\n\n";
  70. }
  71. }
  72. dlclose(pvPluginHandle);
  73. }
  74. void LADSPAPlugin::LoadPluginList(void)
  75. {
  76. m_LADSPAList.clear();
  77. m_CurrentPlugin.Name = "";
  78. m_CurrentPlugin.Filename = "";
  79. m_CurrentPlugin.Label = "";
  80. lg = this;
  81. LADSPAPluginSearch(describePluginLibrary);
  82. lg = NULL;
  83. sort(m_LADSPAList.begin(), m_LADSPAList.end(), LPluginInfoSortAsc());
  84. }
  85. ////////////////////////////////////////////////////
  86. extern "C" {
  87. SpiralPlugin* CreateInstance()
  88. {
  89. return new LADSPAPlugin;
  90. }
  91. char** GetIcon()
  92. {
  93. return SpiralIcon_xpm;
  94. }
  95. int GetID()
  96. {
  97. return 0x0016;
  98. }
  99. }
  100. ///////////////////////////////////////////////////////
  101. LADSPAPlugin::LADSPAPlugin() :
  102. PlugHandle(0),
  103. PlugDesc(NULL),
  104. m_Gain(1.0f),
  105. m_Amped(false)
  106. {
  107. m_Version=3;
  108. m_PluginInfo.Name="LADSPA";
  109. m_PluginInfo.Width=600;
  110. m_PluginInfo.Height=300;
  111. m_PluginInfo.NumInputs=0;
  112. m_PluginInfo.NumOutputs=1;
  113. m_PluginInfo.PortTips.push_back("Nuffink yet");
  114. m_MaxInputPortCount = 0;
  115. m_InputPortCount = 0;
  116. LoadPluginList();
  117. // Examine plugin list and find highest input port count
  118. for (vector<LPluginInfo>::iterator i = m_LADSPAList.begin();
  119. i != m_LADSPAList.end(); i++) {
  120. if ((*i).InputPortCount > m_MaxInputPortCount)
  121. m_MaxInputPortCount = (*i).InputPortCount;
  122. }
  123. // For receiving from GUI
  124. m_AudioCH->Register("SetGain",&(m_InData.Gain));
  125. m_AudioCH->Register("SetAmped",&(m_InData.Amped));
  126. m_AudioCH->RegisterData("SetPluginIndex", ChannelHandler::INPUT,&(m_InData.PluginIndex),sizeof(m_InData.PluginIndex));
  127. // For sending to GUI
  128. m_AudioCH->RegisterData("GetName",ChannelHandler::OUTPUT,m_Name,256);
  129. m_AudioCH->RegisterData("GetMaker",ChannelHandler::OUTPUT,m_Maker,256);
  130. m_AudioCH->RegisterData("GetMaxInputPortCount",ChannelHandler::OUTPUT,&(m_MaxInputPortCount),sizeof(m_MaxInputPortCount));
  131. m_AudioCH->RegisterData("GetInputPortCount",ChannelHandler::OUTPUT,&(m_InputPortCount),sizeof(m_InputPortCount));
  132. m_OutData.InputPortNames = (char *)malloc(256 * m_MaxInputPortCount);
  133. m_OutData.InputPortRanges = (PortRange *)malloc(sizeof(PortRange) * m_MaxInputPortCount);
  134. m_InData.InputPortRanges = (PortRange *)malloc(sizeof(PortRange) * m_MaxInputPortCount);
  135. if (m_OutData.InputPortNames &&
  136. m_OutData.InputPortRanges &&
  137. m_InData.InputPortRanges) {
  138. m_AudioCH->RegisterData("GetInputPortNames", ChannelHandler::OUTPUT, m_OutData.InputPortNames, 256 * m_MaxInputPortCount);
  139. m_AudioCH->RegisterData("GetInputPortRanges", ChannelHandler::OUTPUT, m_OutData.InputPortRanges, sizeof(PortRange) * m_MaxInputPortCount);
  140. m_AudioCH->RegisterData("SetInputPortRanges", ChannelHandler::INPUT, m_InData.InputPortRanges, sizeof(PortRange) * m_MaxInputPortCount);
  141. } else {
  142. cerr<<"Memory allocation error"<<endl;
  143. }
  144. }
  145. LADSPAPlugin::~LADSPAPlugin()
  146. {
  147. // Free allocated buffers
  148. if (m_OutData.InputPortNames) free(m_OutData.InputPortNames);
  149. if (m_OutData.InputPortRanges) free(m_OutData.InputPortRanges);
  150. if (m_InData.InputPortRanges) free(m_InData.InputPortRanges);
  151. }
  152. PluginInfo &LADSPAPlugin::Initialise(const HostInfo *Host)
  153. {
  154. PluginInfo& Info = SpiralPlugin::Initialise(Host);
  155. LADSPA_Data *NewPort = new LADSPA_Data[m_HostInfo->BUFSIZE];
  156. m_LADSPABufVec.push_back(NewPort);
  157. return Info;
  158. }
  159. SpiralGUIType *LADSPAPlugin::CreateGUI()
  160. {
  161. return new LADSPAPluginGUI(m_PluginInfo.Width, m_PluginInfo.Height,
  162. this, m_AudioCH, m_HostInfo, m_LADSPAList);
  163. }
  164. void LADSPAPlugin::Execute()
  165. {
  166. if (PlugDesc)
  167. {
  168. // convert inputs if exist (zero if not)
  169. for (int n=0; n<m_PluginInfo.NumInputs; n++)
  170. {
  171. if (GetInput(n))
  172. {
  173. if (m_PortClamp[n]) {
  174. // scale input to match hinted range
  175. float Offset=m_PortMin[n];
  176. float Scale=m_PortMax[n]-m_PortMin[n];
  177. //cerr<<n<<" ["<<Scale<<"] ["<<Offset<<"]"<<endl;
  178. for (int i=0; i<m_HostInfo->BUFSIZE; i++)
  179. {
  180. m_LADSPABufVec[n][i]=Offset+(GetInput(n,i)*0.5f+0.5f)*Scale;
  181. //cerr<<Scale<<" "<<Offset<<" "<<m_LADSPABufVec[n][i]<<endl;
  182. }
  183. } else {
  184. // pass input as is
  185. for (int i=0; i<m_HostInfo->BUFSIZE; i++)
  186. {
  187. m_LADSPABufVec[n][i]=GetInput(n,i);
  188. }
  189. }
  190. // Update the GUI outputs with the first value in the buffer
  191. //((LADSPAPluginGUI*)m_GUI)->UpdatePortDisplay(n,m_LADSPABufVec[n][0]);
  192. }
  193. else // zero
  194. {
  195. for (int i=0; i<m_HostInfo->BUFSIZE; i++) m_LADSPABufVec[n][i]=0;
  196. }
  197. }
  198. // run plugin
  199. PlugDesc->run(PlugInstHandle,m_HostInfo->BUFSIZE);
  200. // convert outputs
  201. for (int n=0; n<m_PluginInfo.NumOutputs; n++)
  202. {
  203. /*if (m_Amped)
  204. {
  205. for (int i=0; i<m_HostInfo->BUFSIZE; i++)
  206. {
  207. SetOutput(n,i,m_LADSPABufVec[n+m_PluginInfo.NumInputs][i]*m_Gain*10);
  208. }
  209. }
  210. else*/
  211. {
  212. for (int i=0; i<m_HostInfo->BUFSIZE; i++)
  213. {
  214. SetOutput(n,i,m_LADSPABufVec[n+m_PluginInfo.NumInputs][i]*m_Gain);
  215. }
  216. }
  217. }
  218. }
  219. }
  220. void LADSPAPlugin::ExecuteCommands()
  221. {
  222. if (m_AudioCH->IsCommandWaiting())
  223. {
  224. switch(m_AudioCH->GetCommand())
  225. {
  226. case (SETRANGES) : SetPortInfo(); break;
  227. case (SELECTPLUGIN) : UpdatePlugin(m_InData.PluginIndex); break;
  228. };
  229. }
  230. }
  231. void LADSPAPlugin::StreamOut(ostream &s)
  232. {
  233. s<<m_Version<<" ";
  234. switch (m_Version)
  235. {
  236. case 3:
  237. {
  238. s<<m_Gain<<" ";
  239. s<<m_CurrentPlugin.Filename<<" ";
  240. s<<m_CurrentPlugin.Label<<" ";
  241. s<<m_PortMin.size()<<" ";
  242. assert(m_PortMin.size()==m_PortMax.size());
  243. assert(m_PortMin.size()==m_PortClamp.size());
  244. for (vector<float>::iterator i=m_PortMin.begin();
  245. i!=m_PortMin.end(); i++)
  246. {
  247. s<<*i<<" ";
  248. }
  249. for (vector<float>::iterator i=m_PortMax.begin();
  250. i!=m_PortMax.end(); i++)
  251. {
  252. s<<*i<<" ";
  253. }
  254. for (vector<bool>::iterator i=m_PortClamp.begin();
  255. i!=m_PortClamp.end(); i++)
  256. {
  257. s<<*i<<" ";
  258. }
  259. }
  260. break;
  261. case 2:
  262. // Here for consistency - should never actually happen, as
  263. // version is always 3!
  264. {
  265. s<<m_Gain<<" ";
  266. s<<m_CurrentPlugin.Filename<<" ";
  267. s<<m_CurrentPlugin.Label<<" ";
  268. s<<m_PortMin.size()<<" ";
  269. assert(m_PortMin.size()==m_PortMax.size());
  270. for (vector<float>::iterator i=m_PortMin.begin();
  271. i!=m_PortMin.end(); i++)
  272. {
  273. s<<*i<<" ";
  274. }
  275. for (vector<float>::iterator i=m_PortMax.begin();
  276. i!=m_PortMax.end(); i++)
  277. {
  278. s<<*i<<" ";
  279. }
  280. }
  281. break;
  282. case 1:
  283. {
  284. s<<m_Gain<<" ";
  285. s<<m_CurrentPlugin.Filename<<" ";
  286. s<<m_CurrentPlugin.Label<<" ";
  287. }
  288. break;
  289. }
  290. }
  291. void LADSPAPlugin::StreamIn(istream &s)
  292. {
  293. int version;
  294. s>>version;
  295. switch (version)
  296. {
  297. case 3:
  298. {
  299. s>>m_Gain;
  300. string Filename,Label;
  301. s>>Filename>>Label;
  302. int PortCount;
  303. s>>PortCount;
  304. float min,max;
  305. bool clamp;
  306. for (int n=0; n<PortCount; n++)
  307. {
  308. s>>min;
  309. m_PortMin.push_back(min);
  310. }
  311. for (int n=0; n<PortCount; n++)
  312. {
  313. s>>max;
  314. m_PortMax.push_back(max);
  315. }
  316. for (int n=0; n<PortCount; n++)
  317. {
  318. s>>clamp;
  319. m_PortClamp.push_back(clamp);
  320. }
  321. if (Filename!="None")
  322. {
  323. UpdatePlugin(Filename.c_str(), Label.c_str(), false);
  324. }
  325. m_CurrentPlugin.Ports.reserve(PortCount);
  326. for (int n=0; n<PortCount; n++)
  327. {
  328. m_CurrentPlugin.Ports[n].Min=m_PortMin[n];
  329. m_CurrentPlugin.Ports[n].Max=m_PortMax[n];
  330. m_CurrentPlugin.Ports[n].Clamped=m_PortClamp[n];
  331. }
  332. }
  333. break;
  334. case 2:
  335. {
  336. s>>m_Gain;
  337. string Filename,Label;
  338. s>>Filename>>Label;
  339. int PortCount;
  340. s>>PortCount;
  341. float min,max;
  342. for (int n=0; n<PortCount; n++)
  343. {
  344. s>>min;
  345. m_PortMin.push_back(min);
  346. }
  347. for (int n=0; n<PortCount; n++)
  348. {
  349. s>>max;
  350. m_PortMax.push_back(max);
  351. }
  352. for (int n=0; n<PortCount; n++)
  353. {
  354. // Set PortClamp to true as default
  355. m_PortClamp.push_back(true);
  356. }
  357. if (Filename!="None")
  358. {
  359. UpdatePlugin(Filename.c_str(), Label.c_str(), false);
  360. }
  361. m_CurrentPlugin.Ports.reserve(PortCount);
  362. for (int n=0; n<PortCount; n++)
  363. {
  364. m_CurrentPlugin.Ports[n].Min=m_PortMin[n];
  365. m_CurrentPlugin.Ports[n].Max=m_PortMax[n];
  366. m_CurrentPlugin.Ports[n].Clamped=m_PortClamp[n];
  367. }
  368. }
  369. break;
  370. case 1:
  371. {
  372. s>>m_Gain;
  373. string Filename,Label;
  374. s>>Filename>>Label;
  375. if (Filename!="None")
  376. {
  377. UpdatePlugin(Filename.c_str(), Label.c_str());
  378. }
  379. }
  380. break;
  381. }
  382. }
  383. bool LADSPAPlugin::UpdatePlugin(int n)
  384. {
  385. return UpdatePlugin(m_LADSPAList[n].Filename.c_str(),m_LADSPAList[n].Label.c_str());
  386. }
  387. bool LADSPAPlugin::UpdatePlugin(const char * filename, const char * label, bool PortClampReset)
  388. {
  389. // first call with same info, to clear the ports
  390. UpdatePluginInfoWithHost();
  391. if (PlugHandle) {
  392. if (PlugDesc->deactivate) PlugDesc->deactivate(PlugInstHandle);
  393. PlugDesc->cleanup(PlugInstHandle);
  394. unloadLADSPAPluginLibrary(PlugHandle);
  395. PlugHandle = 0;
  396. }
  397. if ((PlugHandle = loadLADSPAPluginLibrary(filename))) {
  398. if (!(PlugDesc = findLADSPAPluginDescriptor(PlugHandle, filename, label))) {
  399. unloadLADSPAPluginLibrary(PlugHandle);
  400. PlugHandle = 0;
  401. } else {
  402. /* Now we can instantiate the LADSPA Plugin and wire it to the datas bytes */
  403. if (!(PlugInstHandle = PlugDesc->instantiate(PlugDesc, m_HostInfo->SAMPLERATE))) {
  404. cerr << "LADSPA Plugin error to instantiate...\n";
  405. unloadLADSPAPluginLibrary(PlugHandle);
  406. PlugDesc = 0;
  407. PlugHandle = 0;
  408. return 0;
  409. }
  410. m_PluginInfo.NumInputs=getPortCountByType(PlugDesc, LADSPA_PORT_INPUT);
  411. m_PluginInfo.NumOutputs=getPortCountByType(PlugDesc, LADSPA_PORT_OUTPUT);
  412. /////////////////////////////////
  413. // LADSPA Buffers
  414. for(vector<LADSPA_Data*>::iterator i=m_LADSPABufVec.begin();
  415. i!=m_LADSPABufVec.end(); i++)
  416. {
  417. if (*i) delete[] (*i);
  418. }
  419. m_LADSPABufVec.clear();
  420. unsigned long c=0;
  421. for (unsigned int n=0; n<PlugDesc->PortCount; n++)
  422. {
  423. if (LADSPA_IS_PORT_INPUT(PlugDesc->PortDescriptors[n]))
  424. {
  425. LADSPA_Data *NewPort = new LADSPA_Data[m_HostInfo->BUFSIZE];
  426. m_LADSPABufVec.push_back(NewPort);
  427. PlugDesc->connect_port(PlugInstHandle, n, m_LADSPABufVec[c]);
  428. m_PortID.push_back(n);
  429. c++;
  430. }
  431. }
  432. for (unsigned int n=0; n<PlugDesc->PortCount; n++)
  433. {
  434. if (LADSPA_IS_PORT_OUTPUT(PlugDesc->PortDescriptors[n]))
  435. {
  436. LADSPA_Data *NewPort = new LADSPA_Data[m_HostInfo->BUFSIZE];
  437. m_LADSPABufVec.push_back(NewPort);
  438. PlugDesc->connect_port(PlugInstHandle, n, m_LADSPABufVec[c]);
  439. m_PortID.push_back(n);
  440. c++;
  441. }
  442. }
  443. // activate the plugin now
  444. if (PlugDesc->activate)
  445. PlugDesc->activate(PlugInstHandle);
  446. /////////////////////////////////
  447. // SSM Buffers
  448. // Clear i/o buffers
  449. RemoveAllInputs();
  450. RemoveAllOutputs();
  451. // Reallocate the i/o buffers required
  452. for (int n=0; n<m_PluginInfo.NumInputs; n++) AddInput();
  453. for (int n=0; n<m_PluginInfo.NumOutputs; n++) AddOutput();
  454. //////////////////////////////
  455. // Update the GUI stuff
  456. m_CurrentPlugin.Name=PlugDesc->Name;
  457. m_CurrentPlugin.Maker=PlugDesc->Maker;
  458. m_CurrentPlugin.Filename=filename;
  459. m_CurrentPlugin.Label=label;
  460. m_CurrentPlugin.Ports.clear();
  461. m_PluginInfo.PortTips.clear();
  462. string desc;
  463. c=0;
  464. for (unsigned int i = 0; i < PlugDesc->PortCount; i++)
  465. {
  466. if (LADSPA_IS_PORT_INPUT(PlugDesc->PortDescriptors[i]))
  467. {
  468. desc = string(PlugDesc->PortNames[i]) +
  469. (LADSPA_IS_PORT_CONTROL(PlugDesc->PortDescriptors[i]) ? " (CV)" : " (AU)");
  470. m_PluginInfo.PortTips.push_back(desc.c_str());
  471. LPluginInfo::LPortDetails PortDetails;
  472. PortDetails.Name=m_PluginInfo.PortTips[c].c_str();
  473. m_CurrentPlugin.Ports.push_back(PortDetails);
  474. c++;
  475. }
  476. }
  477. for (unsigned int i = 0; i < PlugDesc->PortCount; i++)
  478. {
  479. if (LADSPA_IS_PORT_OUTPUT(PlugDesc->PortDescriptors[i])) {
  480. desc = string(PlugDesc->PortNames[i]) +
  481. (LADSPA_IS_PORT_CONTROL(PlugDesc->PortDescriptors[i]) ? " (CV)" : " (AU)");
  482. m_PluginInfo.PortTips.push_back(desc.c_str());
  483. }
  484. }
  485. UpdatePluginInfoWithHost();
  486. if (PortClampReset)
  487. {
  488. m_PortMin.clear();
  489. m_PortMax.clear();
  490. m_PortClamp.clear();
  491. for (int n=0; n<m_PluginInfo.NumInputs; n++)
  492. {
  493. float Max=1.0f, Min=-1.0f;
  494. int Port=m_PortID[n];
  495. // Get the bounding hints for the port
  496. LADSPA_PortRangeHintDescriptor HintDesc=PlugDesc->PortRangeHints[Port].HintDescriptor;
  497. if (LADSPA_IS_HINT_BOUNDED_BELOW(HintDesc))
  498. {
  499. Min=PlugDesc->PortRangeHints[Port].LowerBound;
  500. if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc))
  501. {
  502. Min*=m_HostInfo->SAMPLERATE;
  503. }
  504. }
  505. if (LADSPA_IS_HINT_BOUNDED_ABOVE(HintDesc))
  506. {
  507. Max=PlugDesc->PortRangeHints[Port].UpperBound;
  508. if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc))
  509. {
  510. Max*=m_HostInfo->SAMPLERATE;
  511. }
  512. }
  513. m_PortMin.push_back(Min);
  514. m_PortMax.push_back(Max);
  515. // PortClamp defaults to true
  516. m_PortClamp.push_back(true);
  517. m_CurrentPlugin.Ports[n].Min=Min;
  518. m_CurrentPlugin.Ports[n].Max=Max;
  519. m_CurrentPlugin.Ports[n].Clamped=true;
  520. }
  521. }
  522. m_InputPortCount = m_PluginInfo.NumInputs;
  523. int lbl_length;
  524. char *lbl_start;
  525. lbl_length = m_CurrentPlugin.Name.size();
  526. lbl_length = lbl_length > 255 ? 255 : lbl_length;
  527. strncpy(m_Name, m_CurrentPlugin.Name.substr(0, lbl_length).c_str(), lbl_length);
  528. m_Name[lbl_length] = '\0';
  529. lbl_length = m_CurrentPlugin.Maker.size();
  530. lbl_length = lbl_length > 255 ? 255 : lbl_length;
  531. strncpy(m_Maker, m_CurrentPlugin.Maker.substr(0, lbl_length).c_str(), lbl_length);
  532. m_Maker[lbl_length] = '\0';
  533. lbl_start = m_OutData.InputPortNames;
  534. for (unsigned long n = 0; n < m_InputPortCount; n++) {
  535. lbl_length = m_CurrentPlugin.Ports[n].Name.size();
  536. lbl_length = lbl_length > 255 ? 255 : lbl_length;
  537. strncpy(lbl_start, m_CurrentPlugin.Ports[n].Name.substr(0, lbl_length).c_str(), lbl_length);
  538. lbl_start[lbl_length] = '\0';
  539. lbl_start += 256;
  540. m_OutData.InputPortRanges[n].Min = m_CurrentPlugin.Ports[n].Min;
  541. m_OutData.InputPortRanges[n].Max = m_CurrentPlugin.Ports[n].Max;
  542. m_OutData.InputPortRanges[n].Clamp = m_CurrentPlugin.Ports[n].Clamped;
  543. }
  544. return true;
  545. }
  546. }
  547. cerr << "Error loading LADSPA Plugin.\n";
  548. return false;
  549. }
  550. void LADSPAPlugin::SetPortInfo(void)
  551. {
  552. for (unsigned long n = 0; n < m_InputPortCount; n++) {
  553. m_PortMin[n] = m_InData.InputPortRanges[n].Min;
  554. m_PortMax[n] = m_InData.InputPortRanges[n].Max;
  555. m_PortClamp[n] = m_InData.InputPortRanges[n].Clamp;
  556. }
  557. }