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.

302 lines
9.2KB

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