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]];
184 assert (!audio_callback_active_);
185 monitor_out_source_ = &port;
188 auto * midi_panic_processor ()
const {
return midi_panic_processor_.get (); }
196 return audio_input_processor_.get ();
199 const auto &midi_input_processors ()
const {
return midi_input_processors_; }
206 bool activated ()
const {
return state_ == State::Active; }
207 bool running ()
const {
return run_.load (); }
208 void set_running (
bool run) { run_.store (run); }
209 auto &graph_dispatcher () {
return graph_dispatcher_; }
211 bool exporting ()
const {
return exporting_; }
212 void set_exporting (
bool exporting) { exporting_.store (exporting); }
214 auto get_processing_lock () [[clang::blocking]]
216 return SemaphoreRAII (process_lock_,
true);
227 const std::function<
void ()> &func,
228 bool recalculate_graph);
246 void update_midi_processors (
247 const IHardwareMidiInterface::BufferMap &active_buffers);
255 const dsp::TempoMap &tempo_map_;
268 std::atomic_uint64_t cycle_{ 0 };
291 std::unique_ptr<dsp::MidiPort> midi_in_;
296 moodycamel::LightweightSemaphore process_lock_{ 1 };
299 std::atomic_bool run_{
false };
302 std::atomic_bool exporting_{
false };
304 juce::AudioProcessLoadMeasurer load_measurer_;
310 units::sample_u32_t remaining_latency_preroll_;
313 std::atomic_bool capture_cc_{
false };
316 std::array<midi_byte_t, 3> last_cc_captured_{};
318 std::atomic<State> state_{ State::Uninitialized };
319 static_assert (
decltype (state_)::is_always_lock_free);
321 std::optional<dsp::AudioDeviceInfo> cached_device_info_;
323 utils::QObjectUniquePtr<dsp::MidiPanicProcessor> midi_panic_processor_;
325 std::unique_ptr<AudioCallback> audio_callback_;
327 utils::QObjectUniquePtr<AudioInputProcessor> audio_input_processor_;
329 std::map<utils::Utf8String, utils::QObjectUniquePtr<MidiInputProcessor>>
330 midi_input_processors_;
339 std::span<const float * const> current_hw_input_;
345 bool audio_callback_active_{};
353 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.