Collection of DPF-based plugins for packaging
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.

318 lines
10KB

  1. /*
  2. * DISTRHO SoulForce, a DPF'ied SoulForce.
  3. * Copyright (C) 2006 Niall Moody
  4. * Copyright (C) 2015-2022 Filipe Coelho <falktx@falktx.com>
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a
  7. * copy of this software and associated documentation files (the "Software"),
  8. * to deal in the Software without restriction, including without limitation
  9. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10. * and/or sell copies of the Software, and to permit persons to whom the
  11. * Software is furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22. * DEALINGS IN THE SOFTWARE.
  23. */
  24. #include "DistrhoPluginSoulForce.hpp"
  25. START_NAMESPACE_DISTRHO
  26. // -----------------------------------------------------------------------
  27. DistrhoPluginSoulForce::DistrhoPluginSoulForce()
  28. : Plugin(kParameterCount, kProgramCount, 0),
  29. coeff(0.5f),
  30. wave(0.0f),
  31. env(0.0f),
  32. footEnv(0.0f)
  33. {
  34. // set initial values
  35. loadProgram(0);
  36. }
  37. // -----------------------------------------------------------------------
  38. // Init
  39. void DistrhoPluginSoulForce::initAudioPort(bool input, uint32_t index, AudioPort& port)
  40. {
  41. port.groupId = kPortGroupStereo;
  42. Plugin::initAudioPort(input, index, port);
  43. }
  44. void DistrhoPluginSoulForce::initParameter(uint32_t index, Parameter& parameter)
  45. {
  46. parameter.hints = kParameterIsAutomatable;
  47. parameter.ranges.min = 0.0f;
  48. parameter.ranges.max = 1.0f;
  49. switch (index)
  50. {
  51. case kParameterShape:
  52. parameter.name = "Shape";
  53. parameter.symbol = "shape";
  54. parameter.ranges.def = 0.5f;
  55. break;
  56. case kParameterFeedback:
  57. parameter.name = "FBack";
  58. parameter.symbol = "fback";
  59. parameter.ranges.def = 0.0f;
  60. break;
  61. case kParameterSource:
  62. parameter.hints |= kParameterIsBoolean;
  63. parameter.name = "Source";
  64. parameter.symbol = "source";
  65. parameter.ranges.def = 0.0f;
  66. break;
  67. case kParameterFootswitch:
  68. parameter.hints |= kParameterIsBoolean;
  69. parameter.name = "Foot";
  70. parameter.symbol = "foot";
  71. parameter.ranges.def = 1.0f;
  72. break;
  73. }
  74. }
  75. void DistrhoPluginSoulForce::initProgramName(uint32_t index, String& programName)
  76. {
  77. switch(index)
  78. {
  79. case kProgramDefault:
  80. programName = "Default";
  81. break;
  82. case kProgramStayDown:
  83. programName = "Stay Down";
  84. break;
  85. case kProgramLookingForTheWorld:
  86. programName = "Looking for the World";
  87. break;
  88. case kProgramGuerillaLove:
  89. programName = "Guerilla Love";
  90. break;
  91. case kProgramTumbleToThePower:
  92. programName = "Tumble to the Power";
  93. break;
  94. case kProgramDoYourselfFavour:
  95. programName = "Do Yourself a Favour";
  96. break;
  97. case kProgramPastIsPast:
  98. programName = "Past is Past";
  99. break;
  100. case kProgramYouAndOnlyYou:
  101. programName = "You and Only You";
  102. break;
  103. case kProgramSoulForce:
  104. programName = "Soul Force";
  105. break;
  106. }
  107. }
  108. // -----------------------------------------------------------------------
  109. // Internal data
  110. float DistrhoPluginSoulForce::getParameterValue(uint32_t index) const
  111. {
  112. return parameters[index];
  113. }
  114. void DistrhoPluginSoulForce::setParameterValue(uint32_t index, float value)
  115. {
  116. parameters[index] = value;
  117. switch(index)
  118. {
  119. case kParameterShape:
  120. coeff = (1.0f-(1.0f/((value * 0.99f)+0.005f)));
  121. break;
  122. case kParameterFeedback:
  123. if (d_isZero(value))
  124. coeff = (1.0f-(1.0f/((parameters[kParameterShape] * 0.99f)+0.005f)));
  125. break;
  126. }
  127. }
  128. void DistrhoPluginSoulForce::loadProgram(uint32_t index)
  129. {
  130. switch(index)
  131. {
  132. case kProgramDefault:
  133. parameters[kParameterShape] = 0.5f;
  134. parameters[kParameterFeedback] = 0.0f;
  135. parameters[kParameterSource] = 0.0f;
  136. parameters[kParameterFootswitch] = 1.0f;
  137. break;
  138. case kProgramStayDown:
  139. parameters[kParameterShape] = 0.4f;
  140. parameters[kParameterFeedback] = 0.0f;
  141. parameters[kParameterSource] = 0.0f;
  142. parameters[kParameterFootswitch] = 1.0f;
  143. break;
  144. case kProgramLookingForTheWorld:
  145. parameters[kParameterShape] = 1.0f;
  146. parameters[kParameterFeedback] = 0.0f;
  147. parameters[kParameterSource] = 0.0f;
  148. parameters[kParameterFootswitch] = 1.0f;
  149. break;
  150. case kProgramGuerillaLove:
  151. parameters[kParameterShape] = 0.5f;
  152. parameters[kParameterFeedback] = 1.0f;
  153. parameters[kParameterSource] = 0.0f;
  154. parameters[kParameterFootswitch] = 1.0f;
  155. break;
  156. case kProgramTumbleToThePower:
  157. parameters[kParameterShape] = 0.0f;
  158. parameters[kParameterFeedback] = 1.0f;
  159. parameters[kParameterSource] = 0.0f;
  160. parameters[kParameterFootswitch] = 1.0f;
  161. break;
  162. case kProgramDoYourselfFavour:
  163. parameters[kParameterShape] = 0.5f;
  164. parameters[kParameterFeedback] = 1.0f;
  165. parameters[kParameterSource] = 1.0f;
  166. parameters[kParameterFootswitch] = 1.0f;
  167. break;
  168. case kProgramPastIsPast:
  169. parameters[kParameterShape] = 0.0f;
  170. parameters[kParameterFeedback] = 1.0f;
  171. parameters[kParameterSource] = 1.0f;
  172. parameters[kParameterFootswitch] = 1.0f;
  173. break;
  174. case kProgramYouAndOnlyYou:
  175. parameters[kParameterShape] = 0.3f;
  176. parameters[kParameterFeedback] = 0.5f;
  177. parameters[kParameterSource] = 0.0f;
  178. parameters[kParameterFootswitch] = 1.0f;
  179. break;
  180. case kProgramSoulForce:
  181. parameters[kParameterShape] = 0.3f;
  182. parameters[kParameterFeedback] = 0.5f;
  183. parameters[kParameterSource] = 1.0f;
  184. parameters[kParameterFootswitch] = 1.0f;
  185. break;
  186. }
  187. }
  188. // -----------------------------------------------------------------------
  189. // Process
  190. void DistrhoPluginSoulForce::run(const float** inputs, float** outputs, uint32_t frames)
  191. {
  192. float tempf, tempf2;
  193. float inLeft, inRight;
  194. //frames = sampleFrames;
  195. // Calculate audio.
  196. for (uint32_t i=0; i<frames; ++i)
  197. {
  198. // For footEnv, later.
  199. inLeft = inputs[0][i];
  200. inRight = inputs[1][i];
  201. // Update coeff, if necessary.
  202. if (parameters[kParameterFeedback] > 0.0f)
  203. {
  204. if (parameters[kParameterSource] > 0.5f)
  205. {
  206. tempf2 = (1.0f-parameters[kParameterFeedback]) * parameters[kParameterShape];
  207. tempf2 += parameters[kParameterFeedback] * wave;
  208. coeff = (1.0f-(1.0f/((tempf2 * 0.99f)+0.005f)));
  209. }
  210. else
  211. {
  212. if ((tempf = std::abs(inLeft)) > env)
  213. {
  214. env = tempf;
  215. }
  216. else if (env > 0.0f)
  217. {
  218. env -= 0.001f;
  219. if (env < 0.0f)
  220. env = 0.0f;
  221. }
  222. tempf2 = (1.0f-parameters[kParameterFeedback]) * parameters[kParameterShape];
  223. tempf2 += parameters[kParameterFeedback] * env;
  224. coeff = (1.0f-(1.0f/((tempf2 * 0.99f)+0.005f)));
  225. }
  226. }
  227. tempf = inLeft;
  228. if (tempf > 0.0f)
  229. {
  230. tempf = tempf/(tempf+(coeff*(tempf-1.0f)));
  231. }
  232. else if (d_isZero(tempf))
  233. {
  234. tempf = 0.0f;
  235. }
  236. else
  237. {
  238. tempf = std::abs(tempf);
  239. tempf = 1.0f - (tempf/(tempf+(coeff*(tempf-1.0f))));
  240. tempf -= 1.0f;
  241. }
  242. if (parameters[kParameterShape] < 0.5f)
  243. tempf *= ((0.5f-parameters[kParameterShape])*16.0f)+1.0f;
  244. if (parameters[kParameterSource] > 0.5f)
  245. tempf *= 1.0f + (parameters[kParameterFeedback] * 2.0f);
  246. outputs[0][i] = tempf;
  247. tempf = inRight;
  248. if (tempf > 0.0f)
  249. {
  250. tempf = tempf/(tempf+(coeff*(tempf-1.0f)));
  251. }
  252. else if (d_isZero(tempf))
  253. {
  254. tempf = 0.0f;
  255. }
  256. else
  257. {
  258. tempf = std::abs(tempf);
  259. tempf = 1.0f - (tempf/(tempf+(coeff*(tempf-1.0f))));
  260. tempf -= 1.0f;
  261. }
  262. if (parameters[kParameterShape] < 0.5f)
  263. tempf *= ((0.5f-parameters[kParameterShape])*16.0f)+1.0f;
  264. if (parameters[kParameterSource] > 0.5f)
  265. tempf *= 1.0f + (parameters[kParameterFeedback] * 2.0f);
  266. outputs[1][i] = tempf;
  267. outputs[0][i] = std::tanh(outputs[0][i]) * 0.9f;
  268. outputs[1][i] = std::tanh(outputs[1][i]) * 0.9f;
  269. wave = outputs[0][i];
  270. // Handle footswitch.
  271. outputs[0][i] *= footEnv;
  272. outputs[0][i] += (1.0f-footEnv) * inLeft;
  273. outputs[1][i] *= footEnv;
  274. outputs[1][i] += (1.0f-footEnv) * inRight;
  275. if (parameters[kParameterFootswitch] > 0.5f && footEnv < 1.0f)
  276. footEnv += 0.01f;
  277. else if (parameters[kParameterFootswitch] < 0.5f && footEnv > 0.0f)
  278. footEnv -= 0.01f;
  279. }
  280. }
  281. // -----------------------------------------------------------------------
  282. Plugin* createPlugin()
  283. {
  284. return new DistrhoPluginSoulForce();
  285. }
  286. // -----------------------------------------------------------------------
  287. END_NAMESPACE_DISTRHO