From 195a630060cd4c50fb623469e65b6b175657a0b9 Mon Sep 17 00:00:00 2001 From: xenakios Date: Tue, 27 Feb 2018 15:02:34 +0200 Subject: [PATCH] Implemented free filter processing. Note that the envelope manipulation from the GUI is not handled thread safely yet --- Source/PS_Source/ProcessedStretch.cpp | 8 ++++++++ Source/PS_Source/ProcessedStretch.h | 23 ++++++++++++++++++++++- Source/PS_Source/StretchSource.cpp | 11 +++++++++++ Source/PS_Source/StretchSource.h | 3 +++ Source/PluginEditor.cpp | 14 +++++++++++--- Source/PluginProcessor.cpp | 6 ++++-- Source/PluginProcessor.h | 2 +- Source/jcdp_envelope.h | 2 ++ 8 files changed, 62 insertions(+), 7 deletions(-) diff --git a/Source/PS_Source/ProcessedStretch.cpp b/Source/PS_Source/ProcessedStretch.cpp index b7dbdd5..9650410 100644 --- a/Source/PS_Source/ProcessedStretch.cpp +++ b/Source/PS_Source/ProcessedStretch.cpp @@ -39,6 +39,12 @@ void ProcessedStretch::set_parameters(ProcessParameters *ppar) pars=*ppar; //update_free_filter(); } + +void ProcessedStretch::setFreeFilterEnvelope(shared_envelope env) +{ + m_free_filter_envelope = env; +} + void ProcessedStretch::setBufferSize(int sz) { jassert(sz > 0); @@ -125,6 +131,8 @@ void ProcessedStretch::process_spectrum(REALTYPE *freq) spectrum_do_filter(pars,nfreq,samplerate,infreq.data(), freq); if (e.m_index == 7 && e.m_enabled == true) spectrum_do_compressor(pars,nfreq, infreq.data(), freq); + if (e.m_index == 8 && e.m_enabled == true) + spectrum_do_free_filter(m_free_filter_envelope, nfreq, samplerate, infreq.data(), freq); } #ifdef USE_OLD_SPEC_PROC diff --git a/Source/PS_Source/ProcessedStretch.h b/Source/PS_Source/ProcessedStretch.h index 24772fa..7be7563 100644 --- a/Source/PS_Source/ProcessedStretch.h +++ b/Source/PS_Source/ProcessedStretch.h @@ -21,6 +21,7 @@ #include "FreeEdit.h" #include "Stretch.h" +#include "../jcdp_envelope.h" struct ProcessParameters { @@ -413,6 +414,25 @@ inline void spectrum_do_filter(const ProcessParameters& pars, int nfreq, double }; }; +inline void spectrum_do_free_filter(shared_envelope& env, int nfreq, double samplerate, + REALTYPE *freq1, REALTYPE *freq2) +{ + jassert(env != nullptr); + for (int i = 0; i= 30.0) + { + double norm = jmap(binhz, 0.0, samplerate / 2.0, 0.0, 1.0); + double db = jmap(env->GetInterpolatedNodeValue(pow(norm, 0.25)), 0.0, 1.0, -36.0, 12.0); + freq2[i] = freq1[i] * Decibels::decibelsToGain(db); + } + else + freq2[i] = freq1[i]; + }; +}; + + class SpectrumProcess { public: @@ -430,13 +450,14 @@ public: ProcessedStretch(REALTYPE rap_,int in_bufsize_,FFTWindow w=W_HAMMING,bool bypass_=false,REALTYPE samplerate_=44100.0f,int stereo_mode=0); ~ProcessedStretch(); void set_parameters(ProcessParameters *ppar); + void setFreeFilterEnvelope(shared_envelope env); std::vector m_spectrum_processes; void setBufferSize(int sz) override; private: REALTYPE get_stretch_multiplier(REALTYPE pos_percents) override; // void process_output(REALTYPE *smps,int nsmps); void process_spectrum(REALTYPE *freq) override; - + shared_envelope m_free_filter_envelope; //void copy(const realvector& freq1,realvector& freq2); void copy(REALTYPE* freq1, REALTYPE* freq2); diff --git a/Source/PS_Source/StretchSource.cpp b/Source/PS_Source/StretchSource.cpp index 3027914..e6e6c50 100644 --- a/Source/PS_Source/StretchSource.cpp +++ b/Source/PS_Source/StretchSource.cpp @@ -80,6 +80,16 @@ std::pair, Range> StretchAudioSource::getFileCachedRangesN return m_inputfile->getCachedRangesNormalized(); } +void StretchAudioSource::setFreeFilterEnvelope(shared_envelope env) +{ + ScopedLock locker(m_cs); + m_free_filter_envelope = env; + for (int i = 0; i < m_stretchers.size(); ++i) + { + m_stretchers[i]->setFreeFilterEnvelope(env); + } +} + ValueTree StretchAudioSource::getStateTree() { ValueTree tree("stretchsourcestate"); @@ -456,6 +466,7 @@ void StretchAudioSource::initObjects() m_stretchers[i]->set_onset_detection_sensitivity(onsetsens); m_stretchers[i]->set_parameters(&m_ppar); m_stretchers[i]->set_freezing(m_freezing); + m_stretchers[i]->setFreeFilterEnvelope(m_free_filter_envelope); fill_container(m_stretchers[i]->out_buf, 0.0f); m_stretchers[i]->m_spectrum_processes = m_specproc_order; } diff --git a/Source/PS_Source/StretchSource.h b/Source/PS_Source/StretchSource.h index d16bfe2..77c9809 100644 --- a/Source/PS_Source/StretchSource.h +++ b/Source/PS_Source/StretchSource.h @@ -88,6 +88,8 @@ public: int getFFTWindowingType() { return m_fft_window_type; } std::pair,Range> getFileCachedRangesNormalized(); + void setFreeFilterEnvelope(shared_envelope env); + ValueTree getStateTree(); void setStateTree(ValueTree state); void setClippingEnabled(bool b) { m_clip_output = b; } @@ -144,6 +146,7 @@ private: int64_t m_output_length = 0; bool m_clip_output = true; void initObjects(); + shared_envelope m_free_filter_envelope; AudioFormatManager* m_afm = nullptr; struct { diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index d4dc143..1f479a7 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -34,7 +34,15 @@ PaulstretchpluginAudioProcessorEditor::PaulstretchpluginAudioProcessorEditor(Pau { //addAndMakeVisible(&m_free_filter_component); m_free_filter_component.set_envelope(processor.m_free_filter_envelope); - m_wavefilter_tab.setTabBarDepth(17); + m_free_filter_component.TimeFromNormalized = [this](double x) + { + return jmap(pow(x, 4.0), 0.0, 1.0, 30.0, processor.getSampleRateChecked()/2.0); + }; + m_free_filter_component.ValueFromNormalized = [this](double x) + { + return jmap(x, 0.0, 1.0, -36.0, 12.0); + }; + m_wavefilter_tab.setTabBarDepth(20); addAndMakeVisible(&m_perfmeter); @@ -822,9 +830,9 @@ void SpectralChainEditor::paint(Graphics & g) for (int i = 0; i < m_order.size(); ++i) { //if (i!=m_cur_index) - drawBox(g, i, i*box_w, 0, box_w - 30, box_h); + drawBox(g, i, i*box_w, 0, box_w - 20, box_h); if (i(i*box_w + (box_w - 30), box_h / 2, i*box_w + box_w, box_h / 2), 2.0f, 15.0f, 15.0f); + g.drawArrow(juce::Line(i*box_w + (box_w - 20), box_h / 2, i*box_w + box_w, box_h / 2), 2.0f, 12.0f, 12.0f); } if (m_drag_x>=0 && m_drag_x=0) drawBox(g, m_cur_index, m_drag_x, 0, box_w - 30, box_h); diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index 65459df..5f53501 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -82,7 +82,9 @@ PaulstretchpluginAudioProcessor::PaulstretchpluginAudioProcessor() m_playposinfo.timeInSeconds = 0.0; m_free_filter_envelope = std::make_shared(); - + m_free_filter_envelope->AddNode({ 0.0,0.5 }); + m_free_filter_envelope->AddNode({ 1.0,0.5 }); + m_recbuffer.setSize(2, 44100); m_recbuffer.clear(); if (m_afm->getNumKnownFormats()==0) @@ -364,7 +366,7 @@ void PaulstretchpluginAudioProcessor::setFFTSize(double size) void PaulstretchpluginAudioProcessor::startplay(Range playrange, int numoutchans, int maxBlockSize, String& err) { m_stretch_source->setPlayRange(playrange, true); - + m_stretch_source->setFreeFilterEnvelope(m_free_filter_envelope); int bufamt = m_bufamounts[m_prebuffer_amount]; if (m_buffering_source != nullptr && numoutchans != m_buffering_source->getNumberOfChannels()) diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h index e533d1d..4814335 100644 --- a/Source/PluginProcessor.h +++ b/Source/PluginProcessor.h @@ -170,7 +170,7 @@ public: bool m_show_technical_info = false; Range m_wave_view_range; int m_prepare_count = 0; - std::shared_ptr m_free_filter_envelope; + shared_envelope m_free_filter_envelope; private: diff --git a/Source/jcdp_envelope.h b/Source/jcdp_envelope.h index e131b5f..6a7364d 100644 --- a/Source/jcdp_envelope.h +++ b/Source/jcdp_envelope.h @@ -576,6 +576,7 @@ private: nodes_t m_old_nodes; nodes_t m_repeater_nodes; grid_t m_value_grid; + JUCE_LEAK_DETECTOR(breakpoint_envelope) }; template @@ -586,5 +587,6 @@ inline double derivative(const F& f, double x, const Args&... func_args) return (f(x + epsilon, func_args...) - f(x, func_args...)) / epsilon; } +using shared_envelope = std::shared_ptr; #endif // JCDP_ENVELOPE_H