f@0
|
1 /************************************************************************/
|
f@0
|
2 /*! \class RtAudio
|
f@0
|
3 \brief Realtime audio i/o C++ classes.
|
f@0
|
4
|
f@0
|
5 RtAudio provides a common API (Application Programming Interface)
|
f@0
|
6 for realtime audio input/output across Linux (native ALSA, Jack,
|
f@0
|
7 and OSS), Macintosh OS X (CoreAudio and Jack), and Windows
|
f@0
|
8 (DirectSound, ASIO and WASAPI) operating systems.
|
f@0
|
9
|
f@0
|
10 RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/
|
f@0
|
11
|
f@0
|
12 RtAudio: realtime audio i/o C++ classes
|
f@0
|
13 Copyright (c) 2001-2014 Gary P. Scavone
|
f@0
|
14
|
f@0
|
15 Permission is hereby granted, free of charge, to any person
|
f@0
|
16 obtaining a copy of this software and associated documentation files
|
f@0
|
17 (the "Software"), to deal in the Software without restriction,
|
f@0
|
18 including without limitation the rights to use, copy, modify, merge,
|
f@0
|
19 publish, distribute, sublicense, and/or sell copies of the Software,
|
f@0
|
20 and to permit persons to whom the Software is furnished to do so,
|
f@0
|
21 subject to the following conditions:
|
f@0
|
22
|
f@0
|
23 The above copyright notice and this permission notice shall be
|
f@0
|
24 included in all copies or substantial portions of the Software.
|
f@0
|
25
|
f@0
|
26 Any person wishing to distribute modifications to the Software is
|
f@0
|
27 asked to send the modifications to the original developer so that
|
f@0
|
28 they can be incorporated into the canonical version. This is,
|
f@0
|
29 however, not a binding provision of this license.
|
f@0
|
30
|
f@0
|
31 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
f@0
|
32 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
f@0
|
33 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
f@0
|
34 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
f@0
|
35 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
f@0
|
36 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
f@0
|
37 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
f@0
|
38 */
|
f@0
|
39 /************************************************************************/
|
f@0
|
40
|
f@0
|
41 /*!
|
f@0
|
42 \file RtAudio.h
|
f@0
|
43 */
|
f@0
|
44
|
f@0
|
45 #ifndef __RTAUDIO_H
|
f@0
|
46 #define __RTAUDIO_H
|
f@0
|
47
|
f@0
|
48 #define RTAUDIO_VERSION "4.1.1"
|
f@0
|
49
|
f@0
|
50 #include <string>
|
f@0
|
51 #include <vector>
|
f@0
|
52 #include <exception>
|
f@0
|
53 #include <iostream>
|
f@0
|
54
|
f@0
|
55 /*! \typedef typedef unsigned long RtAudioFormat;
|
f@0
|
56 \brief RtAudio data format type.
|
f@0
|
57
|
f@0
|
58 Support for signed integers and floats. Audio data fed to/from an
|
f@0
|
59 RtAudio stream is assumed to ALWAYS be in host byte order. The
|
f@0
|
60 internal routines will automatically take care of any necessary
|
f@0
|
61 byte-swapping between the host format and the soundcard. Thus,
|
f@0
|
62 endian-ness is not a concern in the following format definitions.
|
f@0
|
63
|
f@0
|
64 - \e RTAUDIO_SINT8: 8-bit signed integer.
|
f@0
|
65 - \e RTAUDIO_SINT16: 16-bit signed integer.
|
f@0
|
66 - \e RTAUDIO_SINT24: 24-bit signed integer.
|
f@0
|
67 - \e RTAUDIO_SINT32: 32-bit signed integer.
|
f@0
|
68 - \e RTAUDIO_FLOAT32: Normalized between plus/minus 1.0.
|
f@0
|
69 - \e RTAUDIO_FLOAT64: Normalized between plus/minus 1.0.
|
f@0
|
70 */
|
f@0
|
71 typedef unsigned long RtAudioFormat;
|
f@0
|
72 static const RtAudioFormat RTAUDIO_SINT8 = 0x1; // 8-bit signed integer.
|
f@0
|
73 static const RtAudioFormat RTAUDIO_SINT16 = 0x2; // 16-bit signed integer.
|
f@0
|
74 static const RtAudioFormat RTAUDIO_SINT24 = 0x4; // 24-bit signed integer.
|
f@0
|
75 static const RtAudioFormat RTAUDIO_SINT32 = 0x8; // 32-bit signed integer.
|
f@0
|
76 static const RtAudioFormat RTAUDIO_FLOAT32 = 0x10; // Normalized between plus/minus 1.0.
|
f@0
|
77 static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; // Normalized between plus/minus 1.0.
|
f@0
|
78
|
f@0
|
79 /*! \typedef typedef unsigned long RtAudioStreamFlags;
|
f@0
|
80 \brief RtAudio stream option flags.
|
f@0
|
81
|
f@0
|
82 The following flags can be OR'ed together to allow a client to
|
f@0
|
83 make changes to the default stream behavior:
|
f@0
|
84
|
f@0
|
85 - \e RTAUDIO_NONINTERLEAVED: Use non-interleaved buffers (default = interleaved).
|
f@0
|
86 - \e RTAUDIO_MINIMIZE_LATENCY: Attempt to set stream parameters for lowest possible latency.
|
f@0
|
87 - \e RTAUDIO_HOG_DEVICE: Attempt grab device for exclusive use.
|
f@0
|
88 - \e RTAUDIO_ALSA_USE_DEFAULT: Use the "default" PCM device (ALSA only).
|
f@0
|
89
|
f@0
|
90 By default, RtAudio streams pass and receive audio data from the
|
f@0
|
91 client in an interleaved format. By passing the
|
f@0
|
92 RTAUDIO_NONINTERLEAVED flag to the openStream() function, audio
|
f@0
|
93 data will instead be presented in non-interleaved buffers. In
|
f@0
|
94 this case, each buffer argument in the RtAudioCallback function
|
f@0
|
95 will point to a single array of data, with \c nFrames samples for
|
f@0
|
96 each channel concatenated back-to-back. For example, the first
|
f@0
|
97 sample of data for the second channel would be located at index \c
|
f@0
|
98 nFrames (assuming the \c buffer pointer was recast to the correct
|
f@0
|
99 data type for the stream).
|
f@0
|
100
|
f@0
|
101 Certain audio APIs offer a number of parameters that influence the
|
f@0
|
102 I/O latency of a stream. By default, RtAudio will attempt to set
|
f@0
|
103 these parameters internally for robust (glitch-free) performance
|
f@0
|
104 (though some APIs, like Windows Direct Sound, make this difficult).
|
f@0
|
105 By passing the RTAUDIO_MINIMIZE_LATENCY flag to the openStream()
|
f@0
|
106 function, internal stream settings will be influenced in an attempt
|
f@0
|
107 to minimize stream latency, though possibly at the expense of stream
|
f@0
|
108 performance.
|
f@0
|
109
|
f@0
|
110 If the RTAUDIO_HOG_DEVICE flag is set, RtAudio will attempt to
|
f@0
|
111 open the input and/or output stream device(s) for exclusive use.
|
f@0
|
112 Note that this is not possible with all supported audio APIs.
|
f@0
|
113
|
f@0
|
114 If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt
|
f@0
|
115 to select realtime scheduling (round-robin) for the callback thread.
|
f@0
|
116
|
f@0
|
117 If the RTAUDIO_ALSA_USE_DEFAULT flag is set, RtAudio will attempt to
|
f@0
|
118 open the "default" PCM device when using the ALSA API. Note that this
|
f@0
|
119 will override any specified input or output device id.
|
f@0
|
120 */
|
f@0
|
121 typedef unsigned int RtAudioStreamFlags;
|
f@0
|
122 static const RtAudioStreamFlags RTAUDIO_NONINTERLEAVED = 0x1; // Use non-interleaved buffers (default = interleaved).
|
f@0
|
123 static const RtAudioStreamFlags RTAUDIO_MINIMIZE_LATENCY = 0x2; // Attempt to set stream parameters for lowest possible latency.
|
f@0
|
124 static const RtAudioStreamFlags RTAUDIO_HOG_DEVICE = 0x4; // Attempt grab device and prevent use by others.
|
f@0
|
125 static const RtAudioStreamFlags RTAUDIO_SCHEDULE_REALTIME = 0x8; // Try to select realtime scheduling for callback thread.
|
f@0
|
126 static const RtAudioStreamFlags RTAUDIO_ALSA_USE_DEFAULT = 0x10; // Use the "default" PCM device (ALSA only).
|
f@0
|
127
|
f@0
|
128 /*! \typedef typedef unsigned long RtAudioStreamStatus;
|
f@0
|
129 \brief RtAudio stream status (over- or underflow) flags.
|
f@0
|
130
|
f@0
|
131 Notification of a stream over- or underflow is indicated by a
|
f@0
|
132 non-zero stream \c status argument in the RtAudioCallback function.
|
f@0
|
133 The stream status can be one of the following two options,
|
f@0
|
134 depending on whether the stream is open for output and/or input:
|
f@0
|
135
|
f@0
|
136 - \e RTAUDIO_INPUT_OVERFLOW: Input data was discarded because of an overflow condition at the driver.
|
f@0
|
137 - \e RTAUDIO_OUTPUT_UNDERFLOW: The output buffer ran low, likely producing a break in the output sound.
|
f@0
|
138 */
|
f@0
|
139 typedef unsigned int RtAudioStreamStatus;
|
f@0
|
140 static const RtAudioStreamStatus RTAUDIO_INPUT_OVERFLOW = 0x1; // Input data was discarded because of an overflow condition at the driver.
|
f@0
|
141 static const RtAudioStreamStatus RTAUDIO_OUTPUT_UNDERFLOW = 0x2; // The output buffer ran low, likely causing a gap in the output sound.
|
f@0
|
142
|
f@0
|
143 //! RtAudio callback function prototype.
|
f@0
|
144 /*!
|
f@0
|
145 All RtAudio clients must create a function of type RtAudioCallback
|
f@0
|
146 to read and/or write data from/to the audio stream. When the
|
f@0
|
147 underlying audio system is ready for new input or output data, this
|
f@0
|
148 function will be invoked.
|
f@0
|
149
|
f@0
|
150 \param outputBuffer For output (or duplex) streams, the client
|
f@0
|
151 should write \c nFrames of audio sample frames into this
|
f@0
|
152 buffer. This argument should be recast to the datatype
|
f@0
|
153 specified when the stream was opened. For input-only
|
f@0
|
154 streams, this argument will be NULL.
|
f@0
|
155
|
f@0
|
156 \param inputBuffer For input (or duplex) streams, this buffer will
|
f@0
|
157 hold \c nFrames of input audio sample frames. This
|
f@0
|
158 argument should be recast to the datatype specified when the
|
f@0
|
159 stream was opened. For output-only streams, this argument
|
f@0
|
160 will be NULL.
|
f@0
|
161
|
f@0
|
162 \param nFrames The number of sample frames of input or output
|
f@0
|
163 data in the buffers. The actual buffer size in bytes is
|
f@0
|
164 dependent on the data type and number of channels in use.
|
f@0
|
165
|
f@0
|
166 \param streamTime The number of seconds that have elapsed since the
|
f@0
|
167 stream was started.
|
f@0
|
168
|
f@0
|
169 \param status If non-zero, this argument indicates a data overflow
|
f@0
|
170 or underflow condition for the stream. The particular
|
f@0
|
171 condition can be determined by comparison with the
|
f@0
|
172 RtAudioStreamStatus flags.
|
f@0
|
173
|
f@0
|
174 \param userData A pointer to optional data provided by the client
|
f@0
|
175 when opening the stream (default = NULL).
|
f@0
|
176
|
f@0
|
177 To continue normal stream operation, the RtAudioCallback function
|
f@0
|
178 should return a value of zero. To stop the stream and drain the
|
f@0
|
179 output buffer, the function should return a value of one. To abort
|
f@0
|
180 the stream immediately, the client should return a value of two.
|
f@0
|
181 */
|
f@0
|
182 typedef int (*RtAudioCallback)( void *outputBuffer, void *inputBuffer,
|
f@0
|
183 unsigned int nFrames,
|
f@0
|
184 double streamTime,
|
f@0
|
185 RtAudioStreamStatus status,
|
f@0
|
186 void *userData );
|
f@0
|
187
|
f@0
|
188 /************************************************************************/
|
f@0
|
189 /*! \class RtAudioError
|
f@0
|
190 \brief Exception handling class for RtAudio.
|
f@0
|
191
|
f@0
|
192 The RtAudioError class is quite simple but it does allow errors to be
|
f@0
|
193 "caught" by RtAudioError::Type. See the RtAudio documentation to know
|
f@0
|
194 which methods can throw an RtAudioError.
|
f@0
|
195 */
|
f@0
|
196 /************************************************************************/
|
f@0
|
197
|
f@0
|
198 class RtAudioError : public std::exception
|
f@0
|
199 {
|
f@0
|
200 public:
|
f@0
|
201 //! Defined RtAudioError types.
|
f@0
|
202 enum Type {
|
f@0
|
203 WARNING, /*!< A non-critical error. */
|
f@0
|
204 DEBUG_WARNING, /*!< A non-critical error which might be useful for debugging. */
|
f@0
|
205 UNSPECIFIED, /*!< The default, unspecified error type. */
|
f@0
|
206 NO_DEVICES_FOUND, /*!< No devices found on system. */
|
f@0
|
207 INVALID_DEVICE, /*!< An invalid device ID was specified. */
|
f@0
|
208 MEMORY_ERROR, /*!< An error occured during memory allocation. */
|
f@0
|
209 INVALID_PARAMETER, /*!< An invalid parameter was specified to a function. */
|
f@0
|
210 INVALID_USE, /*!< The function was called incorrectly. */
|
f@0
|
211 DRIVER_ERROR, /*!< A system driver error occured. */
|
f@0
|
212 SYSTEM_ERROR, /*!< A system error occured. */
|
f@0
|
213 THREAD_ERROR /*!< A thread error occured. */
|
f@0
|
214 };
|
f@0
|
215
|
f@0
|
216 //! The constructor.
|
f@0
|
217 RtAudioError( const std::string& message, Type type = RtAudioError::UNSPECIFIED ) throw() : message_(message), type_(type) {}
|
f@0
|
218
|
f@0
|
219 //! The destructor.
|
f@0
|
220 virtual ~RtAudioError( void ) throw() {}
|
f@0
|
221
|
f@0
|
222 //! Prints thrown error message to stderr.
|
f@0
|
223 virtual void printMessage( void ) const throw() { std::cerr << '\n' << message_ << "\n\n"; }
|
f@0
|
224
|
f@0
|
225 //! Returns the thrown error message type.
|
f@0
|
226 virtual const Type& getType(void) const throw() { return type_; }
|
f@0
|
227
|
f@0
|
228 //! Returns the thrown error message string.
|
f@0
|
229 virtual const std::string& getMessage(void) const throw() { return message_; }
|
f@0
|
230
|
f@0
|
231 //! Returns the thrown error message as a c-style string.
|
f@0
|
232 virtual const char* what( void ) const throw() { return message_.c_str(); }
|
f@0
|
233
|
f@0
|
234 protected:
|
f@0
|
235 std::string message_;
|
f@0
|
236 Type type_;
|
f@0
|
237 };
|
f@0
|
238
|
f@0
|
239 //! RtAudio error callback function prototype.
|
f@0
|
240 /*!
|
f@0
|
241 \param type Type of error.
|
f@0
|
242 \param errorText Error description.
|
f@0
|
243 */
|
f@0
|
244 typedef void (*RtAudioErrorCallback)( RtAudioError::Type type, const std::string &errorText );
|
f@0
|
245
|
f@0
|
246 // **************************************************************** //
|
f@0
|
247 //
|
f@0
|
248 // RtAudio class declaration.
|
f@0
|
249 //
|
f@0
|
250 // RtAudio is a "controller" used to select an available audio i/o
|
f@0
|
251 // interface. It presents a common API for the user to call but all
|
f@0
|
252 // functionality is implemented by the class RtApi and its
|
f@0
|
253 // subclasses. RtAudio creates an instance of an RtApi subclass
|
f@0
|
254 // based on the user's API choice. If no choice is made, RtAudio
|
f@0
|
255 // attempts to make a "logical" API selection.
|
f@0
|
256 //
|
f@0
|
257 // **************************************************************** //
|
f@0
|
258
|
f@0
|
259 class RtApi;
|
f@0
|
260
|
f@0
|
261 class RtAudio
|
f@0
|
262 {
|
f@0
|
263 public:
|
f@0
|
264
|
f@0
|
265 //! Audio API specifier arguments.
|
f@0
|
266 enum Api {
|
f@0
|
267 UNSPECIFIED, /*!< Search for a working compiled API. */
|
f@0
|
268 LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */
|
f@0
|
269 LINUX_PULSE, /*!< The Linux PulseAudio API. */
|
f@0
|
270 LINUX_OSS, /*!< The Linux Open Sound System API. */
|
f@0
|
271 UNIX_JACK, /*!< The Jack Low-Latency Audio Server API. */
|
f@0
|
272 MACOSX_CORE, /*!< Macintosh OS-X Core Audio API. */
|
f@0
|
273 WINDOWS_WASAPI, /*!< The Microsoft WASAPI API. */
|
f@0
|
274 WINDOWS_ASIO, /*!< The Steinberg Audio Stream I/O API. */
|
f@0
|
275 WINDOWS_DS, /*!< The Microsoft Direct Sound API. */
|
f@0
|
276 RTAUDIO_DUMMY /*!< A compilable but non-functional API. */
|
f@0
|
277 };
|
f@0
|
278
|
f@0
|
279 //! The public device information structure for returning queried values.
|
f@0
|
280 struct DeviceInfo {
|
f@0
|
281 bool probed; /*!< true if the device capabilities were successfully probed. */
|
f@0
|
282 std::string name; /*!< Character string device identifier. */
|
f@0
|
283 unsigned int outputChannels; /*!< Maximum output channels supported by device. */
|
f@0
|
284 unsigned int inputChannels; /*!< Maximum input channels supported by device. */
|
f@0
|
285 unsigned int duplexChannels; /*!< Maximum simultaneous input/output channels supported by device. */
|
f@0
|
286 bool isDefaultOutput; /*!< true if this is the default output device. */
|
f@0
|
287 bool isDefaultInput; /*!< true if this is the default input device. */
|
f@0
|
288 std::vector<unsigned int> sampleRates; /*!< Supported sample rates (queried from list of standard rates). */
|
f@0
|
289 RtAudioFormat nativeFormats; /*!< Bit mask of supported data formats. */
|
f@0
|
290
|
f@0
|
291 // Default constructor.
|
f@0
|
292 DeviceInfo()
|
f@0
|
293 :probed(false), outputChannels(0), inputChannels(0), duplexChannels(0),
|
f@0
|
294 isDefaultOutput(false), isDefaultInput(false), nativeFormats(0) {}
|
f@0
|
295 };
|
f@0
|
296
|
f@0
|
297 //! The structure for specifying input or ouput stream parameters.
|
f@0
|
298 struct StreamParameters {
|
f@0
|
299 unsigned int deviceId; /*!< Device index (0 to getDeviceCount() - 1). */
|
f@0
|
300 unsigned int nChannels; /*!< Number of channels. */
|
f@0
|
301 unsigned int firstChannel; /*!< First channel index on device (default = 0). */
|
f@0
|
302
|
f@0
|
303 // Default constructor.
|
f@0
|
304 StreamParameters()
|
f@0
|
305 : deviceId(0), nChannels(0), firstChannel(0) {}
|
f@0
|
306 };
|
f@0
|
307
|
f@0
|
308 //! The structure for specifying stream options.
|
f@0
|
309 /*!
|
f@0
|
310 The following flags can be OR'ed together to allow a client to
|
f@0
|
311 make changes to the default stream behavior:
|
f@0
|
312
|
f@0
|
313 - \e RTAUDIO_NONINTERLEAVED: Use non-interleaved buffers (default = interleaved).
|
f@0
|
314 - \e RTAUDIO_MINIMIZE_LATENCY: Attempt to set stream parameters for lowest possible latency.
|
f@0
|
315 - \e RTAUDIO_HOG_DEVICE: Attempt grab device for exclusive use.
|
f@0
|
316 - \e RTAUDIO_SCHEDULE_REALTIME: Attempt to select realtime scheduling for callback thread.
|
f@0
|
317 - \e RTAUDIO_ALSA_USE_DEFAULT: Use the "default" PCM device (ALSA only).
|
f@0
|
318
|
f@0
|
319 By default, RtAudio streams pass and receive audio data from the
|
f@0
|
320 client in an interleaved format. By passing the
|
f@0
|
321 RTAUDIO_NONINTERLEAVED flag to the openStream() function, audio
|
f@0
|
322 data will instead be presented in non-interleaved buffers. In
|
f@0
|
323 this case, each buffer argument in the RtAudioCallback function
|
f@0
|
324 will point to a single array of data, with \c nFrames samples for
|
f@0
|
325 each channel concatenated back-to-back. For example, the first
|
f@0
|
326 sample of data for the second channel would be located at index \c
|
f@0
|
327 nFrames (assuming the \c buffer pointer was recast to the correct
|
f@0
|
328 data type for the stream).
|
f@0
|
329
|
f@0
|
330 Certain audio APIs offer a number of parameters that influence the
|
f@0
|
331 I/O latency of a stream. By default, RtAudio will attempt to set
|
f@0
|
332 these parameters internally for robust (glitch-free) performance
|
f@0
|
333 (though some APIs, like Windows Direct Sound, make this difficult).
|
f@0
|
334 By passing the RTAUDIO_MINIMIZE_LATENCY flag to the openStream()
|
f@0
|
335 function, internal stream settings will be influenced in an attempt
|
f@0
|
336 to minimize stream latency, though possibly at the expense of stream
|
f@0
|
337 performance.
|
f@0
|
338
|
f@0
|
339 If the RTAUDIO_HOG_DEVICE flag is set, RtAudio will attempt to
|
f@0
|
340 open the input and/or output stream device(s) for exclusive use.
|
f@0
|
341 Note that this is not possible with all supported audio APIs.
|
f@0
|
342
|
f@0
|
343 If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt
|
f@0
|
344 to select realtime scheduling (round-robin) for the callback thread.
|
f@0
|
345 The \c priority parameter will only be used if the RTAUDIO_SCHEDULE_REALTIME
|
f@0
|
346 flag is set. It defines the thread's realtime priority.
|
f@0
|
347
|
f@0
|
348 If the RTAUDIO_ALSA_USE_DEFAULT flag is set, RtAudio will attempt to
|
f@0
|
349 open the "default" PCM device when using the ALSA API. Note that this
|
f@0
|
350 will override any specified input or output device id.
|
f@0
|
351
|
f@0
|
352 The \c numberOfBuffers parameter can be used to control stream
|
f@0
|
353 latency in the Windows DirectSound, Linux OSS, and Linux Alsa APIs
|
f@0
|
354 only. A value of two is usually the smallest allowed. Larger
|
f@0
|
355 numbers can potentially result in more robust stream performance,
|
f@0
|
356 though likely at the cost of stream latency. The value set by the
|
f@0
|
357 user is replaced during execution of the RtAudio::openStream()
|
f@0
|
358 function by the value actually used by the system.
|
f@0
|
359
|
f@0
|
360 The \c streamName parameter can be used to set the client name
|
f@0
|
361 when using the Jack API. By default, the client name is set to
|
f@0
|
362 RtApiJack. However, if you wish to create multiple instances of
|
f@0
|
363 RtAudio with Jack, each instance must have a unique client name.
|
f@0
|
364 */
|
f@0
|
365 struct StreamOptions {
|
f@0
|
366 RtAudioStreamFlags flags; /*!< A bit-mask of stream flags (RTAUDIO_NONINTERLEAVED, RTAUDIO_MINIMIZE_LATENCY, RTAUDIO_HOG_DEVICE, RTAUDIO_ALSA_USE_DEFAULT). */
|
f@0
|
367 unsigned int numberOfBuffers; /*!< Number of stream buffers. */
|
f@0
|
368 std::string streamName; /*!< A stream name (currently used only in Jack). */
|
f@0
|
369 int priority; /*!< Scheduling priority of callback thread (only used with flag RTAUDIO_SCHEDULE_REALTIME). */
|
f@0
|
370
|
f@0
|
371 // Default constructor.
|
f@0
|
372 StreamOptions()
|
f@0
|
373 : flags(0), numberOfBuffers(0), priority(0) {}
|
f@0
|
374 };
|
f@0
|
375
|
f@0
|
376 //! A static function to determine the current RtAudio version.
|
f@0
|
377 static std::string getVersion( void ) throw();
|
f@0
|
378
|
f@0
|
379 //! A static function to determine the available compiled audio APIs.
|
f@0
|
380 /*!
|
f@0
|
381 The values returned in the std::vector can be compared against
|
f@0
|
382 the enumerated list values. Note that there can be more than one
|
f@0
|
383 API compiled for certain operating systems.
|
f@0
|
384 */
|
f@0
|
385 static void getCompiledApi( std::vector<RtAudio::Api> &apis ) throw();
|
f@0
|
386
|
f@0
|
387 //! The class constructor.
|
f@0
|
388 /*!
|
f@0
|
389 The constructor performs minor initialization tasks. An exception
|
f@0
|
390 can be thrown if no API support is compiled.
|
f@0
|
391
|
f@0
|
392 If no API argument is specified and multiple API support has been
|
f@0
|
393 compiled, the default order of use is JACK, ALSA, OSS (Linux
|
f@0
|
394 systems) and ASIO, DS (Windows systems).
|
f@0
|
395 */
|
f@0
|
396 RtAudio( RtAudio::Api api=UNSPECIFIED );
|
f@0
|
397
|
f@0
|
398 //! The destructor.
|
f@0
|
399 /*!
|
f@0
|
400 If a stream is running or open, it will be stopped and closed
|
f@0
|
401 automatically.
|
f@0
|
402 */
|
f@0
|
403 ~RtAudio() throw();
|
f@0
|
404
|
f@0
|
405 //! Returns the audio API specifier for the current instance of RtAudio.
|
f@0
|
406 RtAudio::Api getCurrentApi( void ) throw();
|
f@0
|
407
|
f@0
|
408 //! A public function that queries for the number of audio devices available.
|
f@0
|
409 /*!
|
f@0
|
410 This function performs a system query of available devices each time it
|
f@0
|
411 is called, thus supporting devices connected \e after instantiation. If
|
f@0
|
412 a system error occurs during processing, a warning will be issued.
|
f@0
|
413 */
|
f@0
|
414 unsigned int getDeviceCount( void ) throw();
|
f@0
|
415
|
f@0
|
416 //! Return an RtAudio::DeviceInfo structure for a specified device number.
|
f@0
|
417 /*!
|
f@0
|
418
|
f@0
|
419 Any device integer between 0 and getDeviceCount() - 1 is valid.
|
f@0
|
420 If an invalid argument is provided, an RtAudioError (type = INVALID_USE)
|
f@0
|
421 will be thrown. If a device is busy or otherwise unavailable, the
|
f@0
|
422 structure member "probed" will have a value of "false" and all
|
f@0
|
423 other members are undefined. If the specified device is the
|
f@0
|
424 current default input or output device, the corresponding
|
f@0
|
425 "isDefault" member will have a value of "true".
|
f@0
|
426 */
|
f@0
|
427 RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
|
f@0
|
428
|
f@0
|
429 //! A function that returns the index of the default output device.
|
f@0
|
430 /*!
|
f@0
|
431 If the underlying audio API does not provide a "default
|
f@0
|
432 device", or if no devices are available, the return value will be
|
f@0
|
433 0. Note that this is a valid device identifier and it is the
|
f@0
|
434 client's responsibility to verify that a device is available
|
f@0
|
435 before attempting to open a stream.
|
f@0
|
436 */
|
f@0
|
437 unsigned int getDefaultOutputDevice( void ) throw();
|
f@0
|
438
|
f@0
|
439 //! A function that returns the index of the default input device.
|
f@0
|
440 /*!
|
f@0
|
441 If the underlying audio API does not provide a "default
|
f@0
|
442 device", or if no devices are available, the return value will be
|
f@0
|
443 0. Note that this is a valid device identifier and it is the
|
f@0
|
444 client's responsibility to verify that a device is available
|
f@0
|
445 before attempting to open a stream.
|
f@0
|
446 */
|
f@0
|
447 unsigned int getDefaultInputDevice( void ) throw();
|
f@0
|
448
|
f@0
|
449 //! A public function for opening a stream with the specified parameters.
|
f@0
|
450 /*!
|
f@0
|
451 An RtAudioError (type = SYSTEM_ERROR) is thrown if a stream cannot be
|
f@0
|
452 opened with the specified parameters or an error occurs during
|
f@0
|
453 processing. An RtAudioError (type = INVALID_USE) is thrown if any
|
f@0
|
454 invalid device ID or channel number parameters are specified.
|
f@0
|
455
|
f@0
|
456 \param outputParameters Specifies output stream parameters to use
|
f@0
|
457 when opening a stream, including a device ID, number of channels,
|
f@0
|
458 and starting channel number. For input-only streams, this
|
f@0
|
459 argument should be NULL. The device ID is an index value between
|
f@0
|
460 0 and getDeviceCount() - 1.
|
f@0
|
461 \param inputParameters Specifies input stream parameters to use
|
f@0
|
462 when opening a stream, including a device ID, number of channels,
|
f@0
|
463 and starting channel number. For output-only streams, this
|
f@0
|
464 argument should be NULL. The device ID is an index value between
|
f@0
|
465 0 and getDeviceCount() - 1.
|
f@0
|
466 \param format An RtAudioFormat specifying the desired sample data format.
|
f@0
|
467 \param sampleRate The desired sample rate (sample frames per second).
|
f@0
|
468 \param *bufferFrames A pointer to a value indicating the desired
|
f@0
|
469 internal buffer size in sample frames. The actual value
|
f@0
|
470 used by the device is returned via the same pointer. A
|
f@0
|
471 value of zero can be specified, in which case the lowest
|
f@0
|
472 allowable value is determined.
|
f@0
|
473 \param callback A client-defined function that will be invoked
|
f@0
|
474 when input data is available and/or output data is needed.
|
f@0
|
475 \param userData An optional pointer to data that can be accessed
|
f@0
|
476 from within the callback function.
|
f@0
|
477 \param options An optional pointer to a structure containing various
|
f@0
|
478 global stream options, including a list of OR'ed RtAudioStreamFlags
|
f@0
|
479 and a suggested number of stream buffers that can be used to
|
f@0
|
480 control stream latency. More buffers typically result in more
|
f@0
|
481 robust performance, though at a cost of greater latency. If a
|
f@0
|
482 value of zero is specified, a system-specific median value is
|
f@0
|
483 chosen. If the RTAUDIO_MINIMIZE_LATENCY flag bit is set, the
|
f@0
|
484 lowest allowable value is used. The actual value used is
|
f@0
|
485 returned via the structure argument. The parameter is API dependent.
|
f@0
|
486 \param errorCallback A client-defined function that will be invoked
|
f@0
|
487 when an error has occured.
|
f@0
|
488 */
|
f@0
|
489 void openStream( RtAudio::StreamParameters *outputParameters,
|
f@0
|
490 RtAudio::StreamParameters *inputParameters,
|
f@0
|
491 RtAudioFormat format, unsigned int sampleRate,
|
f@0
|
492 unsigned int *bufferFrames, RtAudioCallback callback,
|
f@0
|
493 void *userData = NULL, RtAudio::StreamOptions *options = NULL, RtAudioErrorCallback errorCallback = NULL );
|
f@0
|
494
|
f@0
|
495 //! A function that closes a stream and frees any associated stream memory.
|
f@0
|
496 /*!
|
f@0
|
497 If a stream is not open, this function issues a warning and
|
f@0
|
498 returns (no exception is thrown).
|
f@0
|
499 */
|
f@0
|
500 void closeStream( void ) throw();
|
f@0
|
501
|
f@0
|
502 //! A function that starts a stream.
|
f@0
|
503 /*!
|
f@0
|
504 An RtAudioError (type = SYSTEM_ERROR) is thrown if an error occurs
|
f@0
|
505 during processing. An RtAudioError (type = INVALID_USE) is thrown if a
|
f@0
|
506 stream is not open. A warning is issued if the stream is already
|
f@0
|
507 running.
|
f@0
|
508 */
|
f@0
|
509 void startStream( void );
|
f@0
|
510
|
f@0
|
511 //! Stop a stream, allowing any samples remaining in the output queue to be played.
|
f@0
|
512 /*!
|
f@0
|
513 An RtAudioError (type = SYSTEM_ERROR) is thrown if an error occurs
|
f@0
|
514 during processing. An RtAudioError (type = INVALID_USE) is thrown if a
|
f@0
|
515 stream is not open. A warning is issued if the stream is already
|
f@0
|
516 stopped.
|
f@0
|
517 */
|
f@0
|
518 void stopStream( void );
|
f@0
|
519
|
f@0
|
520 //! Stop a stream, discarding any samples remaining in the input/output queue.
|
f@0
|
521 /*!
|
f@0
|
522 An RtAudioError (type = SYSTEM_ERROR) is thrown if an error occurs
|
f@0
|
523 during processing. An RtAudioError (type = INVALID_USE) is thrown if a
|
f@0
|
524 stream is not open. A warning is issued if the stream is already
|
f@0
|
525 stopped.
|
f@0
|
526 */
|
f@0
|
527 void abortStream( void );
|
f@0
|
528
|
f@0
|
529 //! Returns true if a stream is open and false if not.
|
f@0
|
530 bool isStreamOpen( void ) const throw();
|
f@0
|
531
|
f@0
|
532 //! Returns true if the stream is running and false if it is stopped or not open.
|
f@0
|
533 bool isStreamRunning( void ) const throw();
|
f@0
|
534
|
f@0
|
535 //! Returns the number of elapsed seconds since the stream was started.
|
f@0
|
536 /*!
|
f@0
|
537 If a stream is not open, an RtAudioError (type = INVALID_USE) will be thrown.
|
f@0
|
538 */
|
f@0
|
539 double getStreamTime( void );
|
f@0
|
540
|
f@0
|
541 //! Set the stream time to a time in seconds greater than or equal to 0.0.
|
f@0
|
542 /*!
|
f@0
|
543 If a stream is not open, an RtAudioError (type = INVALID_USE) will be thrown.
|
f@0
|
544 */
|
f@0
|
545 void setStreamTime( double time );
|
f@0
|
546
|
f@0
|
547 //! Returns the internal stream latency in sample frames.
|
f@0
|
548 /*!
|
f@0
|
549 The stream latency refers to delay in audio input and/or output
|
f@0
|
550 caused by internal buffering by the audio system and/or hardware.
|
f@0
|
551 For duplex streams, the returned value will represent the sum of
|
f@0
|
552 the input and output latencies. If a stream is not open, an
|
f@0
|
553 RtAudioError (type = INVALID_USE) will be thrown. If the API does not
|
f@0
|
554 report latency, the return value will be zero.
|
f@0
|
555 */
|
f@0
|
556 long getStreamLatency( void );
|
f@0
|
557
|
f@0
|
558 //! Returns actual sample rate in use by the stream.
|
f@0
|
559 /*!
|
f@0
|
560 On some systems, the sample rate used may be slightly different
|
f@0
|
561 than that specified in the stream parameters. If a stream is not
|
f@0
|
562 open, an RtAudioError (type = INVALID_USE) will be thrown.
|
f@0
|
563 */
|
f@0
|
564 unsigned int getStreamSampleRate( void );
|
f@0
|
565
|
f@0
|
566 //! Specify whether warning messages should be printed to stderr.
|
f@0
|
567 void showWarnings( bool value = true ) throw();
|
f@0
|
568
|
f@0
|
569 protected:
|
f@0
|
570
|
f@0
|
571 void openRtApi( RtAudio::Api api );
|
f@0
|
572 RtApi *rtapi_;
|
f@0
|
573 };
|
f@0
|
574
|
f@0
|
575 // Operating system dependent thread functionality.
|
f@0
|
576 #if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) || defined(__WINDOWS_WASAPI__)
|
f@0
|
577
|
f@0
|
578 #ifndef NOMINMAX
|
f@0
|
579 #define NOMINMAX
|
f@0
|
580 #endif
|
f@0
|
581 #include <windows.h>
|
f@0
|
582 #include <process.h>
|
f@0
|
583
|
f@0
|
584 typedef uintptr_t ThreadHandle;
|
f@0
|
585 typedef CRITICAL_SECTION StreamMutex;
|
f@0
|
586
|
f@0
|
587 #elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__)
|
f@0
|
588 // Using pthread library for various flavors of unix.
|
f@0
|
589 #include <pthread.h>
|
f@0
|
590
|
f@0
|
591 typedef pthread_t ThreadHandle;
|
f@0
|
592 typedef pthread_mutex_t StreamMutex;
|
f@0
|
593
|
f@0
|
594 #else // Setup for "dummy" behavior
|
f@0
|
595
|
f@0
|
596 #define __RTAUDIO_DUMMY__
|
f@0
|
597 typedef int ThreadHandle;
|
f@0
|
598 typedef int StreamMutex;
|
f@0
|
599
|
f@0
|
600 #endif
|
f@0
|
601
|
f@0
|
602 // This global structure type is used to pass callback information
|
f@0
|
603 // between the private RtAudio stream structure and global callback
|
f@0
|
604 // handling functions.
|
f@0
|
605 struct CallbackInfo {
|
f@0
|
606 void *object; // Used as a "this" pointer.
|
f@0
|
607 ThreadHandle thread;
|
f@0
|
608 void *callback;
|
f@0
|
609 void *userData;
|
f@0
|
610 void *errorCallback;
|
f@0
|
611 void *apiInfo; // void pointer for API specific callback information
|
f@0
|
612 bool isRunning;
|
f@0
|
613 bool doRealtime;
|
f@0
|
614 int priority;
|
f@0
|
615
|
f@0
|
616 // Default constructor.
|
f@0
|
617 CallbackInfo()
|
f@0
|
618 :object(0), callback(0), userData(0), errorCallback(0), apiInfo(0), isRunning(false), doRealtime(false) {}
|
f@0
|
619 };
|
f@0
|
620
|
f@0
|
621 // **************************************************************** //
|
f@0
|
622 //
|
f@0
|
623 // RtApi class declaration.
|
f@0
|
624 //
|
f@0
|
625 // Subclasses of RtApi contain all API- and OS-specific code necessary
|
f@0
|
626 // to fully implement the RtAudio API.
|
f@0
|
627 //
|
f@0
|
628 // Note that RtApi is an abstract base class and cannot be
|
f@0
|
629 // explicitly instantiated. The class RtAudio will create an
|
f@0
|
630 // instance of an RtApi subclass (RtApiOss, RtApiAlsa,
|
f@0
|
631 // RtApiJack, RtApiCore, RtApiDs, or RtApiAsio).
|
f@0
|
632 //
|
f@0
|
633 // **************************************************************** //
|
f@0
|
634
|
f@0
|
635 #pragma pack(push, 1)
|
f@0
|
636 class S24 {
|
f@0
|
637
|
f@0
|
638 protected:
|
f@0
|
639 unsigned char c3[3];
|
f@0
|
640
|
f@0
|
641 public:
|
f@0
|
642 S24() {}
|
f@0
|
643
|
f@0
|
644 S24& operator = ( const int& i ) {
|
f@0
|
645 c3[0] = (i & 0x000000ff);
|
f@0
|
646 c3[1] = (i & 0x0000ff00) >> 8;
|
f@0
|
647 c3[2] = (i & 0x00ff0000) >> 16;
|
f@0
|
648 return *this;
|
f@0
|
649 }
|
f@0
|
650
|
f@0
|
651 S24( const S24& v ) { *this = v; }
|
f@0
|
652 S24( const double& d ) { *this = (int) d; }
|
f@0
|
653 S24( const float& f ) { *this = (int) f; }
|
f@0
|
654 S24( const signed short& s ) { *this = (int) s; }
|
f@0
|
655 S24( const char& c ) { *this = (int) c; }
|
f@0
|
656
|
f@0
|
657 int asInt() {
|
f@0
|
658 int i = c3[0] | (c3[1] << 8) | (c3[2] << 16);
|
f@0
|
659 if (i & 0x800000) i |= ~0xffffff;
|
f@0
|
660 return i;
|
f@0
|
661 }
|
f@0
|
662 };
|
f@0
|
663 #pragma pack(pop)
|
f@0
|
664
|
f@0
|
665 #if defined( HAVE_GETTIMEOFDAY )
|
f@0
|
666 #include <sys/time.h>
|
f@0
|
667 #endif
|
f@0
|
668
|
f@0
|
669 #include <sstream>
|
f@0
|
670
|
f@0
|
671 class RtApi
|
f@0
|
672 {
|
f@0
|
673 public:
|
f@0
|
674
|
f@0
|
675 RtApi();
|
f@0
|
676 virtual ~RtApi();
|
f@0
|
677 virtual RtAudio::Api getCurrentApi( void ) = 0;
|
f@0
|
678 virtual unsigned int getDeviceCount( void ) = 0;
|
f@0
|
679 virtual RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) = 0;
|
f@0
|
680 virtual unsigned int getDefaultInputDevice( void );
|
f@0
|
681 virtual unsigned int getDefaultOutputDevice( void );
|
f@0
|
682 void openStream( RtAudio::StreamParameters *outputParameters,
|
f@0
|
683 RtAudio::StreamParameters *inputParameters,
|
f@0
|
684 RtAudioFormat format, unsigned int sampleRate,
|
f@0
|
685 unsigned int *bufferFrames, RtAudioCallback callback,
|
f@0
|
686 void *userData, RtAudio::StreamOptions *options,
|
f@0
|
687 RtAudioErrorCallback errorCallback );
|
f@0
|
688 virtual void closeStream( void );
|
f@0
|
689 virtual void startStream( void ) = 0;
|
f@0
|
690 virtual void stopStream( void ) = 0;
|
f@0
|
691 virtual void abortStream( void ) = 0;
|
f@0
|
692 long getStreamLatency( void );
|
f@0
|
693 unsigned int getStreamSampleRate( void );
|
f@0
|
694 virtual double getStreamTime( void );
|
f@0
|
695 virtual void setStreamTime( double time );
|
f@0
|
696 bool isStreamOpen( void ) const { return stream_.state != STREAM_CLOSED; }
|
f@0
|
697 bool isStreamRunning( void ) const { return stream_.state == STREAM_RUNNING; }
|
f@0
|
698 void showWarnings( bool value ) { showWarnings_ = value; }
|
f@0
|
699
|
f@0
|
700
|
f@0
|
701 protected:
|
f@0
|
702
|
f@0
|
703 static const unsigned int MAX_SAMPLE_RATES;
|
f@0
|
704 static const unsigned int SAMPLE_RATES[];
|
f@0
|
705
|
f@0
|
706 enum { FAILURE, SUCCESS };
|
f@0
|
707
|
f@0
|
708 enum StreamState {
|
f@0
|
709 STREAM_STOPPED,
|
f@0
|
710 STREAM_STOPPING,
|
f@0
|
711 STREAM_RUNNING,
|
f@0
|
712 STREAM_CLOSED = -50
|
f@0
|
713 };
|
f@0
|
714
|
f@0
|
715 enum StreamMode {
|
f@0
|
716 OUTPUT,
|
f@0
|
717 INPUT,
|
f@0
|
718 DUPLEX,
|
f@0
|
719 UNINITIALIZED = -75
|
f@0
|
720 };
|
f@0
|
721
|
f@0
|
722 // A protected structure used for buffer conversion.
|
f@0
|
723 struct ConvertInfo {
|
f@0
|
724 int channels;
|
f@0
|
725 int inJump, outJump;
|
f@0
|
726 RtAudioFormat inFormat, outFormat;
|
f@0
|
727 std::vector<int> inOffset;
|
f@0
|
728 std::vector<int> outOffset;
|
f@0
|
729 };
|
f@0
|
730
|
f@0
|
731 // A protected structure for audio streams.
|
f@0
|
732 struct RtApiStream {
|
f@0
|
733 unsigned int device[2]; // Playback and record, respectively.
|
f@0
|
734 void *apiHandle; // void pointer for API specific stream handle information
|
f@0
|
735 StreamMode mode; // OUTPUT, INPUT, or DUPLEX.
|
f@0
|
736 StreamState state; // STOPPED, RUNNING, or CLOSED
|
f@0
|
737 char *userBuffer[2]; // Playback and record, respectively.
|
f@0
|
738 char *deviceBuffer;
|
f@0
|
739 bool doConvertBuffer[2]; // Playback and record, respectively.
|
f@0
|
740 bool userInterleaved;
|
f@0
|
741 bool deviceInterleaved[2]; // Playback and record, respectively.
|
f@0
|
742 bool doByteSwap[2]; // Playback and record, respectively.
|
f@0
|
743 unsigned int sampleRate;
|
f@0
|
744 unsigned int bufferSize;
|
f@0
|
745 unsigned int nBuffers;
|
f@0
|
746 unsigned int nUserChannels[2]; // Playback and record, respectively.
|
f@0
|
747 unsigned int nDeviceChannels[2]; // Playback and record channels, respectively.
|
f@0
|
748 unsigned int channelOffset[2]; // Playback and record, respectively.
|
f@0
|
749 unsigned long latency[2]; // Playback and record, respectively.
|
f@0
|
750 RtAudioFormat userFormat;
|
f@0
|
751 RtAudioFormat deviceFormat[2]; // Playback and record, respectively.
|
f@0
|
752 StreamMutex mutex;
|
f@0
|
753 CallbackInfo callbackInfo;
|
f@0
|
754 ConvertInfo convertInfo[2];
|
f@0
|
755 double streamTime; // Number of elapsed seconds since the stream started.
|
f@0
|
756
|
f@0
|
757 #if defined(HAVE_GETTIMEOFDAY)
|
f@0
|
758 struct timeval lastTickTimestamp;
|
f@0
|
759 #endif
|
f@0
|
760
|
f@0
|
761 RtApiStream()
|
f@0
|
762 :apiHandle(0), deviceBuffer(0) { device[0] = 11111; device[1] = 11111; }
|
f@0
|
763 };
|
f@0
|
764
|
f@0
|
765 typedef S24 Int24;
|
f@0
|
766 typedef signed short Int16;
|
f@0
|
767 typedef signed int Int32;
|
f@0
|
768 typedef float Float32;
|
f@0
|
769 typedef double Float64;
|
f@0
|
770
|
f@0
|
771 std::ostringstream errorStream_;
|
f@0
|
772 std::string errorText_;
|
f@0
|
773 bool showWarnings_;
|
f@0
|
774 RtApiStream stream_;
|
f@0
|
775 bool firstErrorOccurred_;
|
f@0
|
776
|
f@0
|
777 /*!
|
f@0
|
778 Protected, api-specific method that attempts to open a device
|
f@0
|
779 with the given parameters. This function MUST be implemented by
|
f@0
|
780 all subclasses. If an error is encountered during the probe, a
|
f@0
|
781 "warning" message is reported and FAILURE is returned. A
|
f@0
|
782 successful probe is indicated by a return value of SUCCESS.
|
f@0
|
783 */
|
f@0
|
784 virtual bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
|
f@0
|
785 unsigned int firstChannel, unsigned int sampleRate,
|
f@0
|
786 RtAudioFormat format, unsigned int *bufferSize,
|
f@0
|
787 RtAudio::StreamOptions *options );
|
f@0
|
788
|
f@0
|
789 //! A protected function used to increment the stream time.
|
f@0
|
790 void tickStreamTime( void );
|
f@0
|
791
|
f@0
|
792 //! Protected common method to clear an RtApiStream structure.
|
f@0
|
793 void clearStreamInfo();
|
f@0
|
794
|
f@0
|
795 /*!
|
f@0
|
796 Protected common method that throws an RtAudioError (type =
|
f@0
|
797 INVALID_USE) if a stream is not open.
|
f@0
|
798 */
|
f@0
|
799 void verifyStream( void );
|
f@0
|
800
|
f@0
|
801 //! Protected common error method to allow global control over error handling.
|
f@0
|
802 void error( RtAudioError::Type type );
|
f@0
|
803
|
f@0
|
804 /*!
|
f@0
|
805 Protected method used to perform format, channel number, and/or interleaving
|
f@0
|
806 conversions between the user and device buffers.
|
f@0
|
807 */
|
f@0
|
808 void convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info );
|
f@0
|
809
|
f@0
|
810 //! Protected common method used to perform byte-swapping on buffers.
|
f@0
|
811 void byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format );
|
f@0
|
812
|
f@0
|
813 //! Protected common method that returns the number of bytes for a given format.
|
f@0
|
814 unsigned int formatBytes( RtAudioFormat format );
|
f@0
|
815
|
f@0
|
816 //! Protected common method that sets up the parameters for buffer conversion.
|
f@0
|
817 void setConvertInfo( StreamMode mode, unsigned int firstChannel );
|
f@0
|
818 };
|
f@0
|
819
|
f@0
|
820 // **************************************************************** //
|
f@0
|
821 //
|
f@0
|
822 // Inline RtAudio definitions.
|
f@0
|
823 //
|
f@0
|
824 // **************************************************************** //
|
f@0
|
825
|
f@0
|
826 inline RtAudio::Api RtAudio :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
|
f@0
|
827 inline unsigned int RtAudio :: getDeviceCount( void ) throw() { return rtapi_->getDeviceCount(); }
|
f@0
|
828 inline RtAudio::DeviceInfo RtAudio :: getDeviceInfo( unsigned int device ) { return rtapi_->getDeviceInfo( device ); }
|
f@0
|
829 inline unsigned int RtAudio :: getDefaultInputDevice( void ) throw() { return rtapi_->getDefaultInputDevice(); }
|
f@0
|
830 inline unsigned int RtAudio :: getDefaultOutputDevice( void ) throw() { return rtapi_->getDefaultOutputDevice(); }
|
f@0
|
831 inline void RtAudio :: closeStream( void ) throw() { return rtapi_->closeStream(); }
|
f@0
|
832 inline void RtAudio :: startStream( void ) { return rtapi_->startStream(); }
|
f@0
|
833 inline void RtAudio :: stopStream( void ) { return rtapi_->stopStream(); }
|
f@0
|
834 inline void RtAudio :: abortStream( void ) { return rtapi_->abortStream(); }
|
f@0
|
835 inline bool RtAudio :: isStreamOpen( void ) const throw() { return rtapi_->isStreamOpen(); }
|
f@0
|
836 inline bool RtAudio :: isStreamRunning( void ) const throw() { return rtapi_->isStreamRunning(); }
|
f@0
|
837 inline long RtAudio :: getStreamLatency( void ) { return rtapi_->getStreamLatency(); }
|
f@0
|
838 inline unsigned int RtAudio :: getStreamSampleRate( void ) { return rtapi_->getStreamSampleRate(); }
|
f@0
|
839 inline double RtAudio :: getStreamTime( void ) { return rtapi_->getStreamTime(); }
|
f@0
|
840 inline void RtAudio :: setStreamTime( double time ) { return rtapi_->setStreamTime( time ); }
|
f@0
|
841 inline void RtAudio :: showWarnings( bool value ) throw() { rtapi_->showWarnings( value ); }
|
f@0
|
842
|
f@0
|
843 // RtApi Subclass prototypes.
|
f@0
|
844
|
f@0
|
845 #if defined(__MACOSX_CORE__)
|
f@0
|
846
|
f@0
|
847 #include <CoreAudio/AudioHardware.h>
|
f@0
|
848
|
f@0
|
849 class RtApiCore: public RtApi
|
f@0
|
850 {
|
f@0
|
851 public:
|
f@0
|
852
|
f@0
|
853 RtApiCore();
|
f@0
|
854 ~RtApiCore();
|
f@0
|
855 RtAudio::Api getCurrentApi( void ) { return RtAudio::MACOSX_CORE; }
|
f@0
|
856 unsigned int getDeviceCount( void );
|
f@0
|
857 RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
|
f@0
|
858 unsigned int getDefaultOutputDevice( void );
|
f@0
|
859 unsigned int getDefaultInputDevice( void );
|
f@0
|
860 void closeStream( void );
|
f@0
|
861 void startStream( void );
|
f@0
|
862 void stopStream( void );
|
f@0
|
863 void abortStream( void );
|
f@0
|
864 long getStreamLatency( void );
|
f@0
|
865
|
f@0
|
866 // This function is intended for internal use only. It must be
|
f@0
|
867 // public because it is called by the internal callback handler,
|
f@0
|
868 // which is not a member of RtAudio. External use of this function
|
f@0
|
869 // will most likely produce highly undesireable results!
|
f@0
|
870 bool callbackEvent( AudioDeviceID deviceId,
|
f@0
|
871 const AudioBufferList *inBufferList,
|
f@0
|
872 const AudioBufferList *outBufferList );
|
f@0
|
873
|
f@0
|
874 private:
|
f@0
|
875
|
f@0
|
876 bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
|
f@0
|
877 unsigned int firstChannel, unsigned int sampleRate,
|
f@0
|
878 RtAudioFormat format, unsigned int *bufferSize,
|
f@0
|
879 RtAudio::StreamOptions *options );
|
f@0
|
880 static const char* getErrorCode( OSStatus code );
|
f@0
|
881 };
|
f@0
|
882
|
f@0
|
883 #endif
|
f@0
|
884
|
f@0
|
885 #if defined(__UNIX_JACK__)
|
f@0
|
886
|
f@0
|
887 class RtApiJack: public RtApi
|
f@0
|
888 {
|
f@0
|
889 public:
|
f@0
|
890
|
f@0
|
891 RtApiJack();
|
f@0
|
892 ~RtApiJack();
|
f@0
|
893 RtAudio::Api getCurrentApi( void ) { return RtAudio::UNIX_JACK; }
|
f@0
|
894 unsigned int getDeviceCount( void );
|
f@0
|
895 RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
|
f@0
|
896 void closeStream( void );
|
f@0
|
897 void startStream( void );
|
f@0
|
898 void stopStream( void );
|
f@0
|
899 void abortStream( void );
|
f@0
|
900 long getStreamLatency( void );
|
f@0
|
901
|
f@0
|
902 // This function is intended for internal use only. It must be
|
f@0
|
903 // public because it is called by the internal callback handler,
|
f@0
|
904 // which is not a member of RtAudio. External use of this function
|
f@0
|
905 // will most likely produce highly undesireable results!
|
f@0
|
906 bool callbackEvent( unsigned long nframes );
|
f@0
|
907
|
f@0
|
908 private:
|
f@0
|
909
|
f@0
|
910 bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
|
f@0
|
911 unsigned int firstChannel, unsigned int sampleRate,
|
f@0
|
912 RtAudioFormat format, unsigned int *bufferSize,
|
f@0
|
913 RtAudio::StreamOptions *options );
|
f@0
|
914 };
|
f@0
|
915
|
f@0
|
916 #endif
|
f@0
|
917
|
f@0
|
918 #if defined(__WINDOWS_ASIO__)
|
f@0
|
919
|
f@0
|
920 class RtApiAsio: public RtApi
|
f@0
|
921 {
|
f@0
|
922 public:
|
f@0
|
923
|
f@0
|
924 RtApiAsio();
|
f@0
|
925 ~RtApiAsio();
|
f@0
|
926 RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_ASIO; }
|
f@0
|
927 unsigned int getDeviceCount( void );
|
f@0
|
928 RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
|
f@0
|
929 void closeStream( void );
|
f@0
|
930 void startStream( void );
|
f@0
|
931 void stopStream( void );
|
f@0
|
932 void abortStream( void );
|
f@0
|
933 long getStreamLatency( void );
|
f@0
|
934
|
f@0
|
935 // This function is intended for internal use only. It must be
|
f@0
|
936 // public because it is called by the internal callback handler,
|
f@0
|
937 // which is not a member of RtAudio. External use of this function
|
f@0
|
938 // will most likely produce highly undesireable results!
|
f@0
|
939 bool callbackEvent( long bufferIndex );
|
f@0
|
940
|
f@0
|
941 private:
|
f@0
|
942
|
f@0
|
943 std::vector<RtAudio::DeviceInfo> devices_;
|
f@0
|
944 void saveDeviceInfo( void );
|
f@0
|
945 bool coInitialized_;
|
f@0
|
946 bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
|
f@0
|
947 unsigned int firstChannel, unsigned int sampleRate,
|
f@0
|
948 RtAudioFormat format, unsigned int *bufferSize,
|
f@0
|
949 RtAudio::StreamOptions *options );
|
f@0
|
950 };
|
f@0
|
951
|
f@0
|
952 #endif
|
f@0
|
953
|
f@0
|
954 #if defined(__WINDOWS_DS__)
|
f@0
|
955
|
f@0
|
956 class RtApiDs: public RtApi
|
f@0
|
957 {
|
f@0
|
958 public:
|
f@0
|
959
|
f@0
|
960 RtApiDs();
|
f@0
|
961 ~RtApiDs();
|
f@0
|
962 RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_DS; }
|
f@0
|
963 unsigned int getDeviceCount( void );
|
f@0
|
964 unsigned int getDefaultOutputDevice( void );
|
f@0
|
965 unsigned int getDefaultInputDevice( void );
|
f@0
|
966 RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
|
f@0
|
967 void closeStream( void );
|
f@0
|
968 void startStream( void );
|
f@0
|
969 void stopStream( void );
|
f@0
|
970 void abortStream( void );
|
f@0
|
971 long getStreamLatency( void );
|
f@0
|
972
|
f@0
|
973 // This function is intended for internal use only. It must be
|
f@0
|
974 // public because it is called by the internal callback handler,
|
f@0
|
975 // which is not a member of RtAudio. External use of this function
|
f@0
|
976 // will most likely produce highly undesireable results!
|
f@0
|
977 void callbackEvent( void );
|
f@0
|
978
|
f@0
|
979 private:
|
f@0
|
980
|
f@0
|
981 bool coInitialized_;
|
f@0
|
982 bool buffersRolling;
|
f@0
|
983 long duplexPrerollBytes;
|
f@0
|
984 std::vector<struct DsDevice> dsDevices;
|
f@0
|
985 bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
|
f@0
|
986 unsigned int firstChannel, unsigned int sampleRate,
|
f@0
|
987 RtAudioFormat format, unsigned int *bufferSize,
|
f@0
|
988 RtAudio::StreamOptions *options );
|
f@0
|
989 };
|
f@0
|
990
|
f@0
|
991 #endif
|
f@0
|
992
|
f@0
|
993 #if defined(__WINDOWS_WASAPI__)
|
f@0
|
994
|
f@0
|
995 struct IMMDeviceEnumerator;
|
f@0
|
996
|
f@0
|
997 class RtApiWasapi : public RtApi
|
f@0
|
998 {
|
f@0
|
999 public:
|
f@0
|
1000 RtApiWasapi();
|
f@0
|
1001 ~RtApiWasapi();
|
f@0
|
1002
|
f@0
|
1003 RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_WASAPI; }
|
f@0
|
1004 unsigned int getDeviceCount( void );
|
f@0
|
1005 RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
|
f@0
|
1006 unsigned int getDefaultOutputDevice( void );
|
f@0
|
1007 unsigned int getDefaultInputDevice( void );
|
f@0
|
1008 void closeStream( void );
|
f@0
|
1009 void startStream( void );
|
f@0
|
1010 void stopStream( void );
|
f@0
|
1011 void abortStream( void );
|
f@0
|
1012
|
f@0
|
1013 private:
|
f@0
|
1014 bool coInitialized_;
|
f@0
|
1015 IMMDeviceEnumerator* deviceEnumerator_;
|
f@0
|
1016
|
f@0
|
1017 bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
|
f@0
|
1018 unsigned int firstChannel, unsigned int sampleRate,
|
f@0
|
1019 RtAudioFormat format, unsigned int* bufferSize,
|
f@0
|
1020 RtAudio::StreamOptions* options );
|
f@0
|
1021
|
f@0
|
1022 static DWORD WINAPI runWasapiThread( void* wasapiPtr );
|
f@0
|
1023 static DWORD WINAPI stopWasapiThread( void* wasapiPtr );
|
f@0
|
1024 static DWORD WINAPI abortWasapiThread( void* wasapiPtr );
|
f@0
|
1025 void wasapiThread();
|
f@0
|
1026 };
|
f@0
|
1027
|
f@0
|
1028 #endif
|
f@0
|
1029
|
f@0
|
1030 #if defined(__LINUX_ALSA__)
|
f@0
|
1031
|
f@0
|
1032 class RtApiAlsa: public RtApi
|
f@0
|
1033 {
|
f@0
|
1034 public:
|
f@0
|
1035
|
f@0
|
1036 RtApiAlsa();
|
f@0
|
1037 ~RtApiAlsa();
|
f@0
|
1038 RtAudio::Api getCurrentApi() { return RtAudio::LINUX_ALSA; }
|
f@0
|
1039 unsigned int getDeviceCount( void );
|
f@0
|
1040 RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
|
f@0
|
1041 void closeStream( void );
|
f@0
|
1042 void startStream( void );
|
f@0
|
1043 void stopStream( void );
|
f@0
|
1044 void abortStream( void );
|
f@0
|
1045
|
f@0
|
1046 // This function is intended for internal use only. It must be
|
f@0
|
1047 // public because it is called by the internal callback handler,
|
f@0
|
1048 // which is not a member of RtAudio. External use of this function
|
f@0
|
1049 // will most likely produce highly undesireable results!
|
f@0
|
1050 void callbackEvent( void );
|
f@0
|
1051
|
f@0
|
1052 private:
|
f@0
|
1053
|
f@0
|
1054 std::vector<RtAudio::DeviceInfo> devices_;
|
f@0
|
1055 void saveDeviceInfo( void );
|
f@0
|
1056 bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
|
f@0
|
1057 unsigned int firstChannel, unsigned int sampleRate,
|
f@0
|
1058 RtAudioFormat format, unsigned int *bufferSize,
|
f@0
|
1059 RtAudio::StreamOptions *options );
|
f@0
|
1060 };
|
f@0
|
1061
|
f@0
|
1062 #endif
|
f@0
|
1063
|
f@0
|
1064 #if defined(__LINUX_PULSE__)
|
f@0
|
1065
|
f@0
|
1066 class RtApiPulse: public RtApi
|
f@0
|
1067 {
|
f@0
|
1068 public:
|
f@0
|
1069 ~RtApiPulse();
|
f@0
|
1070 RtAudio::Api getCurrentApi() { return RtAudio::LINUX_PULSE; }
|
f@0
|
1071 unsigned int getDeviceCount( void );
|
f@0
|
1072 RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
|
f@0
|
1073 void closeStream( void );
|
f@0
|
1074 void startStream( void );
|
f@0
|
1075 void stopStream( void );
|
f@0
|
1076 void abortStream( void );
|
f@0
|
1077
|
f@0
|
1078 // This function is intended for internal use only. It must be
|
f@0
|
1079 // public because it is called by the internal callback handler,
|
f@0
|
1080 // which is not a member of RtAudio. External use of this function
|
f@0
|
1081 // will most likely produce highly undesireable results!
|
f@0
|
1082 void callbackEvent( void );
|
f@0
|
1083
|
f@0
|
1084 private:
|
f@0
|
1085
|
f@0
|
1086 std::vector<RtAudio::DeviceInfo> devices_;
|
f@0
|
1087 void saveDeviceInfo( void );
|
f@0
|
1088 bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
|
f@0
|
1089 unsigned int firstChannel, unsigned int sampleRate,
|
f@0
|
1090 RtAudioFormat format, unsigned int *bufferSize,
|
f@0
|
1091 RtAudio::StreamOptions *options );
|
f@0
|
1092 };
|
f@0
|
1093
|
f@0
|
1094 #endif
|
f@0
|
1095
|
f@0
|
1096 #if defined(__LINUX_OSS__)
|
f@0
|
1097
|
f@0
|
1098 class RtApiOss: public RtApi
|
f@0
|
1099 {
|
f@0
|
1100 public:
|
f@0
|
1101
|
f@0
|
1102 RtApiOss();
|
f@0
|
1103 ~RtApiOss();
|
f@0
|
1104 RtAudio::Api getCurrentApi() { return RtAudio::LINUX_OSS; }
|
f@0
|
1105 unsigned int getDeviceCount( void );
|
f@0
|
1106 RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
|
f@0
|
1107 void closeStream( void );
|
f@0
|
1108 void startStream( void );
|
f@0
|
1109 void stopStream( void );
|
f@0
|
1110 void abortStream( void );
|
f@0
|
1111
|
f@0
|
1112 // This function is intended for internal use only. It must be
|
f@0
|
1113 // public because it is called by the internal callback handler,
|
f@0
|
1114 // which is not a member of RtAudio. External use of this function
|
f@0
|
1115 // will most likely produce highly undesireable results!
|
f@0
|
1116 void callbackEvent( void );
|
f@0
|
1117
|
f@0
|
1118 private:
|
f@0
|
1119
|
f@0
|
1120 bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
|
f@0
|
1121 unsigned int firstChannel, unsigned int sampleRate,
|
f@0
|
1122 RtAudioFormat format, unsigned int *bufferSize,
|
f@0
|
1123 RtAudio::StreamOptions *options );
|
f@0
|
1124 };
|
f@0
|
1125
|
f@0
|
1126 #endif
|
f@0
|
1127
|
f@0
|
1128 #if defined(__RTAUDIO_DUMMY__)
|
f@0
|
1129
|
f@0
|
1130 class RtApiDummy: public RtApi
|
f@0
|
1131 {
|
f@0
|
1132 public:
|
f@0
|
1133
|
f@0
|
1134 RtApiDummy() { errorText_ = "RtApiDummy: This class provides no functionality."; error( RtAudioError::WARNING ); }
|
f@0
|
1135 RtAudio::Api getCurrentApi( void ) { return RtAudio::RTAUDIO_DUMMY; }
|
f@0
|
1136 unsigned int getDeviceCount( void ) { return 0; }
|
f@0
|
1137 RtAudio::DeviceInfo getDeviceInfo( unsigned int /*device*/ ) { RtAudio::DeviceInfo info; return info; }
|
f@0
|
1138 void closeStream( void ) {}
|
f@0
|
1139 void startStream( void ) {}
|
f@0
|
1140 void stopStream( void ) {}
|
f@0
|
1141 void abortStream( void ) {}
|
f@0
|
1142
|
f@0
|
1143 private:
|
f@0
|
1144
|
f@0
|
1145 bool probeDeviceOpen( unsigned int /*device*/, StreamMode /*mode*/, unsigned int /*channels*/,
|
f@0
|
1146 unsigned int /*firstChannel*/, unsigned int /*sampleRate*/,
|
f@0
|
1147 RtAudioFormat /*format*/, unsigned int * /*bufferSize*/,
|
f@0
|
1148 RtAudio::StreamOptions * /*options*/ ) { return false; }
|
f@0
|
1149 };
|
f@0
|
1150
|
f@0
|
1151 #endif
|
f@0
|
1152
|
f@0
|
1153 #endif
|
f@0
|
1154
|
f@0
|
1155 // Indentation settings for Vim and Emacs
|
f@0
|
1156 //
|
f@0
|
1157 // Local Variables:
|
f@0
|
1158 // c-basic-offset: 2
|
f@0
|
1159 // indent-tabs-mode: nil
|
f@0
|
1160 // End:
|
f@0
|
1161 //
|
f@0
|
1162 // vim: et sts=2 sw=2
|