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
49 // Operating system dependent thread functionality.
50 #if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__)
54 typedef unsigned long ThreadHandle;
55 typedef CRITICAL_SECTION StreamMutex;
57 #else // Various unix flavors with pthread support.
60 typedef pthread_t ThreadHandle;
61 typedef pthread_mutex_t StreamMutex;
65 // This global structure type is used to pass callback information
66 // between the private RtAudio stream structure and global callback
67 // handling functions.
69 void *object; // Used as a "this" pointer.
74 void *apiInfo; // void pointer for API specific callback information
76 // Default constructor.
78 :object(0), usingCallback(false), callback(0),
79 userData(0), apiInfo(0) {}
82 // Support for signed integers and floats. Audio data fed to/from
83 // the tickStream() routine is assumed to ALWAYS be in host
84 // byte order. The internal routines will automatically take care of
85 // any necessary byte-swapping between the host format and the
86 // soundcard. Thus, endian-ness is not a concern in the following
87 // format definitions.
88 typedef unsigned long RtAudioFormat;
89 static const RtAudioFormat RTAUDIO_SINT8 = 0x1; /*!< 8-bit signed integer. */
90 static const RtAudioFormat RTAUDIO_SINT16 = 0x2; /*!< 16-bit signed integer. */
91 static const RtAudioFormat RTAUDIO_SINT24 = 0x4; /*!< Upper 3 bytes of 32-bit signed integer. */
92 static const RtAudioFormat RTAUDIO_SINT32 = 0x8; /*!< 32-bit signed integer. */
93 static const RtAudioFormat RTAUDIO_FLOAT32 = 0x10; /*!< Normalized between plus/minus 1.0. */
94 static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; /*!< Normalized between plus/minus 1.0. */
96 typedef int (*RtAudioCallback)(char *buffer, int bufferSize, void *userData);
98 //! The public device information structure for returning queried values.
99 struct RtAudioDeviceInfo {
100 std::string name; /*!< Character string device identifier. */
101 bool probed; /*!< true if the device capabilities were successfully probed. */
102 int outputChannels; /*!< Maximum output channels supported by device. */
103 int inputChannels; /*!< Maximum input channels supported by device. */
104 int duplexChannels; /*!< Maximum simultaneous input/output channels supported by device. */
105 bool isDefault; /*!< true if this is the default output or input device. */
106 std::vector<int> sampleRates; /*!< Supported sample rates (queried from list of standard rates). */
107 RtAudioFormat nativeFormats; /*!< Bit mask of supported data formats. */
109 // Default constructor.
111 :probed(false), outputChannels(0), inputChannels(0),
112 duplexChannels(0), isDefault(false), nativeFormats(0) {}
115 // **************************************************************** //
117 // RtApi class declaration.
119 // Note that RtApi is an abstract base class and cannot be
120 // explicitly instantiated. The class RtAudio will create an
121 // instance of an RtApi subclass (RtApiOss, RtApiAlsa,
122 // RtApiJack, RtApiCore, RtApiAl, RtApiDs, or RtApiAsio).
124 // **************************************************************** //
132 void openStream( int outputDevice, int outputChannels,
133 int inputDevice, int inputChannels,
134 RtAudioFormat format, int sampleRate,
135 int *bufferSize, int numberOfBuffers );
136 virtual void setStreamCallback( RtAudioCallback callback, void *userData ) = 0;
137 virtual void cancelStreamCallback() = 0;
138 int getDeviceCount(void);
139 RtAudioDeviceInfo getDeviceInfo( int device );
140 char * const getStreamBuffer();
141 virtual void tickStream() = 0;
142 virtual void closeStream();
143 virtual void startStream() = 0;
144 virtual void stopStream() = 0;
145 virtual void abortStream() = 0;
149 static const unsigned int MAX_SAMPLE_RATES;
150 static const unsigned int SAMPLE_RATES[];
152 enum { FAILURE, SUCCESS };
166 // A protected structure for audio streams.
168 int device[2]; // Playback and record, respectively.
169 void *apiHandle; // void pointer for API specific stream handle information
170 StreamMode mode; // OUTPUT, INPUT, or DUPLEX.
171 StreamState state; // STOPPED or RUNNING
174 bool doConvertBuffer[2]; // Playback and record, respectively.
175 bool deInterleave[2]; // Playback and record, respectively.
176 bool doByteSwap[2]; // Playback and record, respectively.
180 int nUserChannels[2]; // Playback and record, respectively.
181 int nDeviceChannels[2]; // Playback and record channels, respectively.
182 RtAudioFormat userFormat;
183 RtAudioFormat deviceFormat[2]; // Playback and record, respectively.
185 CallbackInfo callbackInfo;
188 :apiHandle(0), userBuffer(0), deviceBuffer(0) {}
189 // mode(UNINITIALIZED), state(STREAM_STOPPED),
192 // A protected device structure for audio devices.
194 std::string name; /*!< Character string device identifier. */
195 bool probed; /*!< true if the device capabilities were successfully probed. */
196 void *apiDeviceId; // void pointer for API specific device information
197 int maxOutputChannels; /*!< Maximum output channels supported by device. */
198 int maxInputChannels; /*!< Maximum input channels supported by device. */
199 int maxDuplexChannels; /*!< Maximum simultaneous input/output channels supported by device. */
200 int minOutputChannels; /*!< Minimum output channels supported by device. */
201 int minInputChannels; /*!< Minimum input channels supported by device. */
202 int minDuplexChannels; /*!< Minimum simultaneous input/output channels supported by device. */
203 bool hasDuplexSupport; /*!< true if device supports duplex mode. */
204 bool isDefault; /*!< true if this is the default output or input device. */
205 std::vector<int> sampleRates; /*!< Supported sample rates. */
206 RtAudioFormat nativeFormats; /*!< Bit mask of supported data formats. */
208 // Default constructor.
210 :probed(false), apiDeviceId(0), maxOutputChannels(0), maxInputChannels(0),
211 maxDuplexChannels(0), minOutputChannels(0), minInputChannels(0),
212 minDuplexChannels(0), isDefault(false), nativeFormats(0) {}
215 typedef signed short Int16;
216 typedef signed int Int32;
217 typedef float Float32;
218 typedef double Float64;
222 std::vector<RtApiDevice> devices_;
226 Protected, api-specific method to count and identify the system
227 audio devices. This function MUST be implemented by all subclasses.
229 virtual void initialize(void) = 0;
232 Protected, api-specific method which attempts to fill an
233 RtAudioDevice structure for a given device. This function MUST be
234 implemented by all subclasses. If an error is encountered during
235 the probe, a "warning" message is reported and the value of
236 "probed" remains false (no exception is thrown). A successful
237 probe is indicated by probed = true.
239 virtual void probeDeviceInfo( RtApiDevice *info );
242 Protected, api-specific method which attempts to open a device
243 with the given parameters. This function MUST be implemented by
244 all subclasses. If an error is encountered during the probe, a
245 "warning" message is reported and FAILURE is returned (no
246 exception is thrown). A successful probe is indicated by a return
249 virtual bool probeDeviceOpen( int device, StreamMode mode, int channels,
250 int sampleRate, RtAudioFormat format,
251 int *bufferSize, int numberOfBuffers );
254 Protected method which returns the index in the devices array to
255 the default input device.
257 virtual int getDefaultInputDevice(void);
260 Protected method which returns the index in the devices array to
261 the default output device.
263 virtual int getDefaultOutputDevice(void);
265 //! Protected common method to clear an RtApiDevice structure.
266 void clearDeviceInfo( RtApiDevice *info );
268 //! Protected common method to clear an RtApiStream structure.
269 void clearStreamInfo();
271 //! Protected common error method to allow global control over error handling.
272 void error( RtError::Type type );
275 Protected common method used to check whether a stream is open.
276 If not, an "invalid identifier" exception is thrown.
281 Protected method used to perform format, channel number, and/or interleaving
282 conversions between the user and device buffers.
284 void convertStreamBuffer( StreamMode mode );
286 //! Protected common method used to perform byte-swapping on buffers.
287 void byteSwapBuffer( char *buffer, int samples, RtAudioFormat format );
289 //! Protected common method which returns the number of bytes for a given format.
290 int formatBytes( RtAudioFormat format );
294 // **************************************************************** //
296 // RtAudio class declaration.
298 // RtAudio is a "controller" used to select an available audio i/o
299 // interface. It presents a common API for the user to call but all
300 // functionality is implemented by the class RtAudioApi and its
301 // subclasses. RtAudio creates an instance of an RtAudioApi subclass
302 // based on the user's API choice. If no choice is made, RtAudio
303 // attempts to make a "logical" API selection.
305 // **************************************************************** //
311 //! Audio API specifier arguments.
313 UNSPECIFIED, /*!< Search for a working compiled API. */
314 LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */
315 LINUX_OSS, /*!< The Linux Open Sound System API. */
316 LINUX_JACK, /*!< The Linux Jack Low-Latency Audio Server API. */
317 MACOSX_CORE, /*!< Macintosh OS-X Core Audio API. */
318 IRIX_AL, /*!< The Irix Audio Library API. */
319 WINDOWS_ASIO, /*!< The Steinberg Audio Stream I/O API. */
320 WINDOWS_DS /*!< The Microsoft Direct Sound API. */
323 //! The default class constructor.
325 Probes the system to make sure at least one audio input/output
326 device is available and determines the api-specific identifier for
327 each device found. An RtError error can be thrown if no devices
328 are found or if a memory allocation error occurs.
330 If no API argument is specified and multiple API support has been
331 compiled, the default order of use is JACK, ALSA, OSS (Linux
332 systems) and ASIO, DS (Windows systems).
334 RtAudio( RtAudioApi api=UNSPECIFIED );
336 //! A constructor which can be used to open a stream during instantiation.
338 The specified output and/or input device identifiers correspond
339 to those enumerated via the getDeviceInfo() method. If device =
340 0, the default or first available devices meeting the given
341 parameters is selected. If an output or input channel value is
342 zero, the corresponding device value is ignored. When a stream is
343 successfully opened, its identifier is returned via the "streamId"
344 pointer. An RtError can be thrown if no devices are found
345 for the given parameters, if a memory allocation error occurs, or
346 if a driver error occurs. \sa openStream()
348 RtAudio( int outputDevice, int outputChannels,
349 int inputDevice, int inputChannels,
350 RtAudioFormat format, int sampleRate,
351 int *bufferSize, int numberOfBuffers, RtAudioApi api=UNSPECIFIED );
355 Stops and closes an open stream and devices and deallocates
356 buffer and structure memory.
360 //! A public method for opening a stream with the specified parameters.
362 An RtError is thrown if a stream cannot be opened.
364 \param outputDevice: If equal to 0, the default or first device
365 found meeting the given parameters is opened. Otherwise, the
366 device number should correspond to one of those enumerated via
367 the getDeviceInfo() method.
368 \param outputChannels: The desired number of output channels. If
369 equal to zero, the outputDevice identifier is ignored.
370 \param inputDevice: If equal to 0, the default or first device
371 found meeting the given parameters is opened. Otherwise, the
372 device number should correspond to one of those enumerated via
373 the getDeviceInfo() method.
374 \param inputChannels: The desired number of input channels. If
375 equal to zero, the inputDevice identifier is ignored.
376 \param format: An RtAudioFormat specifying the desired sample data format.
377 \param sampleRate: The desired sample rate (sample frames per second).
378 \param *bufferSize: A pointer value indicating the desired internal buffer
379 size in sample frames. The actual value used by the device is
380 returned via the same pointer. A value of zero can be specified,
381 in which case the lowest allowable value is determined.
382 \param numberOfBuffers: A value which can be used to help control device
383 latency. More buffers typically result in more robust performance,
384 though at a cost of greater latency. A value of zero can be
385 specified, in which case the lowest allowable value is used.
387 void openStream( int outputDevice, int outputChannels,
388 int inputDevice, int inputChannels,
389 RtAudioFormat format, int sampleRate,
390 int *bufferSize, int numberOfBuffers );
392 //! A public method which sets a user-defined callback function for a given stream.
394 This method assigns a callback function to a previously opened
395 stream for non-blocking stream functionality. A separate process
396 is initiated, though the user function is called only when the
397 stream is "running" (between calls to the startStream() and
398 stopStream() methods, respectively). The callback process remains
399 active for the duration of the stream and is automatically
400 shutdown when the stream is closed (via the closeStream() method
401 or by object destruction). The callback process can also be
402 shutdown and the user function de-referenced through an explicit
403 call to the cancelStreamCallback() method. Note that the stream
404 can use only blocking or callback functionality at a particular
405 time, though it is possible to alternate modes on the same stream
406 through the use of the setStreamCallback() and
407 cancelStreamCallback() methods (the blocking tickStream() method
408 can be used before a callback is set and/or after a callback is
409 cancelled). An RtError will be thrown if called when no stream is
410 open or a thread errors occurs.
412 void setStreamCallback(RtAudioCallback callback, void *userData) { rtapi_->setStreamCallback( callback, userData ); };
414 //! A public method which cancels a callback process and function for the stream.
416 This method shuts down a callback process and de-references the
417 user function for the stream. Callback functionality can
418 subsequently be restarted on the stream via the
419 setStreamCallback() method. An RtError will be thrown if called
420 when no stream is open.
422 void cancelStreamCallback() { rtapi_->cancelStreamCallback(); };
424 //! A public method which returns the number of audio devices found.
425 int getDeviceCount(void) { return rtapi_->getDeviceCount(); };
427 //! Return an RtAudioDeviceInfo structure for a specified device number.
429 Any device integer between 1 and getDeviceCount() is valid. If
430 a device is busy or otherwise unavailable, the structure member
431 "probed" will have a value of "false" and all other members are
432 undefined. If the specified device is the current default input
433 or output device, the "isDefault" member will have a value of
434 "true". An RtError will be thrown for an invalid device argument.
436 RtAudioDeviceInfo getDeviceInfo(int device) { return rtapi_->getDeviceInfo( device ); };
438 //! A public method which returns a pointer to the buffer for an open stream.
440 The user should fill and/or read the buffer data in interleaved format
441 and then call the tickStream() method. An RtError will be
442 thrown if called when no stream is open.
444 char * const getStreamBuffer() { return rtapi_->getStreamBuffer(); };
446 //! Public method used to trigger processing of input/output data for a stream.
448 This method blocks until all buffer data is read/written. An
449 RtError will be thrown if a driver error occurs or if called when
452 void tickStream() { rtapi_->tickStream(); };
454 //! Public method which closes a stream and frees any associated buffers.
456 If a stream is not open, this method issues a warning and
457 returns (an RtError is not thrown).
459 void closeStream() { rtapi_->closeStream(); };
461 //! Public method which starts a stream.
463 An RtError will be thrown if a driver error occurs or if called
464 when no stream is open.
466 void startStream() { rtapi_->startStream(); };
468 //! Stop a stream, allowing any samples remaining in the queue to be played out and/or read in.
470 An RtError will be thrown if a driver error occurs or if called
471 when no stream is open.
473 void stopStream() { rtapi_->stopStream(); };
475 //! Stop a stream, discarding any samples remaining in the input/output queue.
477 An RtError will be thrown if a driver error occurs or if called
478 when no stream is open.
480 void abortStream() { rtapi_->abortStream(); };
485 void initialize( RtAudioApi api );
491 // RtApi Subclass prototypes.
493 #if defined(__LINUX_ALSA__)
495 class RtApiAlsa: public RtApi
506 int streamWillBlock();
507 void setStreamCallback( RtAudioCallback callback, void *userData );
508 void cancelStreamCallback();
512 void initialize(void);
513 void probeDeviceInfo( RtApiDevice *info );
514 bool probeDeviceOpen( int device, StreamMode mode, int channels,
515 int sampleRate, RtAudioFormat format,
516 int *bufferSize, int numberOfBuffers );
521 #if defined(__LINUX_JACK__)
523 class RtApiJack: public RtApi
534 void setStreamCallback( RtAudioCallback callback, void *userData );
535 void cancelStreamCallback();
536 // This function is intended for internal use only. It must be
537 // public because it is called by the internal callback handler,
538 // which is not a member of RtAudio. External use of this function
539 // will most likely produce highly undesireable results!
540 void callbackEvent( unsigned long nframes );
544 void initialize(void);
545 void probeDeviceInfo( RtApiDevice *info );
546 bool probeDeviceOpen( int device, StreamMode mode, int channels,
547 int sampleRate, RtAudioFormat format,
548 int *bufferSize, int numberOfBuffers );
553 #if defined(__LINUX_OSS__)
555 class RtApiOss: public RtApi
566 int streamWillBlock();
567 void setStreamCallback( RtAudioCallback callback, void *userData );
568 void cancelStreamCallback();
572 void initialize(void);
573 void probeDeviceInfo( RtApiDevice *info );
574 bool probeDeviceOpen( int device, StreamMode mode, int channels,
575 int sampleRate, RtAudioFormat format,
576 int *bufferSize, int numberOfBuffers );
581 #if defined(__MACOSX_CORE__)
583 #include <CoreAudio/AudioHardware.h>
585 class RtApiCore: public RtApi
591 int getDefaultOutputDevice(void);
592 int getDefaultInputDevice(void);
598 void setStreamCallback( RtAudioCallback callback, void *userData );
599 void cancelStreamCallback();
601 // This function is intended for internal use only. It must be
602 // public because it is called by the internal callback handler,
603 // which is not a member of RtAudio. External use of this function
604 // will most likely produce highly undesireable results!
605 void callbackEvent( AudioDeviceID deviceId, void *inData, void *outData );
609 void initialize(void);
610 void probeDeviceInfo( RtApiDevice *info );
611 bool probeDeviceOpen( int device, StreamMode mode, int channels,
612 int sampleRate, RtAudioFormat format,
613 int *bufferSize, int numberOfBuffers );
618 #if defined(__WINDOWS_DS__)
620 class RtApiDs: public RtApi
626 int getDefaultOutputDevice(void);
627 int getDefaultInputDevice(void);
633 int streamWillBlock();
634 void setStreamCallback( RtAudioCallback callback, void *userData );
635 void cancelStreamCallback();
639 void initialize(void);
640 void probeDeviceInfo( RtApiDevice *info );
641 bool probeDeviceOpen( int device, StreamMode mode, int channels,
642 int sampleRate, RtAudioFormat format,
643 int *bufferSize, int numberOfBuffers );
648 #if defined(__WINDOWS_ASIO__)
650 class RtApiAsio: public RtApi
661 void setStreamCallback( RtAudioCallback callback, void *userData );
662 void cancelStreamCallback();
664 // This function is intended for internal use only. It must be
665 // public because it is called by the internal callback handler,
666 // which is not a member of RtAudio. External use of this function
667 // will most likely produce highly undesireable results!
668 void callbackEvent( long bufferIndex );
672 void initialize(void);
673 void probeDeviceInfo( RtApiDevice *info );
674 bool probeDeviceOpen( int device, StreamMode mode, int channels,
675 int sampleRate, RtAudioFormat format,
676 int *bufferSize, int numberOfBuffers );
681 #if defined(__IRIX_AL__)
683 class RtApiAl: public RtApi
689 int getDefaultOutputDevice(void);
690 int getDefaultInputDevice(void);
696 int streamWillBlock();
697 void setStreamCallback( RtAudioCallback callback, void *userData );
698 void cancelStreamCallback();
702 void initialize(void);
703 void probeDeviceInfo( RtApiDevice *info );
704 bool probeDeviceOpen( int device, StreamMode mode, int channels,
705 int sampleRate, RtAudioFormat format,
706 int *bufferSize, int numberOfBuffers );
711 // Define the following flag to have extra information spewed to stderr.
712 //#define __RTAUDIO_DEBUG__