Zrythm v2.0.0-alpha.1
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
device_manager.h
1// SPDX-FileCopyrightText: © 2025-2026 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include <memory>
7
8#include "dsp/hardware_midi_interface.h"
9#include "utils/utf8_string.h"
10
11#include <QObject>
12#include <QtQmlIntegration/qqmlintegration.h>
13
14#include <juce_audio_devices/juce_audio_devices.h>
15#include <juce_gui_basics/juce_gui_basics.h>
16
17namespace zrythm::dsp
18{
20}
21
22namespace zrythm::gui::backend
23{
24
29{
30 Q_GADGET
31 Q_PROPERTY (QString deviceName MEMBER deviceName)
32 Q_PROPERTY (int firstChannel MEMBER firstChannel)
33 Q_PROPERTY (bool stereo MEMBER stereo)
34 QML_VALUE_TYPE (audioInputInfo)
35 QML_UNCREATABLE ("")
36
37public:
38 QString deviceName;
39 int firstChannel = 0;
40 bool stereo = true;
41};
42
47{
48 Q_GADGET
49 Q_PROPERTY (QString deviceName MEMBER deviceName)
50 Q_PROPERTY (QString identifier MEMBER identifier)
51 QML_VALUE_TYPE (midiInputInfo)
52 QML_UNCREATABLE ("")
53
54public:
55 QString deviceName;
56 QString identifier;
57};
58
62class DeviceManager
63 : public QObject,
64 public juce::AudioDeviceManager,
66{
67 Q_OBJECT
68 QML_ELEMENT
69 QML_UNCREATABLE ("")
70 Q_DISABLE_COPY_MOVE (DeviceManager)
71 Q_PROPERTY (
72 QVector<zrythm::gui::backend::AudioInputInfo> availableAudioInputs READ
73 availableAudioInputs NOTIFY availableAudioInputsChanged)
74 Q_PROPERTY (
75 QVector<zrythm::gui::backend::MidiInputInfo> availableMidiInputs READ
76 availableMidiInputs NOTIFY availableMidiInputsChanged)
77
78public:
79 using XmlStateGetter = std::function<std::unique_ptr<juce::XmlElement> ()>;
80 using XmlStateSetter = std::function<void (const juce::XmlElement &)>;
81
82 DeviceManager (XmlStateGetter state_getter, XmlStateSetter state_setter);
83
84 ~DeviceManager () override;
85
101 void initialize (
102 int max_input_channels,
103 int max_output_channels,
104 bool fallback_to_default);
105
106 void save_state ();
107
108 // this can be mocked in tests to add a test device
109 void createAudioDeviceTypes (
110 juce::OwnedArray<juce::AudioIODeviceType> &types) override;
111
112 Q_INVOKABLE void showDeviceSelector ();
113
114 QVector<AudioInputInfo> availableAudioInputs () const;
115 Q_SIGNAL void availableAudioInputsChanged ();
116
117 QVector<MidiInputInfo> availableMidiInputs () const;
118 Q_SIGNAL void availableMidiInputsChanged ();
119
121 midi_buffer_for_device (const utils::Utf8String &identifier) const;
123 // IHardwareMidiInterface
124 void
125 set_device_change_callback (std::optional<DeviceChangeCallback> cb) override;
126 BufferMap device_buffers () const override;
127
128private:
129 struct MidiImpl;
130 friend struct MidiImpl;
131
132 void reconcile_midi_buffers ();
133
134 class DeviceChangeListener final : public juce::ChangeListener
135 {
136 public:
137 explicit DeviceChangeListener (DeviceManager &dev_manager)
138 : dev_manager_ (dev_manager)
139 {
140 }
141
142 private:
143 void changeListenerCallback (juce::ChangeBroadcaster *) override
144 {
145 Q_EMIT dev_manager_.availableAudioInputsChanged ();
146 Q_EMIT dev_manager_.availableMidiInputsChanged ();
147 dev_manager_.reconcile_midi_buffers ();
148 }
149
150 DeviceManager &dev_manager_;
151 };
152
153 class DeviceSelectorWindow : public juce::DocumentWindow
154 {
155 public:
156 DeviceSelectorWindow (DeviceManager &dev_manager);
157 void closeButtonPressed () override;
158
159 private:
160 DeviceManager &dev_manager_;
161 };
162
163private:
164 XmlStateGetter state_getter_;
165 XmlStateSetter state_setter_;
166 std::unique_ptr<DeviceSelectorWindow> device_selector_window_;
167 DeviceChangeListener device_change_listener_{ *this };
168 std::unique_ptr<MidiImpl> midi_impl_;
169};
170} // namespace zrythm::gui::backend
Abstraction for hardware MIDI interface.
Lock-free SPSC buffer for MIDI events between the MIDI device thread and the audio thread.
BufferMap device_buffers() const override
Returns the current map of device identifiers to buffers.
void initialize(int max_input_channels, int max_output_channels, bool fallback_to_default)
Opens a set of devices ready for use.
void set_device_change_callback(std::optional< DeviceChangeCallback > cb) override
Registers a notification-only device change callback.
Lightweight UTF-8 string wrapper with safe conversions.
Definition utf8_string.h:37
Describes a single audio input available from the current device.
Describes a single MIDI input device.