1 /************************************************************************/
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), SGI, Macintosh OS X (CoreAudio), and Windows
8 (DirectSound and ASIO) operating systems.
10 RtAudio WWW site: http://music.mcgill.ca/~gary/rtaudio/
12 RtAudio: a realtime audio i/o C++ class
13 Copyright (c) 2001-2004 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 requested to send the modifications to the original developer so that
28 they can be incorporated into the canonical version.
30 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
31 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
33 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
34 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
35 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
36 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 /************************************************************************/
40 // RtAudio: Version 3.0.1, 22 March 2004
50 // Operating system dependent thread functionality.
51 #if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__)
54 #if defined(__WINDOWS_PTHREAD__)
56 typedef pthread_t ThreadHandle
;
57 typedef pthread_mutex_t StreamMutex
;
60 typedef unsigned long ThreadHandle
;
61 typedef CRITICAL_SECTION StreamMutex
;
63 #else // Various unix flavors with pthread support.
66 typedef pthread_t ThreadHandle
;
67 typedef pthread_mutex_t StreamMutex
;
71 // This global structure type is used to pass callback information
72 // between the private RtAudio stream structure and global callback
73 // handling functions.
75 void *object
; // Used as a "this" pointer.
80 void *apiInfo
; // void pointer for API specific callback information
82 // Default constructor.
84 :object(0), usingCallback(false), callback(0),
85 userData(0), apiInfo(0) {}
88 // Support for signed integers and floats. Audio data fed to/from
89 // the tickStream() routine is assumed to ALWAYS be in host
90 // byte order. The internal routines will automatically take care of
91 // any necessary byte-swapping between the host format and the
92 // soundcard. Thus, endian-ness is not a concern in the following
93 // format definitions.
94 typedef unsigned long RtAudioFormat
;
95 static const RtAudioFormat RTAUDIO_SINT8
= 0x1; /*!< 8-bit signed integer. */
96 static const RtAudioFormat RTAUDIO_SINT16
= 0x2; /*!< 16-bit signed integer. */
97 static const RtAudioFormat RTAUDIO_SINT24
= 0x4; /*!< Upper 3 bytes of 32-bit signed integer. */
98 static const RtAudioFormat RTAUDIO_SINT32
= 0x8; /*!< 32-bit signed integer. */
99 static const RtAudioFormat RTAUDIO_FLOAT32
= 0x10; /*!< Normalized between plus/minus 1.0. */
100 static const RtAudioFormat RTAUDIO_FLOAT64
= 0x20; /*!< Normalized between plus/minus 1.0. */
102 typedef int (*RtAudioCallback
)(char *buffer
, int bufferSize
, void *userData
);
104 //! The public device information structure for returning queried values.
105 struct RtAudioDeviceInfo
{
106 std::string name
; /*!< Character string device identifier. */
107 bool probed
; /*!< true if the device capabilities were successfully probed. */
108 int outputChannels
; /*!< Maximum output channels supported by device. */
109 int inputChannels
; /*!< Maximum input channels supported by device. */
110 int duplexChannels
; /*!< Maximum simultaneous input/output channels supported by device. */
111 bool isDefault
; /*!< true if this is the default output or input device. */
112 std::vector
<int> sampleRates
; /*!< Supported sample rates (queried from list of standard rates). */
113 RtAudioFormat nativeFormats
; /*!< Bit mask of supported data formats. */
115 // Default constructor.
117 :probed(false), outputChannels(0), inputChannels(0),
118 duplexChannels(0), isDefault(false), nativeFormats(0) {}
121 // **************************************************************** //
123 // RtApi class declaration.
125 // Note that RtApi is an abstract base class and cannot be
126 // explicitly instantiated. The class RtAudio will create an
127 // instance of an RtApi subclass (RtApiOss, RtApiAlsa,
128 // RtApiJack, RtApiCore, RtApiAl, RtApiDs, or RtApiAsio).
130 // **************************************************************** //
138 void openStream( int outputDevice
, int outputChannels
,
139 int inputDevice
, int inputChannels
,
140 RtAudioFormat format
, int sampleRate
,
141 int *bufferSize
, int numberOfBuffers
);
142 virtual void setStreamCallback( RtAudioCallback callback
, void *userData
) = 0;
143 virtual void cancelStreamCallback() = 0;
144 int getDeviceCount(void);
145 RtAudioDeviceInfo
getDeviceInfo( int device
);
146 char * const getStreamBuffer();
147 virtual void tickStream() = 0;
148 virtual void closeStream();
149 virtual void startStream() = 0;
150 virtual void stopStream() = 0;
151 virtual void abortStream() = 0;
155 static const unsigned int MAX_SAMPLE_RATES
;
156 static const unsigned int SAMPLE_RATES
[];
158 enum { FAILURE
, SUCCESS
};
172 // A protected structure for audio streams.
174 int device
[2]; // Playback and record, respectively.
175 void *apiHandle
; // void pointer for API specific stream handle information
176 StreamMode mode
; // OUTPUT, INPUT, or DUPLEX.
178 StreamState state
; // STOPPED or RUNNING
181 bool doConvertBuffer
[2]; // Playback and record, respectively.
182 bool deInterleave
[2]; // Playback and record, respectively.
183 bool doByteSwap
[2]; // Playback and record, respectively.
187 int nUserChannels
[2]; // Playback and record, respectively.
188 int nDeviceChannels
[2]; // Playback and record channels, respectively.
189 RtAudioFormat userFormat
;
190 RtAudioFormat deviceFormat
[2]; // Playback and record, respectively.
192 CallbackInfo callbackInfo
;
193 //XXX VC6 throws an error using UNINITIALIZED ( protected member )
195 :apiHandle(0), userBuffer(0), deviceBuffer(0), sub_mode((enum RtApi::StreamMode
)-75) {}
196 // mode(UNINITIALIZED), state(STREAM_STOPPED),
199 // A protected device structure for audio devices.
201 std::string name
; /*!< Character string device identifier. */
202 bool probed
; /*!< true if the device capabilities were successfully probed. */
203 void *apiDeviceId
; // void pointer for API specific device information
204 int maxOutputChannels
; /*!< Maximum output channels supported by device. */
205 int maxInputChannels
; /*!< Maximum input channels supported by device. */
206 int maxDuplexChannels
; /*!< Maximum simultaneous input/output channels supported by device. */
207 int minOutputChannels
; /*!< Minimum output channels supported by device. */
208 int minInputChannels
; /*!< Minimum input channels supported by device. */
209 int minDuplexChannels
; /*!< Minimum simultaneous input/output channels supported by device. */
210 bool hasDuplexSupport
; /*!< true if device supports duplex mode. */
211 bool isDefault
; /*!< true if this is the default output or input device. */
212 std::vector
<int> sampleRates
; /*!< Supported sample rates. */
213 RtAudioFormat nativeFormats
; /*!< Bit mask of supported data formats. */
215 // Default constructor.
217 :probed(false), apiDeviceId(0), maxOutputChannels(0), maxInputChannels(0),
218 maxDuplexChannels(0), minOutputChannels(0), minInputChannels(0),
219 minDuplexChannels(0), isDefault(false), nativeFormats(0) {}
222 typedef signed short Int16
;
223 typedef signed int Int32
;
224 typedef float Float32
;
225 typedef double Float64
;
229 std::vector
<RtApiDevice
> devices_
;
233 Protected, api-specific method to count and identify the system
234 audio devices. This function MUST be implemented by all subclasses.
236 virtual void initialize(void) = 0;
239 Protected, api-specific method which attempts to fill an
240 RtAudioDevice structure for a given device. This function MUST be
241 implemented by all subclasses. If an error is encountered during
242 the probe, a "warning" message is reported and the value of
243 "probed" remains false (no exception is thrown). A successful
244 probe is indicated by probed = true.
246 virtual void probeDeviceInfo( RtApiDevice
*info
);
249 Protected, api-specific method which attempts to open a device
250 with the given parameters. This function MUST be implemented by
251 all subclasses. If an error is encountered during the probe, a
252 "warning" message is reported and FAILURE is returned (no
253 exception is thrown). A successful probe is indicated by a return
256 virtual bool probeDeviceOpen( int device
, StreamMode mode
, int channels
,
257 int sampleRate
, RtAudioFormat format
,
258 int *bufferSize
, int numberOfBuffers
);
261 Protected method which returns the index in the devices array to
262 the default input device.
264 virtual int getDefaultInputDevice(void);
267 Protected method which returns the index in the devices array to
268 the default output device.
270 virtual int getDefaultOutputDevice(void);
272 //! Protected common method to clear an RtApiDevice structure.
273 void clearDeviceInfo( RtApiDevice
*info
);
275 //! Protected common method to clear an RtApiStream structure.
276 void clearStreamInfo();
278 //! Protected common error method to allow global control over error handling.
279 void error( RtError::Type type
);
282 Protected common method used to check whether a stream is open.
283 If not, an "invalid identifier" exception is thrown.
288 Protected method used to perform format, channel number, and/or interleaving
289 conversions between the user and device buffers.
291 void convertStreamBuffer( StreamMode mode
);
293 //! Protected common method used to perform byte-swapping on buffers.
294 void byteSwapBuffer( char *buffer
, int samples
, RtAudioFormat format
);
296 //! Protected common method which returns the number of bytes for a given format.
297 int formatBytes( RtAudioFormat format
);
301 // **************************************************************** //
303 // RtAudio class declaration.
305 // RtAudio is a "controller" used to select an available audio i/o
306 // interface. It presents a common API for the user to call but all
307 // functionality is implemented by the class RtAudioApi and its
308 // subclasses. RtAudio creates an instance of an RtAudioApi subclass
309 // based on the user's API choice. If no choice is made, RtAudio
310 // attempts to make a "logical" API selection.
312 // **************************************************************** //
318 //! Audio API specifier arguments.
320 UNSPECIFIED
, /*!< Search for a working compiled API. */
321 LINUX_ALSA
, /*!< The Advanced Linux Sound Architecture API. */
322 LINUX_OSS
, /*!< The Linux Open Sound System API. */
323 LINUX_JACK
, /*!< The Linux Jack Low-Latency Audio Server API. */
324 MACOSX_CORE
, /*!< Macintosh OS-X Core Audio API. */
325 IRIX_AL
, /*!< The Irix Audio Library API. */
326 WINDOWS_ASIO
, /*!< The Steinberg Audio Stream I/O API. */
327 WINDOWS_DS
/*!< The Microsoft Direct Sound API. */
330 //! The default class constructor.
332 Probes the system to make sure at least one audio input/output
333 device is available and determines the api-specific identifier for
334 each device found. An RtError error can be thrown if no devices
335 are found or if a memory allocation error occurs.
337 If no API argument is specified and multiple API support has been
338 compiled, the default order of use is JACK, ALSA, OSS (Linux
339 systems) and ASIO, DS (Windows systems).
341 RtAudio( RtAudioApi api
=UNSPECIFIED
);
343 //! A constructor which can be used to open a stream during instantiation.
345 The specified output and/or input device identifiers correspond
346 to those enumerated via the getDeviceInfo() method. If device =
347 0, the default or first available devices meeting the given
348 parameters is selected. If an output or input channel value is
349 zero, the corresponding device value is ignored. When a stream is
350 successfully opened, its identifier is returned via the "streamId"
351 pointer. An RtError can be thrown if no devices are found
352 for the given parameters, if a memory allocation error occurs, or
353 if a driver error occurs. \sa openStream()
355 RtAudio( int outputDevice
, int outputChannels
,
356 int inputDevice
, int inputChannels
,
357 RtAudioFormat format
, int sampleRate
,
358 int *bufferSize
, int numberOfBuffers
, RtAudioApi api
=UNSPECIFIED
);
362 Stops and closes an open stream and devices and deallocates
363 buffer and structure memory.
367 //! A public method for opening a stream with the specified parameters.
369 An RtError is thrown if a stream cannot be opened.
371 \param outputDevice: If equal to 0, the default or first device
372 found meeting the given parameters is opened. Otherwise, the
373 device number should correspond to one of those enumerated via
374 the getDeviceInfo() method.
375 \param outputChannels: The desired number of output channels. If
376 equal to zero, the outputDevice identifier is ignored.
377 \param inputDevice: If equal to 0, the default or first device
378 found meeting the given parameters is opened. Otherwise, the
379 device number should correspond to one of those enumerated via
380 the getDeviceInfo() method.
381 \param inputChannels: The desired number of input channels. If
382 equal to zero, the inputDevice identifier is ignored.
383 \param format: An RtAudioFormat specifying the desired sample data format.
384 \param sampleRate: The desired sample rate (sample frames per second).
385 \param *bufferSize: A pointer value indicating the desired internal buffer
386 size in sample frames. The actual value used by the device is
387 returned via the same pointer. A value of zero can be specified,
388 in which case the lowest allowable value is determined.
389 \param numberOfBuffers: A value which can be used to help control device
390 latency. More buffers typically result in more robust performance,
391 though at a cost of greater latency. A value of zero can be
392 specified, in which case the lowest allowable value is used.
394 void openStream( int outputDevice
, int outputChannels
,
395 int inputDevice
, int inputChannels
,
396 RtAudioFormat format
, int sampleRate
,
397 int *bufferSize
, int numberOfBuffers
);
399 //! A public method which sets a user-defined callback function for a given stream.
401 This method assigns a callback function to a previously opened
402 stream for non-blocking stream functionality. A separate process
403 is initiated, though the user function is called only when the
404 stream is "running" (between calls to the startStream() and
405 stopStream() methods, respectively). The callback process remains
406 active for the duration of the stream and is automatically
407 shutdown when the stream is closed (via the closeStream() method
408 or by object destruction). The callback process can also be
409 shutdown and the user function de-referenced through an explicit
410 call to the cancelStreamCallback() method. Note that the stream
411 can use only blocking or callback functionality at a particular
412 time, though it is possible to alternate modes on the same stream
413 through the use of the setStreamCallback() and
414 cancelStreamCallback() methods (the blocking tickStream() method
415 can be used before a callback is set and/or after a callback is
416 cancelled). An RtError will be thrown if called when no stream is
417 open or a thread errors occurs.
419 void setStreamCallback(RtAudioCallback callback
, void *userData
) { rtapi_
->setStreamCallback( callback
, userData
); };
421 //! A public method which cancels a callback process and function for the stream.
423 This method shuts down a callback process and de-references the
424 user function for the stream. Callback functionality can
425 subsequently be restarted on the stream via the
426 setStreamCallback() method. An RtError will be thrown if called
427 when no stream is open.
429 void cancelStreamCallback() { rtapi_
->cancelStreamCallback(); };
431 //! A public method which returns the number of audio devices found.
432 int getDeviceCount(void) { return rtapi_
->getDeviceCount(); };
434 //! Return an RtAudioDeviceInfo structure for a specified device number.
436 Any device integer between 1 and getDeviceCount() is valid. If
437 a device is busy or otherwise unavailable, the structure member
438 "probed" will have a value of "false" and all other members are
439 undefined. If the specified device is the current default input
440 or output device, the "isDefault" member will have a value of
441 "true". An RtError will be thrown for an invalid device argument.
443 RtAudioDeviceInfo
getDeviceInfo(int device
) { return rtapi_
->getDeviceInfo( device
); };
445 //! A public method which returns a pointer to the buffer for an open stream.
447 The user should fill and/or read the buffer data in interleaved format
448 and then call the tickStream() method. An RtError will be
449 thrown if called when no stream is open.
451 char * const getStreamBuffer() { return rtapi_
->getStreamBuffer(); };
453 //! Public method used to trigger processing of input/output data for a stream.
455 This method blocks until all buffer data is read/written. An
456 RtError will be thrown if a driver error occurs or if called when
459 void tickStream() { rtapi_
->tickStream(); };
461 //! Public method which closes a stream and frees any associated buffers.
463 If a stream is not open, this method issues a warning and
464 returns (an RtError is not thrown).
466 void closeStream() { rtapi_
->closeStream(); };
468 //! Public method which starts a stream.
470 An RtError will be thrown if a driver error occurs or if called
471 when no stream is open.
473 void startStream() { rtapi_
->startStream(); };
475 //! Stop a stream, allowing any samples remaining in the queue to be played out and/or read in.
477 An RtError will be thrown if a driver error occurs or if called
478 when no stream is open.
480 void stopStream() { rtapi_
->stopStream(); };
482 //! Stop a stream, discarding any samples remaining in the input/output queue.
484 An RtError will be thrown if a driver error occurs or if called
485 when no stream is open.
487 void abortStream() { rtapi_
->abortStream(); };
492 void initialize( RtAudioApi api
);
498 // RtApi Subclass prototypes.
500 #if defined(__LINUX_ALSA__)
502 class RtApiAlsa
: public RtApi
513 int streamWillBlock();
514 void setStreamCallback( RtAudioCallback callback
, void *userData
);
515 void cancelStreamCallback();
519 void initialize(void);
520 void probeDeviceInfo( RtApiDevice
*info
);
521 bool probeDeviceOpen( int device
, StreamMode mode
, int channels
,
522 int sampleRate
, RtAudioFormat format
,
523 int *bufferSize
, int numberOfBuffers
);
528 #if defined(__LINUX_JACK__)
530 class RtApiJack
: public RtApi
541 void setStreamCallback( RtAudioCallback callback
, void *userData
);
542 void cancelStreamCallback();
543 // This function is intended for internal use only. It must be
544 // public because it is called by the internal callback handler,
545 // which is not a member of RtAudio. External use of this function
546 // will most likely produce highly undesireable results!
547 void callbackEvent( unsigned long nframes
);
551 void initialize(void);
552 void probeDeviceInfo( RtApiDevice
*info
);
553 bool probeDeviceOpen( int device
, StreamMode mode
, int channels
,
554 int sampleRate
, RtAudioFormat format
,
555 int *bufferSize
, int numberOfBuffers
);
560 #if defined(__LINUX_OSS__)
562 class RtApiOss
: public RtApi
573 int streamWillBlock();
574 void setStreamCallback( RtAudioCallback callback
, void *userData
);
575 void cancelStreamCallback();
579 void initialize(void);
580 void probeDeviceInfo( RtApiDevice
*info
);
581 bool probeDeviceOpen( int device
, StreamMode mode
, int channels
,
582 int sampleRate
, RtAudioFormat format
,
583 int *bufferSize
, int numberOfBuffers
);
588 #if defined(__MACOSX_CORE__)
590 #include <CoreAudio/AudioHardware.h>
592 class RtApiCore
: public RtApi
598 int getDefaultOutputDevice(void);
599 int getDefaultInputDevice(void);
605 void setStreamCallback( RtAudioCallback callback
, void *userData
);
606 void cancelStreamCallback();
608 // This function is intended for internal use only. It must be
609 // public because it is called by the internal callback handler,
610 // which is not a member of RtAudio. External use of this function
611 // will most likely produce highly undesireable results!
612 void callbackEvent( AudioDeviceID deviceId
, void *inData
, void *outData
);
616 void initialize(void);
617 void probeDeviceInfo( RtApiDevice
*info
);
618 bool probeDeviceOpen( int device
, StreamMode mode
, int channels
,
619 int sampleRate
, RtAudioFormat format
,
620 int *bufferSize
, int numberOfBuffers
);
625 #if defined(__WINDOWS_DS__)
627 class RtApiDs
: public RtApi
633 int getDefaultOutputDevice(void);
634 int getDefaultInputDevice(void);
640 int streamWillBlock();
641 void setStreamCallback( RtAudioCallback callback
, void *userData
);
642 void cancelStreamCallback();
646 void initialize(void);
647 void probeDeviceInfo( RtApiDevice
*info
);
648 bool probeDeviceOpen( int device
, StreamMode mode
, int channels
,
649 int sampleRate
, RtAudioFormat format
,
650 int *bufferSize
, int numberOfBuffers
);
655 #if defined(__WINDOWS_ASIO__)
657 class RtApiAsio
: public RtApi
668 void setStreamCallback( RtAudioCallback callback
, void *userData
);
669 void cancelStreamCallback();
671 // This function is intended for internal use only. It must be
672 // public because it is called by the internal callback handler,
673 // which is not a member of RtAudio. External use of this function
674 // will most likely produce highly undesireable results!
675 void callbackEvent( long bufferIndex
);
679 void initialize(void);
680 void probeDeviceInfo( RtApiDevice
*info
);
681 bool probeDeviceOpen( int device
, StreamMode mode
, int channels
,
682 int sampleRate
, RtAudioFormat format
,
683 int *bufferSize
, int numberOfBuffers
);
688 #if defined(__IRIX_AL__)
690 class RtApiAl
: public RtApi
696 int getDefaultOutputDevice(void);
697 int getDefaultInputDevice(void);
703 int streamWillBlock();
704 void setStreamCallback( RtAudioCallback callback
, void *userData
);
705 void cancelStreamCallback();
709 void initialize(void);
710 void probeDeviceInfo( RtApiDevice
*info
);
711 bool probeDeviceOpen( int device
, StreamMode mode
, int channels
,
712 int sampleRate
, RtAudioFormat format
,
713 int *bufferSize
, int numberOfBuffers
);
718 // Define the following flag to have extra information spewed to stderr.
719 //#define __RTAUDIO_DEBUG__