MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
RtAudioSingleton.hpp
Go to the documentation of this file.
1#pragma once
2
3#ifdef RTAUDIO_BACKEND
4#include "RtAudio.h"
5#endif
6
7namespace MayaFlux::Core {
8
9/**
10 * @class RtAudioSingleton
11 * @brief Thread-safe global access point for audio system resources
12 *
13 * Implements the Singleton pattern to provide controlled, centralized access
14 * to the RtAudio subsystem. Ensures that only one instance of the audio driver
15 * exists throughout the application lifecycle, preventing resource conflicts
16 * and maintaining system stability.
17 *
18 * This class enforces strict resource management with the following guarantees:
19 * - Thread safety through mutex-protected access
20 * - Lazy initialization of the audio subsystem
21 * - Exclusive stream ownership validation
22 * - Proper resource cleanup on application termination
23 */
25private:
26 /** @brief Singleton instance of the RtAudio driver (nullptr until first access) */
27 static std::unique_ptr<RtAudio> s_instance;
28
29 /** @brief Synchronization primitive for thread-safe access to the singleton */
30 static std::mutex s_mutex;
31
32 /** @brief Stream state flag to enforce exclusive stream ownership */
33 static bool s_stream_open;
34
35 /**
36 * @brief Private constructor prevents direct instantiation
37 *
38 * Enforces the Singleton pattern by making the constructor inaccessible
39 * to client code, ensuring all access occurs through the static interface.
40 */
41 RtAudioSingleton() = default;
42
43public:
44 /**
45 * @brief Provides access to the RtAudio instance with lazy initialization
46 * @return Pointer to the singleton RtAudio instance
47 *
48 * Thread-safe accessor that creates the RtAudio instance on first access
49 * and returns the existing instance on subsequent calls. The returned
50 * pointer remains valid until cleanup() is called.
51 */
52 static RtAudio* get_instance()
53 {
54 std::lock_guard<std::mutex> lock(s_mutex);
55 if (!s_instance) {
56 s_instance = std::make_unique<RtAudio>();
57 }
58 return s_instance.get();
59 }
60
61 /**
62 * @brief Registers an active audio stream in the system
63 * @throws std::runtime_error if a stream is already open
64 *
65 * Thread-safe method that enforces the constraint of having only
66 * one active audio stream at any time. This prevents resource conflicts
67 * that could lead to audio glitches or system instability.
68 */
69 static void mark_stream_open()
70 {
71 std::lock_guard<std::mutex> lock(s_mutex);
72 if (s_stream_open) {
73 throw std::runtime_error("Error: Attempted to open a second RtAudio stream when one is already open");
74 }
75 s_stream_open = true;
76 }
77
78 /**
79 * @brief Deregisters an active audio stream from the system
80 *
81 * Thread-safe method that updates the internal state to reflect
82 * that no audio stream is currently active, allowing a new stream
83 * to be opened if needed.
84 */
85 static void mark_stream_closed()
86 {
87 std::lock_guard<std::mutex> lock(s_mutex);
88 s_stream_open = false;
89 }
90
91 /**
92 * @brief Checks if an audio stream is currently active
93 * @return True if a stream is open, false otherwise
94 *
95 * Thread-safe method that provides the current state of stream
96 * ownership without modifying any internal state.
97 */
98 static bool is_stream_open()
99 {
100 std::lock_guard<std::mutex> lock(s_mutex);
101 return s_stream_open;
102 }
103
104 /**
105 * @brief Releases all audio system resources
106 *
107 * Thread-safe method that performs complete cleanup of the audio
108 * subsystem, including stopping and closing any active streams
109 * and releasing the RtAudio instance. This method is idempotent
110 * and can be safely called multiple times.
111 *
112 * This method should be called only before application termination to
113 * ensure proper resource deallocation and prevent memory leaks. It is not
114 * intended for general use and should not be called during normal
115 * application operation.
116 */
117 static void cleanup()
118 {
119 std::lock_guard<std::mutex> lock(s_mutex);
120 if (s_instance && s_stream_open) {
121 try {
122 if (s_instance->isStreamRunning()) {
123 s_instance->stopStream();
124 }
125 if (s_instance->isStreamOpen()) {
126 s_instance->closeStream();
127 }
128 s_stream_open = false;
129 } catch (const RtAudioErrorType& e) {
130 std::cerr << "Error during RtAudio cleanup: " << s_instance->getErrorText() << std::endl;
131 }
132 }
133 if (s_instance) {
134 s_instance.reset();
135 }
136 }
137};
138
139}
static bool is_stream_open()
Checks if an audio stream is currently active.
static void mark_stream_closed()
Deregisters an active audio stream from the system.
static std::unique_ptr< RtAudio > s_instance
Singleton instance of the RtAudio driver (nullptr until first access)
static bool s_stream_open
Stream state flag to enforce exclusive stream ownership.
static RtAudio * get_instance()
Provides access to the RtAudio instance with lazy initialization.
static std::mutex s_mutex
Synchronization primitive for thread-safe access to the singleton.
static void mark_stream_open()
Registers an active audio stream in the system.
RtAudioSingleton()=default
Private constructor prevents direct instantiation.
static void cleanup()
Releases all audio system resources.
Thread-safe global access point for audio system resources.