MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
AudioSubsystem.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "Subsystem.hpp"
4
6
8struct AudioBackendService;
9}
10
11namespace MayaFlux::Core {
12
13/**
14 * @class AudioSubsystem
15 * @brief Audio processing subsystem managing real-time audio I/O and processing
16 *
17 * Implements the ISubsystem interface to provide audio-specific processing capabilities
18 * within the MayaFlux engine. Manages audio backends, devices, and streams while
19 * coordinating with the token-based processing architecture for buffer, node and scheduling operations.
20 *
21 * Uses AUDIO_BACKEND token for buffer processing and AUDIO_RATE token for node processing,
22 * enabling real-time audio processing with proper thread safety and resource isolation.
23 */
24class MAYAFLUX_API AudioSubsystem : public ISubsystem {
25public:
26 virtual ~AudioSubsystem() = default;
27
28 /** @brief Initialize audio processing with provided handle */
29 void initialize(SubsystemProcessingHandle& handle) override;
30
31 /** @brief Register audio backend callbacks for real-time processing */
32 void register_callbacks() override;
33
34 /** @brief Start audio processing and streaming */
35 void start() override;
36
37 /** @brief Pause audio processing without stopping the stream */
38 void pause() override;
39
40 /** @brief Resume audio processing after pause */
41 void resume() override;
42
43 /** @brief Stop audio processing and streaming */
44 void stop() override;
45
46 /** @brief Shutdown and cleanup audio resources */
47 void shutdown() override;
48
49 /** @brief Get audio subsystem token configuration */
50 inline SubsystemTokens get_tokens() const override { return m_subsystem_tokens; }
51
52 /** @brief Check if audio subsystem is ready for operation */
53 inline bool is_ready() const override { return m_is_ready; }
54
55 /** @brief Check if audio subsystem is currently running */
56 inline bool is_running() const override { return m_is_running.load(); }
57
58 /* @brief Wait until the audio subsystem's processing loop is confirmed live */
59 void wait_until_running() override;
60
61 /** @brief Get access to the underlying audio backend */
62 inline IAudioBackend* get_audio_backend() { return m_audiobackend.get(); }
63
64 /** @brief Get read-only access to stream manager */
65 inline const AudioStream* get_stream_manager() const { return m_audio_stream.get(); }
66
67 /** @brief Get read-only access to device manager */
68 inline const AudioDevice* get_device_manager() const { return m_audio_device.get(); }
69
70 /** @brief Get global stream configuration */
71 inline const GlobalStreamInfo& get_stream_info() const { return m_stream_info; }
72
73 /**
74 * @brief Processes input data from audio interface
75 * @param input_buffer Pointer to interleaved input data
76 * @param num_frames Number of frames to process
77 * @return Status code (0 for success)
78 *
79 * Handles incoming audio data from the audio interface, converting from
80 * interleaved format and routing to appropriate buffer channels for processing.
81 */
82 int process_input(double* input_buffer, unsigned int num_frames);
83
84 /**
85 * @brief Processes output data for audio interface
86 * @param output_buffer Pointer to interleaved output buffer
87 * @param num_frames Number of frames to process
88 * @return Status code (0 for success)
89 *
90 * Processes node graph and buffer operations, then fills the output buffer
91 * with processed audio data in interleaved format for the audio interface.
92 * This is the main processing entry point called by audio callbacks.
93 */
94 int process_output(double* output_buffer, unsigned int num_frames);
95
96 /**
97 * @brief Processes both input and output data in full-duplex mode
98 * @param input_buffer Pointer to input data buffer
99 * @param output_buffer Pointer to output data buffer
100 * @param num_frames Number of frames to process
101 * @return Status code (0 for success)
102 *
103 * Handles full-duplex audio processing, processing input and generating
104 * output simultaneously. Used for real-time effects and monitoring scenarios.
105 */
106 int process_audio(double* input_buffer, double* output_buffer, unsigned int num_frames);
107
108 /**
109 * @brief Constructs AudioSubsystem with stream configuration
110 * @param stream_info Global stream configuration
111 *
112 * Constructor - AudioSubsystem instances are created by Engine.
113 * Initializes audio backend and configures processing tokens.
114 */
115 explicit AudioSubsystem(GlobalStreamInfo& stream_info);
116
117 inline SubsystemType get_type() const override { return m_type; }
118
120
121private:
122 using ObserverMap = std::unordered_map<uint32_t, std::function<void(const double*, uint32_t)>>;
123 void register_backend_service();
124 void notify_loop();
125
126 GlobalStreamInfo m_stream_info; ///< Audio stream configuration
127
128 std::unique_ptr<IAudioBackend> m_audiobackend; ///< Audio backend implementation
129 std::unique_ptr<AudioDevice> m_audio_device; ///< Audio device manager
130 std::unique_ptr<AudioStream> m_audio_stream; ///< Audio stream manager
131
132 std::shared_ptr<Registry::Service::AudioBackendService> m_audio_backend_service;
133
134 SubsystemTokens m_subsystem_tokens; ///< Processing token configuration
135 SubsystemProcessingHandle* m_handle; ///< Reference to processing handle
136
137 bool m_is_ready {}; ///< Subsystem ready state
138 bool m_is_paused {}; ///< Subsystem paused state
139
140 std::atomic<bool> m_is_running { false }; ///< Subsystem running state
141 std::atomic<int> m_callback_active { 0 }; ///< Active callback counter
142
143 std::atomic<uint32_t> m_next_observer_id { 1 };
144 std::atomic<bool> m_notify_running { false };
145
146 alignas(64) std::atomic<const double*> m_snapshot_ptr { nullptr };
147 std::atomic<uint64_t> m_snapshot_generation { 0 };
148 std::atomic<uint32_t> m_snapshot_size { 0 };
149 std::vector<double> m_snapshot_copy; ///< Owned copy of the last output cycle; decouples notification-thread reads from the callback write buffer.
150
151 std::thread m_notify_thread;
152
153#ifdef MAYAFLUX_PLATFORM_MACOS
154 // Apple Clang lacks std::atomic<std::shared_ptr<T>> - raw pointer + hazard
155 std::atomic<const ObserverMap*> m_observers_ptr { nullptr };
156
157 static constexpr size_t MAX_OBSERVER_READERS = 8;
158 mutable std::array<std::atomic<const ObserverMap*>, MAX_OBSERVER_READERS> m_obs_hazard_ptrs {};
159 mutable std::atomic<size_t> m_obs_hazard_counter { 0 };
160
161 std::pair<const ObserverMap*, size_t> acquire_observers() const;
162 void release_observers(size_t slot) const;
163 void retire_observers(const ObserverMap* old);
164 std::vector<const ObserverMap*> m_obs_retired;
165#else
166 std::atomic<std::shared_ptr<ObserverMap>> m_observers {
167 std::make_shared<ObserverMap>()
168 };
169#endif
170
171 static const SubsystemType m_type = SubsystemType::AUDIO;
172};
173
174}
Manages audio endpoint discovery and enumeration.
Manages digital audio data flow between the engine and hardware.
SubsystemProcessingHandle * get_processing_context_handle() override
Get the processing context handle for this subsystem.
SubsystemType get_type() const override
Get the type of this subsystem.
std::unique_ptr< IAudioBackend > m_audiobackend
Audio backend implementation.
bool is_ready() const override
Check if audio subsystem is ready for operation.
bool is_running() const override
Check if audio subsystem is currently running.
const AudioDevice * get_device_manager() const
Get read-only access to device manager.
GlobalStreamInfo m_stream_info
Audio stream configuration.
SubsystemProcessingHandle * m_handle
Reference to processing handle.
const AudioStream * get_stream_manager() const
Get read-only access to stream manager.
IAudioBackend * get_audio_backend()
Get access to the underlying audio backend.
std::unordered_map< uint32_t, std::function< void(const double *, uint32_t)> > ObserverMap
SubsystemTokens get_tokens() const override
Get audio subsystem token configuration.
std::vector< double > m_snapshot_copy
Owned copy of the last output cycle; decouples notification-thread reads from the callback write buff...
const GlobalStreamInfo & get_stream_info() const
Get global stream configuration.
SubsystemTokens m_subsystem_tokens
Processing token configuration.
std::shared_ptr< Registry::Service::AudioBackendService > m_audio_backend_service
std::unique_ptr< AudioDevice > m_audio_device
Audio device manager.
std::unique_ptr< AudioStream > m_audio_stream
Audio stream manager.
virtual ~AudioSubsystem()=default
Audio processing subsystem managing real-time audio I/O and processing.
Interface for audio system abstraction layer.
Base interface for all subsystems in the MayaFlux processing architecture.
Definition Subsystem.hpp:26
Unified interface combining buffer and node processing for subsystems.
void initialize()
Definition main.cpp:11
Comprehensive configuration for digital audio stream processing.
Processing token configuration for subsystem operation.