30 Q_PROPERTY (
int sampleRate READ sampleRate NOTIFY sampleRateChanged)
31 Q_PROPERTY (
int blockLength READ blockLength NOTIFY blockLengthChanged)
36 enum class State : std::uint8_t
65 const dsp::TempoMap &tempo_map,
66 QObject * parent =
nullptr);
77 Q_INVOKABLE
int xRunCount ()
const {
return load_measurer_.getXRunCount (); }
78 Q_INVOKABLE
double loadPercentage ()
const
80 return load_measurer_.getLoadAsPercentage ();
92 Q_SIGNAL
void sampleRateChanged (
int sampleRate);
93 Q_SIGNAL
void blockLengthChanged (
int blockLength);
145 units::sample_u32_t nframes,
147 [[clang::nonblocking]];
149 enum class ProcessReturnStatus : std::uint8_t
166 units::sample_u32_t total_frames_to_process)
noexcept [[clang::nonblocking]]
167 -> ProcessReturnStatus;
179 units::sample_u32_t roll_nframes,
180 units::sample_u32_t nframes)
noexcept [[clang::nonblocking]];
182 auto &get_monitor_out_port () {
return monitor_out_; }
184 auto * midi_panic_processor ()
const {
return midi_panic_processor_.get (); }
192 return audio_input_processor_.get ();
195 const auto &midi_input_processors ()
const {
return midi_input_processors_; }
202 bool activated ()
const {
return state_ == State::Active; }
203 bool running ()
const {
return run_.load (); }
204 void set_running (
bool run) { run_.store (run); }
205 auto &graph_dispatcher () {
return graph_dispatcher_; }
207 bool exporting ()
const {
return exporting_; }
208 void set_exporting (
bool exporting) { exporting_.store (exporting); }
210 auto get_processing_lock () [[clang::blocking]]
212 return SemaphoreRAII (process_lock_,
true);
223 const std::function<
void ()> &func,
224 bool recalculate_graph);
242 void update_midi_processors (
243 const IHardwareMidiInterface::BufferMap &active_buffers);
251 const dsp::TempoMap &tempo_map_;
264 std::atomic_uint64_t cycle_{ 0 };
286 std::unique_ptr<dsp::MidiPort> midi_in_;
291 moodycamel::LightweightSemaphore process_lock_{ 1 };
294 std::atomic_bool run_{
false };
297 std::atomic_bool exporting_{
false };
299 juce::AudioProcessLoadMeasurer load_measurer_;
305 units::sample_u32_t remaining_latency_preroll_;
308 std::atomic_bool capture_cc_{
false };
311 std::array<midi_byte_t, 3> last_cc_captured_{};
313 std::atomic<State> state_{ State::Uninitialized };
314 static_assert (
decltype (state_)::is_always_lock_free);
316 std::optional<dsp::AudioDeviceInfo> cached_device_info_;
318 utils::QObjectUniquePtr<dsp::MidiPanicProcessor> midi_panic_processor_;
320 std::unique_ptr<AudioCallback> audio_callback_;
322 utils::QObjectUniquePtr<AudioInputProcessor> audio_input_processor_;
324 std::map<utils::Utf8String, utils::QObjectUniquePtr<MidiInputProcessor>>
325 midi_input_processors_;
334 std::span<const float * const> current_hw_input_;
340 bool audio_callback_active_{};
348 units::precise_second_t block_start_time_;
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, IHardwareMidiInterface &midi_interface, dsp::DspGraphDispatcher &graph_dispatcher, const dsp::TempoMap &tempo_map, QObject *parent=nullptr)
Create a new audio engine.