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.

471 lines
11KB

  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 <stdio.h>
  21. #include "SpiralIcon.xpm"
  22. #include "utils.h"
  23. extern "C" {
  24. SpiralPlugin* CreateInstance()
  25. {
  26. return new LADSPAPlugin;
  27. }
  28. char** GetIcon()
  29. {
  30. return SpiralIcon_xpm;
  31. }
  32. int GetID()
  33. {
  34. return 0x0016;
  35. }
  36. }
  37. ///////////////////////////////////////////////////////
  38. LADSPAPlugin::LADSPAPlugin() :
  39. PlugHandle(0),
  40. PlugDesc(NULL),
  41. m_Gain(1.0f),
  42. m_Amped(false)
  43. {
  44. m_Version=3;
  45. m_PluginInfo.Name="LADSPA";
  46. m_PluginInfo.Width=600;
  47. m_PluginInfo.Height=300;
  48. m_PluginInfo.NumInputs=0;
  49. m_PluginInfo.NumOutputs=1;
  50. m_PluginInfo.PortTips.push_back("Nuffink yet");
  51. }
  52. LADSPAPlugin::~LADSPAPlugin()
  53. {
  54. }
  55. PluginInfo &LADSPAPlugin::Initialise(const HostInfo *Host)
  56. {
  57. PluginInfo& Info = SpiralPlugin::Initialise(Host);
  58. LADSPA_Data *NewPort = new LADSPA_Data[m_HostInfo->BUFSIZE];
  59. m_LADSPABufVec.push_back(NewPort);
  60. return Info;
  61. }
  62. SpiralGUIType *LADSPAPlugin::CreateGUI()
  63. {
  64. m_GUI = new LADSPAPluginGUI(m_PluginInfo.Width,
  65. m_PluginInfo.Height,
  66. this,m_HostInfo);
  67. m_GUI->hide();
  68. return m_GUI;
  69. }
  70. void LADSPAPlugin::Execute()
  71. {
  72. if (PlugDesc)
  73. {
  74. // convert inputs if exist (zero if not)
  75. for (int n=0; n<m_PluginInfo.NumInputs; n++)
  76. {
  77. if (GetInput(n))
  78. {
  79. if (m_PortClamp[n]) {
  80. // scale input to match hinted range
  81. float Offset=m_PortMin[n];
  82. float Scale=m_PortMax[n]-m_PortMin[n];
  83. //cerr<<n<<" ["<<Scale<<"] ["<<Offset<<"]"<<endl;
  84. for (int i=0; i<m_HostInfo->BUFSIZE; i++)
  85. {
  86. m_LADSPABufVec[n][i]=Offset+(GetInput(n,i)*0.5f+0.5f)*Scale;
  87. //cerr<<Scale<<" "<<Offset<<" "<<m_LADSPABufVec[n][i]<<endl;
  88. }
  89. } else {
  90. // pass input as is
  91. for (int i=0; i<m_HostInfo->BUFSIZE; i++)
  92. {
  93. m_LADSPABufVec[n][i]=GetInput(n,i);
  94. }
  95. }
  96. // Update the GUI outputs with the first value in the buffer
  97. ((LADSPAPluginGUI*)m_GUI)->UpdatePortDisplay(n,m_LADSPABufVec[n][0]);
  98. }
  99. else // zero
  100. {
  101. for (int i=0; i<m_HostInfo->BUFSIZE; i++) m_LADSPABufVec[n][i]=0;
  102. }
  103. }
  104. // run plugin
  105. PlugDesc->run(PlugInstHandle,m_HostInfo->BUFSIZE);
  106. // convert outputs
  107. for (int n=0; n<m_PluginInfo.NumOutputs; n++)
  108. {
  109. /*if (m_Amped)
  110. {
  111. for (int i=0; i<m_HostInfo->BUFSIZE; i++)
  112. {
  113. SetOutput(n,i,m_LADSPABufVec[n+m_PluginInfo.NumInputs][i]*m_Gain*10);
  114. }
  115. }
  116. else*/
  117. {
  118. for (int i=0; i<m_HostInfo->BUFSIZE; i++)
  119. {
  120. SetOutput(n,i,m_LADSPABufVec[n+m_PluginInfo.NumInputs][i]*m_Gain);
  121. }
  122. }
  123. }
  124. }
  125. }
  126. void LADSPAPlugin::StreamOut(ostream &s)
  127. {
  128. s<<m_Version<<" ";
  129. switch (m_Version)
  130. {
  131. case 3:
  132. {
  133. s<<m_Gain<<" ";
  134. s<<((LADSPAPluginGUI*)m_GUI)->GetFilename()<<" ";
  135. s<<((LADSPAPluginGUI*)m_GUI)->GetLabel()<<" ";
  136. s<<m_PortMin.size()<<" ";
  137. assert(m_PortMin.size()==m_PortMax.size());
  138. assert(m_PortMin.size()==m_PortClamp.size());
  139. for (vector<float>::iterator i=m_PortMin.begin();
  140. i!=m_PortMin.end(); i++)
  141. {
  142. s<<*i<<" ";
  143. }
  144. for (vector<float>::iterator i=m_PortMax.begin();
  145. i!=m_PortMax.end(); i++)
  146. {
  147. s<<*i<<" ";
  148. }
  149. for (vector<bool>::iterator i=m_PortClamp.begin();
  150. i!=m_PortClamp.end(); i++)
  151. {
  152. s<<*i<<" ";
  153. }
  154. }
  155. break;
  156. case 2:
  157. // Here for consistency - should never actually happen, as
  158. // version is always 3!
  159. {
  160. s<<m_Gain<<" ";
  161. s<<((LADSPAPluginGUI*)m_GUI)->GetFilename()<<" ";
  162. s<<((LADSPAPluginGUI*)m_GUI)->GetLabel()<<" ";
  163. s<<m_PortMin.size()<<" ";
  164. assert(m_PortMin.size()==m_PortMax.size());
  165. for (vector<float>::iterator i=m_PortMin.begin();
  166. i!=m_PortMin.end(); i++)
  167. {
  168. s<<*i<<" ";
  169. }
  170. for (vector<float>::iterator i=m_PortMax.begin();
  171. i!=m_PortMax.end(); i++)
  172. {
  173. s<<*i<<" ";
  174. }
  175. }
  176. break;
  177. case 1:
  178. {
  179. s<<m_Gain<<" ";
  180. s<<((LADSPAPluginGUI*)m_GUI)->GetFilename()<<" ";
  181. s<<((LADSPAPluginGUI*)m_GUI)->GetLabel()<<" ";
  182. }
  183. break;
  184. }
  185. }
  186. void LADSPAPlugin::StreamIn(istream &s)
  187. {
  188. int version;
  189. s>>version;
  190. switch (version)
  191. {
  192. case 3:
  193. {
  194. s>>m_Gain;
  195. string Filename,Label;
  196. s>>Filename>>Label;
  197. int PortCount;
  198. s>>PortCount;
  199. float min,max;
  200. bool clamp;
  201. for (int n=0; n<PortCount; n++)
  202. {
  203. s>>min;
  204. m_PortMin.push_back(min);
  205. }
  206. for (int n=0; n<PortCount; n++)
  207. {
  208. s>>max;
  209. m_PortMax.push_back(max);
  210. }
  211. for (int n=0; n<PortCount; n++)
  212. {
  213. s>>clamp;
  214. m_PortClamp.push_back(clamp);
  215. }
  216. if (Filename!="None")
  217. {
  218. UpdatePlugin(Filename.c_str(), Label.c_str(), false);
  219. }
  220. for (int n=0; n<PortCount; n++)
  221. {
  222. ((LADSPAPluginGUI*)m_GUI)->SetMinMax(n,m_PortMin[n],m_PortMax[n],m_PortClamp[n]);
  223. }
  224. }
  225. break;
  226. case 2:
  227. {
  228. s>>m_Gain;
  229. string Filename,Label;
  230. s>>Filename>>Label;
  231. int PortCount;
  232. s>>PortCount;
  233. float min,max;
  234. for (int n=0; n<PortCount; n++)
  235. {
  236. s>>min;
  237. m_PortMin.push_back(min);
  238. }
  239. for (int n=0; n<PortCount; n++)
  240. {
  241. s>>max;
  242. m_PortMax.push_back(max);
  243. }
  244. for (int n=0; n<PortCount; n++)
  245. {
  246. // Set PortClamp to true as default
  247. m_PortClamp.push_back(true);
  248. }
  249. if (Filename!="None")
  250. {
  251. UpdatePlugin(Filename.c_str(), Label.c_str(), false);
  252. }
  253. for (int n=0; n<PortCount; n++)
  254. {
  255. ((LADSPAPluginGUI*)m_GUI)->SetMinMax(n,m_PortMin[n],m_PortMax[n],m_PortClamp[n]);
  256. }
  257. }
  258. break;
  259. case 1:
  260. {
  261. s>>m_Gain;
  262. string Filename,Label;
  263. s>>Filename>>Label;
  264. if (Filename!="None")
  265. {
  266. UpdatePlugin(Filename.c_str(), Label.c_str());
  267. }
  268. }
  269. break;
  270. }
  271. }
  272. bool LADSPAPlugin::UpdatePlugin(const char * filename, const char * label, bool PortClampReset)
  273. {
  274. // first call with same info, to clear the ports
  275. UpdatePluginInfoWithHost();
  276. if (PlugHandle) {
  277. if (PlugDesc->deactivate) PlugDesc->deactivate(PlugInstHandle);
  278. PlugDesc->cleanup(PlugInstHandle);
  279. unloadLADSPAPluginLibrary(PlugHandle);
  280. PlugHandle = 0;
  281. }
  282. if ((PlugHandle = loadLADSPAPluginLibrary(filename))) {
  283. if (!(PlugDesc = findLADSPAPluginDescriptor(PlugHandle, filename, label))) {
  284. unloadLADSPAPluginLibrary(PlugHandle);
  285. PlugHandle = 0;
  286. } else {
  287. /* Now we can instantiate the LADSPA Plugin and wire it to the datas bytes */
  288. if (!(PlugInstHandle = PlugDesc->instantiate(PlugDesc, m_HostInfo->SAMPLERATE))) {
  289. cerr << "LADSPA Plugin error to instantiate...\n";
  290. unloadLADSPAPluginLibrary(PlugHandle);
  291. PlugDesc = 0;
  292. PlugHandle = 0;
  293. return 0;
  294. }
  295. m_PluginInfo.NumInputs=getPortCountByType(PlugDesc, LADSPA_PORT_INPUT);
  296. m_PluginInfo.NumOutputs=getPortCountByType(PlugDesc, LADSPA_PORT_OUTPUT);
  297. /////////////////////////////////
  298. // LADSPA Buffers
  299. for(vector<LADSPA_Data*>::iterator i=m_LADSPABufVec.begin();
  300. i!=m_LADSPABufVec.end(); i++)
  301. {
  302. if (*i) delete[] (*i);
  303. }
  304. m_LADSPABufVec.clear();
  305. unsigned long c=0;
  306. for (unsigned int n=0; n<PlugDesc->PortCount; n++)
  307. {
  308. if (LADSPA_IS_PORT_INPUT(PlugDesc->PortDescriptors[n]))
  309. {
  310. LADSPA_Data *NewPort = new LADSPA_Data[m_HostInfo->BUFSIZE];
  311. m_LADSPABufVec.push_back(NewPort);
  312. PlugDesc->connect_port(PlugInstHandle, n, m_LADSPABufVec[c]);
  313. m_PortID.push_back(n);
  314. c++;
  315. }
  316. }
  317. for (unsigned int n=0; n<PlugDesc->PortCount; n++)
  318. {
  319. if (LADSPA_IS_PORT_OUTPUT(PlugDesc->PortDescriptors[n]))
  320. {
  321. LADSPA_Data *NewPort = new LADSPA_Data[m_HostInfo->BUFSIZE];
  322. m_LADSPABufVec.push_back(NewPort);
  323. PlugDesc->connect_port(PlugInstHandle, n, m_LADSPABufVec[c]);
  324. m_PortID.push_back(n);
  325. c++;
  326. }
  327. }
  328. // activate the plugin now
  329. if (PlugDesc->activate)
  330. PlugDesc->activate(PlugInstHandle);
  331. /////////////////////////////////
  332. // SSM Buffers
  333. // Clear i/o buffers
  334. RemoveAllInputs();
  335. RemoveAllOutputs();
  336. // Reallocate the i/o buffers required
  337. for (int n=0; n<m_PluginInfo.NumInputs; n++) AddInput();
  338. for (int n=0; n<m_PluginInfo.NumOutputs; n++) AddOutput();
  339. //////////////////////////////
  340. // Update the GUI stuff
  341. ((LADSPAPluginGUI*)m_GUI)->SetName(PlugDesc->Name);
  342. ((LADSPAPluginGUI*)m_GUI)->SetMaker(PlugDesc->Maker);
  343. m_PluginInfo.PortTips.clear();
  344. ((LADSPAPluginGUI*)m_GUI)->ClearPortInfo();
  345. string desc;
  346. c=0;
  347. for (unsigned int i = 0; i < PlugDesc->PortCount; i++)
  348. {
  349. if (LADSPA_IS_PORT_INPUT(PlugDesc->PortDescriptors[i]))
  350. {
  351. desc = string(PlugDesc->PortNames[i]) +
  352. (LADSPA_IS_PORT_CONTROL(PlugDesc->PortDescriptors[i]) ? " (CV)" : " (AU)");
  353. m_PluginInfo.PortTips.push_back(desc.c_str());
  354. ((LADSPAPluginGUI*)m_GUI)->AddPortInfo(m_PluginInfo.PortTips[c].c_str());
  355. c++;
  356. }
  357. }
  358. for (unsigned int i = 0; i < PlugDesc->PortCount; i++)
  359. {
  360. if (LADSPA_IS_PORT_OUTPUT(PlugDesc->PortDescriptors[i])) {
  361. desc = string(PlugDesc->PortNames[i]) +
  362. (LADSPA_IS_PORT_CONTROL(PlugDesc->PortDescriptors[i]) ? " (CV)" : " (AU)");
  363. m_PluginInfo.PortTips.push_back(desc.c_str());
  364. }
  365. }
  366. ((LADSPAPluginGUI*)m_GUI)->SetFilename(filename);
  367. ((LADSPAPluginGUI*)m_GUI)->SetLabel(label);
  368. UpdatePluginInfoWithHost();
  369. if (PortClampReset)
  370. {
  371. m_PortMin.clear();
  372. m_PortMax.clear();
  373. m_PortClamp.clear();
  374. for (int n=0; n<m_PluginInfo.NumInputs; n++)
  375. {
  376. float Max=1.0f, Min=-1.0f;
  377. int Port=m_PortID[n];
  378. // Get the bounding hints for the port
  379. LADSPA_PortRangeHintDescriptor HintDesc=PlugDesc->PortRangeHints[Port].HintDescriptor;
  380. if (LADSPA_IS_HINT_BOUNDED_BELOW(HintDesc))
  381. {
  382. Min=PlugDesc->PortRangeHints[Port].LowerBound;
  383. if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc))
  384. {
  385. Min*=m_HostInfo->SAMPLERATE;
  386. }
  387. }
  388. if (LADSPA_IS_HINT_BOUNDED_ABOVE(HintDesc))
  389. {
  390. Max=PlugDesc->PortRangeHints[Port].UpperBound;
  391. if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc))
  392. {
  393. Max*=m_HostInfo->SAMPLERATE;
  394. }
  395. }
  396. m_PortMin.push_back(Min);
  397. m_PortMax.push_back(Max);
  398. // PortClamp defaults to true
  399. m_PortClamp.push_back(true);
  400. ((LADSPAPluginGUI*)m_GUI)->SetMinMax(n, Min, Max, true);
  401. }
  402. }
  403. return true;
  404. }
  405. }
  406. cerr << "Error loading LADSPA Plugin.\n";
  407. return false;
  408. }