| @@ -38,8 +38,7 @@ FFT::FFT(int nsamples_, bool no_inverse) | |||||
| window.data[i]=0.707f; | window.data[i]=0.707f; | ||||
| window.type=W_RECTANGULAR; | window.type=W_RECTANGULAR; | ||||
| phases.resize(nsamples); | |||||
| data.resize(nsamples,true); | |||||
| data.resize(nsamples,true); | |||||
| bool allow_long_planning = false; // g_propsfile->getBoolValue("fftw_allow_long_planning", false); | bool allow_long_planning = false; // g_propsfile->getBoolValue("fftw_allow_long_planning", false); | ||||
| //double t0 = Time::getMillisecondCounterHiRes(); | //double t0 = Time::getMillisecondCounterHiRes(); | ||||
| if (allow_long_planning) | if (allow_long_planning) | ||||
| @@ -92,15 +91,9 @@ void FFT::smp2freq() | |||||
| void FFT::freq2smp() | void FFT::freq2smp() | ||||
| { | { | ||||
| REALTYPE inv_2p15_2pi=1.0f/16384.0f*(float)c_PI; | REALTYPE inv_2p15_2pi=1.0f/16384.0f*(float)c_PI; | ||||
| if (m_phaserefreshcounter % m_phaserefreshrate == 0) | |||||
| { | |||||
| updatePhases(); | |||||
| //Logger::writeToLog("phases updated "+String(m_phaserefreshrate)); | |||||
| } | |||||
| ++m_phaserefreshcounter; | |||||
| for (int i=1;i<nsamples/2;i++) | for (int i=1;i<nsamples/2;i++) | ||||
| { | { | ||||
| unsigned int rand = phases[i]; // m_randdist(m_randgen); | |||||
| unsigned int rand = m_randdist(m_randgen); | |||||
| REALTYPE phase=rand*inv_2p15_2pi; | REALTYPE phase=rand*inv_2p15_2pi; | ||||
| data[i]=freq[i]*cos(phase); | data[i]=freq[i]*cos(phase); | ||||
| data[nsamples-i]=freq[i]*sin(phase); | data[nsamples-i]=freq[i]*sin(phase); | ||||
| @@ -139,23 +132,6 @@ void FFT::applywindow(FFTWindow type) | |||||
| for (int i=0;i<nsamples;i++) smp[i]*=window.data[i]; | for (int i=0;i<nsamples;i++) smp[i]*=window.data[i]; | ||||
| } | } | ||||
| void FFT::setPhaseRefreshRate(int rate) | |||||
| { | |||||
| m_phaserefreshrate = rate; | |||||
| } | |||||
| void FFT::updatePhases() | |||||
| { | |||||
| for (int i = 1; i < nsamples / 2; i++) | |||||
| { | |||||
| phases[i] = m_randdist(m_randgen); | |||||
| } | |||||
| } | |||||
| /*******************************************/ | |||||
| Stretch::Stretch(REALTYPE rap_,int /*bufsize_*/,FFTWindow w,bool bypass_,REALTYPE samplerate_,int /*stereo_mode_*/) | Stretch::Stretch(REALTYPE rap_,int /*bufsize_*/,FFTWindow w,bool bypass_,REALTYPE samplerate_,int /*stereo_mode_*/) | ||||
| { | { | ||||
| freezing=false; | freezing=false; | ||||
| @@ -381,12 +357,6 @@ void Stretch::here_is_onset(REALTYPE onset){ | |||||
| }; | }; | ||||
| }; | }; | ||||
| void Stretch::setPhaseRefreshRate(int rate) | |||||
| { | |||||
| jassert(fft != nullptr); | |||||
| fft->setPhaseRefreshRate(rate); | |||||
| } | |||||
| int Stretch::get_nsamples(REALTYPE current_pos_percents){ | int Stretch::get_nsamples(REALTYPE current_pos_percents){ | ||||
| if (bypass) return bufsize; | if (bypass) return bufsize; | ||||
| if (freezing) return 0; | if (freezing) return 0; | ||||
| @@ -124,19 +124,17 @@ class FFT | |||||
| void applywindow(FFTWindow type); | void applywindow(FFTWindow type); | ||||
| std::vector<REALTYPE> smp;//size of samples/2 | std::vector<REALTYPE> smp;//size of samples/2 | ||||
| std::vector<REALTYPE> freq;//size of samples | std::vector<REALTYPE> freq;//size of samples | ||||
| std::vector<unsigned int> phases; | |||||
| int nsamples=0; | int nsamples=0; | ||||
| void setPhaseRefreshRate(int rate); | |||||
| private: | private: | ||||
| fftwf_plan planfftw,planifftw; | fftwf_plan planfftw,planifftw; | ||||
| FFTWBuffer<REALTYPE> data; | FFTWBuffer<REALTYPE> data; | ||||
| int m_phaserefreshcounter = 0; | |||||
| int m_phaserefreshrate = 1; | |||||
| void updatePhases(); | |||||
| struct{ | struct{ | ||||
| std::vector<REALTYPE> data; | std::vector<REALTYPE> data; | ||||
| FFTWindow type; | FFTWindow type; | ||||
| @@ -171,7 +169,7 @@ class Stretch | |||||
| freezing=new_freezing; | freezing=new_freezing; | ||||
| }; | }; | ||||
| bool isFreezing() { return freezing; } | bool isFreezing() { return freezing; } | ||||
| void setPhaseRefreshRate(int rate); | |||||
| std::vector<REALTYPE> out_buf;//pot sa pun o variabila "max_out_bufsize" si asta sa fie marimea lui out_buf si pe out_bufsize sa il folosesc ca marime adaptiva | std::vector<REALTYPE> out_buf;//pot sa pun o variabila "max_out_bufsize" si asta sa fie marimea lui out_buf si pe out_bufsize sa il folosesc ca marime adaptiva | ||||
| int get_nsamples(REALTYPE current_pos_percents);//how many samples are required | int get_nsamples(REALTYPE current_pos_percents);//how many samples are required | ||||
| @@ -277,23 +277,6 @@ void StretchAudioSource::setSpectralOrderPreset(int id) | |||||
| } | } | ||||
| } | } | ||||
| void StretchAudioSource::setPhaseRefreshRate(int rate) | |||||
| { | |||||
| for (auto& e : m_stretchers) | |||||
| e->setPhaseRefreshRate(rate); | |||||
| return; | |||||
| if (rate == m_phase_refresh_rate) | |||||
| return; | |||||
| if (m_cs.tryEnter()) | |||||
| { | |||||
| for (auto& e : m_stretchers) | |||||
| e->setPhaseRefreshRate(rate); | |||||
| m_phase_refresh_rate = rate; | |||||
| ++m_param_change_count; | |||||
| m_cs.exit(); | |||||
| } | |||||
| } | |||||
| void StretchAudioSource::getNextAudioBlock(const AudioSourceChannelInfo & bufferToFill) | void StretchAudioSource::getNextAudioBlock(const AudioSourceChannelInfo & bufferToFill) | ||||
| { | { | ||||
| ScopedLock locker(m_cs); | ScopedLock locker(m_cs); | ||||
| @@ -114,8 +114,7 @@ public: | |||||
| int64_t getLastSourcePosition() const { return m_last_filepos; } | int64_t getLastSourcePosition() const { return m_last_filepos; } | ||||
| int m_prebuffersize = 0; | int m_prebuffersize = 0; | ||||
| void setSpectralOrderPreset(int id); | void setSpectralOrderPreset(int id); | ||||
| int getPhaseRefreshRate() const { return m_phase_refresh_rate; } | |||||
| void setPhaseRefreshRate(int rate); | |||||
| private: | private: | ||||
| CircularBuffer<float> m_stretchoutringbuf{ 1024 * 1024 }; | CircularBuffer<float> m_stretchoutringbuf{ 1024 * 1024 }; | ||||
| AudioBuffer<float> m_file_inbuf; | AudioBuffer<float> m_file_inbuf; | ||||
| @@ -144,7 +143,7 @@ private: | |||||
| int m_pause_state = 0; | int m_pause_state = 0; | ||||
| Range<double> m_playrange{ 0.0,1.0 }; | Range<double> m_playrange{ 0.0,1.0 }; | ||||
| int64_t m_rand_count = 0; | int64_t m_rand_count = 0; | ||||
| int m_phase_refresh_rate = 1; | |||||
| bool m_stream_end_reached = false; | bool m_stream_end_reached = false; | ||||
| int64_t m_output_silence_counter = 0; | int64_t m_output_silence_counter = 0; | ||||
| File m_curfile; | File m_curfile; | ||||
| @@ -184,7 +184,7 @@ PaulstretchpluginAudioProcessor::PaulstretchpluginAudioProcessor() | |||||
| addParameter(new AudioParameterFloat("dryplayrate0", "Dry playrate", | addParameter(new AudioParameterFloat("dryplayrate0", "Dry playrate", | ||||
| NormalisableRange<float>(0.1f, 8.0f, | NormalisableRange<float>(0.1f, 8.0f, | ||||
| dprate_convertFrom0To1Func, dprate_convertTo0To1Func), 1.0f)); // 62 | dprate_convertFrom0To1Func, dprate_convertTo0To1Func), 1.0f)); // 62 | ||||
| addParameter(new AudioParameterInt("phaserefreshrate0", "Phase randomization rate", 1, 32, 32)); // 63 | |||||
| auto& pars = getParameters(); | auto& pars = getParameters(); | ||||
| for (const auto& p : pars) | for (const auto& p : pars) | ||||
| m_reset_pars.push_back(p->getValue()); | m_reset_pars.push_back(p->getValue()); | ||||
| @@ -745,7 +745,7 @@ void PaulstretchpluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, M | |||||
| m_free_filter_envelope->m_transform_y_random_rate = *getIntParameter(cpi_freefilter_randomy_rate); | m_free_filter_envelope->m_transform_y_random_rate = *getIntParameter(cpi_freefilter_randomy_rate); | ||||
| m_free_filter_envelope->m_transform_y_random_amount = *getFloatParameter(cpi_freefilter_randomy_amount); | m_free_filter_envelope->m_transform_y_random_amount = *getFloatParameter(cpi_freefilter_randomy_amount); | ||||
| m_stretch_source->setPhaseRefreshRate(*getIntParameter(cpi_phase_refresh_rate)); | |||||
| //m_stretch_source->setSpectralModulesEnabled(m_sm_enab_pars); | //m_stretch_source->setSpectralModulesEnabled(m_sm_enab_pars); | ||||
| @@ -88,7 +88,6 @@ const int cpi_octaves_ratio7 = 59; | |||||
| const int cpi_looping_enabled = 60; | const int cpi_looping_enabled = 60; | ||||
| const int cpi_rewind = 61; | const int cpi_rewind = 61; | ||||
| const int cpi_dryplayrate = 62; | const int cpi_dryplayrate = 62; | ||||
| const int cpi_phase_refresh_rate = 63; | |||||
| class MyThreadPool : public ThreadPool | class MyThreadPool : public ThreadPool | ||||
| { | { | ||||
| @@ -7,13 +7,12 @@ Copyright (C) 2017-2018 Xenakios | |||||
| Released under GNU General Public License v.3 license. | Released under GNU General Public License v.3 license. | ||||
| History : | History : | ||||
| 08-01-2019 1.3.0 | |||||
| 01-17-2019 1.3.0 | |||||
| -Captured audio buffers can optionally be saved as files on disk for later recall. | -Captured audio buffers can optionally be saved as files on disk for later recall. | ||||
| -Added varispeed (resampling speed change) feature when spectral stretch engine is bypassed | -Added varispeed (resampling speed change) feature when spectral stretch engine is bypassed | ||||
| -Added shortcut key (may not work properly in all plugin formats and hosts) : | -Added shortcut key (may not work properly in all plugin formats and hosts) : | ||||
| "I" to open file import dialog | "I" to open file import dialog | ||||
| -Attempt to prevent capture enabled state from being recalled when undoing in the host | -Attempt to prevent capture enabled state from being recalled when undoing in the host | ||||
| -Added VST3 version | |||||
| 07-09-2018 1.2.2 | 07-09-2018 1.2.2 | ||||
| -Add option to mute audio when capturing audio | -Add option to mute audio when capturing audio | ||||
| -Automatically adjust play range after capturing to captured length | -Automatically adjust play range after capturing to captured length | ||||