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.

301 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.6f));
  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->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_ready_to_play = true;
  120. }
  121. return;
  122. m_ready_to_play = false;
  123. m_control->set_input_file(File("C:/MusicAudio/sourcesamples/sheila.wav"), [this](String cberr)
  124. {
  125. if (cberr.isEmpty())
  126. {
  127. m_ready_to_play = true;
  128. String err;
  129. m_control->update_player_stretch();
  130. m_control->update_process_parameters();
  131. m_control->startplay(false, true, { 0.0,1.0 }, 2, err);
  132. auto ed = dynamic_cast<PaulstretchpluginAudioProcessorEditor*>(getActiveEditor());
  133. if (ed)
  134. {
  135. ed->setAudioFile(m_control->getStretchAudioSource()->getAudioFile());
  136. }
  137. }
  138. else m_ready_to_play = false;
  139. });
  140. }
  141. void PaulstretchpluginAudioProcessor::releaseResources()
  142. {
  143. //m_control->stopplay();
  144. //m_ready_to_play = false;
  145. }
  146. #ifndef JucePlugin_PreferredChannelConfigurations
  147. bool PaulstretchpluginAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const
  148. {
  149. #if JucePlugin_IsMidiEffect
  150. ignoreUnused (layouts);
  151. return true;
  152. #else
  153. // This is the place where you check if the layout is supported.
  154. // In this template code we only support mono or stereo.
  155. if (layouts.getMainOutputChannelSet() != AudioChannelSet::mono()
  156. && layouts.getMainOutputChannelSet() != AudioChannelSet::stereo())
  157. return false;
  158. // This checks if the input layout matches the output layout
  159. #if ! JucePlugin_IsSynth
  160. if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())
  161. return false;
  162. #endif
  163. return true;
  164. #endif
  165. }
  166. #endif
  167. void PaulstretchpluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
  168. {
  169. std::lock_guard<std::mutex> locker(m_mutex);
  170. ScopedNoDenormals noDenormals;
  171. const int totalNumInputChannels = getTotalNumInputChannels();
  172. const int totalNumOutputChannels = getTotalNumOutputChannels();
  173. for (int i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
  174. buffer.clear (i, 0, buffer.getNumSamples());
  175. if (m_ready_to_play == false)
  176. return;
  177. if (m_is_recording == true)
  178. {
  179. if (m_rec_pos + buffer.getNumSamples() < m_recbuffer.getNumSamples())
  180. {
  181. m_recbuffer.copyFrom(0, m_rec_pos, buffer, 0, 0, buffer.getNumSamples());
  182. m_recbuffer.copyFrom(1, m_rec_pos, buffer, 1, 0, buffer.getNumSamples());
  183. }
  184. m_rec_pos += buffer.getNumSamples();
  185. if (m_rec_pos >= m_max_reclen * getSampleRate())
  186. {
  187. finishRecording(m_max_reclen*getSampleRate());
  188. }
  189. return;
  190. }
  191. m_control->getStretchAudioSource()->setRate(*getFloatParameter(1));
  192. m_control->getStretchAudioSource()->val_XFadeLen = 0.1;
  193. //m_control->setFFTSize(*getFloatParameter(2));
  194. m_control->ppar.pitch_shift.cents = *getFloatParameter(3) * 100.0;
  195. m_control->ppar.freq_shift.Hz = *getFloatParameter(4);
  196. double t0 = *getFloatParameter(5);
  197. double t1 = *getFloatParameter(6);
  198. if (t0 > t1)
  199. std::swap(t0, t1);
  200. if (t1 - t0 < 0.001)
  201. t1 = t0 + 0.001;
  202. m_control->getStretchAudioSource()->setPlayRange({ t0,t1 }, true);
  203. m_control->update_process_parameters();
  204. m_control->processAudio(buffer);
  205. }
  206. //==============================================================================
  207. bool PaulstretchpluginAudioProcessor::hasEditor() const
  208. {
  209. return true; // (change this to false if you choose to not supply an editor)
  210. }
  211. AudioProcessorEditor* PaulstretchpluginAudioProcessor::createEditor()
  212. {
  213. return new PaulstretchpluginAudioProcessorEditor (*this);
  214. }
  215. //==============================================================================
  216. void PaulstretchpluginAudioProcessor::getStateInformation (MemoryBlock& destData)
  217. {
  218. // You should use this method to store your parameters in the memory block.
  219. // You could do that either as raw data, or use the XML or ValueTree classes
  220. // as intermediaries to make it easy to save and load complex data.
  221. }
  222. void PaulstretchpluginAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
  223. {
  224. // You should use this method to restore your parameters from this memory block,
  225. // whose contents will have been created by the getStateInformation() call.
  226. }
  227. void PaulstretchpluginAudioProcessor::setRecordingEnabled(bool b)
  228. {
  229. std::lock_guard<std::mutex> locker(m_mutex);
  230. if (b == true)
  231. {
  232. m_is_recording = true;
  233. m_recbuffer.setSize(2, m_max_reclen*getSampleRate()+4096);
  234. m_recbuffer.clear();
  235. m_rec_pos = 0;
  236. }
  237. else
  238. {
  239. if (m_is_recording == true)
  240. {
  241. finishRecording(m_rec_pos);
  242. }
  243. }
  244. }
  245. double PaulstretchpluginAudioProcessor::getRecordingPositionPercent()
  246. {
  247. if (m_is_recording==false)
  248. return 0.0;
  249. return 1.0 / m_recbuffer.getNumSamples()*m_rec_pos;
  250. }
  251. void PaulstretchpluginAudioProcessor::finishRecording(int lenrecording)
  252. {
  253. m_is_recording = false;
  254. m_control->getStretchAudioSource()->setAudioBufferAsInputSource(&m_recbuffer, getSampleRate(), lenrecording);
  255. m_control->getStretchAudioSource()->setPlayRange({ *getFloatParameter(5),*getFloatParameter(6) }, true);
  256. auto ed = dynamic_cast<PaulstretchpluginAudioProcessorEditor*>(getActiveEditor());
  257. if (ed)
  258. {
  259. ed->setAudioBuffer(&m_recbuffer, getSampleRate(), lenrecording);
  260. }
  261. }
  262. //==============================================================================
  263. // This creates new instances of the plugin..
  264. AudioProcessor* JUCE_CALLTYPE createPluginFilter()
  265. {
  266. return new PaulstretchpluginAudioProcessor();
  267. }