24 Q_PROPERTY (
int sampleRate READ sampleRate NOTIFY sampleRateChanged)
29 enum class State : std::uint8_t
57 const dsp::TempoMap &tempo_map,
58 QObject * parent =
nullptr);
69 Q_INVOKABLE
int xRunCount ()
const {
return load_measurer_.getXRunCount (); }
70 Q_INVOKABLE
double loadPercentage ()
const
72 return load_measurer_.getLoadAsPercentage ();
75 int sampleRate ()
const {
return get_sample_rate ().in (units::sample_rate); }
77 Q_SIGNAL
void sampleRateChanged (
int sampleRate);
90 Q_INVOKABLE
void activate ();
91 Q_INVOKABLE
void deactivate ();
105 units::sample_u32_t nframes,
107 [[clang::nonblocking]];
109 enum class ProcessReturnStatus : std::uint8_t
126 units::sample_u32_t total_frames_to_process)
noexcept [[clang::nonblocking]]
127 -> ProcessReturnStatus;
139 units::sample_u32_t roll_nframes,
140 units::sample_u32_t nframes)
noexcept [[clang::nonblocking]];
142 auto &get_monitor_out_port () {
return monitor_out_; }
144 auto * midi_panic_processor ()
const {
return midi_panic_processor_.get (); }
151 bool activated ()
const {
return state_ == State::Active; }
152 bool running ()
const {
return run_.load (); }
153 void set_running (
bool run) { run_.store (run); }
154 auto &graph_dispatcher () {
return graph_dispatcher_; }
156 bool exporting ()
const {
return exporting_; }
157 void set_exporting (
bool exporting) { exporting_.store (exporting); }
159 auto get_processing_lock () [[clang::blocking]]
161 return SemaphoreRAII (process_lock_,
true);
164 units::sample_u32_t get_block_length ()
const
166 return hw_interface_.get_block_length ();
169 units::sample_rate_t get_sample_rate ()
const
171 return hw_interface_.get_sample_rate ();
182 const std::function<
void ()> &func,
183 bool recalculate_graph);
191 void activate_impl (
bool activate);
194 dsp::PortRegistry port_registry_;
200 const dsp::TempoMap &tempo_map_;
212 std::atomic_uint64_t cycle_{ 0 };
234 std::unique_ptr<dsp::MidiPort> midi_in_;
239 moodycamel::LightweightSemaphore process_lock_{ 1 };
242 std::atomic_bool run_{
false };
245 std::atomic_bool exporting_{
false };
247 juce::AudioProcessLoadMeasurer load_measurer_;
253 units::sample_u32_t remaining_latency_preroll_;
256 std::atomic_bool capture_cc_{
false };
259 std::array<midi_byte_t, 3> last_cc_captured_{};
261 std::atomic<State> state_{ State::Uninitialized };
262 static_assert (
decltype (state_)::is_always_lock_free);
264 utils::QObjectUniquePtr<dsp::MidiPanicProcessor> midi_panic_processor_;
266 std::unique_ptr<AudioCallback> audio_callback_;
272 bool callback_running_{};
void advance_playhead_after_processing(dsp::Transport::TransportSnapshot &transport_snapshot, const dsp::PlayheadProcessingGuard &playhead_guard, units::sample_u32_t roll_nframes, units::sample_u32_t nframes) noexcept
Advances the playhead if transport is rolling.
bool process_prepare(dsp::Transport::TransportSnapshot &transport_snapshot, units::sample_u32_t nframes, SemaphoreRAII< moodycamel::LightweightSemaphore > &sem) noexcept
To be called by each implementation to prepare the structures before processing.
AudioEngine(dsp::Transport &transport, IHardwareAudioInterface &hw_interface, dsp::DspGraphDispatcher &graph_dispatcher, const dsp::TempoMap &tempo_map, QObject *parent=nullptr)
Create a new audio engine.