Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
engine_jack.h
1// SPDX-FileCopyrightText: © 2018-2019, 2022, 2025 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include "zrythm-config.h"
7
8#include "engine/device_io/engine.h"
9
10#ifdef HAVE_JACK
11
12# include <cstdlib>
13
14# define JACK_PORT_T(exp) (static_cast<jack_port_t *> (exp))
15
16namespace zrythm::engine::device_io
17{
18class JackDriver : public AudioEngine::AudioDriver, public AudioEngine::MidiDriver
19{
20public:
21 enum class TransportType : basic_enum_base_type_t
22 {
23 TimebaseMaster,
24 TransportClient,
25 NoJackTransport,
26 };
27
28 JackDriver (AudioEngine &engine) : engine_ (engine) { }
29
30 utils::Utf8String get_driver_name () const override { return u8"JACK"; }
31
32 // Audio driver implementation
33 void set_buffer_size (uint32_t buf_size) override
34 {
35 jack_set_buffer_size (client_, buf_size);
36 z_debug ("called jack_set_buffer_size");
37 }
38 bool buffer_size_change_handled () const override
39 {
40 return handled_jack_buffer_size_change_;
41 }
42 void handle_buf_size_change (uint32_t frames) override;
43 void handle_sample_rate_change (uint32_t samplerate) override;
44 bool setup_audio () override;
45 bool activate_audio (bool activate) override;
46 void tear_down_audio () override;
47 void handle_start () override;
48 void handle_stop () override;
49 void prepare_process_audio () override;
50 bool
51 sanity_check_should_return_early (nframes_t total_frames_to_process) override;
52 void handle_position_change () override;
53 std::unique_ptr<PortBackend> create_audio_port_backend () const override
54 {
55 return std::make_unique<JackPortBackend> (*client_);
56 }
57 std::vector<ExtPort>
58 get_ext_audio_ports (dsp::PortFlow flow, bool hw) const override;
59
60 // MIDI driver implementation
61 bool setup_midi () override;
62 bool activate_midi (bool activate) override { /* noop */ return true; }
63 void tear_down_midi () override { /* noop */ }
64 std::unique_ptr<PortBackend> create_midi_port_backend () const override
65 {
66 return std::make_unique<JackPortBackend> (*client_);
67 }
68 std::vector<ExtPort>
69 get_ext_midi_ports (dsp::PortFlow flow, bool hw) const override;
70
71 jack_client_t * get_client () const { return client_; }
72
73private:
77 void rescan_ports ();
78
85 void reconnect_monitor (bool left);
86
90 void set_transport_type (TransportType type);
91
95 void fill_out_bufs (const nframes_t nframes);
96
97 void process_change_request ();
98
106 static int sample_rate_cb (uint32_t nframes, void * data);
107
109 static int buffer_size_cb (uint32_t nframes, void * data);
114 static int process_cb (uint32_t nframes, void * data);
122 static int xrun_cb (void * data);
123
124 static void timebase_cb (
125 jack_transport_state_t state,
126 jack_nframes_t nframes,
127 jack_position_t * pos,
128 int new_pos,
129 void * arg);
134 static void shutdown_cb (void * arg);
135 static void freewheel_cb (int starting, void * arg);
136 static void
137 port_registration_cb (jack_port_id_t port_id, int registered, void * arg);
138 static void
139 port_connect_cb (jack_port_id_t a, jack_port_id_t b, int connect, void * arg);
140
144 bool is_pipewire () const;
145
146 void get_ext_ports (
147 dsp::PortType type,
148 dsp::PortFlow flow,
149 bool hw,
150 std::vector<ExtPort> &ports) const;
151
152private:
153 AudioEngine &engine_;
154
158 TransportType transport_type_{};
159
166 std::atomic_bool handled_jack_buffer_size_change_ = false;
167
169 jack_client_t * client_ = nullptr;
170};
171}
172#endif // HAVE_JACK
Implementation that drives the audio callbacks.
Definition engine.h:109
Implementation that handles MIDI from/to devices.
Definition engine.h:161
uint32_t nframes_t
Frame count.
Definition types.h:55