@@ -675,6 +675,8 @@ void MultiStretchAudioSource::setFFTWindowingType(int windowtype) | |||||
void MultiStretchAudioSource::setFFTSize(int size) | void MultiStretchAudioSource::setFFTSize(int size) | ||||
{ | { | ||||
if (size == getActiveStretchSource()->getFFTSize()) | |||||
return; | |||||
if (m_is_playing == false) | if (m_is_playing == false) | ||||
{ | { | ||||
getActiveStretchSource()->setFFTSize(size); | getActiveStretchSource()->setFFTSize(size); | ||||
@@ -16,9 +16,14 @@ | |||||
PaulstretchpluginAudioProcessorEditor::PaulstretchpluginAudioProcessorEditor (PaulstretchpluginAudioProcessor& p) | PaulstretchpluginAudioProcessorEditor::PaulstretchpluginAudioProcessorEditor (PaulstretchpluginAudioProcessor& p) | ||||
: AudioProcessorEditor (&p), processor (p) | : AudioProcessorEditor (&p), processor (p) | ||||
{ | { | ||||
// Make sure that before the constructor has finished, you've set the | |||||
// editor's size to whatever you need it to be. | |||||
setSize (400, 300); | |||||
const auto& pars = processor.getParameters(); | |||||
for (int i=0;i<pars.size();++i) | |||||
{ | |||||
m_parcomps.push_back(std::make_shared<ParameterComponent>(pars[i])); | |||||
m_parcomps.back()->setBounds(1, i * 25, 598, 24); | |||||
addAndMakeVisible(m_parcomps.back().get()); | |||||
} | |||||
setSize (600, pars.size()*25); | |||||
} | } | ||||
PaulstretchpluginAudioProcessorEditor::~PaulstretchpluginAudioProcessorEditor() | PaulstretchpluginAudioProcessorEditor::~PaulstretchpluginAudioProcessorEditor() | ||||
@@ -28,12 +33,7 @@ PaulstretchpluginAudioProcessorEditor::~PaulstretchpluginAudioProcessorEditor() | |||||
//============================================================================== | //============================================================================== | ||||
void PaulstretchpluginAudioProcessorEditor::paint (Graphics& g) | void PaulstretchpluginAudioProcessorEditor::paint (Graphics& g) | ||||
{ | { | ||||
// (Our component is opaque, so we must completely fill the background with a solid colour) | |||||
g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); | |||||
g.setColour (Colours::white); | |||||
g.setFont (15.0f); | |||||
g.drawFittedText ("Hello World!", getLocalBounds(), Justification::centred, 1); | |||||
g.fillAll(Colours::darkgrey); | |||||
} | } | ||||
void PaulstretchpluginAudioProcessorEditor::resized() | void PaulstretchpluginAudioProcessorEditor::resized() | ||||
@@ -12,11 +12,55 @@ | |||||
#include "../JuceLibraryCode/JuceHeader.h" | #include "../JuceLibraryCode/JuceHeader.h" | ||||
#include "PluginProcessor.h" | #include "PluginProcessor.h" | ||||
#include <memory> | |||||
#include <vector> | |||||
class ParameterComponent : public Component, | |||||
public Slider::Listener | |||||
{ | |||||
public: | |||||
ParameterComponent(AudioProcessorParameter* par) : m_par(par) | |||||
{ | |||||
addAndMakeVisible(&m_label); | |||||
m_label.setText(par->getName(50),dontSendNotification); | |||||
AudioParameterFloat* floatpar = dynamic_cast<AudioParameterFloat*>(par); | |||||
if (floatpar) | |||||
{ | |||||
m_slider = std::make_unique<Slider>(); | |||||
m_slider->setRange(floatpar->range.start, floatpar->range.end, floatpar->range.interval); | |||||
m_slider->setValue(*floatpar, dontSendNotification); | |||||
m_slider->addListener(this); | |||||
addAndMakeVisible(m_slider.get()); | |||||
} | |||||
AudioParameterChoice* choicepar = dynamic_cast<AudioParameterChoice*>(par); | |||||
if (choicepar) | |||||
{ | |||||
} | |||||
AudioParameterBool* boolpar = dynamic_cast<AudioParameterBool*>(par); | |||||
if (boolpar) | |||||
{ | |||||
} | |||||
} | |||||
void resized() override | |||||
{ | |||||
m_label.setBounds(0, 0, 200, 24); | |||||
if (m_slider) | |||||
m_slider->setBounds(m_label.getRight() + 1, 0, getWidth() - 2 - m_label.getWidth(), 24); | |||||
} | |||||
void sliderValueChanged(Slider* slid) override | |||||
{ | |||||
} | |||||
private: | |||||
Label m_label; | |||||
AudioProcessorParameter* m_par = nullptr; | |||||
std::unique_ptr<Slider> m_slider; | |||||
std::unique_ptr<ComboBox> m_combobox; | |||||
std::unique_ptr<ToggleButton> m_togglebut; | |||||
}; | |||||
//============================================================================== | |||||
/** | |||||
*/ | |||||
class PaulstretchpluginAudioProcessorEditor : public AudioProcessorEditor | class PaulstretchpluginAudioProcessorEditor : public AudioProcessorEditor | ||||
{ | { | ||||
public: | public: | ||||
@@ -28,9 +72,7 @@ public: | |||||
void resized() override; | void resized() override; | ||||
private: | private: | ||||
// This reference is provided as a quick way for your editor to | |||||
// access the processor object that created it. | |||||
PaulstretchpluginAudioProcessor& processor; | PaulstretchpluginAudioProcessor& processor; | ||||
std::vector<std::shared_ptr<ParameterComponent>> m_parcomps; | |||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PaulstretchpluginAudioProcessorEditor) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PaulstretchpluginAudioProcessorEditor) | ||||
}; | }; |
@@ -28,11 +28,14 @@ PaulstretchpluginAudioProcessor::PaulstretchpluginAudioProcessor() | |||||
m_afm = std::make_unique<AudioFormatManager>(); | m_afm = std::make_unique<AudioFormatManager>(); | ||||
m_afm->registerBasicFormats(); | m_afm->registerBasicFormats(); | ||||
m_control = std::make_unique<Control>(m_afm.get()); | m_control = std::make_unique<Control>(m_afm.get()); | ||||
m_control->ppar.pitch_shift.enabled = true; | |||||
m_control->ppar.freq_shift.enabled = true; | |||||
m_control->getStretchAudioSource()->setLoopingEnabled(true); | m_control->getStretchAudioSource()->setLoopingEnabled(true); | ||||
addParameter(new AudioParameterFloat("mainvolume0", "Main volume", -24.0f, 12.0f, -3.0f)); | addParameter(new AudioParameterFloat("mainvolume0", "Main volume", -24.0f, 12.0f, -3.0f)); | ||||
addParameter(new AudioParameterFloat("stretchamount0", "Stretch amount", 0.1f, 128.0f, 1.0f)); | addParameter(new AudioParameterFloat("stretchamount0", "Stretch amount", 0.1f, 128.0f, 1.0f)); | ||||
addParameter(new AudioParameterFloat("fftsize0", "FFT size", 0.0f, 1.0f, 0.6f)); | |||||
addParameter(new AudioParameterFloat("pitchshift0", "Pitch shift", -24.0f, 24.0f, 0.0f)); | addParameter(new AudioParameterFloat("pitchshift0", "Pitch shift", -24.0f, 24.0f, 0.0f)); | ||||
addParameter(new AudioParameterFloat("freqshift0", "Frequency shift", -1000.0f, 1000.0f, 0.0f)); | |||||
} | } | ||||
PaulstretchpluginAudioProcessor::~PaulstretchpluginAudioProcessor() | PaulstretchpluginAudioProcessor::~PaulstretchpluginAudioProcessor() | ||||
@@ -156,22 +159,14 @@ void PaulstretchpluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, M | |||||
const int totalNumInputChannels = getTotalNumInputChannels(); | const int totalNumInputChannels = getTotalNumInputChannels(); | ||||
const int totalNumOutputChannels = getTotalNumOutputChannels(); | const int totalNumOutputChannels = getTotalNumOutputChannels(); | ||||
// In case we have more outputs than inputs, this code clears any output | |||||
// channels that didn't contain input data, (because these aren't | |||||
// guaranteed to be empty - they may contain garbage). | |||||
// This is here to avoid people getting screaming feedback | |||||
// when they first compile a plugin, but obviously you don't need to keep | |||||
// this code if your algorithm always overwrites all the output channels. | |||||
for (int i = totalNumInputChannels; i < totalNumOutputChannels; ++i) | for (int i = totalNumInputChannels; i < totalNumOutputChannels; ++i) | ||||
buffer.clear (i, 0, buffer.getNumSamples()); | buffer.clear (i, 0, buffer.getNumSamples()); | ||||
if (m_ready_to_play == false) | if (m_ready_to_play == false) | ||||
return; | return; | ||||
auto& params = getParameters(); | |||||
AudioParameterFloat* par = (AudioParameterFloat*)params[1]; | |||||
m_control->getStretchAudioSource()->setRate(*par); | |||||
par = (AudioParameterFloat*)params[2]; | |||||
m_control->ppar.pitch_shift.enabled = true; | |||||
m_control->ppar.pitch_shift.cents = *par * 100.0; | |||||
m_control->getStretchAudioSource()->setRate(*getFloatParameter(1)); | |||||
//m_control->setFFTSize(*getFloatParameter(2)); | |||||
m_control->ppar.pitch_shift.cents = *getFloatParameter(3) * 100.0; | |||||
m_control->ppar.freq_shift.Hz = *getFloatParameter(4); | |||||
m_control->update_process_parameters(); | m_control->update_process_parameters(); | ||||
m_control->processAudio(buffer); | m_control->processAudio(buffer); | ||||
} | } | ||||
@@ -184,8 +179,7 @@ bool PaulstretchpluginAudioProcessor::hasEditor() const | |||||
AudioProcessorEditor* PaulstretchpluginAudioProcessor::createEditor() | AudioProcessorEditor* PaulstretchpluginAudioProcessor::createEditor() | ||||
{ | { | ||||
return new GenericAudioProcessorEditor(this); | |||||
//return new PaulstretchpluginAudioProcessorEditor (*this); | |||||
return new PaulstretchpluginAudioProcessorEditor (*this); | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
@@ -55,7 +55,10 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
void getStateInformation (MemoryBlock& destData) override; | void getStateInformation (MemoryBlock& destData) override; | ||||
void setStateInformation (const void* data, int sizeInBytes) override; | void setStateInformation (const void* data, int sizeInBytes) override; | ||||
AudioParameterFloat* getFloatParameter(int index) | |||||
{ | |||||
return dynamic_cast<AudioParameterFloat*>(getParameters()[index]); | |||||
} | |||||
private: | private: | ||||
std::unique_ptr<Control> m_control; | std::unique_ptr<Control> m_control; | ||||
std::unique_ptr<AudioFormatManager> m_afm; | std::unique_ptr<AudioFormatManager> m_afm; | ||||