diff --git a/zones_convolver/ConvolutionEngine.cpp b/zones_convolver/ConvolutionEngine.cpp index 235a4ee..062b94d 100644 --- a/zones_convolver/ConvolutionEngine.cpp +++ b/zones_convolver/ConvolutionEngine.cpp @@ -1,15 +1,21 @@ #include "ConvolutionEngine.h" +#include + namespace zones { LoadIRJob::LoadIRJob (juce::dsp::AudioBlock ir_block, const juce::dsp::ProcessSpec & spec, const Convolver::ConvolverSpec & convolver_spec, - ConvolutionCommandQueue::VisitorQueue & command_queue) + ConvolutionCommandQueue::VisitorQueue & command_queue, + std::mutex & load_mutex, + std::function on_loading_complete) : ThreadPoolJob ("load_ir_job") , spec_ (spec) , convolver_spec_ (convolver_spec) , command_queue_ (command_queue) + , load_mutex_ (load_mutex) + , on_loading_complete_ (on_loading_complete) { ir_buffer_.setSize (static_cast (ir_block.getNumChannels ()), static_cast (ir_block.getNumSamples ())); @@ -22,8 +28,13 @@ juce::ThreadPoolJob::JobStatus LoadIRJob::runJob () ConvolutionCommandQueue::Commands command = ConvolutionCommandQueue::EngineReadyCommand {.convolver = std::move (convolver)}; + std::lock_guard guard {load_mutex_}; + if (! shouldExit ()) + { command_queue_.PushCommand (command); + on_loading_complete_ (); + } return jobHasFinished; } @@ -109,11 +120,34 @@ void ConvolutionEngine::reset () void ConvolutionEngine::LoadIR (juce::dsp::AudioBlock ir_block, const Convolver::ConvolverSpec & convolver_spec) { + std::lock_guard guard ( + load_mutex_); // Obtained to guarantee load order - probably not the best way to do this... + thread_pool_.removeAllJobs (true, 0); if (spec_ != std::nullopt) - thread_pool_.addJob (new LoadIRJob (ir_block, *spec_, convolver_spec, command_queue_), + { + is_loading_ = true; + if (OnLoadingUpdated) + OnLoadingUpdated (); + + thread_pool_.addJob (new LoadIRJob (ir_block, + *spec_, + convolver_spec, + command_queue_, + load_mutex_, + [&] + { + is_loading_ = false; + juce::MessageManager::callAsync ( + [&] + { + if (OnLoadingUpdated) + OnLoadingUpdated (); + }); + }), true); + } } void ConvolutionEngine::Clear () diff --git a/zones_convolver/ConvolutionEngine.h b/zones_convolver/ConvolutionEngine.h index a624605..04d8b74 100644 --- a/zones_convolver/ConvolutionEngine.h +++ b/zones_convolver/ConvolutionEngine.h @@ -95,7 +95,9 @@ class LoadIRJob : public juce::ThreadPoolJob explicit LoadIRJob (juce::dsp::AudioBlock ir_block, const juce::dsp::ProcessSpec & spec, const Convolver::ConvolverSpec & convolver_spec, - ConvolutionCommandQueue::VisitorQueue & command_queue); + ConvolutionCommandQueue::VisitorQueue & command_queue, + std::mutex & load_mutex, + std::function on_loading_complete); ~LoadIRJob () override = default; JobStatus runJob () override; @@ -104,6 +106,8 @@ class LoadIRJob : public juce::ThreadPoolJob juce::dsp::ProcessSpec spec_; Convolver::ConvolverSpec convolver_spec_; ConvolutionCommandQueue::VisitorQueue & command_queue_; + std::mutex & load_mutex_; + std::function on_loading_complete_; }; class ConvolutionEngine @@ -130,6 +134,9 @@ class ConvolutionEngine void process (const juce::dsp::ProcessContextReplacing & replacing) override; void reset () override; + [[nodiscard]] bool IsLoading () const; + std::function OnLoadingUpdated; + private: std::unique_ptr convolver_; std::unique_ptr pending_convolver_; @@ -140,5 +147,8 @@ class ConvolutionEngine juce::ThreadPool & thread_pool_; ConvolutionCommandQueue::VisitorQueue command_queue_; ConvolutionNotificationQueue::VisitorQueue notification_queue_; + + std::mutex load_mutex_; + bool is_loading_ = false; }; } \ No newline at end of file