2017-11-13 15:06:08 +00:00
|
|
|
/*
|
2017-12-17 19:40:35 +00:00
|
|
|
Copyright (C) 2006-2011 Nasca Octavian Paul
|
|
|
|
Author: Nasca Octavian Paul
|
2017-11-13 15:06:08 +00:00
|
|
|
|
2017-12-17 19:40:35 +00:00
|
|
|
Copyright (C) 2017 Xenakios
|
2017-11-13 15:06:08 +00:00
|
|
|
|
2017-12-17 19:40:35 +00:00
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of version 2 of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation.
|
2017-11-13 15:06:08 +00:00
|
|
|
|
2017-12-17 19:40:35 +00:00
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License (version 2) for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License (version 2)
|
|
|
|
along with this program; if not, write to the Free Software Foundation,
|
|
|
|
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
2017-11-13 15:06:08 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "../JuceLibraryCode/JuceHeader.h"
|
|
|
|
#include "PluginProcessor.h"
|
2017-11-13 18:45:23 +00:00
|
|
|
#include <memory>
|
|
|
|
#include <vector>
|
2017-11-13 15:06:08 +00:00
|
|
|
|
2017-12-03 20:00:40 +00:00
|
|
|
class SpectralVisualizer : public Component
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
SpectralVisualizer();
|
2017-12-03 21:28:54 +00:00
|
|
|
void setState(const ProcessParameters& pars, int nfreqs, double samplerate);
|
2017-12-03 20:00:40 +00:00
|
|
|
void paint(Graphics& g) override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
Image m_img;
|
2017-12-03 20:51:57 +00:00
|
|
|
std::vector<REALTYPE> m_insamples,m_freqs1, m_freqs2, m_freqs3;
|
|
|
|
std::unique_ptr<FFT> m_fft;
|
|
|
|
int m_nfreqs = 0;
|
|
|
|
double m_elapsed = 0.0;
|
2017-12-03 20:00:40 +00:00
|
|
|
};
|
|
|
|
|
2017-11-16 15:38:59 +00:00
|
|
|
inline void attachCallback(Button& button, std::function<void()> callback)
|
|
|
|
{
|
|
|
|
struct ButtonCallback : public Button::Listener,
|
|
|
|
private ComponentListener
|
|
|
|
{
|
|
|
|
ButtonCallback(Button& b, std::function<void()> f) : target(b), fn(f)
|
|
|
|
{
|
|
|
|
target.addListener(this);
|
|
|
|
target.addComponentListener(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
~ButtonCallback()
|
|
|
|
{
|
|
|
|
target.removeListener(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void componentBeingDeleted(Component&) override { delete this; }
|
|
|
|
void buttonClicked(Button*) override { fn(); }
|
|
|
|
|
|
|
|
Button& target;
|
|
|
|
std::function<void()> fn;
|
|
|
|
|
|
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ButtonCallback)
|
|
|
|
};
|
|
|
|
|
|
|
|
new ButtonCallback(button, callback);
|
|
|
|
}
|
|
|
|
|
2017-11-24 22:22:07 +00:00
|
|
|
class MySlider : public Slider
|
|
|
|
{
|
|
|
|
public:
|
2017-12-13 22:19:46 +00:00
|
|
|
MySlider() {}
|
2017-11-24 22:22:07 +00:00
|
|
|
MySlider(NormalisableRange<float>* range) : m_range(range)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
double proportionOfLengthToValue(double x) override
|
|
|
|
{
|
2017-12-13 22:19:46 +00:00
|
|
|
if (m_range)
|
|
|
|
return m_range->convertFrom0to1(x);
|
|
|
|
return Slider::proportionOfLengthToValue(x);
|
2017-11-24 22:22:07 +00:00
|
|
|
}
|
|
|
|
double valueToProportionOfLength(double x) override
|
|
|
|
{
|
2017-12-13 22:19:46 +00:00
|
|
|
if (m_range)
|
|
|
|
return m_range->convertTo0to1(x);
|
|
|
|
return Slider::valueToProportionOfLength(x);
|
2017-11-24 22:22:07 +00:00
|
|
|
}
|
|
|
|
private:
|
|
|
|
NormalisableRange<float>* m_range = nullptr;
|
|
|
|
};
|
|
|
|
|
2017-11-13 18:45:23 +00:00
|
|
|
class ParameterComponent : public Component,
|
2017-11-16 17:45:40 +00:00
|
|
|
public Slider::Listener, public Button::Listener
|
2017-11-13 18:45:23 +00:00
|
|
|
{
|
|
|
|
public:
|
2017-12-22 20:59:45 +00:00
|
|
|
ParameterComponent(AudioProcessorParameter* par, bool notifyOnlyOnRelease);
|
|
|
|
void resized() override;
|
|
|
|
void sliderValueChanged(Slider* slid) override;
|
|
|
|
void sliderDragStarted(Slider* slid) override;
|
|
|
|
void sliderDragEnded(Slider* slid) override;
|
|
|
|
void buttonClicked(Button* but) override;
|
|
|
|
void updateComponent();
|
2017-11-13 18:45:23 +00:00
|
|
|
private:
|
|
|
|
Label m_label;
|
|
|
|
AudioProcessorParameter* m_par = nullptr;
|
2017-11-24 22:22:07 +00:00
|
|
|
std::unique_ptr<MySlider> m_slider;
|
2017-11-13 18:45:23 +00:00
|
|
|
std::unique_ptr<ComboBox> m_combobox;
|
|
|
|
std::unique_ptr<ToggleButton> m_togglebut;
|
2017-11-17 14:41:33 +00:00
|
|
|
bool m_notify_only_on_release = false;
|
|
|
|
bool m_dragging = false;
|
2017-11-13 18:45:23 +00:00
|
|
|
};
|
2017-11-13 15:06:08 +00:00
|
|
|
|
2017-11-23 17:36:46 +00:00
|
|
|
class MyThumbCache : public AudioThumbnailCache
|
|
|
|
{
|
|
|
|
public:
|
2017-11-24 22:22:07 +00:00
|
|
|
MyThumbCache() : AudioThumbnailCache(100) { /*Logger::writeToLog("Constructed AudioThumbNailCache");*/ }
|
|
|
|
~MyThumbCache() { /*Logger::writeToLog("Destructed AudioThumbNailCache");*/ }
|
2017-11-23 17:36:46 +00:00
|
|
|
};
|
|
|
|
|
2017-11-13 21:42:13 +00:00
|
|
|
class WaveformComponent : public Component, public ChangeListener, public Timer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
WaveformComponent(AudioFormatManager* afm);
|
|
|
|
~WaveformComponent();
|
|
|
|
void changeListenerCallback(ChangeBroadcaster* cb) override;
|
|
|
|
void paint(Graphics& g) override;
|
|
|
|
void setAudioFile(File f);
|
2017-11-16 14:58:04 +00:00
|
|
|
const File& getAudioFile() const { return m_curfile; }
|
2017-12-13 03:23:57 +00:00
|
|
|
bool isUsingAudioBuffer() const { return m_using_audio_buffer; }
|
|
|
|
void setAudioBuffer(AudioBuffer<float>* buf, int samplerate, int len);
|
2017-11-15 15:52:47 +00:00
|
|
|
void beginAddingAudioBlocks(int channels, int samplerate, int totalllen);
|
|
|
|
void addAudioBlock(AudioBuffer<float>& buf, int samplerate, int pos);
|
2017-11-13 21:42:13 +00:00
|
|
|
void timerCallback() override;
|
|
|
|
std::function<double()> CursorPosCallback;
|
|
|
|
std::function<void(double)> SeekCallback;
|
|
|
|
std::function<void(Range<double>, int)> TimeSelectionChangedCallback;
|
|
|
|
void mouseDown(const MouseEvent& e) override;
|
|
|
|
void mouseUp(const MouseEvent& e) override;
|
|
|
|
void mouseDrag(const MouseEvent& e) override;
|
|
|
|
void mouseMove(const MouseEvent& e) override;
|
|
|
|
Range<double> getTimeSelection()
|
|
|
|
{
|
|
|
|
if (m_time_sel_start >= 0.0 && m_time_sel_end>m_time_sel_start + 0.001)
|
|
|
|
return { m_time_sel_start, m_time_sel_end };
|
|
|
|
return { 0.0, 1.0 };
|
|
|
|
}
|
|
|
|
void setTimeSelection(Range<double> rng)
|
|
|
|
{
|
2017-11-16 14:58:04 +00:00
|
|
|
if (m_lock_timesel_set == true)
|
|
|
|
return;
|
2017-11-13 21:42:13 +00:00
|
|
|
if (rng.isEmpty())
|
|
|
|
rng = { -1.0,1.0 };
|
|
|
|
m_time_sel_start = rng.getStart();
|
|
|
|
m_time_sel_end = rng.getEnd();
|
|
|
|
repaint();
|
|
|
|
}
|
|
|
|
void setFileCachedRange(std::pair<Range<double>, Range<double>> rng);
|
|
|
|
void setTimerEnabled(bool b);
|
|
|
|
void setViewRange(Range<double> rng);
|
|
|
|
Value ShowFileCacheRange;
|
2017-11-15 15:52:47 +00:00
|
|
|
void setRecordingPosition(double pos) { m_rec_pos = pos; }
|
2017-11-13 21:42:13 +00:00
|
|
|
private:
|
2017-11-23 17:36:46 +00:00
|
|
|
SharedResourcePointer<MyThumbCache> m_thumbcache;
|
2017-11-13 21:42:13 +00:00
|
|
|
|
|
|
|
std::unique_ptr<AudioThumbnail> m_thumb;
|
|
|
|
Range<double> m_view_range{ 0.0,1.0 };
|
|
|
|
int m_time_sel_drag_target = 0;
|
|
|
|
double m_time_sel_start = -1.0;
|
|
|
|
double m_time_sel_end = -1.0;
|
|
|
|
double m_drag_time_start = 0.0;
|
|
|
|
bool m_mousedown = false;
|
|
|
|
bool m_didseek = false;
|
|
|
|
bool m_didchangetimeselection = false;
|
|
|
|
int m_topmargin = 0;
|
|
|
|
int getTimeSelectionEdge(int x, int y);
|
|
|
|
std::pair<Range<double>, Range<double>> m_file_cached;
|
|
|
|
File m_curfile;
|
|
|
|
Image m_waveimage;
|
|
|
|
OpenGLContext m_ogl;
|
|
|
|
bool m_use_opengl = false;
|
2017-11-15 15:52:47 +00:00
|
|
|
double m_rec_pos = 0.0;
|
2017-11-16 14:58:04 +00:00
|
|
|
bool m_lock_timesel_set = false;
|
2017-12-13 03:23:57 +00:00
|
|
|
bool m_using_audio_buffer = false;
|
2017-11-13 21:42:13 +00:00
|
|
|
};
|
|
|
|
|
2017-12-13 17:55:35 +00:00
|
|
|
class SpectralChainEditor : public Component
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
SpectralChainEditor() {}
|
|
|
|
void paint(Graphics& g) override;
|
|
|
|
void setSource(StretchAudioSource* src)
|
|
|
|
{
|
|
|
|
m_src = src;
|
|
|
|
m_order = m_src->getSpectrumProcessOrder();
|
|
|
|
repaint();
|
|
|
|
}
|
|
|
|
void mouseDown(const MouseEvent& ev) override;
|
|
|
|
void mouseDrag(const MouseEvent& ev) override;
|
|
|
|
void mouseUp(const MouseEvent& ev) override;
|
|
|
|
private:
|
|
|
|
StretchAudioSource * m_src = nullptr;
|
|
|
|
bool m_did_drag = false;
|
|
|
|
int m_cur_index = -1;
|
2017-12-13 19:25:42 +00:00
|
|
|
int m_drag_x = 0;
|
2017-12-13 17:55:35 +00:00
|
|
|
std::vector<int> m_order;
|
2017-12-13 19:25:42 +00:00
|
|
|
void drawBox(Graphics& g, int index, int x, int y, int w, int h);
|
2017-12-13 17:55:35 +00:00
|
|
|
};
|
|
|
|
|
2017-12-12 17:14:43 +00:00
|
|
|
class MyDynamicObject : public DynamicObject
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
bool hasMethod(const Identifier& methodName) const override
|
|
|
|
{
|
|
|
|
if (methodName == Identifier("setLabelBounds") ||
|
|
|
|
methodName == Identifier("setComponentBounds"))
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
var invokeMethod(Identifier methodName,
|
|
|
|
const var::NativeFunctionArgs& args) override
|
|
|
|
{
|
|
|
|
return var();
|
|
|
|
}
|
|
|
|
};
|
2017-11-13 21:42:13 +00:00
|
|
|
|
2017-12-22 20:35:02 +00:00
|
|
|
class ParamLayoutInfo
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ParamLayoutInfo() {}
|
|
|
|
ParamLayoutInfo(int c, int x, int y, int w, int h) :
|
|
|
|
m_comp(c), m_col(x), m_row(y), m_w(w), m_h(h) {}
|
|
|
|
int m_comp = 0;
|
|
|
|
int m_col = 0;
|
|
|
|
int m_row = 0;
|
|
|
|
int m_w = 1;
|
|
|
|
int m_h = 1;
|
|
|
|
};
|
|
|
|
|
2017-11-13 18:54:08 +00:00
|
|
|
class PaulstretchpluginAudioProcessorEditor : public AudioProcessorEditor,
|
2017-12-27 14:56:37 +00:00
|
|
|
public MultiTimer, public FileDragAndDropTarget, public DragAndDropContainer
|
2017-11-13 15:06:08 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
PaulstretchpluginAudioProcessorEditor (PaulstretchpluginAudioProcessor&);
|
|
|
|
~PaulstretchpluginAudioProcessorEditor();
|
2017-11-16 15:38:59 +00:00
|
|
|
void paint (Graphics&) override;
|
2017-11-13 15:06:08 +00:00
|
|
|
void resized() override;
|
2017-11-13 18:54:08 +00:00
|
|
|
void timerCallback(int id) override;
|
2017-11-13 21:42:13 +00:00
|
|
|
void setAudioFile(File f);
|
|
|
|
void setAudioBuffer(AudioBuffer<float>* buf, int samplerate, int len);
|
2017-11-15 15:52:47 +00:00
|
|
|
void beginAddingAudioBlocks(int channels, int samplerate, int totalllen);
|
|
|
|
void addAudioBlock(AudioBuffer<float>& buf, int samplerate, int pos);
|
2017-12-27 14:56:37 +00:00
|
|
|
bool isInterestedInFileDrag(const StringArray &files) override;
|
|
|
|
void filesDropped(const StringArray &files, int x, int y) override;
|
|
|
|
|
2017-11-15 19:47:26 +00:00
|
|
|
WaveformComponent m_wavecomponent;
|
2017-11-13 15:06:08 +00:00
|
|
|
private:
|
|
|
|
PaulstretchpluginAudioProcessor& processor;
|
2017-11-13 18:45:23 +00:00
|
|
|
std::vector<std::shared_ptr<ParameterComponent>> m_parcomps;
|
2017-12-17 16:16:39 +00:00
|
|
|
//SpectralVisualizer m_specvis;
|
2017-12-13 16:48:52 +00:00
|
|
|
|
2017-11-14 16:14:14 +00:00
|
|
|
TextButton m_import_button;
|
2017-12-19 22:50:47 +00:00
|
|
|
TextButton m_settings_button;
|
2017-11-13 20:35:36 +00:00
|
|
|
Label m_info_label;
|
2017-12-13 17:55:35 +00:00
|
|
|
SpectralChainEditor m_spec_order_ed;
|
2017-11-16 15:38:59 +00:00
|
|
|
void chooseFile();
|
2017-12-19 22:50:47 +00:00
|
|
|
void showSettingsMenu();
|
2017-12-15 04:17:11 +00:00
|
|
|
String m_last_err;
|
2017-11-13 15:06:08 +00:00
|
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PaulstretchpluginAudioProcessorEditor)
|
|
|
|
};
|
2017-11-23 17:12:29 +00:00
|
|
|
|