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:
xenakios 2018-04-03 16:34:20 +03:00
parent 3729c4ec28
commit 941ebf31a5
6 changed files with 155 additions and 6 deletions

View File

@ -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)

View File

@ -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

View File

@ -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)
{

View File

@ -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);
}
}

View File

@ -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)
};

View File

@ -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);