diff --git a/Source/PS_Source/ProcessedStretch.cpp b/Source/PS_Source/ProcessedStretch.cpp index 5377b75..3307cd8 100644 --- a/Source/PS_Source/ProcessedStretch.cpp +++ b/Source/PS_Source/ProcessedStretch.cpp @@ -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) diff --git a/Source/PS_Source/ProcessedStretch.h b/Source/PS_Source/ProcessedStretch.h index 8241f0c..653bcbe 100644 --- a/Source/PS_Source/ProcessedStretch.h +++ b/Source/PS_Source/ProcessedStretch.h @@ -20,6 +20,7 @@ #pragma once #include "Stretch.h" +#include #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 ratios; + std::array 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& sumfreq, + std::vector& 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; using float2dvector = std::vector>; using float3dvector = std::vector>>; +template +using uptrvec = std::vector>; + +template +using sptrvec = std::vector>; + template inline std::unique_ptr unique_from_raw(T* ptr) { diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index 9d0714f..23b0776 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -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::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(); + 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); + } +} diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h index 6e04b41..866b629 100644 --- a/Source/PluginEditor.h +++ b/Source/PluginEditor.h @@ -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 OnRatioChanged; + std::function OnRatioLevelChanged; + std::function GetParameterValue; + void timerCallback() override; +private: + uptrvec m_ratio_sliders; + uptrvec 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> m_parcomps; + uptrvec 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) }; diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index 6651002..eb1e585 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -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);