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.

294 lines
9.1KB

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