Line data Source code
1 : #pragma once
2 :
3 : #include <memory>
4 : #include <nlohmann/json.hpp>
5 : #include <string>
6 : #include <vector>
7 :
8 : #include "audio/backend/audio_device_info.h"
9 :
10 : namespace Amplitron {
11 :
12 : class Effect;
13 : class AudioGraph;
14 : class IRecorder;
15 :
16 : /**
17 : * @brief Interface for managing lifecycle operations.
18 : * @note Threading Contract: Call only from the GUI/Main thread.
19 : */
20 275 : class ILifecycle {
21 : public:
22 814 : virtual ~ILifecycle() = default;
23 : virtual bool initialize() = 0;
24 : virtual void shutdown() = 0;
25 : virtual bool start() = 0;
26 : virtual void stop() = 0;
27 : virtual bool restart() = 0;
28 : virtual std::string get_last_error() const = 0;
29 : virtual void clear_error() = 0;
30 : };
31 :
32 : /**
33 : * @brief Abstract interface for audio device, latency, and sample rate management.
34 : * Satisfies the Interface Segregation Principle (ISP) and Dependency Inversion Principle (DIP).
35 : * @note Threading Contract: Call only from the GUI/Main thread.
36 : */
37 275 : class IDeviceManager {
38 : public:
39 814 : virtual ~IDeviceManager() = default;
40 :
41 : virtual std::vector<AudioDeviceInfo> get_input_devices() const = 0;
42 : virtual std::vector<AudioDeviceInfo> get_output_devices() const = 0;
43 :
44 : virtual bool set_input_device(int device_index) = 0;
45 : virtual bool set_output_device(int device_index) = 0;
46 :
47 : virtual int get_input_device() const = 0;
48 : virtual int get_output_device() const = 0;
49 :
50 : virtual std::string get_input_device_name() const = 0;
51 : virtual std::string get_output_device_name() const = 0;
52 :
53 : virtual int get_buffer_size() const = 0;
54 : virtual int get_sample_rate() const = 0;
55 :
56 : virtual void set_buffer_size(int size) = 0;
57 : virtual void set_sample_rate(int rate) = 0;
58 :
59 : virtual bool is_running() const = 0;
60 : };
61 :
62 : /**
63 : * @brief Abstract interface for audio level, RMS, clipping, and CPU load metrics.
64 : * Satisfies the Interface Segregation Principle (ISP) and Dependency Inversion Principle (DIP).
65 : * @note Threading Contract: Safe to call from the GUI/Main thread. Reads atomic variables updated
66 : * by the audio thread.
67 : */
68 275 : class IAudioMetricsService {
69 : public:
70 814 : virtual ~IAudioMetricsService() = default;
71 :
72 : virtual float get_input_level() const = 0;
73 : virtual float get_output_level() const = 0;
74 :
75 : virtual float get_input_rms() const = 0;
76 : virtual float get_output_rms() const = 0;
77 :
78 : virtual bool consume_input_clipped() = 0;
79 : virtual bool consume_output_clipped() = 0;
80 :
81 : virtual float get_cpu_load() const = 0;
82 : };
83 :
84 : /**
85 : * @brief Interface for inspecting and mutating the effect chain.
86 : * @note Threading Contract: Call only from the GUI/Main thread. Modifies graph structure.
87 : */
88 275 : class IEffectChain {
89 : public:
90 814 : virtual ~IEffectChain() = default;
91 : virtual std::vector<std::shared_ptr<Effect>>& effects() = 0;
92 : virtual void add_effect(std::shared_ptr<Effect> fx) = 0;
93 : virtual void add_initial_effects(const std::vector<std::shared_ptr<Effect>>& fxs) = 0;
94 : virtual void insert_effect(int index, std::shared_ptr<Effect> fx) = 0;
95 : virtual void remove_effect(int index) = 0;
96 : virtual void clear_effects() = 0;
97 : virtual void move_effect(int from, int to) = 0;
98 : virtual void restore_effects_state(std::vector<std::shared_ptr<Effect>> state) = 0;
99 : };
100 :
101 : /**
102 : * @brief Interface for transport settings, master gains, and metronome controls.
103 : * @note Threading Contract: Call only from the GUI/Main thread.
104 : */
105 275 : class ITransportControl {
106 : public:
107 814 : virtual ~ITransportControl() = default;
108 : virtual void set_input_gain(float gain) = 0;
109 : virtual void set_output_gain(float gain) = 0;
110 : virtual float get_input_gain() const = 0;
111 : virtual float get_output_gain() const = 0;
112 :
113 : virtual void toggle_metronome() = 0;
114 : virtual void set_metronome_bpm(int bpm) = 0;
115 : virtual void set_metronome_volume(float volume) = 0;
116 : virtual bool get_metronome_enabled() const = 0;
117 : virtual int get_metronome_bpm() const = 0;
118 : virtual float get_metronome_volume() const = 0;
119 : };
120 :
121 : /**
122 : * @brief Interface for driving real-time audio block processing.
123 : * @note Threading Contract: Called exclusively from the high-priority real-time audio callback
124 : * thread. Must be lock-free and memory-allocation-free.
125 : */
126 275 : class IAudioProcessor {
127 : public:
128 814 : virtual ~IAudioProcessor() = default;
129 : virtual void process_audio(const float* input, float* output, int frame_count) = 0;
130 : };
131 :
132 : /**
133 : * @brief Interface for configuring and retrieving FFT analyzer snapshots.
134 : * @note Threading Contract: Safe to call from the GUI/Main thread. Uses locks to copy shared
135 : * buffers.
136 : */
137 550 : class IAnalyzerProvider {
138 : public:
139 : static constexpr int ANALYZER_FFT_SIZE = 2048;
140 :
141 1353 : virtual ~IAnalyzerProvider() = default;
142 : virtual void set_analyzer_enabled(bool enabled) = 0;
143 : virtual bool is_analyzer_enabled() const = 0;
144 : virtual uint64_t get_analyzer_sequence() const = 0;
145 : virtual bool copy_analyzer_snapshot(float* input_dest, float* output_dest,
146 : int sample_count) const = 0;
147 : };
148 :
149 : /**
150 : * @brief Interface for pushing thread-safe real-time parameter changes.
151 : * @note Threading Contract: Safe to call from any thread (non-blocking lock-free SPSC queue).
152 : */
153 275 : class IParameterDispatch {
154 : public:
155 814 : virtual ~IParameterDispatch() = default;
156 : virtual void push_param_change(int effect_index, int param_index, float value) = 0;
157 : virtual void push_mixer_gain_change(int node_id, int pin_index, float gain) = 0;
158 : virtual void push_effect_enabled(int effect_index, float enabled) = 0;
159 : virtual void push_effect_mix(int effect_index, float mix) = 0;
160 : };
161 :
162 : /**
163 : * @brief Interface for serialization and deserialization of the session state.
164 : * @note Threading Contract: Call only from the GUI/Main thread.
165 : */
166 275 : class ISessionSerializer {
167 : public:
168 814 : virtual ~ISessionSerializer() = default;
169 : virtual nlohmann::json serialize() = 0;
170 : virtual void deserialize(const nlohmann::json& j) = 0;
171 : };
172 :
173 : /**
174 : * @brief Interface for accessing and committing topological audio graph changes.
175 : * @note Threading Contract: Call only from the GUI/Main thread.
176 : */
177 275 : class IGraphProvider {
178 : public:
179 814 : virtual ~IGraphProvider() = default;
180 : virtual AudioGraph& graph() = 0;
181 : virtual const AudioGraph& graph() const = 0;
182 : virtual void commit_graph_changes() = 0;
183 : };
184 :
185 : /**
186 : * @brief Unified interface for the audio processing engine.
187 : * Satisfies the Dependency Inversion Principle (DIP).
188 : */
189 275 : class IAudioEngine : public ILifecycle,
190 : public IDeviceManager,
191 : public IAudioMetricsService,
192 : public IEffectChain,
193 : public ITransportControl,
194 : public IAudioProcessor,
195 : public IAnalyzerProvider,
196 : public IParameterDispatch,
197 : public ISessionSerializer,
198 : public IGraphProvider {
199 : public:
200 814 : virtual ~IAudioEngine() = default;
201 :
202 : virtual int get_suggested_buffer_size() const = 0;
203 : virtual bool is_auto_buffer_enabled() const = 0;
204 : virtual void set_auto_buffer_enabled(bool enabled) = 0;
205 :
206 : virtual IRecorder& recorder() = 0;
207 : virtual void set_tuner_tap(std::shared_ptr<Effect> tap) = 0;
208 : virtual void clear_tuner_tap() = 0;
209 : virtual bool has_tuner_tap() const = 0;
210 :
211 : #ifdef AMPLITRON_ANDROID_OBOE
212 : virtual const char* get_oboe_sharing_mode_label() const = 0;
213 : #endif
214 : };
215 :
216 : } // namespace Amplitron
|