From 7805f1a0aa3213ed24f3f10d365e084ab1dd29f3 Mon Sep 17 00:00:00 2001 From: xenakios Date: Tue, 12 Dec 2017 20:27:29 +0200 Subject: [PATCH] Switch to using Juce CriticalSection in StretchSource. Especially when used with tryEnter, seems to help the audio glitches a lot, even when running under the debugger... --- Source/PS_Source/StretchSource.cpp | 83 +++++++++++++++--------------- Source/PS_Source/StretchSource.h | 2 +- 2 files changed, 43 insertions(+), 42 deletions(-) diff --git a/Source/PS_Source/StretchSource.cpp b/Source/PS_Source/StretchSource.cpp index 80e5854..bc29199 100644 --- a/Source/PS_Source/StretchSource.cpp +++ b/Source/PS_Source/StretchSource.cpp @@ -58,7 +58,7 @@ std::vector StretchAudioSource::getSpectrumProcessOrder() void StretchAudioSource::setSpectrumProcessOrder(std::vector order) { - std::lock_guard locker(m_mutex); + ScopedLock locker(m_cs); m_specproc_order = order; for (int i = 0; i < m_stretchers.size(); ++i) { @@ -88,7 +88,7 @@ ValueTree StretchAudioSource::getStateTree() void StretchAudioSource::setStateTree(ValueTree state) { - std::lock_guard locker(m_mutex); + ScopedLock locker(m_cs); getFromTreeProperties(state, "pitch_shift", m_ppar.pitch_shift.cents, "octaves_minus2", m_ppar.octave.om2, "octaves_minus1", m_ppar.octave.om1, @@ -111,7 +111,7 @@ bool StretchAudioSource::isLoopingEnabled() void StretchAudioSource::setLoopingEnabled(bool b) { - std::lock_guard locker(m_mutex); + ScopedLock locker(m_cs); if (m_inputfile != nullptr) { m_inputfile->setLoopEnabled(b); @@ -120,20 +120,21 @@ void StretchAudioSource::setLoopingEnabled(bool b) void StretchAudioSource::setAudioBufferAsInputSource(AudioBuffer* buf, int sr, int len) { - std::lock_guard locker(m_mutex); + ScopedLock locker(m_cs); m_inputfile->setAudioBuffer(buf, sr, len); m_seekpos = 0.0; - + m_curfile = File(); if (m_playrange.isEmpty()) setPlayRange({ 0.0,1.0 }, true); + ++m_param_change_count; } void StretchAudioSource::setMainVolume(double decibels) { if (decibels == m_main_volume) return; - std::lock_guard locker(m_mutex); + ScopedLock locker(m_cs); m_main_volume = jlimit(-144.0, 12.0, decibels); ++m_param_change_count; } @@ -142,15 +143,14 @@ void StretchAudioSource::setLoopXFadeLength(double lenseconds) { if (lenseconds == m_loopxfadelen) return; - std::lock_guard locker(m_mutex); + ScopedLock locker(m_cs); m_loopxfadelen = jlimit(0.0, 1.0, lenseconds); ++m_param_change_count; } void StretchAudioSource::getNextAudioBlock(const AudioSourceChannelInfo & bufferToFill) { - // for realtime play, this is assumed to be used with BufferingAudioSource, so mutex locking should not be too bad... - std::lock_guard locker(m_mutex); + ScopedLock locker(m_cs); if (m_stretchoutringbuf.available() > 0) m_output_has_begun = true; bool freezing = m_freezing; @@ -356,7 +356,7 @@ bool StretchAudioSource::isLooping() const String StretchAudioSource::setAudioFile(File file) { - std::lock_guard locker(m_mutex); + ScopedLock locker(m_cs); if (m_inputfile->openAudioFile(file)) { m_curfile = file; @@ -378,7 +378,7 @@ void StretchAudioSource::setNumOutChannels(int chans) void StretchAudioSource::initObjects() { - std::lock_guard locker(m_mutex); + ScopedLock locker(m_cs); m_inputfile->setActiveRange(m_playrange); m_inputfile->seek(m_seekpos); @@ -448,33 +448,31 @@ void StretchAudioSource::setRate(double rate) { if (rate == m_playrate) return; - std::lock_guard locker(m_mutex); - //if (rate != m_lastplayrate) + if (m_cs.tryEnter()) { - //m_output_counter = m_output_counter*rate; - //m_output_length = (2*m_process_fftsize)+m_inputfile->getActiveRangeFrames().getLength()*rate; - //Logger::writeToLog("new len " + String(m_output_length) + " new output pos " + String(m_output_counter)); m_playrate = rate; for (int i = 0; i < m_stretchers.size(); ++i) { m_stretchers[i]->set_rap((float)rate); } + ++m_param_change_count; } - ++m_param_change_count; } void StretchAudioSource::setProcessParameters(ProcessParameters * pars) { if (*pars == m_ppar) return; - //SpinLock::ScopedLockType - std::lock_guard locker(m_mutex); - m_ppar = *pars; - for (int i = 0; i < m_stretchers.size(); ++i) + if (m_cs.tryEnter()) { - m_stretchers[i]->set_parameters(pars); + m_ppar = *pars; + for (int i = 0; i < m_stretchers.size(); ++i) + { + m_stretchers[i]->set_parameters(pars); + } + ++m_param_change_count; + m_cs.exit(); } - ++m_param_change_count; } const ProcessParameters& StretchAudioSource::getProcessParameters() @@ -486,7 +484,7 @@ void StretchAudioSource::setFFTWindowingType(int windowtype) { if (windowtype==m_fft_window_type) return; - std::lock_guard locker(m_mutex); + ScopedLock locker(m_cs); m_fft_window_type = windowtype; for (int i = 0; i < m_stretchers.size(); ++i) { @@ -499,7 +497,7 @@ void StretchAudioSource::setFFTSize(int size) jassert(size>0); if (m_xfadetask.state == 0 && (m_process_fftsize == 0 || size != m_process_fftsize)) { - std::lock_guard locker(m_mutex); + ScopedLock locker(m_cs); if (m_xfadetask.buffer.getNumChannels() < m_num_outchans) { m_xfadetask.buffer.setSize(m_num_outchans, m_xfadetask.buffer.getNumSamples()); @@ -524,10 +522,10 @@ void StretchAudioSource::setFFTSize(int size) void StretchAudioSource::seekPercent(double pos) { - std::lock_guard locker(m_mutex); + ScopedLock locker(m_cs); m_seekpos = pos; m_inputfile->seek(pos); - + ++m_param_change_count; } double StretchAudioSource::getOutputDurationSecondsForRange(Range range, int fftsize) @@ -540,31 +538,34 @@ double StretchAudioSource::getOutputDurationSecondsForRange(Range range, void StretchAudioSource::setOnsetDetection(double x) { - std::lock_guard locker(m_mutex); + ScopedLock locker(m_cs); m_onsetdetection = x; for (int i = 0; i < m_stretchers.size(); ++i) { m_stretchers[i]->set_onset_detection_sensitivity((float)x); } + ++m_param_change_count; } void StretchAudioSource::setPlayRange(Range playrange, bool isloop) { if (m_playrange.isEmpty() == false && playrange == m_playrange) return; - std::lock_guard locker(m_mutex); - if (playrange.isEmpty()) - m_playrange = { 0.0,1.0 }; - else - m_playrange = playrange; - m_stream_end_reached = false; - m_inputfile->setActiveRange(m_playrange); - m_inputfile->setLoopEnabled(isloop); - if (m_playrange.contains(m_seekpos)==false) - m_inputfile->seek(m_playrange.getStart()); - m_seekpos = m_playrange.getStart(); - ++m_param_change_count; - + if (m_cs.tryEnter()) + { + if (playrange.isEmpty()) + m_playrange = { 0.0,1.0 }; + else + m_playrange = playrange; + m_stream_end_reached = false; + m_inputfile->setActiveRange(m_playrange); + m_inputfile->setLoopEnabled(isloop); + if (m_playrange.contains(m_seekpos) == false) + m_inputfile->seek(m_playrange.getStart()); + m_seekpos = m_playrange.getStart(); + ++m_param_change_count; + m_cs.exit(); + } } bool StretchAudioSource::isLoopEnabled() diff --git a/Source/PS_Source/StretchSource.h b/Source/PS_Source/StretchSource.h index 6112632..3ffc413 100644 --- a/Source/PS_Source/StretchSource.h +++ b/Source/PS_Source/StretchSource.h @@ -128,7 +128,7 @@ private: int64_t m_maxloops = 0; std::unique_ptr m_resampler; std::vector m_resampler_outbuf; - std::recursive_mutex m_mutex; + CriticalSection m_cs; std::vector m_specproc_order; bool m_stop_play_requested = false; double m_freeze_pos = 0.0;