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.

273 lines
7.9KB

  1. /*
  2. Copyright (C) 2006-2011 Nasca Octavian Paul
  3. Author: Nasca Octavian Paul
  4. Copyright (C) 2017 Xenakios
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of version 2 of the GNU General Public License
  7. as published by the Free Software Foundation.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License (version 2) for more details.
  12. You should have received a copy of the GNU General Public License (version 2)
  13. along with this program; if not, write to the Free Software Foundation,
  14. Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  15. */
  16. #pragma once
  17. #include "../JuceLibraryCode/JuceHeader.h"
  18. #include "PluginProcessor.h"
  19. #include <memory>
  20. #include <vector>
  21. class SpectralVisualizer : public Component
  22. {
  23. public:
  24. SpectralVisualizer();
  25. void setState(const ProcessParameters& pars, int nfreqs, double samplerate);
  26. void paint(Graphics& g) override;
  27. private:
  28. Image m_img;
  29. std::vector<REALTYPE> m_insamples,m_freqs1, m_freqs2, m_freqs3;
  30. std::unique_ptr<FFT> m_fft;
  31. int m_nfreqs = 0;
  32. double m_elapsed = 0.0;
  33. };
  34. inline void attachCallback(Button& button, std::function<void()> callback)
  35. {
  36. struct ButtonCallback : public Button::Listener,
  37. private ComponentListener
  38. {
  39. ButtonCallback(Button& b, std::function<void()> f) : target(b), fn(f)
  40. {
  41. target.addListener(this);
  42. target.addComponentListener(this);
  43. }
  44. ~ButtonCallback()
  45. {
  46. target.removeListener(this);
  47. }
  48. void componentBeingDeleted(Component&) override { delete this; }
  49. void buttonClicked(Button*) override { fn(); }
  50. Button& target;
  51. std::function<void()> fn;
  52. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ButtonCallback)
  53. };
  54. new ButtonCallback(button, callback);
  55. }
  56. class MySlider : public Slider
  57. {
  58. public:
  59. MySlider() {}
  60. MySlider(NormalisableRange<float>* range) : m_range(range)
  61. {
  62. }
  63. double proportionOfLengthToValue(double x) override
  64. {
  65. if (m_range)
  66. return m_range->convertFrom0to1(x);
  67. return Slider::proportionOfLengthToValue(x);
  68. }
  69. double valueToProportionOfLength(double x) override
  70. {
  71. if (m_range)
  72. return m_range->convertTo0to1(x);
  73. return Slider::valueToProportionOfLength(x);
  74. }
  75. private:
  76. NormalisableRange<float>* m_range = nullptr;
  77. };
  78. class ParameterComponent : public Component,
  79. public Slider::Listener, public Button::Listener
  80. {
  81. public:
  82. ParameterComponent(AudioProcessorParameter* par, bool notifyOnlyOnRelease);
  83. void resized() override;
  84. void sliderValueChanged(Slider* slid) override;
  85. void sliderDragStarted(Slider* slid) override;
  86. void sliderDragEnded(Slider* slid) override;
  87. void buttonClicked(Button* but) override;
  88. void updateComponent();
  89. private:
  90. Label m_label;
  91. AudioProcessorParameter* m_par = nullptr;
  92. std::unique_ptr<MySlider> m_slider;
  93. std::unique_ptr<ComboBox> m_combobox;
  94. std::unique_ptr<ToggleButton> m_togglebut;
  95. bool m_notify_only_on_release = false;
  96. bool m_dragging = false;
  97. };
  98. class MyThumbCache : public AudioThumbnailCache
  99. {
  100. public:
  101. MyThumbCache() : AudioThumbnailCache(100) { /*Logger::writeToLog("Constructed AudioThumbNailCache");*/ }
  102. ~MyThumbCache() { /*Logger::writeToLog("Destructed AudioThumbNailCache");*/ }
  103. };
  104. class WaveformComponent : public Component, public ChangeListener, public Timer
  105. {
  106. public:
  107. WaveformComponent(AudioFormatManager* afm);
  108. ~WaveformComponent();
  109. void changeListenerCallback(ChangeBroadcaster* cb) override;
  110. void paint(Graphics& g) override;
  111. void setAudioFile(File f);
  112. const File& getAudioFile() const { return m_curfile; }
  113. bool isUsingAudioBuffer() const { return m_using_audio_buffer; }
  114. void setAudioBuffer(AudioBuffer<float>* buf, int samplerate, int len);
  115. void beginAddingAudioBlocks(int channels, int samplerate, int totalllen);
  116. void addAudioBlock(AudioBuffer<float>& buf, int samplerate, int pos);
  117. void timerCallback() override;
  118. std::function<double()> CursorPosCallback;
  119. std::function<void(double)> SeekCallback;
  120. std::function<void(Range<double>, int)> TimeSelectionChangedCallback;
  121. void mouseDown(const MouseEvent& e) override;
  122. void mouseUp(const MouseEvent& e) override;
  123. void mouseDrag(const MouseEvent& e) override;
  124. void mouseMove(const MouseEvent& e) override;
  125. Range<double> getTimeSelection()
  126. {
  127. if (m_time_sel_start >= 0.0 && m_time_sel_end>m_time_sel_start + 0.001)
  128. return { m_time_sel_start, m_time_sel_end };
  129. return { 0.0, 1.0 };
  130. }
  131. void setTimeSelection(Range<double> rng)
  132. {
  133. if (m_lock_timesel_set == true)
  134. return;
  135. if (rng.isEmpty())
  136. rng = { -1.0,1.0 };
  137. m_time_sel_start = rng.getStart();
  138. m_time_sel_end = rng.getEnd();
  139. repaint();
  140. }
  141. void setFileCachedRange(std::pair<Range<double>, Range<double>> rng);
  142. void setTimerEnabled(bool b);
  143. void setViewRange(Range<double> rng);
  144. Value ShowFileCacheRange;
  145. void setRecordingPosition(double pos) { m_rec_pos = pos; }
  146. private:
  147. SharedResourcePointer<MyThumbCache> m_thumbcache;
  148. std::unique_ptr<AudioThumbnail> m_thumb;
  149. Range<double> m_view_range{ 0.0,1.0 };
  150. int m_time_sel_drag_target = 0;
  151. double m_time_sel_start = -1.0;
  152. double m_time_sel_end = -1.0;
  153. double m_drag_time_start = 0.0;
  154. bool m_mousedown = false;
  155. bool m_didseek = false;
  156. bool m_didchangetimeselection = false;
  157. int m_topmargin = 0;
  158. int getTimeSelectionEdge(int x, int y);
  159. std::pair<Range<double>, Range<double>> m_file_cached;
  160. File m_curfile;
  161. Image m_waveimage;
  162. OpenGLContext m_ogl;
  163. bool m_use_opengl = false;
  164. double m_rec_pos = 0.0;
  165. bool m_lock_timesel_set = false;
  166. bool m_using_audio_buffer = false;
  167. };
  168. class SpectralChainEditor : public Component
  169. {
  170. public:
  171. SpectralChainEditor() {}
  172. void paint(Graphics& g) override;
  173. void setSource(StretchAudioSource* src)
  174. {
  175. m_src = src;
  176. m_order = m_src->getSpectrumProcessOrder();
  177. repaint();
  178. }
  179. void mouseDown(const MouseEvent& ev) override;
  180. void mouseDrag(const MouseEvent& ev) override;
  181. void mouseUp(const MouseEvent& ev) override;
  182. private:
  183. StretchAudioSource * m_src = nullptr;
  184. bool m_did_drag = false;
  185. int m_cur_index = -1;
  186. int m_drag_x = 0;
  187. std::vector<int> m_order;
  188. void drawBox(Graphics& g, int index, int x, int y, int w, int h);
  189. };
  190. class MyDynamicObject : public DynamicObject
  191. {
  192. public:
  193. bool hasMethod(const Identifier& methodName) const override
  194. {
  195. if (methodName == Identifier("setLabelBounds") ||
  196. methodName == Identifier("setComponentBounds"))
  197. return true;
  198. return false;
  199. }
  200. var invokeMethod(Identifier methodName,
  201. const var::NativeFunctionArgs& args) override
  202. {
  203. return var();
  204. }
  205. };
  206. class ParamLayoutInfo
  207. {
  208. public:
  209. ParamLayoutInfo() {}
  210. ParamLayoutInfo(int c, int x, int y, int w, int h) :
  211. m_comp(c), m_col(x), m_row(y), m_w(w), m_h(h) {}
  212. int m_comp = 0;
  213. int m_col = 0;
  214. int m_row = 0;
  215. int m_w = 1;
  216. int m_h = 1;
  217. };
  218. class PaulstretchpluginAudioProcessorEditor : public AudioProcessorEditor,
  219. public MultiTimer, public FileDragAndDropTarget, public DragAndDropContainer
  220. {
  221. public:
  222. PaulstretchpluginAudioProcessorEditor (PaulstretchpluginAudioProcessor&);
  223. ~PaulstretchpluginAudioProcessorEditor();
  224. void paint (Graphics&) override;
  225. void resized() override;
  226. void timerCallback(int id) override;
  227. void setAudioFile(File f);
  228. void setAudioBuffer(AudioBuffer<float>* buf, int samplerate, int len);
  229. void beginAddingAudioBlocks(int channels, int samplerate, int totalllen);
  230. void addAudioBlock(AudioBuffer<float>& buf, int samplerate, int pos);
  231. bool isInterestedInFileDrag(const StringArray &files) override;
  232. void filesDropped(const StringArray &files, int x, int y) override;
  233. WaveformComponent m_wavecomponent;
  234. private:
  235. PaulstretchpluginAudioProcessor& processor;
  236. std::vector<std::shared_ptr<ParameterComponent>> m_parcomps;
  237. //SpectralVisualizer m_specvis;
  238. TextButton m_import_button;
  239. TextButton m_settings_button;
  240. Label m_info_label;
  241. SpectralChainEditor m_spec_order_ed;
  242. void chooseFile();
  243. void showSettingsMenu();
  244. String m_last_err;
  245. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PaulstretchpluginAudioProcessorEditor)
  246. };