CLAM-Development  1.4.0
RtAudio.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG)
3  * UNIVERSITAT POMPEU FABRA
4  *
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 
22 /************************************************************************/
59 /************************************************************************/
60 
61 #if !defined(__RTAUDIO_H)
62 #define __RTAUDIO_H
63 
64 #include <map>
65 
66 #if defined(__LINUX_ALSA__)
67 
68  /* alsa 0.9 backward compat for alsa 1.0 */
69  #define ALSA_PCM_OLD_HW_PARAMS_API
70  #define ALSA_PCM_OLD_SW_PARAMS_API
71 
72  #include <alsa/asoundlib.h>
73  #include <pthread.h>
74  #include <unistd.h>
75 
76  typedef snd_pcm_t *AUDIO_HANDLE;
77  typedef int DEVICE_ID;
78  typedef pthread_t THREAD_HANDLE;
79  typedef pthread_mutex_t MUTEX;
80 
81 #elif defined(__LINUX_OSS__)
82  #include <pthread.h>
83  #include <unistd.h>
84 
85  typedef int AUDIO_HANDLE;
86  typedef int DEVICE_ID;
87  typedef pthread_t THREAD_HANDLE;
88  typedef pthread_mutex_t MUTEX;
89 
90 #elif defined(__WINDOWS_DS__)
91  #include "CLAM_windows.h"
92  #include <process.h>
93 
94  // The following struct is used to hold the extra variables
95  // specific to the DirectSound implementation.
96  typedef struct {
97  void * object;
98  void * buffer;
99  UINT bufferPointer;
100  } AUDIO_HANDLE;
101 
102  typedef LPGUID DEVICE_ID;
103  typedef unsigned long THREAD_HANDLE;
104  typedef CRITICAL_SECTION MUTEX;
105 
106 #elif defined(__WINDOWS_ASIO__)
107  #include "CLAM_windows.h"
108  #include <process.h>
109 
110  typedef int AUDIO_HANDLE;
111  typedef int DEVICE_ID;
112  typedef unsigned long THREAD_HANDLE;
113  typedef CRITICAL_SECTION MUTEX;
114 
115 #elif defined(__IRIX_AL__)
116  #include <dmedia/audio.h>
117  #include <pthread.h>
118  #include <unistd.h>
119 
120  typedef ALport AUDIO_HANDLE;
121  typedef long DEVICE_ID;
122  typedef pthread_t THREAD_HANDLE;
123  typedef pthread_mutex_t MUTEX;
124 
125 #elif defined(__MACOSX_CORE__)
126 
127  #include <CoreAudio/AudioHardware.h>
128  #include <pthread.h>
129 
130  typedef unsigned int AUDIO_HANDLE;
131  typedef AudioDeviceID DEVICE_ID;
132  typedef pthread_t THREAD_HANDLE;
133  typedef pthread_mutex_t MUTEX;
134 
135 #endif
136 
137 
138 /************************************************************************/
151 /************************************************************************/
152 
153 class RtError
154 {
155 public:
157  enum TYPE {
169  };
170 
171 protected:
172  char error_message[256];
174 
175 public:
177  RtError(const char *p, TYPE tipe = RtError::UNSPECIFIED);
178 
180  virtual ~RtError(void);
181 
183  virtual void printMessage(void);
184 
186  virtual const TYPE& getType(void) { return type; }
187 
189  virtual const char *getMessage(void) { return error_message; }
190 };
191 
192 
193 // This public structure type is used to pass callback information
194 // between the private RtAudio stream structure and global callback
195 // handling functions.
196 typedef struct {
197  void *object; // Used as a "this" pointer.
198  int streamId;
199  DEVICE_ID device[2];
200  THREAD_HANDLE thread;
201  void *callback;
202  void *buffers;
203  unsigned long waitTime;
204  bool blockTick;
207  void *userData;
208 } CALLBACK_INFO;
209 
210 
211 // *************************************************** //
212 //
213 // RtAudio class declaration.
214 //
215 // *************************************************** //
216 
217 class RtAudio
218 {
219 public:
220 
221  // Support for signed integers and floats. Audio data fed to/from
222  // the tickStream() routine is assumed to ALWAYS be in host
223  // byte order. The internal routines will automatically take care of
224  // any necessary byte-swapping between the host format and the
225  // soundcard. Thus, endian-ness is not a concern in the following
226  // format definitions.
227  typedef unsigned long RTAUDIO_FORMAT;
235  //static const int MAX_SAMPLE_RATES = 14;
236  enum { MAX_SAMPLE_RATES = 14 };
237 
238  typedef int (*RTAUDIO_CALLBACK)(char *buffer, int bufferSize, void *userData);
239 
241  typedef struct {
242  char name[128];
243  DEVICE_ID id[2]; /* No value reported by getDeviceInfo(). */
244  bool probed;
252  bool isDefault;
254  int sampleRates[MAX_SAMPLE_RATES];
256  } RTAUDIO_DEVICE;
257 
259 
265  RtAudio();
266 
268 
279  RtAudio(int *streamId,
280  int outputDevice, int outputChannels,
281  int inputDevice, int inputChannels,
282  RTAUDIO_FORMAT format, int sampleRate,
283  int *bufferSize, int numberOfBuffers);
284 
286 
290  ~RtAudio();
291 
293 
320  int openStream(int outputDevice, int outputChannels,
321  int inputDevice, int inputChannels,
322  RTAUDIO_FORMAT format, int sampleRate,
323  int *bufferSize, int numberOfBuffers);
324 
326 
345  void setStreamCallback(int streamId, RTAUDIO_CALLBACK callback, void *userData);
346 
348 
355  void cancelStreamCallback(int streamId);
356 
358  int getDeviceCount(void);
359 
361 
369  void getDeviceInfo(int device, RTAUDIO_DEVICE *info);
370 
372 
377  char * const getStreamBuffer(int streamId);
378 
380 
385  void tickStream(int streamId);
386 
388 
392  void closeStream(int streamId);
393 
395 
399  void startStream(int streamId);
400 
402 
406  void stopStream(int streamId);
407 
409 
413  void abortStream(int streamId);
414 
416 
421  int streamWillBlock(int streamId);
422 
423 #if (defined(__MACOSX_CORE__) || defined(__WINDOWS_ASIO__))
424  // This function is intended for internal use only. It must be
425  // public because it is called by the internal callback handler,
426  // which is not a member of RtAudio. External use of this function
427  // will most likely produce highly undesireable results!
428  void callbackEvent(int streamId, DEVICE_ID deviceId, void *inData, void *outData);
429 #endif
430 
431 protected:
432 
433 private:
434 
435  static const unsigned int SAMPLE_RATES[MAX_SAMPLE_RATES];
436 
437  enum { FAILURE, SUCCESS };
438 
439  enum STREAM_MODE {
440  OUTPUT,
441  INPUT,
442  DUPLEX,
443  UNINITIALIZED = -75
444  };
445 
446  enum STREAM_STATE {
447  STREAM_STOPPED,
448  STREAM_RUNNING
449  };
450 
451  typedef struct {
452  int device[2]; // Playback and record, respectively.
453  STREAM_MODE mode; // OUTPUT, INPUT, or DUPLEX.
454  AUDIO_HANDLE handle[2]; // Playback and record handles, respectively.
455  STREAM_STATE state; // STOPPED or RUNNING
456  char *userBuffer;
457  char *deviceBuffer;
458  bool doConvertBuffer[2]; // Playback and record, respectively.
459  bool deInterleave[2]; // Playback and record, respectively.
460  bool doByteSwap[2]; // Playback and record, respectively.
461  int sampleRate;
462  int bufferSize;
463  int nBuffers;
464  int nUserChannels[2]; // Playback and record, respectively.
465  int nDeviceChannels[2]; // Playback and record channels, respectively.
466  RTAUDIO_FORMAT userFormat;
467  RTAUDIO_FORMAT deviceFormat[2]; // Playback and record, respectively.
468  MUTEX mutex;
469  CALLBACK_INFO callbackInfo;
470  } RTAUDIO_STREAM;
471 
472  typedef signed short INT16;
473  typedef signed int INT32;
474  typedef float FLOAT32;
475  typedef double FLOAT64;
476 
477  char message[256];
478  int nDevices;
479  RTAUDIO_DEVICE *devices;
480 
481  std::map<int, void *> streams;
482 
484  void error(RtError::TYPE type);
485 
490  void initialize(void);
491 
496  int getDefaultInputDevice(void);
497 
502  int getDefaultOutputDevice(void);
503 
505  void clearDeviceInfo(RTAUDIO_DEVICE *info);
506 
514  void probeDeviceInfo(RTAUDIO_DEVICE *info);
515 
522  bool probeDeviceOpen(int device, RTAUDIO_STREAM *stream,
523  STREAM_MODE mode, int channels,
524  int sampleRate, RTAUDIO_FORMAT format,
525  int *bufferSize, int numberOfBuffers);
526 
533  void *verifyStream(int streamId);
534 
539  void convertStreamBuffer(RTAUDIO_STREAM *stream, STREAM_MODE mode);
540 
542  void byteSwapBuffer(char *buffer, int samples, RTAUDIO_FORMAT format);
543 
545  int formatBytes(RTAUDIO_FORMAT format);
546 };
547 
548 // Define the following flag to have extra information spewed to stderr.
549 //#define __RTAUDIO_DEBUG__
550 
551 #endif
552