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.

337 lines
10KB

  1. /*
  2. ==============================================================================
  3. This file was auto-generated!
  4. It contains the basic framework code for a JUCE plugin editor.
  5. ==============================================================================
  6. */
  7. #pragma once
  8. #include "../JuceLibraryCode/JuceHeader.h"
  9. #include "PluginProcessor.h"
  10. #include <memory>
  11. #include <vector>
  12. class SpectralVisualizer : public Component
  13. {
  14. public:
  15. SpectralVisualizer();
  16. void setState(const ProcessParameters& pars, int nfreqs, double samplerate);
  17. void paint(Graphics& g) override;
  18. private:
  19. Image m_img;
  20. std::vector<REALTYPE> m_insamples,m_freqs1, m_freqs2, m_freqs3;
  21. std::unique_ptr<FFT> m_fft;
  22. int m_nfreqs = 0;
  23. double m_elapsed = 0.0;
  24. };
  25. inline void attachCallback(Button& button, std::function<void()> callback)
  26. {
  27. struct ButtonCallback : public Button::Listener,
  28. private ComponentListener
  29. {
  30. ButtonCallback(Button& b, std::function<void()> f) : target(b), fn(f)
  31. {
  32. target.addListener(this);
  33. target.addComponentListener(this);
  34. }
  35. ~ButtonCallback()
  36. {
  37. target.removeListener(this);
  38. }
  39. void componentBeingDeleted(Component&) override { delete this; }
  40. void buttonClicked(Button*) override { fn(); }
  41. Button& target;
  42. std::function<void()> fn;
  43. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ButtonCallback)
  44. };
  45. new ButtonCallback(button, callback);
  46. }
  47. class MySlider : public Slider
  48. {
  49. public:
  50. MySlider() {}
  51. MySlider(NormalisableRange<float>* range) : m_range(range)
  52. {
  53. }
  54. double proportionOfLengthToValue(double x) override
  55. {
  56. if (m_range)
  57. return m_range->convertFrom0to1(x);
  58. return Slider::proportionOfLengthToValue(x);
  59. }
  60. double valueToProportionOfLength(double x) override
  61. {
  62. if (m_range)
  63. return m_range->convertTo0to1(x);
  64. return Slider::valueToProportionOfLength(x);
  65. }
  66. private:
  67. NormalisableRange<float>* m_range = nullptr;
  68. };
  69. class ParameterComponent : public Component,
  70. public Slider::Listener, public Button::Listener
  71. {
  72. public:
  73. ParameterComponent(AudioProcessorParameter* par, bool notifyOnlyOnRelease) : m_par(par)
  74. {
  75. addAndMakeVisible(&m_label);
  76. m_label.setText(par->getName(50),dontSendNotification);
  77. AudioParameterFloat* floatpar = dynamic_cast<AudioParameterFloat*>(par);
  78. if (floatpar)
  79. {
  80. m_slider = std::make_unique<MySlider>(&floatpar->range);
  81. m_notify_only_on_release = notifyOnlyOnRelease;
  82. m_slider->setRange(floatpar->range.start, floatpar->range.end, floatpar->range.interval);
  83. m_slider->setValue(*floatpar, dontSendNotification);
  84. m_slider->addListener(this);
  85. addAndMakeVisible(m_slider.get());
  86. }
  87. AudioParameterInt* intpar = dynamic_cast<AudioParameterInt*>(par);
  88. if (intpar)
  89. {
  90. m_slider = std::make_unique<MySlider>();
  91. m_notify_only_on_release = notifyOnlyOnRelease;
  92. m_slider->setRange(intpar->getRange().getStart(), intpar->getRange().getEnd(), 1.0);
  93. m_slider->setValue(*intpar, dontSendNotification);
  94. m_slider->addListener(this);
  95. addAndMakeVisible(m_slider.get());
  96. }
  97. AudioParameterChoice* choicepar = dynamic_cast<AudioParameterChoice*>(par);
  98. if (choicepar)
  99. {
  100. }
  101. AudioParameterBool* boolpar = dynamic_cast<AudioParameterBool*>(par);
  102. if (boolpar)
  103. {
  104. m_togglebut = std::make_unique<ToggleButton>();
  105. m_togglebut->setToggleState(*boolpar, dontSendNotification);
  106. m_togglebut->addListener(this);
  107. addAndMakeVisible(m_togglebut.get());
  108. }
  109. }
  110. void resized() override
  111. {
  112. m_label.setBounds(0, 0, 200, 24);
  113. if (m_slider)
  114. m_slider->setBounds(m_label.getRight() + 1, 0, getWidth() - 2 - m_label.getWidth(), 24);
  115. if (m_togglebut)
  116. m_togglebut->setBounds(m_label.getRight() + 1, 0, getWidth() - 2 - m_label.getWidth(), 24);
  117. }
  118. void sliderValueChanged(Slider* slid) override
  119. {
  120. if (m_notify_only_on_release == true)
  121. return;
  122. AudioParameterFloat* floatpar = dynamic_cast<AudioParameterFloat*>(m_par);
  123. if (floatpar!=nullptr)
  124. *floatpar = slid->getValue();
  125. AudioParameterInt* intpar = dynamic_cast<AudioParameterInt*>(m_par);
  126. if (intpar != nullptr)
  127. *intpar = slid->getValue();
  128. }
  129. void sliderDragStarted(Slider* slid) override
  130. {
  131. m_dragging = true;
  132. }
  133. void sliderDragEnded(Slider* slid) override
  134. {
  135. m_dragging = false;
  136. if (m_notify_only_on_release == false)
  137. return;
  138. AudioParameterFloat* floatpar = dynamic_cast<AudioParameterFloat*>(m_par);
  139. if (floatpar!=nullptr)
  140. *floatpar = slid->getValue();
  141. AudioParameterInt* intpar = dynamic_cast<AudioParameterInt*>(m_par);
  142. if (intpar != nullptr)
  143. *intpar = slid->getValue();
  144. }
  145. void buttonClicked(Button* but) override
  146. {
  147. AudioParameterBool* boolpar = dynamic_cast<AudioParameterBool*>(m_par);
  148. if (m_togglebut != nullptr && m_togglebut->getToggleState() != *boolpar)
  149. {
  150. *boolpar = m_togglebut->getToggleState();
  151. }
  152. }
  153. void updateComponent()
  154. {
  155. AudioParameterFloat* floatpar = dynamic_cast<AudioParameterFloat*>(m_par);
  156. if (floatpar!=nullptr && m_slider != nullptr && m_dragging == false && (float)m_slider->getValue() != *floatpar)
  157. {
  158. m_slider->setValue(*floatpar, dontSendNotification);
  159. }
  160. AudioParameterInt* intpar = dynamic_cast<AudioParameterInt*>(m_par);
  161. if (intpar != nullptr && m_slider != nullptr && m_dragging == false && (int)m_slider->getValue() != *intpar)
  162. {
  163. m_slider->setValue(*intpar, dontSendNotification);
  164. }
  165. AudioParameterBool* boolpar = dynamic_cast<AudioParameterBool*>(m_par);
  166. if (m_togglebut != nullptr && m_togglebut->getToggleState() != *boolpar)
  167. {
  168. m_togglebut->setToggleState(*boolpar, dontSendNotification);
  169. }
  170. }
  171. private:
  172. Label m_label;
  173. AudioProcessorParameter* m_par = nullptr;
  174. std::unique_ptr<MySlider> m_slider;
  175. std::unique_ptr<ComboBox> m_combobox;
  176. std::unique_ptr<ToggleButton> m_togglebut;
  177. bool m_notify_only_on_release = false;
  178. bool m_dragging = false;
  179. };
  180. class MyThumbCache : public AudioThumbnailCache
  181. {
  182. public:
  183. MyThumbCache() : AudioThumbnailCache(100) { /*Logger::writeToLog("Constructed AudioThumbNailCache");*/ }
  184. ~MyThumbCache() { /*Logger::writeToLog("Destructed AudioThumbNailCache");*/ }
  185. };
  186. class WaveformComponent : public Component, public ChangeListener, public Timer
  187. {
  188. public:
  189. WaveformComponent(AudioFormatManager* afm);
  190. ~WaveformComponent();
  191. void changeListenerCallback(ChangeBroadcaster* cb) override;
  192. void paint(Graphics& g) override;
  193. void setAudioFile(File f);
  194. const File& getAudioFile() const { return m_curfile; }
  195. bool isUsingAudioBuffer() const { return m_using_audio_buffer; }
  196. void setAudioBuffer(AudioBuffer<float>* buf, int samplerate, int len);
  197. void beginAddingAudioBlocks(int channels, int samplerate, int totalllen);
  198. void addAudioBlock(AudioBuffer<float>& buf, int samplerate, int pos);
  199. void timerCallback() override;
  200. std::function<double()> CursorPosCallback;
  201. std::function<void(double)> SeekCallback;
  202. std::function<void(Range<double>, int)> TimeSelectionChangedCallback;
  203. void mouseDown(const MouseEvent& e) override;
  204. void mouseUp(const MouseEvent& e) override;
  205. void mouseDrag(const MouseEvent& e) override;
  206. void mouseMove(const MouseEvent& e) override;
  207. Range<double> getTimeSelection()
  208. {
  209. if (m_time_sel_start >= 0.0 && m_time_sel_end>m_time_sel_start + 0.001)
  210. return { m_time_sel_start, m_time_sel_end };
  211. return { 0.0, 1.0 };
  212. }
  213. void setTimeSelection(Range<double> rng)
  214. {
  215. if (m_lock_timesel_set == true)
  216. return;
  217. if (rng.isEmpty())
  218. rng = { -1.0,1.0 };
  219. m_time_sel_start = rng.getStart();
  220. m_time_sel_end = rng.getEnd();
  221. repaint();
  222. }
  223. void setFileCachedRange(std::pair<Range<double>, Range<double>> rng);
  224. void setTimerEnabled(bool b);
  225. void setViewRange(Range<double> rng);
  226. Value ShowFileCacheRange;
  227. void setRecordingPosition(double pos) { m_rec_pos = pos; }
  228. private:
  229. SharedResourcePointer<MyThumbCache> m_thumbcache;
  230. std::unique_ptr<AudioThumbnail> m_thumb;
  231. Range<double> m_view_range{ 0.0,1.0 };
  232. int m_time_sel_drag_target = 0;
  233. double m_time_sel_start = -1.0;
  234. double m_time_sel_end = -1.0;
  235. double m_drag_time_start = 0.0;
  236. bool m_mousedown = false;
  237. bool m_didseek = false;
  238. bool m_didchangetimeselection = false;
  239. int m_topmargin = 0;
  240. int getTimeSelectionEdge(int x, int y);
  241. std::pair<Range<double>, Range<double>> m_file_cached;
  242. File m_curfile;
  243. Image m_waveimage;
  244. OpenGLContext m_ogl;
  245. bool m_use_opengl = false;
  246. double m_rec_pos = 0.0;
  247. bool m_lock_timesel_set = false;
  248. bool m_using_audio_buffer = false;
  249. };
  250. class SpectralChainEditor : public Component
  251. {
  252. public:
  253. SpectralChainEditor() {}
  254. void paint(Graphics& g) override;
  255. void setSource(StretchAudioSource* src)
  256. {
  257. m_src = src;
  258. m_order = m_src->getSpectrumProcessOrder();
  259. repaint();
  260. }
  261. void mouseDown(const MouseEvent& ev) override;
  262. void mouseDrag(const MouseEvent& ev) override;
  263. void mouseUp(const MouseEvent& ev) override;
  264. private:
  265. StretchAudioSource * m_src = nullptr;
  266. bool m_did_drag = false;
  267. int m_cur_index = -1;
  268. int m_drag_x = 0;
  269. std::vector<int> m_order;
  270. void drawBox(Graphics& g, int index, int x, int y, int w, int h);
  271. };
  272. class MyDynamicObject : public DynamicObject
  273. {
  274. public:
  275. bool hasMethod(const Identifier& methodName) const override
  276. {
  277. if (methodName == Identifier("setLabelBounds") ||
  278. methodName == Identifier("setComponentBounds"))
  279. return true;
  280. return false;
  281. }
  282. var invokeMethod(Identifier methodName,
  283. const var::NativeFunctionArgs& args) override
  284. {
  285. return var();
  286. }
  287. };
  288. class PaulstretchpluginAudioProcessorEditor : public AudioProcessorEditor,
  289. public MultiTimer
  290. {
  291. public:
  292. PaulstretchpluginAudioProcessorEditor (PaulstretchpluginAudioProcessor&);
  293. ~PaulstretchpluginAudioProcessorEditor();
  294. void paint (Graphics&) override;
  295. void resized() override;
  296. void timerCallback(int id) override;
  297. void setAudioFile(File f);
  298. void setAudioBuffer(AudioBuffer<float>* buf, int samplerate, int len);
  299. void beginAddingAudioBlocks(int channels, int samplerate, int totalllen);
  300. void addAudioBlock(AudioBuffer<float>& buf, int samplerate, int pos);
  301. WaveformComponent m_wavecomponent;
  302. private:
  303. PaulstretchpluginAudioProcessor& processor;
  304. std::vector<std::shared_ptr<ParameterComponent>> m_parcomps;
  305. //SpectralVisualizer m_specvis;
  306. TextButton m_import_button;
  307. Label m_info_label;
  308. SpectralChainEditor m_spec_order_ed;
  309. void chooseFile();
  310. String m_last_err;
  311. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PaulstretchpluginAudioProcessorEditor)
  312. };