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
#if defined(LINUX_ALSA) || defined(LINUX_OSS) || defined(LINUX_JACK) || defined(MACOSX_CORE)
67
#define HAVE_GETTIMEOFDAY 1
70
// This global structure type is used to pass callback information
71
// between the private RtAudio stream structure and global callback
72
// handling functions.
74
void *object; // Used as a "this" pointer.
79
void *apiInfo; // void pointer for API specific callback information
81
// Default constructor.
83
:object(0), usingCallback(false), callback(0),
84
userData(0), apiInfo(0) {}
87
// Support for signed integers and floats. Audio data fed to/from
88
// the tickStream() routine is assumed to ALWAYS be in host
89
// byte order. The internal routines will automatically take care of
90
// any necessary byte-swapping between the host format and the
91
// soundcard. Thus, endian-ness is not a concern in the following
92
// format definitions.
93
typedef unsigned long RtAudioFormat;
94
static const RtAudioFormat RTAUDIO_SINT8 = 0x1; /*!< 8-bit signed integer. */
95
static const RtAudioFormat RTAUDIO_SINT16 = 0x2; /*!< 16-bit signed integer. */
96
static const RtAudioFormat RTAUDIO_SINT24 = 0x4; /*!< Upper 3 bytes of 32-bit signed integer. */
97
static const RtAudioFormat RTAUDIO_SINT32 = 0x8; /*!< 32-bit signed integer. */
98
static const RtAudioFormat RTAUDIO_FLOAT32 = 0x10; /*!< Normalized between plus/minus 1.0. */
99
static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; /*!< Normalized between plus/minus 1.0. */
101
typedef int (*RtAudioCallback)(char *buffer, int bufferSize, void *userData);
103
//! The public device information structure for returning queried values.
104
struct RtAudioDeviceInfo {
105
std::string name; /*!< Character string device identifier. */
106
bool probed; /*!< true if the device capabilities were successfully probed. */
107
int outputChannels; /*!< Maximum output channels supported by device. */
108
int inputChannels; /*!< Maximum input channels supported by device. */
109
int duplexChannels; /*!< Maximum simultaneous input/output channels supported by device. */
110
bool isDefault; /*!< true if this is the default output or input device. */
111
std::vector<int> sampleRates; /*!< Supported sample rates (queried from list of standard rates). */
112
RtAudioFormat nativeFormats; /*!< Bit mask of supported data formats. */
114
// Default constructor.
116
:probed(false), outputChannels(0), inputChannels(0),
117
duplexChannels(0), isDefault(false), nativeFormats(0) {}
120
// **************************************************************** //
122
// RtApi class declaration.
124
// Note that RtApi is an abstract base class and cannot be
125
// explicitly instantiated. The class RtAudio will create an
126
// instance of an RtApi subclass (RtApiOss, RtApiAlsa,
127
// RtApiJack, RtApiCore, RtApiAl, RtApiDs, or RtApiAsio).
129
// **************************************************************** //
137
void openStream( int outputDevice, int outputChannels,
138
int inputDevice, int inputChannels,
139
RtAudioFormat format, int sampleRate,
140
int *bufferSize, int numberOfBuffers );
141
virtual void setStreamCallback( RtAudioCallback callback, void *userData ) = 0;
142
virtual void cancelStreamCallback() = 0;
143
int getDeviceCount(void);
144
RtAudioDeviceInfo getDeviceInfo( int device );
145
char * const getStreamBuffer();
146
virtual void tickStream();
147
virtual void closeStream();
148
virtual void startStream() = 0;
149
virtual void stopStream() = 0;
150
virtual void abortStream() = 0;
151
virtual bool isStreamRunning();
152
virtual double getStreamTime();
156
static const unsigned int MAX_SAMPLE_RATES;
157
static const unsigned int SAMPLE_RATES[];
159
enum { FAILURE, SUCCESS };
173
// A protected structure for audio streams.
175
int device[2]; // Playback and record, respectively.
176
void *apiHandle; // void pointer for API specific stream handle information
177
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
double streamTime; // Number of elapsed seconds since the
196
#if defined(HAVE_GETTIMEOFDAY)
197
struct timeval lastTickTimestamp;
201
:apiHandle(0), userBuffer(0), deviceBuffer(0) {}
202
// mode(UNINITIALIZED), state(STREAM_STOPPED),
205
// A protected device structure for audio devices.
207
std::string name; /*!< Character string device identifier. */
208
bool probed; /*!< true if the device capabilities were successfully probed. */
209
void *apiDeviceId; // void pointer for API specific device information
210
int maxOutputChannels; /*!< Maximum output channels supported by device. */
211
int maxInputChannels; /*!< Maximum input channels supported by device. */
212
int maxDuplexChannels; /*!< Maximum simultaneous input/output channels supported by device. */
213
int minOutputChannels; /*!< Minimum output channels supported by device. */
214
int minInputChannels; /*!< Minimum input channels supported by device. */
215
int minDuplexChannels; /*!< Minimum simultaneous input/output channels supported by device. */
216
bool hasDuplexSupport; /*!< true if device supports duplex mode. */
217
bool isDefault; /*!< true if this is the default output or input device. */
218
std::vector<int> sampleRates; /*!< Supported sample rates. */
219
RtAudioFormat nativeFormats; /*!< Bit mask of supported data formats. */
221
// Default constructor.
223
:probed(false), apiDeviceId(0), maxOutputChannels(0), maxInputChannels(0),
224
maxDuplexChannels(0), minOutputChannels(0), minInputChannels(0),
225
minDuplexChannels(0), isDefault(false), nativeFormats(0) {}
228
typedef signed short Int16;
229
typedef signed int Int32;
230
typedef float Float32;
231
typedef double Float64;
235
std::vector<RtApiDevice> devices_;
239
Protected, api-specific method to count and identify the system
240
audio devices. This function MUST be implemented by all subclasses.
242
virtual void initialize(void) = 0;
245
Protected, api-specific method which attempts to fill an
246
RtAudioDevice structure for a given device. This function MUST be
247
implemented by all subclasses. If an error is encountered during
248
the probe, a "warning" message is reported and the value of
249
"probed" remains false (no exception is thrown). A successful
250
probe is indicated by probed = true.
252
virtual void probeDeviceInfo( RtApiDevice *info );
255
Protected, api-specific method which attempts to open a device
256
with the given parameters. This function MUST be implemented by
257
all subclasses. If an error is encountered during the probe, a
258
"warning" message is reported and FAILURE is returned (no
259
exception is thrown). A successful probe is indicated by a return
262
virtual bool probeDeviceOpen( int device, StreamMode mode, int channels,
263
int sampleRate, RtAudioFormat format,
264
int *bufferSize, int numberOfBuffers );
267
Protected method which returns the index in the devices array to
268
the default input device.
270
virtual int getDefaultInputDevice(void);
273
Protected method which returns the index in the devices array to
274
the default output device.
276
virtual int getDefaultOutputDevice(void);
278
//! Protected common method to clear an RtApiDevice structure.
279
void clearDeviceInfo( RtApiDevice *info );
281
//! Protected common method to clear an RtApiStream structure.
282
void clearStreamInfo();
284
//! Protected common error method to allow global control over error handling.
285
void error( RtError::Type type );
288
Protected common method used to check whether a stream is open.
289
If not, an "invalid identifier" exception is thrown.
294
Protected method used to perform format, channel number, and/or interleaving
295
conversions between the user and device buffers.
297
void convertStreamBuffer( StreamMode mode );
299
//! Protected common method used to perform byte-swapping on buffers.
300
void byteSwapBuffer( char *buffer, int samples, RtAudioFormat format );
302
//! Protected common method which returns the number of bytes for a given format.
303
int formatBytes( RtAudioFormat format );
307
// **************************************************************** //
309
// RtAudio class declaration.
311
// RtAudio is a "controller" used to select an available audio i/o
312
// interface. It presents a common API for the user to call but all
313
// functionality is implemented by the class RtAudioApi and its
314
// subclasses. RtAudio creates an instance of an RtAudioApi subclass
315
// based on the user's API choice. If no choice is made, RtAudio
316
// attempts to make a "logical" API selection.
318
// **************************************************************** //
324
//! Audio API specifier arguments.
326
UNSPECIFIED, /*!< Search for a working compiled API. */
327
LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */
328
LINUX_OSS, /*!< The Linux Open Sound System API. */
329
LINUX_JACK, /*!< The Linux Jack Low-Latency Audio Server API. */
330
MACOSX_CORE, /*!< Macintosh OS-X Core Audio API. */
331
IRIX_AL, /*!< The Irix Audio Library API. */
332
WINDOWS_ASIO, /*!< The Steinberg Audio Stream I/O API. */
333
WINDOWS_DS /*!< The Microsoft Direct Sound API. */
336
//! The default class constructor.
338
Probes the system to make sure at least one audio input/output
339
device is available and determines the api-specific identifier for
340
each device found. An RtError error can be thrown if no devices
341
are found or if a memory allocation error occurs.
343
If no API argument is specified and multiple API support has been
344
compiled, the default order of use is JACK, ALSA, OSS (Linux
345
systems) and ASIO, DS (Windows systems).
347
RtAudio( RtAudioApi api=UNSPECIFIED );
349
//! A constructor which can be used to open a stream during instantiation.
351
The specified output and/or input device identifiers correspond
352
to those enumerated via the getDeviceInfo() method. If device =
353
0, the default or first available devices meeting the given
354
parameters is selected. If an output or input channel value is
355
zero, the corresponding device value is ignored. When a stream is
356
successfully opened, its identifier is returned via the "streamId"
357
pointer. An RtError can be thrown if no devices are found
358
for the given parameters, if a memory allocation error occurs, or
359
if a driver error occurs. \sa openStream()
361
RtAudio( int outputDevice, int outputChannels,
362
int inputDevice, int inputChannels,
363
RtAudioFormat format, int sampleRate,
364
int *bufferSize, int numberOfBuffers, RtAudioApi api=UNSPECIFIED );
368
Stops and closes an open stream and devices and deallocates
369
buffer and structure memory.
373
//! A public method for opening a stream with the specified parameters.
375
An RtError is thrown if a stream cannot be opened.
377
\param outputDevice: 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 outputChannels: The desired number of output channels. If
382
equal to zero, the outputDevice identifier is ignored.
383
\param inputDevice: If equal to 0, the default or first device
384
found meeting the given parameters is opened. Otherwise, the
385
device number should correspond to one of those enumerated via
386
the getDeviceInfo() method.
387
\param inputChannels: The desired number of input channels. If
388
equal to zero, the inputDevice identifier is ignored.
389
\param format: An RtAudioFormat specifying the desired sample data format.
390
\param sampleRate: The desired sample rate (sample frames per second).
391
\param *bufferSize: A pointer value indicating the desired internal buffer
392
size in sample frames. The actual value used by the device is
393
returned via the same pointer. A value of zero can be specified,
394
in which case the lowest allowable value is determined.
395
\param numberOfBuffers: A value which can be used to help control device
396
latency. More buffers typically result in more robust performance,
397
though at a cost of greater latency. A value of zero can be
398
specified, in which case the lowest allowable value is used.
400
void openStream( int outputDevice, int outputChannels,
401
int inputDevice, int inputChannels,
402
RtAudioFormat format, int sampleRate,
403
int *bufferSize, int numberOfBuffers );
405
//! A public method which sets a user-defined callback function for a given stream.
407
This method assigns a callback function to a previously opened
408
stream for non-blocking stream functionality. A separate process
409
is initiated, though the user function is called only when the
410
stream is "running" (between calls to the startStream() and
411
stopStream() methods, respectively). The callback process remains
412
active for the duration of the stream and is automatically
413
shutdown when the stream is closed (via the closeStream() method
414
or by object destruction). The callback process can also be
415
shutdown and the user function de-referenced through an explicit
416
call to the cancelStreamCallback() method. Note that the stream
417
can use only blocking or callback functionality at a particular
418
time, though it is possible to alternate modes on the same stream
419
through the use of the setStreamCallback() and
420
cancelStreamCallback() methods (the blocking tickStream() method
421
can be used before a callback is set and/or after a callback is
422
cancelled). An RtError will be thrown if called when no stream is
423
open or a thread errors occurs.
425
void setStreamCallback(RtAudioCallback callback, void *userData) { rtapi_->setStreamCallback( callback, userData ); };
427
//! A public method which cancels a callback process and function for the stream.
429
This method shuts down a callback process and de-references the
430
user function for the stream. Callback functionality can
431
subsequently be restarted on the stream via the
432
setStreamCallback() method. An RtError will be thrown if called
433
when no stream is open.
435
void cancelStreamCallback() { rtapi_->cancelStreamCallback(); };
437
//! A public method which returns the number of audio devices found.
438
int getDeviceCount(void) { return rtapi_->getDeviceCount(); };
440
//! Return an RtAudioDeviceInfo structure for a specified device number.
442
Any device integer between 1 and getDeviceCount() is valid. If
443
a device is busy or otherwise unavailable, the structure member
444
"probed" will have a value of "false" and all other members are
445
undefined. If the specified device is the current default input
446
or output device, the "isDefault" member will have a value of
447
"true". An RtError will be thrown for an invalid device argument.
449
RtAudioDeviceInfo getDeviceInfo(int device) { return rtapi_->getDeviceInfo( device ); };
451
//! A public method which returns a pointer to the buffer for an open stream.
453
The user should fill and/or read the buffer data in interleaved format
454
and then call the tickStream() method. An RtError will be
455
thrown if called when no stream is open.
457
char * const getStreamBuffer() { return rtapi_->getStreamBuffer(); };
459
//! Public method used to trigger processing of input/output data for a stream.
461
This method blocks until all buffer data is read/written. An
462
RtError will be thrown if a driver error occurs or if called when
465
void tickStream() { rtapi_->tickStream(); };
467
//! Public method which closes a stream and frees any associated buffers.
469
If a stream is not open, this method issues a warning and
470
returns (an RtError is not thrown).
472
void closeStream() { rtapi_->closeStream(); };
474
//! Public method which starts a stream.
476
An RtError will be thrown if a driver error occurs or if called
477
when no stream is open.
479
void startStream() { rtapi_->startStream(); };
481
//! Stop a stream, allowing any samples remaining in the queue to be played out and/or read in.
483
An RtError will be thrown if a driver error occurs or if called
484
when no stream is open.
486
void stopStream() { rtapi_->stopStream(); };
488
//! Stop a stream, discarding any samples remaining in the input/output queue.
490
An RtError will be thrown if a driver error occurs or if called
491
when no stream is open.
493
void abortStream() { rtapi_->abortStream(); };
495
//! Returns true is the stream is running, and false if it is stopped.
498
An RtError will be thrown if a driver error occurs or if called
499
when no stream is open.
501
bool isStreamRunning() { return rtapi_->isStreamRunning(); };
503
//! Returns the number of elapsed seconds since the stream was started.
506
An RtError will be thrown if a driver error occurs or if called
507
when no stream is open.
509
double getStreamTime() { return rtapi_->getStreamTime(); };
513
void initialize( RtAudioApi api );
519
// RtApi Subclass prototypes.
521
#if defined(__LINUX_ALSA__)
523
class RtApiAlsa: public RtApi
534
int streamWillBlock();
535
void setStreamCallback( RtAudioCallback callback, void *userData );
536
void cancelStreamCallback();
540
void initialize(void);
541
void probeDeviceInfo( RtApiDevice *info );
542
bool probeDeviceOpen( int device, StreamMode mode, int channels,
543
int sampleRate, RtAudioFormat format,
544
int *bufferSize, int numberOfBuffers );
549
#if defined(__LINUX_JACK__)
551
class RtApiJack: public RtApi
562
void setStreamCallback( RtAudioCallback callback, void *userData );
563
void cancelStreamCallback();
564
// This function is intended for internal use only. It must be
565
// public because it is called by the internal callback handler,
566
// which is not a member of RtAudio. External use of this function
567
// will most likely produce highly undesireable results!
568
void callbackEvent( unsigned long nframes );
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(__LINUX_OSS__)
583
class RtApiOss: public RtApi
594
int streamWillBlock();
595
void setStreamCallback( RtAudioCallback callback, void *userData );
596
void cancelStreamCallback();
600
void initialize(void);
601
void probeDeviceInfo( RtApiDevice *info );
602
bool probeDeviceOpen( int device, StreamMode mode, int channels,
603
int sampleRate, RtAudioFormat format,
604
int *bufferSize, int numberOfBuffers );
609
#if defined(__MACOSX_CORE__)
611
#include <CoreAudio/AudioHardware.h>
613
class RtApiCore: public RtApi
619
int getDefaultOutputDevice(void);
620
int getDefaultInputDevice(void);
626
void setStreamCallback( RtAudioCallback callback, void *userData );
627
void cancelStreamCallback();
629
// This function is intended for internal use only. It must be
630
// public because it is called by the internal callback handler,
631
// which is not a member of RtAudio. External use of this function
632
// will most likely produce highly undesireable results!
633
void callbackEvent( AudioDeviceID deviceId, void *inData, void *outData );
637
void initialize(void);
638
void probeDeviceInfo( RtApiDevice *info );
639
bool probeDeviceOpen( int device, StreamMode mode, int channels,
640
int sampleRate, RtAudioFormat format,
641
int *bufferSize, int numberOfBuffers );
646
#if defined(__WINDOWS_DS__)
648
class RtApiDs: public RtApi
654
int getDefaultOutputDevice(void);
655
int getDefaultInputDevice(void);
661
int streamWillBlock();
662
void setStreamCallback( RtAudioCallback callback, void *userData );
663
void cancelStreamCallback();
667
void initialize(void);
668
void probeDeviceInfo( RtApiDevice *info );
669
bool probeDeviceOpen( int device, StreamMode mode, int channels,
670
int sampleRate, RtAudioFormat format,
671
int *bufferSize, int numberOfBuffers );
676
#if defined(__WINDOWS_ASIO__)
678
class RtApiAsio: public RtApi
689
void setStreamCallback( RtAudioCallback callback, void *userData );
690
void cancelStreamCallback();
692
// This function is intended for internal use only. It must be
693
// public because it is called by the internal callback handler,
694
// which is not a member of RtAudio. External use of this function
695
// will most likely produce highly undesireable results!
696
void callbackEvent( long bufferIndex );
700
void initialize(void);
701
void probeDeviceInfo( RtApiDevice *info );
702
bool probeDeviceOpen( int device, StreamMode mode, int channels,
703
int sampleRate, RtAudioFormat format,
704
int *bufferSize, int numberOfBuffers );
709
#if defined(__IRIX_AL__)
711
class RtApiAl: public RtApi
717
int getDefaultOutputDevice(void);
718
int getDefaultInputDevice(void);
724
int streamWillBlock();
725
void setStreamCallback( RtAudioCallback callback, void *userData );
726
void cancelStreamCallback();
730
void initialize(void);
731
void probeDeviceInfo( RtApiDevice *info );
732
bool probeDeviceOpen( int device, StreamMode mode, int channels,
733
int sampleRate, RtAudioFormat format,
734
int *bufferSize, int numberOfBuffers );
739
// Define the following flag to have extra information spewed to stderr.
740
//#define __RTAUDIO_DEBUG__
744
// Indentation settings for Vim and Emacs
748
// indent-tabs-mode: nil
751
// vim: et sts=2 sw=2