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.

623 lines
15KB

  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 "LADSPAInfo.h"
  21. #include <cstdio>
  22. #include <cstdlib>
  23. #include <cstring>
  24. #include "SpiralIcon.xpm"
  25. ////////////////////////////////////////////////////
  26. extern "C" {
  27. SpiralPlugin* CreateInstance()
  28. {
  29. return new LADSPAPlugin;
  30. }
  31. char** GetIcon()
  32. {
  33. return SpiralIcon_xpm;
  34. }
  35. int GetID()
  36. {
  37. return 0x0016;
  38. }
  39. }
  40. ///////////////////////////////////////////////////////
  41. LADSPAPlugin::LADSPAPlugin() :
  42. PlugHandle(0),
  43. PlugDesc(NULL),
  44. m_Gain(1.0f),
  45. m_Amped(false)
  46. {
  47. m_Version=4;
  48. m_PluginInfo.Name="LADSPA";
  49. m_PluginInfo.Width=500;
  50. m_PluginInfo.Height=320;
  51. m_PluginInfo.NumInputs=0;
  52. m_PluginInfo.NumOutputs=1;
  53. m_PluginInfo.PortTips.push_back("Nuffink yet");
  54. m_PluginIndex = 0;
  55. m_MaxInputPortCount = m_LADSPAInfo.GetMaxInputPortCount();
  56. m_InputPortCount = 0;
  57. // For receiving from GUI
  58. m_AudioCH->Register("SetGain",&(m_InData.Gain));
  59. m_AudioCH->Register("SetAmped",&(m_InData.Amped));
  60. m_AudioCH->RegisterData("SetPluginIndex", ChannelHandler::INPUT,&(m_InData.PluginIndex),sizeof(m_InData.PluginIndex));
  61. // For sending to GUI
  62. m_AudioCH->RegisterData("GetName",ChannelHandler::OUTPUT,m_Name,256);
  63. m_AudioCH->RegisterData("GetMaker",ChannelHandler::OUTPUT,m_Maker,256);
  64. m_AudioCH->RegisterData("GetMaxInputPortCount",ChannelHandler::OUTPUT,&(m_MaxInputPortCount),sizeof(m_MaxInputPortCount));
  65. m_AudioCH->RegisterData("GetInputPortCount",ChannelHandler::OUTPUT,&(m_InputPortCount),sizeof(m_InputPortCount));
  66. m_AudioCH->RegisterData("GetPluginIndex",ChannelHandler::OUTPUT,&(m_PluginIndex),sizeof(m_PluginIndex));
  67. m_OutData.InputPortNames = (char *)malloc(256 * m_MaxInputPortCount);
  68. m_OutData.InputPortSettings = (PortSettings *)malloc(sizeof(PortSettings) * m_MaxInputPortCount);
  69. m_OutData.InputPortValues = (float *)calloc(m_MaxInputPortCount, sizeof(float));
  70. m_InData.InputPortSettings = (PortSettings *)malloc(sizeof(PortSettings) * m_MaxInputPortCount);
  71. if (m_OutData.InputPortNames &&
  72. m_OutData.InputPortSettings &&
  73. m_InData.InputPortSettings) {
  74. m_AudioCH->RegisterData("GetInputPortNames", ChannelHandler::OUTPUT, m_OutData.InputPortNames, 256 * m_MaxInputPortCount);
  75. m_AudioCH->RegisterData("GetInputPortSettings", ChannelHandler::OUTPUT, m_OutData.InputPortSettings, sizeof(PortSettings) * m_MaxInputPortCount);
  76. m_AudioCH->RegisterData("GetInputPortValues", ChannelHandler::OUTPUT, m_OutData.InputPortValues, sizeof(float) * m_MaxInputPortCount);
  77. m_AudioCH->RegisterData("SetInputPortSettings", ChannelHandler::INPUT, m_InData.InputPortSettings, sizeof(PortSettings) * m_MaxInputPortCount);
  78. } else {
  79. cerr<<"Memory allocation error"<<endl;
  80. }
  81. }
  82. LADSPAPlugin::~LADSPAPlugin()
  83. {
  84. // Free allocated buffers
  85. if (m_OutData.InputPortNames) free(m_OutData.InputPortNames);
  86. if (m_OutData.InputPortSettings) free(m_OutData.InputPortSettings);
  87. if (m_OutData.InputPortValues) free(m_OutData.InputPortValues);
  88. if (m_InData.InputPortSettings) free(m_InData.InputPortSettings);
  89. }
  90. PluginInfo &LADSPAPlugin::Initialise(const HostInfo *Host)
  91. {
  92. PluginInfo& Info = SpiralPlugin::Initialise(Host);
  93. LADSPA_Data *NewPort = new LADSPA_Data[m_HostInfo->BUFSIZE];
  94. m_LADSPABufVec.push_back(NewPort);
  95. return Info;
  96. }
  97. SpiralGUIType *LADSPAPlugin::CreateGUI()
  98. {
  99. return new LADSPAPluginGUI(m_PluginInfo.Width, m_PluginInfo.Height,
  100. this, m_AudioCH, m_HostInfo, m_LADSPAInfo.GetPluginList());
  101. }
  102. void LADSPAPlugin::Execute()
  103. {
  104. if (PlugDesc)
  105. {
  106. // convert inputs if exist (use default if not)
  107. for (int n=0; n<m_PluginInfo.NumInputs; n++)
  108. {
  109. if (GetInput(n))
  110. {
  111. if (m_PortClamp[n]) {
  112. // scale input to match hinted range
  113. float Offset=m_PortMin[n];
  114. float Scale=m_PortMax[n]-m_PortMin[n];
  115. //cerr<<n<<" ["<<Scale<<"] ["<<Offset<<"]"<<endl;
  116. for (int i=0; i<m_HostInfo->BUFSIZE; i++)
  117. {
  118. m_LADSPABufVec[n][i]=Offset+(GetInput(n,i)*0.5f+0.5f)*Scale;
  119. //cerr<<Scale<<" "<<Offset<<" "<<m_LADSPABufVec[n][i]<<endl;
  120. }
  121. } else {
  122. // pass input as is
  123. for (int i=0; i<m_HostInfo->BUFSIZE; i++)
  124. {
  125. m_LADSPABufVec[n][i]=GetInput(n,i);
  126. }
  127. }
  128. // Copy values into OutData value buffer for display in GUI
  129. m_OutData.InputPortValues[n] = m_LADSPABufVec[n][0];
  130. }
  131. else // Use default
  132. {
  133. for (int i=0; i<m_HostInfo->BUFSIZE; i++) {
  134. m_LADSPABufVec[n][i]=m_PortDefault[n];
  135. }
  136. }
  137. }
  138. // run plugin
  139. PlugDesc->run(PlugInstHandle,m_HostInfo->BUFSIZE);
  140. // convert outputs
  141. for (int n=0; n<m_PluginInfo.NumOutputs; n++)
  142. {
  143. /*if (m_Amped)
  144. {
  145. for (int i=0; i<m_HostInfo->BUFSIZE; i++)
  146. {
  147. SetOutput(n,i,m_LADSPABufVec[n+m_PluginInfo.NumInputs][i]*m_Gain*10);
  148. }
  149. }
  150. else*/
  151. {
  152. for (int i=0; i<m_HostInfo->BUFSIZE; i++)
  153. {
  154. SetOutput(n,i,m_LADSPABufVec[n+m_PluginInfo.NumInputs][i]*m_Gain);
  155. }
  156. }
  157. }
  158. }
  159. }
  160. void LADSPAPlugin::ExecuteCommands()
  161. {
  162. if (m_AudioCH->IsCommandWaiting())
  163. {
  164. switch(m_AudioCH->GetCommand())
  165. {
  166. case (SETPORTSETTINGS) :
  167. SetPortSettings();
  168. break;
  169. case (SELECTPLUGIN) :
  170. vector<LADSPAInfo::PluginEntry> pe = m_LADSPAInfo.GetPluginList();
  171. UpdatePlugin(pe[m_InData.PluginIndex].UniqueID);
  172. break;
  173. }
  174. }
  175. }
  176. void LADSPAPlugin::StreamOut(ostream &s)
  177. {
  178. s<<m_Version<<" ";
  179. switch (m_Version)
  180. {
  181. case 4:
  182. {
  183. s<<m_Gain<<" ";
  184. s<<m_UniqueID<<" ";
  185. s<<m_PortMin.size()<<" ";
  186. assert(m_PortMin.size()==m_PortMax.size());
  187. assert(m_PortMin.size()==m_PortClamp.size());
  188. assert(m_PortMin.size()==m_PortDefault.size());
  189. for (vector<float>::iterator i=m_PortMin.begin();
  190. i!=m_PortMin.end(); i++)
  191. {
  192. s<<*i<<" ";
  193. }
  194. for (vector<float>::iterator i=m_PortMax.begin();
  195. i!=m_PortMax.end(); i++)
  196. {
  197. s<<*i<<" ";
  198. }
  199. for (vector<bool>::iterator i=m_PortClamp.begin();
  200. i!=m_PortClamp.end(); i++)
  201. {
  202. s<<*i<<" ";
  203. }
  204. for (vector<float>::iterator i=m_PortDefault.begin();
  205. i!=m_PortDefault.end(); i++)
  206. {
  207. s<<*i<<" ";
  208. }
  209. }
  210. break;
  211. case 3:
  212. {
  213. // Here for consistency - should never actually happen, as
  214. // version is always 4!
  215. // s<<m_Gain<<" ";
  216. // s<<m_Filename<<" ";
  217. // s<<m_Label<<" ";
  218. // s<<m_PortMin.size()<<" ";
  219. // assert(m_PortMin.size()==m_PortMax.size());
  220. // assert(m_PortMin.size()==m_PortClamp.size());
  221. // for (vector<float>::iterator i=m_PortMin.begin();
  222. // i!=m_PortMin.end(); i++)
  223. // {
  224. // s<<*i<<" ";
  225. // }
  226. // for (vector<float>::iterator i=m_PortMax.begin();
  227. // i!=m_PortMax.end(); i++)
  228. // {
  229. // s<<*i<<" ";
  230. // }
  231. // for (vector<bool>::iterator i=m_PortClamp.begin();
  232. // i!=m_PortClamp.end(); i++)
  233. // {
  234. // s<<*i<<" ";
  235. // }
  236. }
  237. break;
  238. case 2:
  239. {
  240. // s<<m_Gain<<" ";
  241. // s<<m_Filename<<" ";
  242. // s<<m_Label<<" ";
  243. // s<<m_PortMin.size()<<" ";
  244. // assert(m_PortMin.size()==m_PortMax.size());
  245. // for (vector<float>::iterator i=m_PortMin.begin();
  246. // i!=m_PortMin.end(); i++)
  247. // {
  248. // s<<*i<<" ";
  249. // }
  250. // for (vector<float>::iterator i=m_PortMax.begin();
  251. // i!=m_PortMax.end(); i++)
  252. // {
  253. // s<<*i<<" ";
  254. // }
  255. }
  256. break;
  257. case 1:
  258. {
  259. // s<<m_Gain<<" ";
  260. // s<<m_Filename<<" ";
  261. // s<<m_Label<<" ";
  262. }
  263. break;
  264. }
  265. }
  266. void LADSPAPlugin::StreamIn(istream &s)
  267. {
  268. int version;
  269. s>>version;
  270. switch (version)
  271. {
  272. case 4:
  273. {
  274. s>>m_Gain;
  275. unsigned long UniqueID;
  276. s>>UniqueID;
  277. int PortCount;
  278. s>>PortCount;
  279. float min,max;
  280. bool clamp;
  281. float defolt;
  282. for (int n=0; n<PortCount; n++)
  283. {
  284. s>>min;
  285. m_PortMin.push_back(min);
  286. }
  287. for (int n=0; n<PortCount; n++)
  288. {
  289. s>>max;
  290. m_PortMax.push_back(max);
  291. }
  292. for (int n=0; n<PortCount; n++)
  293. {
  294. s>>clamp;
  295. m_PortClamp.push_back(clamp);
  296. }
  297. for (int n=0; n<PortCount; n++)
  298. {
  299. s>>defolt;
  300. m_PortDefault.push_back(defolt);
  301. }
  302. UpdatePlugin(UniqueID, false);
  303. }
  304. break;
  305. case 3:
  306. {
  307. s>>m_Gain;
  308. string Filename,Label;
  309. s>>Filename>>Label;
  310. int PortCount;
  311. s>>PortCount;
  312. float min,max;
  313. bool clamp;
  314. for (int n=0; n<PortCount; n++)
  315. {
  316. s>>min;
  317. m_PortMin.push_back(min);
  318. }
  319. for (int n=0; n<PortCount; n++)
  320. {
  321. s>>max;
  322. m_PortMax.push_back(max);
  323. }
  324. for (int n=0; n<PortCount; n++)
  325. {
  326. s>>clamp;
  327. m_PortClamp.push_back(clamp);
  328. }
  329. if (Filename!="None")
  330. {
  331. // Get Unique ID from filename and label
  332. unsigned long id = m_LADSPAInfo.GetIDFromFilenameAndLabel(Filename, Label);
  333. if (id) UpdatePlugin(id, false);
  334. }
  335. }
  336. break;
  337. case 2:
  338. {
  339. s>>m_Gain;
  340. string Filename,Label;
  341. s>>Filename>>Label;
  342. int PortCount;
  343. s>>PortCount;
  344. float min,max;
  345. for (int n=0; n<PortCount; n++)
  346. {
  347. s>>min;
  348. m_PortMin.push_back(min);
  349. }
  350. for (int n=0; n<PortCount; n++)
  351. {
  352. s>>max;
  353. m_PortMax.push_back(max);
  354. }
  355. for (int n=0; n<PortCount; n++)
  356. {
  357. // Set PortClamp to true as default
  358. m_PortClamp.push_back(true);
  359. }
  360. if (Filename!="None")
  361. {
  362. // Get Unique ID from filename and label
  363. unsigned long id = m_LADSPAInfo.GetIDFromFilenameAndLabel(Filename, Label);
  364. if (id) UpdatePlugin(id, false);
  365. }
  366. }
  367. break;
  368. case 1:
  369. {
  370. s>>m_Gain;
  371. string Filename,Label;
  372. s>>Filename>>Label;
  373. if (Filename!="None")
  374. {
  375. // Get Unique ID from filename and label
  376. unsigned long id = m_LADSPAInfo.GetIDFromFilenameAndLabel(Filename, Label);
  377. if (id) UpdatePlugin(id, false);
  378. }
  379. }
  380. break;
  381. }
  382. }
  383. bool LADSPAPlugin::UpdatePlugin(unsigned long UniqueID, bool PortClampReset)
  384. {
  385. // first call with same info, to clear the ports
  386. UpdatePluginInfoWithHost();
  387. if (PlugDesc) {
  388. if (PlugDesc->deactivate) PlugDesc->deactivate(PlugInstHandle);
  389. PlugDesc->cleanup(PlugInstHandle);
  390. }
  391. PlugDesc = m_LADSPAInfo.GetDescriptorByID(UniqueID, true);
  392. if (PlugDesc) {
  393. // Create instance
  394. if (!(PlugInstHandle = PlugDesc->instantiate(PlugDesc, m_HostInfo->SAMPLERATE))) {
  395. cerr << "WARNING: Could not instantiate plugin " << UniqueID << endl;
  396. m_LADSPAInfo.UnloadLibraryByID(UniqueID);
  397. PlugDesc = 0;
  398. return 0;
  399. }
  400. // Find number of input and output ports
  401. m_PluginInfo.NumInputs = m_PluginInfo.NumOutputs = 0;
  402. for (unsigned long i = 0; i < PlugDesc->PortCount; i++) {
  403. if (LADSPA_IS_PORT_INPUT(PlugDesc->PortDescriptors[i])) {
  404. m_PluginInfo.NumInputs++;
  405. } else if (LADSPA_IS_PORT_OUTPUT(PlugDesc->PortDescriptors[i])) {
  406. m_PluginInfo.NumOutputs++;
  407. }
  408. }
  409. /////////////////////////////////
  410. // LADSPA Buffers
  411. for(vector<LADSPA_Data*>::iterator i=m_LADSPABufVec.begin();
  412. i!=m_LADSPABufVec.end(); i++)
  413. {
  414. if (*i) delete[] (*i);
  415. }
  416. m_LADSPABufVec.clear();
  417. unsigned long c=0;
  418. for (unsigned int n=0; n<PlugDesc->PortCount; n++)
  419. {
  420. if (LADSPA_IS_PORT_INPUT(PlugDesc->PortDescriptors[n]))
  421. {
  422. LADSPA_Data *NewPort = new LADSPA_Data[m_HostInfo->BUFSIZE];
  423. m_LADSPABufVec.push_back(NewPort);
  424. PlugDesc->connect_port(PlugInstHandle, n, m_LADSPABufVec[c]);
  425. m_PortID.push_back(n);
  426. c++;
  427. }
  428. }
  429. for (unsigned int n=0; n<PlugDesc->PortCount; n++)
  430. {
  431. if (LADSPA_IS_PORT_OUTPUT(PlugDesc->PortDescriptors[n]))
  432. {
  433. LADSPA_Data *NewPort = new LADSPA_Data[m_HostInfo->BUFSIZE];
  434. m_LADSPABufVec.push_back(NewPort);
  435. PlugDesc->connect_port(PlugInstHandle, n, m_LADSPABufVec[c]);
  436. m_PortID.push_back(n);
  437. c++;
  438. }
  439. }
  440. // activate the plugin now
  441. if (PlugDesc->activate)
  442. PlugDesc->activate(PlugInstHandle);
  443. /////////////////////////////////
  444. // SSM Buffers
  445. // Clear i/o buffers
  446. RemoveAllInputs();
  447. RemoveAllOutputs();
  448. // Reallocate the i/o buffers required
  449. for (int n=0; n<m_PluginInfo.NumInputs; n++) AddInput();
  450. for (int n=0; n<m_PluginInfo.NumOutputs; n++) AddOutput();
  451. //////////////////////////////
  452. // Update the GUI stuff
  453. m_PluginInfo.PortTips.clear();
  454. string desc;
  455. c=0;
  456. for (unsigned int i = 0; i < PlugDesc->PortCount; i++)
  457. {
  458. if (LADSPA_IS_PORT_INPUT(PlugDesc->PortDescriptors[i]))
  459. {
  460. desc = string(PlugDesc->PortNames[i]) +
  461. (LADSPA_IS_PORT_CONTROL(PlugDesc->PortDescriptors[i]) ? " (CV)" : " (AU)");
  462. m_PluginInfo.PortTips.push_back(desc.c_str());
  463. c++;
  464. }
  465. }
  466. for (unsigned int i = 0; i < PlugDesc->PortCount; i++)
  467. {
  468. if (LADSPA_IS_PORT_OUTPUT(PlugDesc->PortDescriptors[i])) {
  469. desc = string(PlugDesc->PortNames[i]) +
  470. (LADSPA_IS_PORT_CONTROL(PlugDesc->PortDescriptors[i]) ? " (CV)" : " (AU)");
  471. m_PluginInfo.PortTips.push_back(desc.c_str());
  472. }
  473. }
  474. UpdatePluginInfoWithHost();
  475. if (PortClampReset)
  476. {
  477. m_PortMin.clear();
  478. m_PortMax.clear();
  479. m_PortClamp.clear();
  480. for (int n=0; n<m_PluginInfo.NumInputs; n++)
  481. {
  482. float Max=1.0f, Min=-1.0f;
  483. int Port=m_PortID[n];
  484. // Get the bounding hints for the port
  485. LADSPA_PortRangeHintDescriptor HintDesc=PlugDesc->PortRangeHints[Port].HintDescriptor;
  486. if (LADSPA_IS_HINT_BOUNDED_BELOW(HintDesc))
  487. {
  488. Min=PlugDesc->PortRangeHints[Port].LowerBound;
  489. if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc))
  490. {
  491. Min*=m_HostInfo->SAMPLERATE;
  492. }
  493. }
  494. if (LADSPA_IS_HINT_BOUNDED_ABOVE(HintDesc))
  495. {
  496. Max=PlugDesc->PortRangeHints[Port].UpperBound;
  497. if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc))
  498. {
  499. Max*=m_HostInfo->SAMPLERATE;
  500. }
  501. }
  502. m_PortMin.push_back(Min);
  503. m_PortMax.push_back(Max);
  504. m_PortClamp.push_back(true);
  505. m_PortDefault.push_back(0.0f);
  506. }
  507. }
  508. int lbl_length;
  509. char *lbl_start;
  510. m_UniqueID = PlugDesc->UniqueID;
  511. m_InputPortCount = m_PluginInfo.NumInputs;
  512. lbl_length = strlen(PlugDesc->Name);
  513. lbl_length = lbl_length > 255 ? 255 : lbl_length;
  514. strncpy(m_Name, PlugDesc->Name, lbl_length);
  515. m_Name[lbl_length] = '\0';
  516. lbl_length = strlen(PlugDesc->Maker);
  517. lbl_length = lbl_length > 255 ? 255 : lbl_length;
  518. strncpy(m_Maker, PlugDesc->Maker, lbl_length);
  519. m_Maker[lbl_length] = '\0';
  520. lbl_start = m_OutData.InputPortNames;
  521. for (unsigned long n = 0; n < m_InputPortCount; n++) {
  522. lbl_length = m_PluginInfo.PortTips[n].size();
  523. lbl_length = lbl_length > 255 ? 255 : lbl_length;
  524. strncpy(lbl_start, m_PluginInfo.PortTips[n].c_str(), lbl_length);
  525. lbl_start[lbl_length] = '\0';
  526. lbl_start += 256;
  527. m_OutData.InputPortSettings[n].Min = m_PortMin[n];
  528. m_OutData.InputPortSettings[n].Max = m_PortMax[n];
  529. m_OutData.InputPortSettings[n].Clamp = m_PortClamp[n];
  530. m_OutData.InputPortSettings[n].Default = m_PortDefault[n];
  531. }
  532. return true;
  533. }
  534. cerr << "Error loading LADSPA Plugin.\n";
  535. return false;
  536. }
  537. void LADSPAPlugin::SetPortSettings(void)
  538. {
  539. for (unsigned long n = 0; n < m_InputPortCount; n++) {
  540. m_PortMin[n] = m_InData.InputPortSettings[n].Min;
  541. m_PortMax[n] = m_InData.InputPortSettings[n].Max;
  542. m_PortClamp[n] = m_InData.InputPortSettings[n].Clamp;
  543. m_PortDefault[n] = m_InData.InputPortSettings[n].Default;
  544. }
  545. }