|
Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
|
The audio engine. More...
#include <src/gui/dsp/engine.h>


Data Structures | |
| class | Event |
| Audio engine event. More... | |
| struct | PositionInfo |
| struct | State |
Public Types | |
| enum class | JackTransportType { TimebaseMaster , TransportClient , NoJackTransport } |
| enum class | SampleRate { SR_22050 , SR_32000 , SR_44100 , SR_48000 , SR_88200 , SR_96000 , SR_192000 } |
| Samplerates to be used in comboboxes. More... | |
| enum class | AudioEngineEventType { AUDIO_ENGINE_EVENT_BUFFER_SIZE_CHANGE , AUDIO_ENGINE_EVENT_SAMPLE_RATE_CHANGE } |
| Audio engine event type. More... | |
| enum class | BufferSize { _16 , _32 , _64 , _128 , _256 , _512 , _1024 , _2048 , _4096 } |
| Buffer sizes to be used in combo boxes. More... | |
Public Types inherited from IPortOwner | |
| using | TrackUuid = dsp::PortIdentifier::TrackUuid |
| using | PluginUuid = dsp::PortIdentifier::PluginUuid |
| using | PortUuid = dsp::PortIdentifier::PortUuid |
Public Member Functions | |
| AudioEngine (Project *project=nullptr) | |
| Create a new audio engine. | |
| ~AudioEngine () override | |
| Closes any connections and free's data. | |
| auto & | get_port_registry () |
| auto & | get_port_registry () const |
| TrackRegistry & | get_track_registry () |
| TrackRegistry & | get_track_registry () const |
| bool | has_handled_buffer_size_change () const |
| bool | is_in_active_project () const override |
| void | set_port_metadata_from_owner (dsp::PortIdentifier &id, PortRange &range) const override |
| Function that will be called by the Port to update the identifier's relevant members based on this port owner. | |
| utils::Utf8String | get_full_designation_for_port (const dsp::PortIdentifier &id) const override |
| void | wait_for_pause (State &state, bool force_pause, bool with_fadeout) |
| void | realloc_port_buffers (nframes_t buf_size) |
| void | rename_port_backend (Port &port) |
| Renames the port on the backend side. | |
| void | set_port_exposed_to_backend (Port &port, bool expose) |
| Sets whether to expose the port to the backend and exposes it or removes it. | |
| void | init_loaded (Project *project) |
| void | resume (State &state) |
| void | wait_n_cycles (int n) |
| Waits for n processing cycles to finish. | |
| void | append_ports (std::vector< Port * > &ports) |
| void | pre_setup () |
| Sets up the audio engine before the project is initialized/loaded. | |
| void | setup () |
| Sets up the audio engine after the project is initialized/loaded. | |
| void | activate (bool activate) |
| Activates the audio engine to start processing and receiving events. | |
| void | update_frames_per_tick (int beats_per_bar, bpm_t bpm, sample_rate_t sample_rate, bool thread_check, bool update_from_ticks, bool bpm_change) |
| Updates frames per tick based on the time sig, the BPM, and the sample rate. | |
| bool | process_events () |
| Timeout function to be called periodically by Glib. | |
| bool | process_prepare (nframes_t nframes, SemaphoreRAII< moodycamel::LightweightSemaphore > *sem=nullptr) |
| To be called by each implementation to prepare the structures before processing. | |
| int | process (nframes_t total_frames_to_process) |
| Processes current cycle. | |
| void | post_process (nframes_t roll_nframes, nframes_t nframes) |
| To be called after processing for common logic. | |
| void | fill_out_bufs (nframes_t nframes) |
| Called to fill in the external buffers at the end of the processing cycle. | |
| void | set_buffer_size (uint32_t buf_size) |
| Request the backend to set the buffer size. | |
| void | reset_bounce_mode () |
| Reset the bounce mode on the engine, all tracks and regions to OFF. | |
| void | init_after_cloning (const AudioEngine &other, ObjectCloneType clone_type) override |
| Initializes the cloned object. | |
| std::pair< AudioPort &, AudioPort & > | get_monitor_out_ports () |
| std::pair< AudioPort &, AudioPort & > | get_dummy_input_ports () |
| void | panic_all () |
| Queues MIDI note off to event queues. | |
Public Member Functions inherited from ICloneable< AudioEngine > | |
| std::unique_ptr< AudioEngine > | clone_unique (ObjectCloneType clone_type=ObjectCloneType::Snapshot, Args &&... args) const |
| std::shared_ptr< AudioEngine > | clone_shared (ObjectCloneType clone_type=ObjectCloneType::Snapshot, Args &&... args) const |
| AudioEngine * | clone_raw_ptr (ObjectCloneType clone_type=ObjectCloneType::Snapshot, Args &&... args) const |
| AudioEngine * | clone_qobject (QObject *parent, ObjectCloneType clone_type=ObjectCloneType::Snapshot, Args &&... args) const |
| QScopedPointer< AudioEngine > | clone_unique_qobject (QObject *parent, ObjectCloneType clone_type=ObjectCloneType::Snapshot, Args &&... args) const |
Public Member Functions inherited from IPortOwner | |
| virtual void | on_control_change_event (const PortUuid &port_uuid, const dsp::PortIdentifier &id, float val) |
| Will be called when a control port's value changes. | |
| virtual void | on_midi_activity (const dsp::PortIdentifier &id) |
| Called during processing if the MIDI port contains new MIDI events. | |
| virtual bool | should_sum_data_from_backend () const |
| Whether during processing, the port should sum the data from its backend buffers coming in. | |
| virtual bool | should_bounce_to_master (utils::audio::BounceStep step) const |
| Whether the port should add its data to the master output when bouncing. | |
| virtual bool | are_events_on_midi_channel_approved (midi_byte_t channel) const |
| Returns whether MIDI events on this channel on an input port should be processed (not ignored). | |
Static Public Member Functions | |
| static AudioEngine * | get_active_instance () |
| static int | buffer_size_enum_to_int (BufferSize buffer_size) |
| Returns the int value corresponding to the given AudioEngineBufferSize. | |
| static int | samplerate_enum_to_int (SampleRate samplerate) |
| Returns the int value corresponding to the given AudioEngineSamplerate. | |
| static void | set_default_backends (bool reset_to_dummy) |
| Detects the best backends on the system and sets them to GSettings. | |
Data Fields | |
| Project * | project_ = nullptr |
| Pointer to owner project, if any. | |
| std::atomic_uint64_t | cycle_ = 0 |
| Cycle count to know which cycle we are in. | |
| void * | client_ = nullptr |
| std::atomic_bool | handled_jack_buffer_size_change_ = false |
| Whether pending jack buffer change was handled (buffers reallocated). | |
| JackTransportType | transport_type_ = (JackTransportType) 0 |
| Whether transport master/client or no connection with jack transport. | |
| AudioBackend | audio_backend_ = (AudioBackend) 0 |
| Current audio backend. | |
| MidiBackend | midi_backend_ = (MidiBackend) 0 |
| Current MIDI backend. | |
| nframes_t | block_length_ = 0 |
| Audio buffer size (block length), per channel. | |
| size_t | midi_buf_size_ = 0 |
| Size of MIDI port buffers in bytes. | |
| sample_rate_t | sample_rate_ = 0 |
| Sample rate. | |
| dsp::FramesPerTick | frames_per_tick_ |
| Number of frames/samples per tick. | |
| dsp::TicksPerFrame | ticks_per_frame_ |
| Reciprocal of frames_per_tick_. | |
| int | buf_size_set_ = 0 |
| True iff buffer size callback fired. | |
| std::unique_ptr< Router > | router_ |
| The processing graph router. | |
| std::unique_ptr< HardwareProcessor > | hw_in_processor_ |
| Input device processor. | |
| std::unique_ptr< HardwareProcessor > | hw_out_processor_ |
| Output device processor. | |
| std::unique_ptr< MidiPort > | midi_clock_in_ |
| MIDI Clock input TODO. | |
| std::unique_ptr< MidiPort > | midi_clock_out_ |
| MIDI Clock output. | |
| std::unique_ptr< ControlRoom > | control_room_ |
| The ControlRoom. | |
| std::unique_ptr< AudioPool > | pool_ |
| Audio file pool. | |
| std::optional< PortUuidReference > | dummy_left_input_ |
| Used during tests to pass input data for recording. | |
| std::optional< PortUuidReference > | dummy_right_input_ |
| std::optional< PortUuidReference > | monitor_out_left_ |
| Monitor - these should be the last ports in the signal chain. | |
| std::optional< PortUuidReference > | monitor_out_right_ |
| std::atomic_bool | trigger_midi_activity_ { false } |
| Flag to tell the UI that this channel had MIDI activity. | |
| std::unique_ptr< MidiPort > | midi_editor_manual_press_ |
| Manual note press events from the piano roll. | |
| std::unique_ptr< MidiPort > | midi_in_ |
| Port used for receiving MIDI in messages for binding CC and other non-recording purposes. | |
| nframes_t | nframes_ = 0 |
| Number of frames/samples in the current cycle, per channel. | |
| moodycamel::LightweightSemaphore | port_operation_lock_ { 1 } |
| Semaphore for blocking DSP while a plugin and its ports are deleted. | |
| std::atomic_bool | run_ { false } |
| Ok to process or not. | |
| bool | preparing_to_export_ = false |
| To be set to true when preparing to export. | |
| std::atomic_bool | exporting_ { false } |
| Whether currently exporting. | |
| std::atomic_bool | panic_ { false } |
| Send note off MIDI everywhere. | |
| std::unique_ptr< juce::Thread > | dummy_audio_thread_ |
| Dummy audio DSP processing thread. | |
| dsp::PanLaw | pan_law_ = {} |
| Pan law. | |
| dsp::PanAlgorithm | pan_algo_ = {} |
| Pan algorithm. | |
| RtDuration | max_time_taken_ {} |
| Time taken to process in the last cycle. | |
| RtTimePoint | timestamp_start_ {} |
| Timestamp at the start of the current cycle. | |
| RtTimePoint | last_timestamp_start_ {} |
| Expected timestamp at the end of the current cycle. | |
| nframes_t | remaining_latency_preroll_ = 0 |
| Timestamp at end of previous cycle. | |
| QPointer< dsp::PortConnectionsManager > | port_connections_manager_ |
| std::unique_ptr< SampleProcessor > | sample_processor_ |
| std::atomic_bool | capture_cc_ { false } |
| To be set to 1 when the CC from the Midi in port should be captured. | |
| std::array< midi_byte_t, 3 > | last_cc_captured_ {} |
| Last MIDI CC captured. | |
| SteadyTimePoint | last_xrun_notification_ |
| Last time an XRUN notification was shown. | |
| bool | denormal_prevention_val_positive_ = true |
| Whether the denormal prevention value (1e-12 ~ 1e-20) is positive. | |
| float | denormal_prevention_val_ = 1e-12f |
| BounceMode | bounce_mode_ = BounceMode::BOUNCE_OFF |
| If this is on, only tracks/regions marked as "for bounce" will be allowed to make sound. | |
| utils::audio::BounceStep | bounce_step_ = {} |
| Bounce step cache. | |
| bool | bounce_with_parents_ = false |
| Whether currently bouncing with parents (cache). | |
| std::unique_ptr< Metronome > | metronome_ |
| The metronome. | |
| MPMCQueue< Event * > | ev_queue_ { ENGINE_MAX_EVENTS } |
| Event queue. | |
| ObjectPool< Event > | ev_pool_ { ENGINE_MAX_EVENTS } |
| Object pool of event structs to avoid allocation. | |
| bool | processing_events_ = false |
| ID of the event processing source func. | |
| SteadyTimePoint | last_events_process_started_ |
| Time last event processing started. | |
| SteadyTimePoint | last_events_processed_ |
| Time last event processing completed. | |
| std::atomic_bool | cycle_running_ { false } |
| Whether the cycle is currently running. | |
| bool | pre_setup_ = false |
| Whether the engine is already pre-set up. | |
| bool | setup_ = false |
| Whether the engine is already set up. | |
| bool | activated_ = false |
| Whether the engine is currently activated. | |
| bool | destroying_ = false |
| Whether the engine is currently undergoing destruction. | |
| bool | updating_frames_per_tick_ = false |
| True while updating frames per tick. | |
| PositionInfo | pos_nfo_before_ = {} |
| Position info at the end of the previous cycle before moving the transport. | |
| PositionInfo | pos_nfo_current_ = {} |
| Position info at the start of the current cycle. | |
| PositionInfo | pos_nfo_at_end_ = {} |
| Expected position info at the end of the current cycle. | |
Data Fields inherited from ICloneable< AudioEngine > | |
| friend | Derived |
Friends | |
| void | to_json (nlohmann::json &j, const AudioEngine &engine) |
| void | from_json (const nlohmann::json &j, AudioEngine &engine) |
|
strong |
|
strong |
|
strong |
| AudioEngine::AudioEngine | ( | Project * | project = nullptr | ) |
Create a new audio engine.
This only initializes the engine and does not connect to any backend.
| void AudioEngine::activate | ( | bool | activate | ) |
Activates the audio engine to start processing and receiving events.
| activate | Activate or deactivate. |
|
overridevirtual |
Reimplemented from IPortOwner.
|
inline |
|
overridevirtual |
Initializes the cloned object.
| ZrythmException | If the object could not be cloned. |
Implements ICloneable< AudioEngine >.
| void AudioEngine::init_loaded | ( | Project * | project | ) |
| project |
| ZrythmError | if failed to initialize. |
|
overridevirtual |
Implements IPortOwner.
| void AudioEngine::panic_all | ( | ) |
Queues MIDI note off to event queues.
To be called after processing for common logic.
| roll_nframes | Frames to roll (add to the playhead - if transport rolling). |
| nframes | Total frames for this processing cycle. |
| int AudioEngine::process | ( | nframes_t | total_frames_to_process | ) |
Processes current cycle.
To be called by each implementation in its callback.
| bool AudioEngine::process_prepare | ( | nframes_t | nframes, |
| SemaphoreRAII< moodycamel::LightweightSemaphore > * | sem = nullptr ) |
To be called by each implementation to prepare the structures before processing.
Clears buffers, marks all as unprocessed, etc.
| sem | SemamphoreRAII to check if acquired. If not acquired before calling this function, it will only clear output buffers and return true. |
|
inline |
| void AudioEngine::set_buffer_size | ( | uint32_t | buf_size | ) |
Request the backend to set the buffer size.
The backend is expected to call the buffer size change callbacks.
|
static |
Detects the best backends on the system and sets them to GSettings.
| reset_to_dummy | Whether to reset the backends to dummy before attempting to set defaults. |
| void AudioEngine::set_port_exposed_to_backend | ( | Port & | port, |
| bool | expose ) |
Sets whether to expose the port to the backend and exposes it or removes it.
It checks what the backend is using the engine's audio backend or midi backend settings.
|
overridevirtual |
Function that will be called by the Port to update the identifier's relevant members based on this port owner.
| id | The identifier to update. |
Implements IPortOwner.
| void AudioEngine::update_frames_per_tick | ( | int | beats_per_bar, |
| bpm_t | bpm, | ||
| sample_rate_t | sample_rate, | ||
| bool | thread_check, | ||
| bool | update_from_ticks, | ||
| bool | bpm_change ) |
Updates frames per tick based on the time sig, the BPM, and the sample rate.
| thread_check | Whether to throw a warning if not called from GTK thread. |
| update_from_ticks | Whether to update the positions based on ticks (true) or frames (false). |
| bpm_change | Whether this is a BPM change. |
| void AudioEngine::wait_for_pause | ( | State & | state, |
| bool | force_pause, | ||
| bool | with_fadeout ) |
| force_pause | Whether to force transport pause, otherwise for engine to process and handle the pause request. |
| void AudioEngine::wait_n_cycles | ( | int | n | ) |
Waits for n processing cycles to finish.
Used during tests.
|
friend |
| bool AudioEngine::activated_ = false |
| AudioBackend AudioEngine::audio_backend_ = (AudioBackend) 0 |
| nframes_t AudioEngine::block_length_ = 0 |
| BounceMode AudioEngine::bounce_mode_ = BounceMode::BOUNCE_OFF |
| utils::audio::BounceStep AudioEngine::bounce_step_ = {} |
| bool AudioEngine::bounce_with_parents_ = false |
| int AudioEngine::buf_size_set_ = 0 |
| std::atomic_bool AudioEngine::capture_cc_ { false } |
| std::unique_ptr<ControlRoom> AudioEngine::control_room_ |
The ControlRoom.
| std::atomic_uint64_t AudioEngine::cycle_ = 0 |
| std::atomic_bool AudioEngine::cycle_running_ { false } |
| bool AudioEngine::denormal_prevention_val_positive_ = true |
Whether the denormal prevention value (1e-12 ~ 1e-20) is positive.
This should be swapped often to avoid DC offset prevention algorithms removing it.
See https://www.earlevel.com/main/2019/04/19/floating-point-denormals/ for details.
| bool AudioEngine::destroying_ = false |
| std::unique_ptr<juce::Thread> AudioEngine::dummy_audio_thread_ |
| std::optional<PortUuidReference> AudioEngine::dummy_left_input_ |
| std::optional<PortUuidReference> AudioEngine::dummy_right_input_ |
| ObjectPool<Event> AudioEngine::ev_pool_ { ENGINE_MAX_EVENTS } |
| std::atomic_bool AudioEngine::exporting_ { false } |
| dsp::FramesPerTick AudioEngine::frames_per_tick_ |
| std::atomic_bool AudioEngine::handled_jack_buffer_size_change_ = false |
| std::unique_ptr<HardwareProcessor> AudioEngine::hw_in_processor_ |
| std::unique_ptr<HardwareProcessor> AudioEngine::hw_out_processor_ |
| std::array<midi_byte_t, 3> AudioEngine::last_cc_captured_ {} |
| SteadyTimePoint AudioEngine::last_events_process_started_ |
| SteadyTimePoint AudioEngine::last_events_processed_ |
| RtTimePoint AudioEngine::last_timestamp_start_ {} |
| SteadyTimePoint AudioEngine::last_xrun_notification_ |
| RtDuration AudioEngine::max_time_taken_ {} |
Time taken to process in the last cycle.
Max time taken in the last few processing cycles.
This is used by the DSP usage meter, which also clears the value to 0 upon reading it.
| std::unique_ptr<Metronome> AudioEngine::metronome_ |
| MidiBackend AudioEngine::midi_backend_ = (MidiBackend) 0 |
| size_t AudioEngine::midi_buf_size_ = 0 |
| std::unique_ptr<MidiPort> AudioEngine::midi_clock_in_ |
| std::unique_ptr<MidiPort> AudioEngine::midi_clock_out_ |
| std::unique_ptr<MidiPort> AudioEngine::midi_editor_manual_press_ |
Manual note press events from the piano roll.
The events from here should be read by the corresponding track processor's MIDI in port (TrackProcessor.midi_in). To avoid having to recalculate the graph to reattach this port to the correct track processor, only connect this port to the initial processor in the routing graph and fetch the events manually when processing the corresponding track processor.
| std::unique_ptr<MidiPort> AudioEngine::midi_in_ |
| std::optional<PortUuidReference> AudioEngine::monitor_out_left_ |
| std::optional<PortUuidReference> AudioEngine::monitor_out_right_ |
| nframes_t AudioEngine::nframes_ = 0 |
| dsp::PanAlgorithm AudioEngine::pan_algo_ = {} |
| std::atomic_bool AudioEngine::panic_ { false } |
| std::unique_ptr<AudioPool> AudioEngine::pool_ |
| QPointer<dsp::PortConnectionsManager> AudioEngine::port_connections_manager_ |
| moodycamel::LightweightSemaphore AudioEngine::port_operation_lock_ { 1 } |
| PositionInfo AudioEngine::pos_nfo_at_end_ = {} |
| PositionInfo AudioEngine::pos_nfo_before_ = {} |
| PositionInfo AudioEngine::pos_nfo_current_ = {} |
| bool AudioEngine::pre_setup_ = false |
| bool AudioEngine::preparing_to_export_ = false |
| bool AudioEngine::processing_events_ = false |
| Project* AudioEngine::project_ = nullptr |
| nframes_t AudioEngine::remaining_latency_preroll_ = 0 |
| std::unique_ptr<Router> AudioEngine::router_ |
| std::atomic_bool AudioEngine::run_ { false } |
| std::unique_ptr<SampleProcessor> AudioEngine::sample_processor_ |
| sample_rate_t AudioEngine::sample_rate_ = 0 |
| bool AudioEngine::setup_ = false |
| dsp::TicksPerFrame AudioEngine::ticks_per_frame_ |
Reciprocal of frames_per_tick_.
| RtTimePoint AudioEngine::timestamp_start_ {} |
| JackTransportType AudioEngine::transport_type_ = (JackTransportType) 0 |
| std::atomic_bool AudioEngine::trigger_midi_activity_ { false } |
| bool AudioEngine::updating_frames_per_tick_ = false |