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.

297 lines
10KB

  1. /*
  2. Copyright (C) 2017 Xenakios
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of version 3 of the GNU General Public License
  5. as published by the Free Software Foundation.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License (version 3) for more details.
  10. www.gnu.org/licenses
  11. */
  12. #pragma once
  13. #include "../JuceLibraryCode/JuceHeader.h"
  14. #include "PS_Source/PaulStretchControl.h"
  15. #include "jcdp_envelope.h"
  16. #include <array>
  17. class MyThumbCache;
  18. class AudioFilePreviewComponent;
  19. const int cpi_main_volume = 0;
  20. const int cpi_stretchamount = 1;
  21. const int cpi_fftsize = 2;
  22. const int cpi_pitchshift = 3;
  23. const int cpi_frequencyshift = 4;
  24. const int cpi_soundstart = 5;
  25. const int cpi_soundend = 6;
  26. const int cpi_freeze = 7;
  27. const int cpi_spreadamount = 8;
  28. const int cpi_compress = 9;
  29. const int cpi_loopxfadelen = 10;
  30. const int cpi_numharmonics = 11;
  31. const int cpi_harmonicsfreq = 12;
  32. const int cpi_harmonicsbw = 13;
  33. const int cpi_harmonicsgauss = 14;
  34. const int cpi_octavesm2 = 15;
  35. const int cpi_octavesm1 = 16;
  36. const int cpi_octaves0 = 17;
  37. const int cpi_octaves1 = 18;
  38. const int cpi_octaves15 = 19;
  39. const int cpi_octaves2 = 20;
  40. const int cpi_tonalvsnoisebw = 21;
  41. const int cpi_tonalvsnoisepreserve = 22;
  42. const int cpi_filter_low = 23;
  43. const int cpi_filter_high = 24;
  44. const int cpi_onsetdetection = 25;
  45. const int cpi_capture_trigger = 26;
  46. const int cpi_num_outchans = 27;
  47. const int cpi_pause_enabled = 28;
  48. const int cpi_max_capture_len = 29;
  49. const int cpi_passthrough = 30;
  50. const int cpi_markdirty = 31;
  51. const int cpi_num_inchans = 32;
  52. const int cpi_bypass_stretch = 33;
  53. const int cpi_freefilter_shiftx = 34;
  54. const int cpi_freefilter_shifty = 35;
  55. const int cpi_freefilter_scaley = 36;
  56. const int cpi_freefilter_tilty = 37;
  57. const int cpi_freefilter_randomy_numbands = 38;
  58. const int cpi_freefilter_randomy_rate = 39;
  59. const int cpi_freefilter_randomy_amount = 40;
  60. const int cpi_enable_spec_module0 = 41;
  61. const int cpi_enable_spec_module1 = 42;
  62. const int cpi_enable_spec_module2 = 43;
  63. const int cpi_enable_spec_module3 = 44;
  64. const int cpi_enable_spec_module4 = 45;
  65. const int cpi_enable_spec_module5 = 46;
  66. const int cpi_enable_spec_module6 = 47;
  67. const int cpi_enable_spec_module7 = 48;
  68. const int cpi_enable_spec_module8 = 49;
  69. const int cpi_octaves_extra1 = 50;
  70. const int cpi_octaves_extra2 = 51;
  71. const int cpi_octaves_ratio0 = 52;
  72. const int cpi_octaves_ratio1 = 53;
  73. const int cpi_octaves_ratio2 = 54;
  74. const int cpi_octaves_ratio3 = 55;
  75. const int cpi_octaves_ratio4 = 56;
  76. const int cpi_octaves_ratio5 = 57;
  77. const int cpi_octaves_ratio6 = 58;
  78. const int cpi_octaves_ratio7 = 59;
  79. const int cpi_looping_enabled = 60;
  80. const int cpi_rewind = 61;
  81. const int cpi_dryplayrate = 62;
  82. class MyThreadPool : public ThreadPool
  83. {
  84. public:
  85. MyThreadPool() : ThreadPool(2) {}
  86. };
  87. class MyPropertiesFile
  88. {
  89. public:
  90. MyPropertiesFile()
  91. {
  92. PropertiesFile::Options poptions;
  93. poptions.applicationName = "PaulXStretch3";
  94. poptions.folderName = "PaulXStretch3";
  95. poptions.commonToAllUsers = false;
  96. poptions.doNotSave = false;
  97. poptions.storageFormat = PropertiesFile::storeAsXML;
  98. poptions.millisecondsBeforeSaving = 1000;
  99. poptions.ignoreCaseOfKeyNames = false;
  100. poptions.processLock = nullptr;
  101. poptions.filenameSuffix = ".xml";
  102. poptions.osxLibrarySubFolder = "Application Support";
  103. m_props_file = std::make_unique<PropertiesFile>(poptions);
  104. }
  105. std::unique_ptr<PropertiesFile> m_props_file;
  106. };
  107. class PaulstretchpluginAudioProcessorEditor;
  108. struct OfflineRenderParams
  109. {
  110. OfflineRenderParams(File ofile, double osr, int oformat, double omaxdur, int onumloops, CallOutBox* ocb=nullptr) :
  111. outputfile(ofile), outsr(osr), outputformat(oformat), maxoutdur(omaxdur), numloops(onumloops), cbox(ocb)
  112. {}
  113. File outputfile;
  114. double outsr = 44100.0;
  115. double maxoutdur = 3600.0;
  116. int numloops = 1;
  117. int outputformat = 0; // 0=16 bit pcm, 1=24 bit pcm, 2=32 bit float, 3=32 bit float clipped
  118. CallOutBox* cbox = nullptr;
  119. };
  120. class PaulstretchpluginAudioProcessor : public AudioProcessor,
  121. public MultiTimer, public VSTCallbackHandler, public AudioProcessorParameter::Listener
  122. {
  123. public:
  124. using EditorType = PaulstretchpluginAudioProcessorEditor;
  125. PaulstretchpluginAudioProcessor(bool is_stand_alone_offline=false);
  126. ~PaulstretchpluginAudioProcessor();
  127. //==============================================================================
  128. void prepareToPlay (double sampleRate, int samplesPerBlock) override;
  129. void releaseResources() override;
  130. #ifndef JucePlugin_PreferredChannelConfigurations
  131. bool isBusesLayoutSupported (const BusesLayout& layouts) const override;
  132. #endif
  133. void processBlock (AudioSampleBuffer&, MidiBuffer&) override;
  134. //void processBlock (AudioBuffer<double>&, MidiBuffer&) override;
  135. //bool supportsDoublePrecisionProcessing() const override { return true; }
  136. //==============================================================================
  137. AudioProcessorEditor* createEditor() override;
  138. bool hasEditor() const override;
  139. //==============================================================================
  140. const String getName() const override;
  141. bool acceptsMidi() const override;
  142. bool producesMidi() const override;
  143. bool isMidiEffect () const override;
  144. double getTailLengthSeconds() const override;
  145. //==============================================================================
  146. int getNumPrograms() override;
  147. int getCurrentProgram() override;
  148. void setCurrentProgram (int index) override;
  149. const String getProgramName (int index) override;
  150. void changeProgramName (int index, const String& newName) override;
  151. void parameterValueChanged(int parameterIndex, float newValue) override;
  152. void parameterGestureChanged(int parameterIndex, bool gestureIsStarting) override;
  153. //==============================================================================
  154. void getStateInformation (MemoryBlock& destData) override;
  155. void setStateInformation (const void* data, int sizeInBytes) override;
  156. AudioParameterFloat* getFloatParameter(int index)
  157. {
  158. return dynamic_cast<AudioParameterFloat*>(getParameters()[index]);
  159. }
  160. AudioParameterInt* getIntParameter(int index)
  161. {
  162. return dynamic_cast<AudioParameterInt*>(getParameters()[index]);
  163. }
  164. AudioParameterBool* getBoolParameter(int index)
  165. {
  166. return dynamic_cast<AudioParameterBool*>(getParameters()[index]);
  167. }
  168. void setDirty();
  169. void setRecordingEnabled(bool b);
  170. bool isRecordingEnabled() { return m_is_recording; }
  171. double getRecordingPositionPercent();
  172. String setAudioFile(File f);
  173. File getAudioFile() { return m_current_file; }
  174. Range<double> getTimeSelection();
  175. SharedResourcePointer<AudioFormatManager> m_afm;
  176. SharedResourcePointer<MyPropertiesFile> m_propsfile;
  177. StretchAudioSource* getStretchSource() { return m_stretch_source.get(); }
  178. double getPreBufferingPercent();
  179. void timerCallback(int id) override;
  180. double getSampleRateChecked();
  181. int m_abnormal_output_samples = 0;
  182. AudioPlayHead::CurrentPositionInfo m_playposinfo;
  183. bool m_play_when_host_plays = false;
  184. bool m_capture_when_host_plays = false;
  185. bool m_mute_while_capturing = false;
  186. bool m_use_backgroundbuffering = true;
  187. void resetParameters();
  188. void setPreBufferAmount(int x);
  189. int getPreBufferAmount();
  190. bool m_load_file_with_state = true;
  191. ValueTree getStateTree(bool ignoreoptions, bool ignorefile);
  192. void setStateFromTree(ValueTree tree);
  193. String offlineRender(OfflineRenderParams renderpars);
  194. std::atomic<int> m_offline_render_state{ -1 };
  195. std::atomic<bool> m_offline_render_cancel_requested{ false };
  196. std::atomic<int> m_capture_save_state{ 0 };
  197. bool m_state_dirty = false;
  198. std::unique_ptr<AudioThumbnail> m_thumb;
  199. bool m_show_technical_info = false;
  200. Range<double> m_wave_view_range;
  201. int m_prepare_count = 0;
  202. shared_envelope m_free_filter_envelope;
  203. bool m_import_dlg_open = false;
  204. void setAudioPreview(AudioFilePreviewComponent* afpc);
  205. CriticalSection& getCriticalSection() { return m_cs; }
  206. pointer_sized_int handleVstPluginCanDo(int32 index,
  207. pointer_sized_int value,
  208. void* ptr,
  209. float opt) override;
  210. pointer_sized_int handleVstManufacturerSpecific(int32 index,
  211. pointer_sized_int value,
  212. void* ptr,
  213. float opt) override;
  214. int m_cur_tab_index = 0;
  215. bool m_save_captured_audio = true;
  216. String m_capture_location;
  217. bool m_midinote_control = false;
  218. std::function<void(const FileChooser&)> m_filechoose_callback;
  219. private:
  220. bool m_prebuffering_inited = false;
  221. AudioBuffer<float> m_recbuffer;
  222. double m_max_reclen = 10.0;
  223. int m_rec_pos = 0;
  224. int m_rec_count = 0;
  225. Range<int> m_recorded_range;
  226. void finishRecording(int lenrecorded);
  227. bool m_using_memory_buffer = true;
  228. int m_cur_num_out_chans = 2;
  229. CriticalSection m_cs;
  230. File m_current_file;
  231. Time m_current_file_date;
  232. bool m_is_recording = false;
  233. TimeSliceThread m_bufferingthread;
  234. std::unique_ptr<StretchAudioSource> m_stretch_source;
  235. std::unique_ptr<MyBufferingAudioSource> m_buffering_source;
  236. int m_prebuffer_amount = 1;
  237. bool m_recreate_buffering_source = true;
  238. double m_smoothed_prebuffer_ready = 0.0;
  239. SignalSmoother m_prebufsmoother;
  240. int m_fft_size_to_use = 1024;
  241. double m_last_outpos_pos = 0.0;
  242. double m_last_in_pos = 0.0;
  243. std::vector<int> m_bufamounts{ 4096,8192,16384,32768,65536,262144 };
  244. ProcessParameters m_ppar;
  245. void setFFTSize(double size);
  246. void startplay(Range<double> playrange, int numoutchans, int maxBlockSize, String& err);
  247. SharedResourcePointer<MyThumbCache> m_thumbcache;
  248. AudioParameterInt* m_outchansparam = nullptr;
  249. AudioParameterInt* m_inchansparam = nullptr;
  250. int m_curmaxblocksize = 0;
  251. double m_cur_sr = 0.0;
  252. bool m_last_host_playing = false;
  253. AudioBuffer<float> m_input_buffer;
  254. std::vector<float> m_reset_pars;
  255. int m_cur_program = 0;
  256. void setParameters(const std::vector<double>& pars);
  257. float m_cur_playrangeoffset = 0.0;
  258. void updateStretchParametersFromPluginParameters(ProcessParameters& pars);
  259. std::array<AudioParameterBool*, 9> m_sm_enab_pars;
  260. bool m_lastrewind = false;
  261. AudioFilePreviewComponent* m_previewcomponent = nullptr;
  262. void saveCaptureBuffer();
  263. SharedResourcePointer<MyThreadPool> m_threadpool;
  264. int m_midinote_to_use = -1;
  265. ADSR m_adsr;
  266. bool m_is_stand_alone_offline = false;
  267. //==============================================================================
  268. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PaulstretchpluginAudioProcessor)
  269. };