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.

423 lines
11KB

  1. /*
  2. ==============================================================================
  3. This file was auto-generated by the Jucer!
  4. It contains the basic startup code for a Juce application.
  5. ==============================================================================
  6. */
  7. #include "PluginProcessor.h"
  8. #include "PluginEditor.h"
  9. #include <cmath>
  10. //==============================================================================
  11. TheFunctionAudioProcessor::TheFunctionAudioProcessor()
  12. {
  13. gain = 1.0f;
  14. gainL = 1.0f;
  15. gainR = 1.0f;
  16. panL = 0.0f;
  17. panR = 1.0f;
  18. phaseL = 0.0f;
  19. phaseR = 0.0f;
  20. currentPreset = 0;
  21. timeSinceChunkCalled = 0;
  22. }
  23. TheFunctionAudioProcessor::~TheFunctionAudioProcessor()
  24. {
  25. }
  26. //==============================================================================
  27. const String TheFunctionAudioProcessor::getName() const
  28. {
  29. return JucePlugin_Name;
  30. }
  31. int TheFunctionAudioProcessor::getNumParameters()
  32. {
  33. return totalNumParams;
  34. }
  35. float TheFunctionAudioProcessor::getParameter (int index)
  36. {
  37. switch (index)
  38. {
  39. case gainParam: return gain;
  40. case gainLParam: return gainL;
  41. case gainRParam: return gainR;
  42. case panLParam: return panL;
  43. case panRParam: return panR;
  44. case phaseLParam: return phaseL;
  45. case phaseRParam: return phaseR;
  46. default: return 0.0f;
  47. }
  48. }
  49. void TheFunctionAudioProcessor::setParameter (int index, float newValue)
  50. {
  51. switch (index)
  52. {
  53. case gainParam: gain = newValue; break;
  54. case gainLParam: gainL = newValue; break;
  55. case gainRParam: gainR = newValue; break;
  56. case panLParam: panL = newValue; break;
  57. case panRParam: panR = newValue; break;
  58. case phaseLParam: phaseL = newValue; break;
  59. case phaseRParam: phaseR = newValue; break;
  60. default: break;
  61. }
  62. }
  63. const String TheFunctionAudioProcessor::getParameterName (int index)
  64. {
  65. switch (index)
  66. {
  67. case gainParam: return "Gain";
  68. case gainLParam: return "Gain L";
  69. case gainRParam: return "Gain R";
  70. case panLParam: return "Pan L";
  71. case panRParam: return "Pan R";
  72. case phaseLParam: return "Phase L";
  73. case phaseRParam: return "Phase R";
  74. default: return String::empty;
  75. }
  76. }
  77. const String TheFunctionAudioProcessor::getParameterText (int index)
  78. {
  79. return String (getParameter (index), 2);
  80. }
  81. const String TheFunctionAudioProcessor::getInputChannelName (int channelIndex) const
  82. {
  83. return String (channelIndex + 1);
  84. }
  85. const String TheFunctionAudioProcessor::getOutputChannelName (int channelIndex) const
  86. {
  87. return String (channelIndex + 1);
  88. }
  89. bool TheFunctionAudioProcessor::isInputChannelStereoPair (int index) const
  90. {
  91. return true;
  92. }
  93. bool TheFunctionAudioProcessor::isOutputChannelStereoPair (int index) const
  94. {
  95. return true;
  96. }
  97. bool TheFunctionAudioProcessor::acceptsMidi() const
  98. {
  99. #if JucePlugin_WantsMidiInput
  100. return true;
  101. #else
  102. return false;
  103. #endif
  104. }
  105. bool TheFunctionAudioProcessor::producesMidi() const
  106. {
  107. #if JucePlugin_ProducesMidiOutput
  108. return true;
  109. #else
  110. return false;
  111. #endif
  112. }
  113. int TheFunctionAudioProcessor::getNumPrograms()
  114. {
  115. return 5;
  116. }
  117. int TheFunctionAudioProcessor::getCurrentProgram()
  118. {
  119. return currentPreset;
  120. }
  121. void TheFunctionAudioProcessor::setCurrentProgram (int index)
  122. {
  123. if((Time::getMillisecondCounter()-timeSinceChunkCalled)<200) // Thanks to "valhallasound" from the JUCE forum for this tip! :)
  124. return;
  125. switch(index)
  126. {
  127. case 0:
  128. gain = 1.0f;
  129. gainL = 1.0f;
  130. gainR = 1.0f;
  131. panL = 0.0f;
  132. panR = 1.0f;
  133. phaseL = 0.0f;
  134. phaseR = 0.0f;
  135. currentPreset = 0;
  136. break;
  137. case 1:
  138. gain = 1.0f;
  139. gainL = 1.0f;
  140. gainR = 1.0f;
  141. panL = 0.0f;
  142. panR = 1.0f;
  143. phaseL = 1.0f;
  144. phaseR = 0.0f;
  145. currentPreset = 1;
  146. break;
  147. case 2:
  148. gain = 0.5f;
  149. gainL = 1.0f;
  150. gainR = 1.0f;
  151. panL = 0.5f;
  152. panR = 0.5f;
  153. phaseL = 0.0f;
  154. phaseR = 0.0f;
  155. currentPreset = 2;
  156. break;
  157. case 3:
  158. gain = 1.0f;
  159. gainL = 1.0f;
  160. gainR = 1.0f;
  161. panL = 0.5f;
  162. panR = 0.5f;
  163. phaseL = 0.0f;
  164. phaseR = 1.0f;
  165. currentPreset = 3;
  166. break;
  167. case 4:
  168. gain = 0.3f;
  169. gainL = 1.0f;
  170. gainR = 1.0f;
  171. panL = 0.0f;
  172. panR = 1.0f;
  173. phaseL = 0.0f;
  174. phaseR = 0.0f;
  175. currentPreset = 4;
  176. break;
  177. }
  178. }
  179. const String TheFunctionAudioProcessor::getProgramName (int index)
  180. {
  181. switch(index)
  182. {
  183. case 0:
  184. return "Blank Canvas";
  185. break;
  186. case 1:
  187. return "Phased";
  188. break;
  189. case 2:
  190. return "Stereo->Mono";
  191. break;
  192. case 3:
  193. return "Mono Blocker";
  194. break;
  195. case 4:
  196. return "Gain Reduction";
  197. break;
  198. default:
  199. return "This isn't a preset";
  200. break;
  201. }
  202. }
  203. void TheFunctionAudioProcessor::changeProgramName (int index, const String& newName)
  204. {
  205. }
  206. //==============================================================================
  207. void TheFunctionAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
  208. {
  209. // Use this method as the place to do any pre-playback
  210. // initialisation that you need..
  211. tmpBuffer.setSize(2, samplesPerBlock);
  212. tmpBuffer.clear();
  213. }
  214. void TheFunctionAudioProcessor::releaseResources()
  215. {
  216. // When playback stops, you can use this as an opportunity to free up any
  217. // spare memory, etc.
  218. }
  219. void TheFunctionAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
  220. {
  221. // This is the place where you'd normally do the guts of your plugin's
  222. // audio processing...
  223. const int numberOfSamples = buffer.getNumSamples();
  224. float* channelDataL = buffer.getWritePointer (0);
  225. float* channelDataR = buffer.getWritePointer (1);
  226. tmpBuffer.copyFrom(0, 0, channelDataL, numberOfSamples);
  227. tmpBuffer.copyFrom(1, 0, channelDataR, numberOfSamples);
  228. float* inputDataL = tmpBuffer.getWritePointer (0);
  229. float* inputDataR = tmpBuffer.getWritePointer (1);
  230. float LinLout; // Left IN Left OUT - Gain
  231. float LinRout; // Left IN Right OUT - Gain
  232. float RinLout; // Right IN Left OUT - Gain
  233. float RinRout; // Right IN Right OUT - Gain
  234. // Work out L+R channel pan positions
  235. if (panL < 0.5)
  236. {
  237. LinLout = 1;
  238. LinRout = panL * 2;
  239. }
  240. else
  241. {
  242. LinLout = ((panL *2) -2) *-1;
  243. LinRout = 1;
  244. }
  245. if (panR < 0.5)
  246. {
  247. RinLout = 1;
  248. RinRout = panR * 2;
  249. }
  250. else
  251. {
  252. RinLout = ((panR *2) -2) *-1;
  253. RinRout = 1;
  254. }
  255. //******************
  256. // Apply individual channel phase, pan and gain
  257. float peakLevelL = 0;
  258. float peakLevelR = 0;
  259. float RMSLevelL = 0;
  260. float RMSLevelR = 0;
  261. for (int i = 0; i < numberOfSamples; ++i)
  262. {
  263. // Phase
  264. if (phaseL >= 0.5)
  265. inputDataL[i] *= -1;
  266. if (phaseR >= 0.5)
  267. inputDataR[i] *= -1;
  268. // Pan
  269. channelDataR[i] = (inputDataR[i] * RinRout) + (inputDataL[i] * LinRout);
  270. channelDataL[i] = (inputDataL[i] * LinLout) + (inputDataR[i] * RinLout);
  271. // Gain
  272. channelDataL[i] *= gainL;
  273. channelDataR[i] *= gainR;
  274. if (channelDataL[i] > peakLevelL)
  275. peakLevelL = channelDataL[i];
  276. if (channelDataR[i] > peakLevelR)
  277. peakLevelR = channelDataR[i];
  278. RMSLevelL += std::abs(channelDataL[i]);
  279. RMSLevelR += std::abs(channelDataR[i]);
  280. }
  281. //******************
  282. // Master Gain
  283. buffer.applyGain (0, numberOfSamples, gain);
  284. // In case we have more outputs than inputs, we'll clear any output
  285. // channels that didn't contain input data, (because these aren't
  286. // guaranteed to be empty - they may contain garbage).
  287. for (int i = getTotalNumInputChannels(); i < getTotalNumOutputChannels(); ++i)
  288. buffer.clear (i, 0, numberOfSamples);
  289. }
  290. #if ! JUCE_AUDIOPROCESSOR_NO_GUI
  291. //==============================================================================
  292. bool TheFunctionAudioProcessor::hasEditor() const
  293. {
  294. return true; // (change this to false if you choose to not supply an editor)
  295. }
  296. AudioProcessorEditor* TheFunctionAudioProcessor::createEditor()
  297. {
  298. return new TheFunctionAudioProcessorEditor (this);
  299. }
  300. #endif
  301. //==============================================================================
  302. void TheFunctionAudioProcessor::getStateInformation (MemoryBlock& destData)
  303. {
  304. // You should use this method to store your parameters in the memory block.
  305. // You could do that either as raw data, or use the XML or ValueTree classes
  306. // as intermediaries to make it easy to save and load complex data.
  307. // Create an outer XML element..
  308. XmlElement xml ("MYPLUGINSETTINGS");
  309. // add some attributes to it..
  310. // xml.setAttribute ("uiWidth", lastUIWidth);
  311. // xml.setAttribute ("uiHeight", lastUIHeight);
  312. //xml.setAttribute ("gain", gain);
  313. // xml.setAttribute ("delay", delay);
  314. xml.setAttribute ("gain", gain);
  315. xml.setAttribute ("gainL", gainL);
  316. xml.setAttribute ("gainR", gainR);
  317. xml.setAttribute ("panL", panL);
  318. xml.setAttribute ("panR", panR);
  319. xml.setAttribute ("phaseL", phaseL);
  320. xml.setAttribute ("phaseR", phaseR);
  321. // then use this helper function to stuff it into the binary blob and return it..
  322. copyXmlToBinary (xml, destData);
  323. }
  324. void TheFunctionAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
  325. {
  326. // You should use this method to restore your parameters from this memory block,
  327. // whose contents will have been created by the getStateInformation() call.
  328. timeSinceChunkCalled = Time::getMillisecondCounter();
  329. ScopedPointer<XmlElement> xmlState (getXmlFromBinary (data, sizeInBytes));
  330. if (xmlState != 0)
  331. {
  332. // make sure that it's actually our type of XML object..
  333. if (xmlState->hasTagName ("MYPLUGINSETTINGS"))
  334. {
  335. // ok, now pull out our parameters..
  336. // gain = xmlState->getIntAttribute ("gain", gain);
  337. //lastUIHeight = xmlState->getIntAttribute ("uiHeight", lastUIHeight);
  338. gain = (float) xmlState->getDoubleAttribute ("gain", gain);
  339. gainL = (float) xmlState->getDoubleAttribute ("gainL", gainL);
  340. gainR = (float) xmlState->getDoubleAttribute ("gainR", gainR);
  341. panL = (float) xmlState->getDoubleAttribute ("panL", panL);
  342. panR = (float) xmlState->getDoubleAttribute ("panR", panR);
  343. phaseL = (float) xmlState->getDoubleAttribute ("phaseL", phaseL);
  344. phaseR = (float) xmlState->getDoubleAttribute ("phaseR", phaseR);
  345. // delay = (float) xmlState->getDoubleAttribute ("delay", delay);
  346. }
  347. }
  348. }
  349. //==============================================================================
  350. // This creates new instances of the plugin..
  351. AudioProcessor* JUCE_CALLTYPE createPluginFilter()
  352. {
  353. return new TheFunctionAudioProcessor();
  354. }