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