Initial work to change octave mixer spectral module to a more generic ratio mixer module that has more shifters and allows changing the shift ratios. Also added a separate tab page in the GUI for it.
This commit is contained in:
parent
3729c4ec28
commit
941ebf31a5
@ -112,8 +112,10 @@ void ProcessedStretch::process_spectrum(REALTYPE *freq)
|
||||
spectrum_do_freq_shift(pars,nfreq,samplerate,m_infreq.data(), freq);
|
||||
if (e.m_index == 3 && *e.m_enabled == true)
|
||||
spectrum_do_pitch_shift(pars,nfreq,m_infreq.data(), freq, pow(2.0f, pars.pitch_shift.cents / 1200.0f));
|
||||
//if (e.m_index == 4 && *e.m_enabled == true)
|
||||
// spectrum_do_octave(pars,nfreq,samplerate, m_sumfreq, m_tmpfreq1, m_infreq.data(), freq);
|
||||
if (e.m_index == 4 && *e.m_enabled == true)
|
||||
spectrum_do_octave(pars,nfreq,samplerate, m_sumfreq, m_tmpfreq1, m_infreq.data(), freq);
|
||||
spectrum_do_ratiomix(pars,nfreq,samplerate, m_sumfreq, m_tmpfreq1, m_infreq.data(), freq);
|
||||
if (e.m_index == 5 && *e.m_enabled == true)
|
||||
spectrum_spread(nfreq,samplerate,m_tmpfreq1,m_infreq.data(), freq, pars.spread.bandwidth);
|
||||
if (e.m_index == 6 && *e.m_enabled == true)
|
||||
|
@ -20,6 +20,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "Stretch.h"
|
||||
#include <array>
|
||||
#include "../jcdp_envelope.h"
|
||||
|
||||
struct ProcessParameters
|
||||
@ -28,6 +29,8 @@ struct ProcessParameters
|
||||
{
|
||||
pitch_shift.cents=0;
|
||||
|
||||
ratiomix.ratios = { 0.25,0.5,1.0,2.0,3.0,4.0,0.0,0.0 };
|
||||
|
||||
octave.om2=octave.om1=octave.o1=octave.o15=octave.o2=0.0f;
|
||||
octave.o0=1.0f;
|
||||
|
||||
@ -58,9 +61,17 @@ struct ProcessParameters
|
||||
int cents;
|
||||
}pitch_shift;
|
||||
|
||||
|
||||
struct{
|
||||
REALTYPE om2,om1,o0,o1,o15,o2;
|
||||
}octave;
|
||||
|
||||
|
||||
struct
|
||||
{
|
||||
std::array<double, 8> ratios;
|
||||
std::array<double, 8> ratiolevels;
|
||||
} ratiomix;
|
||||
|
||||
struct{
|
||||
int Hz;
|
||||
@ -152,7 +163,9 @@ struct ProcessParameters
|
||||
filter.hdamp == other.filter.hdamp &&
|
||||
filter.high == other.filter.high &&
|
||||
filter.low == other.filter.low &&
|
||||
filter.stop == other.filter.stop;
|
||||
filter.stop == other.filter.stop &&
|
||||
ratiomix.ratiolevels == other.ratiomix.ratiolevels &&
|
||||
ratiomix.ratios == other.ratiomix.ratios;
|
||||
}
|
||||
};
|
||||
|
||||
@ -393,6 +406,30 @@ inline void spectrum_do_octave(const ProcessParameters& pars, int nfreq, double
|
||||
for (int i = 0; i<nfreq; i++) freq2[i] = sumfreq[i] / sum;
|
||||
};
|
||||
|
||||
inline void spectrum_do_ratiomix(const ProcessParameters& pars, int nfreq, double /*samplerate*/,
|
||||
std::vector<REALTYPE>& sumfreq,
|
||||
std::vector<REALTYPE>& tmpfreq1,
|
||||
REALTYPE *freq1, REALTYPE *freq2)
|
||||
{
|
||||
spectrum_zero(nfreq, sumfreq.data());
|
||||
double ratiolevelsum = 0.01;
|
||||
for (int i = 0; i < pars.ratiomix.ratios.size(); ++i)
|
||||
{
|
||||
double ratiolevel = pars.ratiomix.ratiolevels[i];
|
||||
double ratio = pars.ratiomix.ratios[i];
|
||||
ratiolevelsum += ratiolevel;
|
||||
if (ratiolevel > 1e-3 && ratio > 0.0)
|
||||
{
|
||||
spectrum_do_pitch_shift(pars, nfreq, freq1, tmpfreq1.data(), ratio);
|
||||
spectrum_add(nfreq, sumfreq.data(), tmpfreq1.data(), ratiolevel);
|
||||
}
|
||||
}
|
||||
if (ratiolevelsum<0.5f)
|
||||
ratiolevelsum = 0.5f;
|
||||
for (int i = 0; i<nfreq; i++)
|
||||
freq2[i] = sumfreq[i] / ratiolevelsum;
|
||||
};
|
||||
|
||||
inline void spectrum_do_filter(const ProcessParameters& pars, int nfreq, double samplerate, REALTYPE *freq1, REALTYPE *freq2) {
|
||||
REALTYPE low = 0, high = 0;
|
||||
if (pars.filter.low<pars.filter.high) {//sort the low/high freqs
|
||||
|
@ -27,6 +27,12 @@ using floatvector = std::vector<REALTYPE>;
|
||||
using float2dvector = std::vector<std::vector<float>>;
|
||||
using float3dvector = std::vector<std::vector<std::vector<float>>>;
|
||||
|
||||
template<typename T>
|
||||
using uptrvec = std::vector<std::unique_ptr<T>>;
|
||||
|
||||
template<typename T>
|
||||
using sptrvec = std::vector<std::shared_ptr<T>>;
|
||||
|
||||
template<typename T>
|
||||
inline std::unique_ptr<T> unique_from_raw(T* ptr)
|
||||
{
|
||||
|
@ -155,9 +155,48 @@ PaulstretchpluginAudioProcessorEditor::PaulstretchpluginAudioProcessorEditor(Pau
|
||||
*/
|
||||
processor.setDirty();
|
||||
};
|
||||
|
||||
m_ratiomixeditor.GetParameterValue = [this](int which, int index)
|
||||
{
|
||||
if (which == 0)
|
||||
return processor.getStretchSource()->getProcessParameters().ratiomix.ratios[index];
|
||||
if (which == 1)
|
||||
{
|
||||
if (index == 0)
|
||||
return (double)*processor.getFloatParameter(cpi_octavesm2);
|
||||
if (index == 1)
|
||||
return (double)*processor.getFloatParameter(cpi_octavesm1);
|
||||
if (index == 2)
|
||||
return (double)*processor.getFloatParameter(cpi_octaves0);
|
||||
if (index == 3)
|
||||
return (double)*processor.getFloatParameter(cpi_octaves1);
|
||||
if (index == 4)
|
||||
return (double)*processor.getFloatParameter(cpi_octaves15);
|
||||
if (index == 5)
|
||||
return (double)*processor.getFloatParameter(cpi_octaves2);
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
};
|
||||
m_ratiomixeditor.OnRatioLevelChanged = [this](int index, double val)
|
||||
{
|
||||
if (index == 0)
|
||||
*processor.getFloatParameter(cpi_octavesm2) = val;
|
||||
if (index == 1)
|
||||
*processor.getFloatParameter(cpi_octavesm1) = val;
|
||||
if (index == 2)
|
||||
*processor.getFloatParameter(cpi_octaves0) = val;
|
||||
if (index == 3)
|
||||
*processor.getFloatParameter(cpi_octaves1) = val;
|
||||
if (index == 4)
|
||||
*processor.getFloatParameter(cpi_octaves15) = val;
|
||||
if (index == 5)
|
||||
*processor.getFloatParameter(cpi_octaves2) = val;
|
||||
};
|
||||
m_wave_container->addAndMakeVisible(&m_wavecomponent);
|
||||
m_wavefilter_tab.addTab("Waveform", Colours::white, m_wave_container, true);
|
||||
m_wavefilter_tab.addTab("Free filter", Colours::white, &m_free_filter_component, false);
|
||||
m_wavefilter_tab.addTab("Ratio mixer", Colours::grey, &m_ratiomixeditor, false);
|
||||
m_wavefilter_tab.addTab("Free filter", Colours::white, &m_free_filter_component, false);
|
||||
|
||||
addAndMakeVisible(&m_wavefilter_tab);
|
||||
setSize (1200, 30+(pars.size()/2)*25+100+15);
|
||||
@ -1334,3 +1373,46 @@ zoom_scrollbar::hot_area zoom_scrollbar::get_hot_area(int x, int)
|
||||
return ha_handle;
|
||||
return ha_none;
|
||||
}
|
||||
|
||||
RatioMixerEditor::RatioMixerEditor(int numratios)
|
||||
{
|
||||
for (int i = 0; i < numratios; ++i)
|
||||
{
|
||||
auto ratslid = std::make_unique<Slider>(Slider::LinearHorizontal,Slider::TextBoxBelow);
|
||||
ratslid->setRange(0.125, 8.0);
|
||||
ratslid->onValueChange = [this]() {};
|
||||
addAndMakeVisible(ratslid.get());
|
||||
m_ratio_sliders.emplace_back(std::move(ratslid));
|
||||
|
||||
auto ratlevslid = std::make_unique<Slider>();
|
||||
ratlevslid->setRange(0.0, 1.0);
|
||||
ratlevslid->setSliderStyle(Slider::LinearVertical);
|
||||
if (i==3)
|
||||
ratlevslid->setValue(1.0,dontSendNotification);
|
||||
else ratlevslid->setValue(0.0,dontSendNotification);
|
||||
ratlevslid->onValueChange = [this, i]() { OnRatioLevelChanged(i, m_ratio_level_sliders[i]->getValue()); };
|
||||
addAndMakeVisible(ratlevslid.get());
|
||||
m_ratio_level_sliders.emplace_back(std::move(ratlevslid));
|
||||
}
|
||||
startTimer(200);
|
||||
}
|
||||
|
||||
void RatioMixerEditor::resized()
|
||||
{
|
||||
int nsliders = m_ratio_sliders.size();
|
||||
int slidw = getWidth() / nsliders;
|
||||
for (int i = 0; i < nsliders; ++i)
|
||||
{
|
||||
m_ratio_level_sliders[i]->setBounds(slidw/2+ slidw * i, 1, 20, getHeight() - 50);
|
||||
m_ratio_sliders[i]->setBounds(slidw * i, getHeight() - 48, slidw - 5, 47);
|
||||
}
|
||||
}
|
||||
|
||||
void RatioMixerEditor::timerCallback()
|
||||
{
|
||||
for (int i = 0; i < m_ratio_level_sliders.size(); ++i)
|
||||
{
|
||||
m_ratio_sliders[i]->setValue(GetParameterValue(0, i), dontSendNotification);
|
||||
m_ratio_level_sliders[i]->setValue(GetParameterValue(1, i), dontSendNotification);
|
||||
}
|
||||
}
|
||||
|
@ -209,6 +209,20 @@ private:
|
||||
void drawBox(Graphics& g, int index, int x, int y, int w, int h);
|
||||
};
|
||||
|
||||
class RatioMixerEditor : public Component, public Timer
|
||||
{
|
||||
public:
|
||||
RatioMixerEditor(int numratios);
|
||||
void resized() override;
|
||||
std::function<void(int, double)> OnRatioChanged;
|
||||
std::function<void(int, double)> OnRatioLevelChanged;
|
||||
std::function<double(int which, int index)> GetParameterValue;
|
||||
void timerCallback() override;
|
||||
private:
|
||||
uptrvec<Slider> m_ratio_sliders;
|
||||
uptrvec<Slider> m_ratio_level_sliders;
|
||||
};
|
||||
|
||||
class PaulstretchpluginAudioProcessorEditor : public AudioProcessorEditor,
|
||||
public MultiTimer, public FileDragAndDropTarget, public DragAndDropContainer
|
||||
{
|
||||
@ -227,7 +241,7 @@ public:
|
||||
void chooseFile();
|
||||
private:
|
||||
PaulstretchpluginAudioProcessor& processor;
|
||||
std::vector<std::unique_ptr<ParameterComponent>> m_parcomps;
|
||||
uptrvec<ParameterComponent> m_parcomps;
|
||||
//SpectralVisualizer m_specvis;
|
||||
PerfMeterComponent m_perfmeter;
|
||||
TextButton m_import_button;
|
||||
@ -238,8 +252,9 @@ private:
|
||||
void showSettingsMenu();
|
||||
String m_last_err;
|
||||
zoom_scrollbar m_zs;
|
||||
EnvelopeComponent m_free_filter_component;
|
||||
TabbedComponent m_wavefilter_tab;
|
||||
RatioMixerEditor m_ratiomixeditor{ 8 };
|
||||
EnvelopeComponent m_free_filter_component;
|
||||
TabbedComponent m_wavefilter_tab;
|
||||
Component* m_wave_container=nullptr;
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PaulstretchpluginAudioProcessorEditor)
|
||||
};
|
||||
|
@ -412,6 +412,13 @@ void PaulstretchpluginAudioProcessor::updateStretchParametersFromPluginParameter
|
||||
pars.octave.o15 = *getFloatParameter(cpi_octaves15);
|
||||
pars.octave.o2 = *getFloatParameter(cpi_octaves2);
|
||||
|
||||
pars.ratiomix.ratiolevels[0]= *getFloatParameter(cpi_octavesm2);
|
||||
pars.ratiomix.ratiolevels[1] = *getFloatParameter(cpi_octavesm1);
|
||||
pars.ratiomix.ratiolevels[2] = *getFloatParameter(cpi_octaves0);
|
||||
pars.ratiomix.ratiolevels[3] = *getFloatParameter(cpi_octaves1);
|
||||
pars.ratiomix.ratiolevels[4] = *getFloatParameter(cpi_octaves15);
|
||||
pars.ratiomix.ratiolevels[5] = *getFloatParameter(cpi_octaves2);
|
||||
|
||||
pars.filter.low = *getFloatParameter(cpi_filter_low);
|
||||
pars.filter.high = *getFloatParameter(cpi_filter_high);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user