1 /******************************************/
3 RtAudio - realtime sound I/O C++ class
4 Version 2.0 by Gary P. Scavone, 2001-2002.
6 /******************************************/
8 #if !defined(__RtAudio_h)
13 #if defined(__LINUX_ALSA_)
14 #include <alsa/asoundlib.h>
18 typedef snd_pcm_t *AUDIO_HANDLE;
19 typedef int DEVICE_ID;
20 typedef pthread_t THREAD_HANDLE;
21 typedef pthread_mutex_t MUTEX;
23 #elif defined(__LINUX_OSS_)
27 typedef int AUDIO_HANDLE;
28 typedef int DEVICE_ID;
29 typedef pthread_t THREAD_HANDLE;
30 typedef pthread_mutex_t MUTEX;
32 #elif defined(__WINDOWS_DS_)
36 // The following struct is used to hold the extra variables
37 // specific to the DirectSound implementation.
44 typedef LPGUID DEVICE_ID;
45 typedef unsigned long THREAD_HANDLE;
46 typedef CRITICAL_SECTION MUTEX;
48 #elif defined(__IRIX_AL_)
49 #include <dmedia/audio.h>
53 typedef ALport AUDIO_HANDLE;
54 typedef int DEVICE_ID;
55 typedef pthread_t THREAD_HANDLE;
56 typedef pthread_mutex_t MUTEX;
61 // *************************************************** //
63 // RtAudioError class declaration.
65 // *************************************************** //
85 char error_message[256];
90 RtAudioError(const char *p, TYPE tipe = RtAudioError::UNSPECIFIED);
93 virtual ~RtAudioError(void);
95 //! Prints "thrown" error message to stdout.
96 virtual void printMessage(void);
98 //! Returns the "thrown" error message TYPE.
99 virtual const TYPE& getType(void) { return type; }
101 //! Returns the "thrown" error message string.
102 virtual const char *getMessage(void) { return error_message; }
106 // *************************************************** //
108 // RtAudio class declaration.
110 // *************************************************** //
116 // Support for signed integers and floats. Audio data fed to/from
117 // the tickStream() routine is assumed to ALWAYS be in host
118 // byte order. The internal routines will automatically take care of
119 // any necessary byte-swapping between the host format and the
120 // soundcard. Thus, endian-ness is not a concern in the following
121 // format definitions.
122 typedef unsigned long RTAUDIO_FORMAT;
123 static const RTAUDIO_FORMAT RTAUDIO_SINT8;
124 static const RTAUDIO_FORMAT RTAUDIO_SINT16;
125 static const RTAUDIO_FORMAT RTAUDIO_SINT24; /*!< Upper 3 bytes of 32-bit integer. */
126 static const RTAUDIO_FORMAT RTAUDIO_SINT32;
127 static const RTAUDIO_FORMAT RTAUDIO_FLOAT32; /*!< Normalized between plus/minus 1.0. */
128 static const RTAUDIO_FORMAT RTAUDIO_FLOAT64; /*!< Normalized between plus/minus 1.0. */
130 //static const int MAX_SAMPLE_RATES = 14;
131 enum { MAX_SAMPLE_RATES = 14 };
133 typedef int (*RTAUDIO_CALLBACK)(char *buffer, int bufferSize, void *userData);
137 DEVICE_ID id[2]; /*!< No value reported by getDeviceInfo(). */
138 bool probed; /*!< true if the device capabilities were successfully probed. */
139 int maxOutputChannels;
140 int maxInputChannels;
141 int maxDuplexChannels;
142 int minOutputChannels;
143 int minInputChannels;
144 int minDuplexChannels;
145 bool hasDuplexSupport; /*!< true if device supports duplex mode. */
146 int nSampleRates; /*!< Number of discrete rates or -1 if range supported. */
147 int sampleRates[MAX_SAMPLE_RATES]; /*!< Supported rates or (min, max) if range. */
148 RTAUDIO_FORMAT nativeFormats; /*!< Bit mask of supported data formats. */
151 //! The default constructor.
153 Probes the system to make sure at least one audio
154 input/output device is available and determines
155 the api-specific identifier for each device found.
156 An RtAudioError error can be thrown if no devices are
157 found or if a memory allocation error occurs.
161 //! A constructor which can be used to open a stream during instantiation.
163 The specified output and/or input device identifiers correspond
164 to those enumerated via the getDeviceInfo() method. If device =
165 0, the default or first available devices meeting the given
166 parameters is selected. If an output or input channel value is
167 zero, the corresponding device value is ignored. When a stream is
168 successfully opened, its identifier is returned via the "streamID"
169 pointer. An RtAudioError can be thrown if no devices are found
170 for the given parameters, if a memory allocation error occurs, or
171 if a driver error occurs. \sa openStream()
173 RtAudio(int *streamID,
174 int outputDevice, int outputChannels,
175 int inputDevice, int inputChannels,
176 RTAUDIO_FORMAT format, int sampleRate,
177 int *bufferSize, int numberOfBuffers);
181 Stops and closes any open streams and devices and deallocates
182 buffer and structure memory.
186 //! A public method for opening a stream with the specified parameters.
188 If successful, the opened stream ID is returned. Otherwise, an
189 RtAudioError is thrown.
191 \param outputDevice: If equal to 0, the default or first device
192 found meeting the given parameters is opened. Otherwise, the
193 device number should correspond to one of those enumerated via
194 the getDeviceInfo() method.
195 \param outputChannels: The desired number of output channels. If
196 equal to zero, the outputDevice identifier is ignored.
197 \param inputDevice: If equal to 0, the default or first device
198 found meeting the given parameters is opened. Otherwise, the
199 device number should correspond to one of those enumerated via
200 the getDeviceInfo() method.
201 \param inputChannels: The desired number of input channels. If
202 equal to zero, the inputDevice identifier is ignored.
203 \param format: An RTAUDIO_FORMAT specifying the desired sample data format.
204 \param sampleRate: The desired sample rate (sample frames per second).
205 \param *bufferSize: A pointer value indicating the desired internal buffer
206 size in sample frames. The actual value used by the device is
207 returned via the same pointer. A value of zero can be specified,
208 in which case the lowest allowable value is determined.
209 \param numberOfBuffers: A value which can be used to help control device
210 latency. More buffers typically result in more robust performance,
211 though at a cost of greater latency. A value of zero can be
212 specified, in which case the lowest allowable value is used.
214 int openStream(int outputDevice, int outputChannels,
215 int inputDevice, int inputChannels,
216 RTAUDIO_FORMAT format, int sampleRate,
217 int *bufferSize, int numberOfBuffers);
219 //! A public method which sets a user-defined callback function for a given stream.
221 This method assigns a callback function to a specific,
222 previously opened stream for non-blocking stream functionality. A
223 separate process is initiated, though the user function is called
224 only when the stream is "running" (between calls to the
225 startStream() and stopStream() methods, respectively). The
226 callback process remains active for the duration of the stream and
227 is automatically shutdown when the stream is closed (via the
228 closeStream() method or by object destruction). The callback
229 process can also be shutdown and the user function de-referenced
230 through an explicit call to the cancelStreamCallback() method.
231 Note that a single stream can use only blocking or callback
232 functionality at the same time, though it is possible to alternate
233 modes on the same stream through the use of the
234 setStreamCallback() and cancelStreamCallback() methods (the
235 blocking tickStream() method can be used before a callback is set
236 and/or after a callback is cancelled). An RtAudioError will be
237 thrown for an invalid device argument.
239 void setStreamCallback(int streamID, RTAUDIO_CALLBACK callback, void *userData);
241 //! A public method which cancels a callback process and function for a given stream.
243 This method shuts down a callback process and de-references the
244 user function for a specific stream. Callback functionality can
245 subsequently be restarted on the stream via the
246 setStreamCallback() method. An RtAudioError will be thrown for an
247 invalid device argument.
249 void cancelStreamCallback(int streamID);
251 //! A public method which returns the number of audio devices found.
252 int getDeviceCount(void);
254 //! Fill a user-supplied RTAUDIO_DEVICE structure for a specified device.
256 Any device between 0 and getDeviceCount()-1 is valid. If a
257 device is busy or otherwise unavailable, the structure member
258 "probed" has a value of "false". The system default input and
259 output devices are referenced by device identifier = 0. On
260 systems which allow dynamic default device settings, the default
261 devices are not identified by name (specific device enumerations
262 are assigned device identifiers > 0). An RtAudioError will be
263 thrown for an invalid device argument.
265 void getDeviceInfo(int device, RTAUDIO_DEVICE *info);
267 //! A public method which returns a pointer to the buffer for an open stream.
269 The user should fill and/or read the buffer data in interleaved format
270 and then call the tickStream() method. An RtAudioError will be
271 thrown for an invalid stream identifier.
273 char * const getStreamBuffer(int streamID);
275 //! Public method used to trigger processing of input/output data for a stream.
277 This method blocks until all buffer data is read/written. An
278 RtAudioError will be thrown for an invalid stream identifier or if
279 a driver error occurs.
281 void tickStream(int streamID);
283 //! Public method which closes a stream and frees any associated buffers.
285 If an invalid stream identifier is specified, this method
286 issues a warning and returns (an RtAudioError is not thrown).
288 void closeStream(int streamID);
290 //! Public method which starts a stream.
292 An RtAudioError will be thrown for an invalid stream identifier
293 or if a driver error occurs.
295 void startStream(int streamID);
297 //! Stop a stream, allowing any samples remaining in the queue to be played out and/or read in.
299 An RtAudioError will be thrown for an invalid stream identifier
300 or if a driver error occurs.
302 void stopStream(int streamID);
304 //! Stop a stream, discarding any samples remaining in the input/output queue.
306 An RtAudioError will be thrown for an invalid stream identifier
307 or if a driver error occurs.
309 void abortStream(int streamID);
311 //! Queries a stream to determine whether a call to the tickStream() method will block.
313 A return value of 0 indicates that the stream will NOT block. A positive
314 return value indicates the number of sample frames that cannot yet be
315 processed without blocking.
317 int streamWillBlock(int streamID);
323 static const unsigned int SAMPLE_RATES[MAX_SAMPLE_RATES];
325 enum { FAILURE, SUCCESS };
340 int device[2]; // Playback and record, respectively.
341 STREAM_MODE mode; // PLAYBACK, RECORD, or DUPLEX.
342 AUDIO_HANDLE handle[2]; // Playback and record handles, respectively.
343 STREAM_STATE state; // STOPPED or RUNNING
346 bool doConvertBuffer[2]; // Playback and record, respectively.
347 bool deInterleave[2]; // Playback and record, respectively.
348 bool doByteSwap[2]; // Playback and record, respectively.
352 int nUserChannels[2]; // Playback and record, respectively.
353 int nDeviceChannels[2]; // Playback and record channels, respectively.
354 RTAUDIO_FORMAT userFormat;
355 RTAUDIO_FORMAT deviceFormat[2]; // Playback and record, respectively.
357 THREAD_HANDLE thread;
359 RTAUDIO_CALLBACK callback;
363 typedef signed short INT16;
364 typedef signed int INT32;
365 typedef float FLOAT32;
366 typedef double FLOAT64;
370 RTAUDIO_DEVICE *devices;
372 std::map<int, void *> streams;
374 //! Private error method to allow global control over error handling.
375 void error(RtAudioError::TYPE type);
378 Private method to count the system audio devices, allocate the
379 RTAUDIO_DEVICE structures, and probe the device capabilities.
381 void initialize(void);
383 //! Private method to clear an RTAUDIO_DEVICE structure.
384 void clearDeviceInfo(RTAUDIO_DEVICE *info);
387 Private method which attempts to fill an RTAUDIO_DEVICE
388 structure for a given device. If an error is encountered during
389 the probe, a "warning" message is reported and the value of
390 "probed" remains false (no exception is thrown). A successful
391 probe is indicated by probed = true.
393 void probeDeviceInfo(RTAUDIO_DEVICE *info);
396 Private method which attempts to open a device with the given parameters.
397 If an error is encountered during the probe, a "warning" message is
398 reported and FAILURE is returned (no exception is thrown). A
399 successful probe is indicated by a return value of SUCCESS.
401 bool probeDeviceOpen(int device, RTAUDIO_STREAM *stream,
402 STREAM_MODE mode, int channels,
403 int sampleRate, RTAUDIO_FORMAT format,
404 int *bufferSize, int numberOfBuffers);
407 Private common method used to check validity of a user-passed
408 stream ID. When the ID is valid, this method returns a pointer to
409 an RTAUDIO_STREAM structure (in the form of a void pointer).
410 Otherwise, an "invalid identifier" exception is thrown.
412 void *verifyStream(int streamID);
415 Private method used to perform format, channel number, and/or interleaving
416 conversions between the user and device buffers.
418 void convertStreamBuffer(RTAUDIO_STREAM *stream, STREAM_MODE mode);
420 //! Private method used to perform byte-swapping on buffers.
421 void byteSwapBuffer(char *buffer, int samples, RTAUDIO_FORMAT format);
423 //! Private method which returns the number of bytes for a given format.
424 int formatBytes(RTAUDIO_FORMAT format);
427 // Uncomment the following definition to have extra information spewed to stderr.
428 //#define RTAUDIO_DEBUG