8#include "dsp/audio_callback.h"
9#include "dsp/audio_input_processor.h"
10#include "dsp/audio_port.h"
11#include "dsp/graph_dispatcher.h"
12#include "dsp/hardware_audio_interface.h"
13#include "dsp/midi_panic_processor.h"
14#include "dsp/midi_port.h"
15#include "dsp/transport.h"
16#include "utils/concurrency.h"
27 Q_PROPERTY (
int sampleRate READ sampleRate NOTIFY sampleRateChanged)
28 Q_PROPERTY (
int blockLength READ blockLength NOTIFY blockLengthChanged)
33 enum class State : std::uint8_t
61 const dsp::TempoMap &tempo_map,
62 QObject * parent =
nullptr);
73 Q_INVOKABLE
int xRunCount ()
const {
return load_measurer_.getXRunCount (); }
74 Q_INVOKABLE
double loadPercentage ()
const
76 return load_measurer_.getLoadAsPercentage ();
88 Q_SIGNAL
void sampleRateChanged (
int sampleRate);
89 Q_SIGNAL
void blockLengthChanged (
int blockLength);
141 units::sample_u32_t nframes,
143 [[clang::nonblocking]];
145 enum class ProcessReturnStatus : std::uint8_t
162 units::sample_u32_t total_frames_to_process)
noexcept [[clang::nonblocking]]
163 -> ProcessReturnStatus;
175 units::sample_u32_t roll_nframes,
176 units::sample_u32_t nframes)
noexcept [[clang::nonblocking]];
178 auto &get_monitor_out_port () {
return monitor_out_; }
180 auto * midi_panic_processor ()
const {
return midi_panic_processor_.get (); }
188 return audio_input_processor_.get ();
196 bool activated ()
const {
return state_ == State::Active; }
197 bool running ()
const {
return run_.load (); }
198 void set_running (
bool run) { run_.store (run); }
199 auto &graph_dispatcher () {
return graph_dispatcher_; }
201 bool exporting ()
const {
return exporting_; }
202 void set_exporting (
bool exporting) { exporting_.store (exporting); }
204 auto get_processing_lock () [[clang::blocking]]
206 return SemaphoreRAII (process_lock_,
true);
217 const std::function<
void ()> &func,
218 bool recalculate_graph);
229 dsp::PortRegistry port_registry_;
235 const dsp::TempoMap &tempo_map_;
247 std::atomic_uint64_t cycle_{ 0 };
269 std::unique_ptr<dsp::MidiPort> midi_in_;
274 moodycamel::LightweightSemaphore process_lock_{ 1 };
277 std::atomic_bool run_{
false };
280 std::atomic_bool exporting_{
false };
282 juce::AudioProcessLoadMeasurer load_measurer_;
288 units::sample_u32_t remaining_latency_preroll_;
291 std::atomic_bool capture_cc_{
false };
294 std::array<midi_byte_t, 3> last_cc_captured_{};
296 std::atomic<State> state_{ State::Uninitialized };
297 static_assert (
decltype (state_)::is_always_lock_free);
299 std::optional<dsp::AudioDeviceInfo> cached_device_info_;
301 utils::QObjectUniquePtr<dsp::MidiPanicProcessor> midi_panic_processor_;
303 std::unique_ptr<AudioCallback> audio_callback_;
305 utils::QObjectUniquePtr<AudioInputProcessor> audio_input_processor_;
314 std::span<const float * const> current_hw_input_;
320 bool callback_running_{};
RAII wrapper class for std::binary_semaphore.
Q_INVOKABLE void deactivate()
Deactivates the engine if active.
auto process(const dsp::PlayheadProcessingGuard &playhead_guard, units::sample_u32_t total_frames_to_process) noexcept -> ProcessReturnStatus
Processes current cycle.
~AudioEngine() override
Closes any connections and free's data.
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.
auto * audio_input_processor() const
Returns the audio input processor, or nullptr if no audio device has started.
void execute_function_with_paused_processing_synchronously(const std::function< void()> &func, bool recalculate_graph)
Executes the given function after pausing processing and then resumes processing.
int sampleRate() const
Current sample rate from the hardware interface (QML-friendly).
units::sample_u32_t block_length() const
Current block length as a unit type.
utils::Utf8String device_name() const
Current audio device name from the hardware interface.
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.
Q_INVOKABLE void activate()
Activate the engine if not already active.
void wait_for_pause(EngineState &state, bool force_pause, bool with_fadeout)
AudioEngine(dsp::Transport &transport, IHardwareAudioInterface &hw_interface, dsp::DspGraphDispatcher &graph_dispatcher, const dsp::TempoMap &tempo_map, QObject *parent=nullptr)
Create a new audio engine.
units::sample_rate_t sample_rate() const
Current sample rate as a unit type.
int blockLength() const
Current block length from the hardware interface (QML-friendly).
void panic_all()
Queues MIDI note off to event queues.
The DspGraphDispatcher class manages the processing graph for the audio engine.
Abstraction for hardware audio interface.
RAII helper for Playhead audio processing block.
Wrapper over a Uuid registry that provides (slow) lookup by unique ID.
The Transport class represents the transport controls and state for an audio engine.
Lightweight UTF-8 string wrapper with safe conversions.
bool looping_
Transport loop.
bool running_
Engine running.