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.

284 lines
9.3KB

  1. /*
  2. ==============================================================================
  3. This file was auto-generated!
  4. It contains the basic framework code for a JUCE plugin processor.
  5. ==============================================================================
  6. */
  7. #include "PluginProcessor.h"
  8. #include "PluginEditor.h"
  9. #include "TemperDsp.hpp"
  10. const int kOversampleFactor = 3;
  11. //==============================================================================
  12. TemperAudioProcessor::TemperAudioProcessor()
  13. #ifndef JucePlugin_PreferredChannelConfigurations
  14. : AudioProcessor (BusesProperties()
  15. #if ! JucePlugin_IsMidiEffect
  16. #if ! JucePlugin_IsSynth
  17. .withInput ("Input", AudioChannelSet::stereo(), true)
  18. #endif
  19. .withOutput ("Output", AudioChannelSet::stereo(), true)
  20. #endif
  21. ),
  22. m_params (*this, nullptr)
  23. #else
  24. : m_params (*this, nullptr)
  25. #endif
  26. {
  27. m_restriction = new RestrictionProcessor();
  28. m_bridge = new FaustUIBridge(m_params);
  29. m_lastKnownSampleRate = 0.0;
  30. m_currentProgram = -1;
  31. // Initialize the dsp units
  32. for (int i = 0; i < getTotalNumInputChannels(); ++i)
  33. {
  34. TemperDsp* dsp = new TemperDsp();
  35. dsp->buildUserInterface(m_bridge);
  36. m_dsps.add(dsp);
  37. }
  38. // Initialize the AudioProcessorValueTreeState root
  39. ValueTree root (Identifier("TEMPER"));
  40. m_params.state = root;
  41. }
  42. TemperAudioProcessor::~TemperAudioProcessor()
  43. {
  44. }
  45. //==============================================================================
  46. const String TemperAudioProcessor::getName() const
  47. {
  48. return JucePlugin_Name;
  49. }
  50. bool TemperAudioProcessor::acceptsMidi() const
  51. {
  52. #if JucePlugin_WantsMidiInput
  53. return true;
  54. #else
  55. return false;
  56. #endif
  57. }
  58. bool TemperAudioProcessor::producesMidi() const
  59. {
  60. #if JucePlugin_ProducesMidiOutput
  61. return true;
  62. #else
  63. return false;
  64. #endif
  65. }
  66. double TemperAudioProcessor::getTailLengthSeconds() const
  67. {
  68. return 0.0;
  69. }
  70. int TemperAudioProcessor::getNumPrograms()
  71. {
  72. return 5; // NB: some hosts don't cope very well if you tell them there are 0 programs,
  73. // so this should be at least 1, even if you're not really implementing programs.
  74. }
  75. int TemperAudioProcessor::getCurrentProgram()
  76. {
  77. return m_currentProgram;
  78. }
  79. void TemperAudioProcessor::setCurrentProgram (int index)
  80. {
  81. switch (index) {
  82. case 0:
  83. setStateInformation(BinaryData::DefaultPreset_xml,
  84. BinaryData::DefaultPreset_xmlSize);
  85. break;
  86. case 1:
  87. setStateInformation(BinaryData::StubbedToePreset_xml,
  88. BinaryData::StubbedToePreset_xmlSize);
  89. break;
  90. case 2:
  91. setStateInformation(BinaryData::BeeStingPreset_xml,
  92. BinaryData::BeeStingPreset_xmlSize);
  93. break;
  94. case 3:
  95. setStateInformation(BinaryData::MorningAtTheDMVPreset_xml,
  96. BinaryData::MorningAtTheDMVPreset_xmlSize);
  97. break;
  98. case 4:
  99. setStateInformation(BinaryData::FlyingUnitedPreset_xml,
  100. BinaryData::FlyingUnitedPreset_xmlSize);
  101. break;
  102. default:
  103. break;
  104. }
  105. m_currentProgram = index;
  106. }
  107. const String TemperAudioProcessor::getProgramName (int index)
  108. {
  109. switch (index) {
  110. case 0:
  111. return String("Default");
  112. case 1:
  113. return String("Stubbed Toe");
  114. case 2:
  115. return String("Bee Sting");
  116. case 3:
  117. return String("Morning at the DMV");
  118. case 4:
  119. return String("Flying United");
  120. default:
  121. return String();
  122. }
  123. }
  124. void TemperAudioProcessor::changeProgramName (int index, const String& newName)
  125. {
  126. }
  127. //==============================================================================
  128. void TemperAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
  129. {
  130. auto filterType = juce::dsp::Oversampling<float>::filterHalfBandPolyphaseIIR;
  131. m_oversampler = std::unique_ptr<juce::dsp::Oversampling<float>>(new juce::dsp::Oversampling<float>(getTotalNumInputChannels(),
  132. kOversampleFactor, filterType, false));
  133. // Re-initialize the dsp modules at the upsampled rate.
  134. if (m_lastKnownSampleRate == 0.0)
  135. for (int i = 0; i < m_dsps.size(); ++i)
  136. m_dsps.getUnchecked(i)->init(sampleRate * pow(2, kOversampleFactor));
  137. else
  138. for (int i = 0; i < m_dsps.size(); ++i)
  139. m_dsps.getUnchecked(i)->instanceConstants(sampleRate * pow(2, kOversampleFactor));
  140. m_oversampler->initProcessing(static_cast<size_t> (samplesPerBlock));
  141. m_restriction->prepareToPlay(samplesPerBlock, sampleRate);
  142. m_lastKnownSampleRate = sampleRate;
  143. setLatencySamples(static_cast<int>(m_oversampler->getLatencyInSamples()));
  144. }
  145. void TemperAudioProcessor::releaseResources()
  146. {
  147. // When playback stops, you can use this as an opportunity to free up any
  148. // spare memory, etc.
  149. }
  150. #ifndef JucePlugin_PreferredChannelConfigurations
  151. bool TemperAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const
  152. {
  153. #if JucePlugin_IsMidiEffect
  154. ignoreUnused (layouts);
  155. return true;
  156. #else
  157. // This is the place where you check if the layout is supported.
  158. // In this template code we only support mono or stereo.
  159. if (layouts.getMainOutputChannelSet() != AudioChannelSet::mono()
  160. && layouts.getMainOutputChannelSet() != AudioChannelSet::stereo())
  161. return false;
  162. // This checks if the input layout matches the output layout
  163. #if ! JucePlugin_IsSynth
  164. if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())
  165. return false;
  166. #endif
  167. return true;
  168. #endif
  169. }
  170. #endif
  171. void TemperAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
  172. {
  173. const int totalNumInputChannels = getTotalNumInputChannels();
  174. const int totalNumOutputChannels = getTotalNumOutputChannels();
  175. TemperAudioProcessorEditor* editor = static_cast<TemperAudioProcessorEditor*>(getActiveEditor());
  176. // In case we have more outputs than inputs, this code clears any output
  177. // channels that didn't contain input data, (because these aren't
  178. // guaranteed to be empty - they may contain garbage).
  179. // This is here to avoid people getting screaming feedback
  180. // when they first compile a plugin, but obviously you don't need to keep
  181. // this code if your algorithm always overwrites all the output channels.
  182. for (int i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
  183. buffer.clear (i, 0, buffer.getNumSamples());
  184. // Push input buffer into the Pre spectroscope component.
  185. if (editor)
  186. editor->m_vizPre->pushBuffer(buffer);
  187. // Now the guts of the processing; oversampling and applying the Faust dsp module.
  188. const int numInputChannels = buffer.getNumChannels();
  189. const int numInputSamples = buffer.getNumSamples();
  190. juce::dsp::AudioBlock<float> block (buffer.getArrayOfWritePointers(),
  191. numInputChannels,
  192. numInputSamples);
  193. juce::dsp::AudioBlock<float> oversampledBlock = m_oversampler->processSamplesUp(block);
  194. // Run the faust processors on each channel of the oversampled block.
  195. for (int i = 0; i < numInputChannels; ++i)
  196. {
  197. auto* processor = m_dsps.getUnchecked(i);
  198. auto* data = oversampledBlock.getChannelPointer(i);
  199. int len = static_cast<int>(oversampledBlock.getNumSamples());
  200. processor->compute(len, &data, &data);
  201. }
  202. m_oversampler->processSamplesDown(block);
  203. #ifdef TEMPER_DEMO_BUILD
  204. // After the Faust processing, add the demo restriction to the output stream
  205. m_restriction->processBlock(buffer);
  206. #endif
  207. // Push resulting buffer into the Post spectroscope component.
  208. if (editor)
  209. editor->m_vizPost->pushBuffer(buffer);
  210. }
  211. //==============================================================================
  212. bool TemperAudioProcessor::hasEditor() const
  213. {
  214. return true; // (change this to false if you choose to not supply an editor)
  215. }
  216. AudioProcessorEditor* TemperAudioProcessor::createEditor()
  217. {
  218. return new TemperAudioProcessorEditor (*this, m_params);
  219. }
  220. //==============================================================================
  221. void TemperAudioProcessor::getStateInformation (MemoryBlock& destData)
  222. {
  223. ScopedPointer<XmlElement> xml (m_params.state.createXml());
  224. copyXmlToBinary(*xml, destData);
  225. }
  226. void TemperAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
  227. {
  228. ScopedPointer<XmlElement> xmlState (getXmlFromBinary (data, sizeInBytes));
  229. if (xmlState != nullptr)
  230. if (xmlState->hasTagName (m_params.state.getType()))
  231. m_params.state = ValueTree::fromXml (*xmlState);
  232. }
  233. //==============================================================================
  234. // This creates new instances of the plugin..
  235. AudioProcessor* JUCE_CALLTYPE createPluginFilter()
  236. {
  237. return new TemperAudioProcessor();
  238. }