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.

282 lines
8.5KB

  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. std::unique_ptr<PropertiesFile> g_propsfile;
  10. //==============================================================================
  11. PaulstretchpluginAudioProcessor::PaulstretchpluginAudioProcessor()
  12. #ifndef JucePlugin_PreferredChannelConfigurations
  13. : AudioProcessor (BusesProperties()
  14. #if ! JucePlugin_IsMidiEffect
  15. #if ! JucePlugin_IsSynth
  16. .withInput ("Input", AudioChannelSet::stereo(), true)
  17. #endif
  18. .withOutput ("Output", AudioChannelSet::stereo(), true)
  19. #endif
  20. )
  21. #endif
  22. {
  23. m_afm = std::make_unique<AudioFormatManager>();
  24. m_afm->registerBasicFormats();
  25. m_control = std::make_unique<Control>(m_afm.get());
  26. m_control->ppar.pitch_shift.enabled = true;
  27. m_control->ppar.freq_shift.enabled = true;
  28. m_control->getStretchAudioSource()->setLoopingEnabled(true);
  29. addParameter(new AudioParameterFloat("mainvolume0", "Main volume", -24.0f, 12.0f, -3.0f));
  30. addParameter(new AudioParameterFloat("stretchamount0", "Stretch amount", 0.1f, 128.0f, 1.0f));
  31. addParameter(new AudioParameterFloat("fftsize0", "FFT size", 0.0f, 1.0f, 0.6f));
  32. addParameter(new AudioParameterFloat("pitchshift0", "Pitch shift", -24.0f, 24.0f, 0.0f));
  33. addParameter(new AudioParameterFloat("freqshift0", "Frequency shift", -1000.0f, 1000.0f, 0.0f));
  34. addParameter(new AudioParameterFloat("playrange_start0", "Sound start", 0.0f, 1.0f, 0.0f));
  35. addParameter(new AudioParameterFloat("playrange_end0", "Sound end", 0.0f, 1.0f, 1.0f));
  36. }
  37. PaulstretchpluginAudioProcessor::~PaulstretchpluginAudioProcessor()
  38. {
  39. m_control->stopplay();
  40. }
  41. //==============================================================================
  42. const String PaulstretchpluginAudioProcessor::getName() const
  43. {
  44. return JucePlugin_Name;
  45. }
  46. bool PaulstretchpluginAudioProcessor::acceptsMidi() const
  47. {
  48. #if JucePlugin_WantsMidiInput
  49. return true;
  50. #else
  51. return false;
  52. #endif
  53. }
  54. bool PaulstretchpluginAudioProcessor::producesMidi() const
  55. {
  56. #if JucePlugin_ProducesMidiOutput
  57. return true;
  58. #else
  59. return false;
  60. #endif
  61. }
  62. bool PaulstretchpluginAudioProcessor::isMidiEffect() const
  63. {
  64. #if JucePlugin_IsMidiEffect
  65. return true;
  66. #else
  67. return false;
  68. #endif
  69. }
  70. double PaulstretchpluginAudioProcessor::getTailLengthSeconds() const
  71. {
  72. return 0.0;
  73. }
  74. int PaulstretchpluginAudioProcessor::getNumPrograms()
  75. {
  76. return 1; // NB: some hosts don't cope very well if you tell them there are 0 programs,
  77. // so this should be at least 1, even if you're not really implementing programs.
  78. }
  79. int PaulstretchpluginAudioProcessor::getCurrentProgram()
  80. {
  81. return 0;
  82. }
  83. void PaulstretchpluginAudioProcessor::setCurrentProgram (int index)
  84. {
  85. }
  86. const String PaulstretchpluginAudioProcessor::getProgramName (int index)
  87. {
  88. return {};
  89. }
  90. void PaulstretchpluginAudioProcessor::changeProgramName (int index, const String& newName)
  91. {
  92. }
  93. //==============================================================================
  94. void PaulstretchpluginAudioProcessor::prepareToPlay(double sampleRate, int samplesPerBlock)
  95. {
  96. if (m_ready_to_play == false)
  97. {
  98. m_control->update_player_stretch();
  99. m_control->update_process_parameters();
  100. String err;
  101. m_control->startplay(false, true,
  102. { *getFloatParameter(5),*getFloatParameter(6) },
  103. 2, err);
  104. m_ready_to_play = true;
  105. }
  106. return;
  107. m_ready_to_play = false;
  108. m_control->set_input_file(File("C:/MusicAudio/sourcesamples/sheila.wav"), [this](String cberr)
  109. {
  110. if (cberr.isEmpty())
  111. {
  112. m_ready_to_play = true;
  113. String err;
  114. m_control->update_player_stretch();
  115. m_control->update_process_parameters();
  116. m_control->startplay(false, true, { 0.0,1.0 }, 2, err);
  117. auto ed = dynamic_cast<PaulstretchpluginAudioProcessorEditor*>(getActiveEditor());
  118. if (ed)
  119. {
  120. ed->setAudioFile(m_control->getStretchAudioSource()->getAudioFile());
  121. }
  122. }
  123. else m_ready_to_play = false;
  124. });
  125. }
  126. void PaulstretchpluginAudioProcessor::releaseResources()
  127. {
  128. //m_control->stopplay();
  129. //m_ready_to_play = false;
  130. }
  131. #ifndef JucePlugin_PreferredChannelConfigurations
  132. bool PaulstretchpluginAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const
  133. {
  134. #if JucePlugin_IsMidiEffect
  135. ignoreUnused (layouts);
  136. return true;
  137. #else
  138. // This is the place where you check if the layout is supported.
  139. // In this template code we only support mono or stereo.
  140. if (layouts.getMainOutputChannelSet() != AudioChannelSet::mono()
  141. && layouts.getMainOutputChannelSet() != AudioChannelSet::stereo())
  142. return false;
  143. // This checks if the input layout matches the output layout
  144. #if ! JucePlugin_IsSynth
  145. if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())
  146. return false;
  147. #endif
  148. return true;
  149. #endif
  150. }
  151. #endif
  152. void PaulstretchpluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
  153. {
  154. ScopedNoDenormals noDenormals;
  155. const int totalNumInputChannels = getTotalNumInputChannels();
  156. const int totalNumOutputChannels = getTotalNumOutputChannels();
  157. for (int i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
  158. buffer.clear (i, 0, buffer.getNumSamples());
  159. if (m_ready_to_play == false)
  160. return;
  161. if (m_is_recording == true)
  162. {
  163. if (m_rec_pos + buffer.getNumSamples() < m_recbuffer.getNumSamples())
  164. {
  165. m_recbuffer.copyFrom(0, m_rec_pos, buffer, 0, 0, buffer.getNumSamples());
  166. m_recbuffer.copyFrom(1, m_rec_pos, buffer, 1, 0, buffer.getNumSamples());
  167. }
  168. m_rec_pos += buffer.getNumSamples();
  169. if (m_rec_pos >= m_max_reclen * getSampleRate())
  170. {
  171. finishRecording(m_max_reclen*getSampleRate());
  172. }
  173. return;
  174. }
  175. m_control->getStretchAudioSource()->setRate(*getFloatParameter(1));
  176. m_control->getStretchAudioSource()->val_XFadeLen = 0.1;
  177. //m_control->setFFTSize(*getFloatParameter(2));
  178. m_control->ppar.pitch_shift.cents = *getFloatParameter(3) * 100.0;
  179. m_control->ppar.freq_shift.Hz = *getFloatParameter(4);
  180. double t0 = *getFloatParameter(5);
  181. double t1 = *getFloatParameter(6);
  182. if (t0 > t1)
  183. std::swap(t0, t1);
  184. if (t1 - t0 < 0.001)
  185. t1 = t0 + 0.001;
  186. m_control->getStretchAudioSource()->setPlayRange({ t0,t1 }, true);
  187. m_control->update_process_parameters();
  188. m_control->processAudio(buffer);
  189. }
  190. //==============================================================================
  191. bool PaulstretchpluginAudioProcessor::hasEditor() const
  192. {
  193. return true; // (change this to false if you choose to not supply an editor)
  194. }
  195. AudioProcessorEditor* PaulstretchpluginAudioProcessor::createEditor()
  196. {
  197. return new PaulstretchpluginAudioProcessorEditor (*this);
  198. }
  199. //==============================================================================
  200. void PaulstretchpluginAudioProcessor::getStateInformation (MemoryBlock& destData)
  201. {
  202. // You should use this method to store your parameters in the memory block.
  203. // You could do that either as raw data, or use the XML or ValueTree classes
  204. // as intermediaries to make it easy to save and load complex data.
  205. }
  206. void PaulstretchpluginAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
  207. {
  208. // You should use this method to restore your parameters from this memory block,
  209. // whose contents will have been created by the getStateInformation() call.
  210. }
  211. void PaulstretchpluginAudioProcessor::setRecordingEnabled(bool b)
  212. {
  213. if (b == true)
  214. {
  215. m_is_recording = true;
  216. m_recbuffer.setSize(2, m_max_reclen*getSampleRate()+4096);
  217. m_recbuffer.clear();
  218. m_rec_pos = 0;
  219. }
  220. else
  221. {
  222. if (m_is_recording == true)
  223. {
  224. finishRecording(m_rec_pos);
  225. }
  226. }
  227. }
  228. double PaulstretchpluginAudioProcessor::getRecordingPositionPercent()
  229. {
  230. if (m_is_recording==false)
  231. return 0.0;
  232. return 1.0 / m_recbuffer.getNumSamples()*m_rec_pos;
  233. }
  234. void PaulstretchpluginAudioProcessor::finishRecording(int lenrecording)
  235. {
  236. m_is_recording = false;
  237. m_control->getStretchAudioSource()->setAudioBufferAsInputSource(&m_recbuffer, getSampleRate(), lenrecording);
  238. auto ed = dynamic_cast<PaulstretchpluginAudioProcessorEditor*>(getActiveEditor());
  239. if (ed)
  240. {
  241. ed->setAudioBuffer(&m_recbuffer, getSampleRate(), m_rec_pos);
  242. }
  243. }
  244. //==============================================================================
  245. // This creates new instances of the plugin..
  246. AudioProcessor* JUCE_CALLTYPE createPluginFilter()
  247. {
  248. return new PaulstretchpluginAudioProcessor();
  249. }