00001 /* $Id: taptaudio.h 2 2006-03-15 23:09:28Z boogalord $ $URL: https://svn.sourceforge.net/svnroot/tappedaudio/tappedaudio/trunk/include/taptaudio.h $ */ 00002 #ifndef TAPTAUDIO_DOT_AITCH 00003 #define TAPTAUDIO_DOT_AITCH 00004 00005 /**\file taptaudio.h 00006 * Tapted's Audio Subsystem manager singleton 00007 * \author Trent Apted <tapted@it.usyd.edu.au> 00008 * $Revision: 2 $ 00009 * $Date: 2006-03-16 10:09:28 +1100 (Thu, 16 Mar 2006) $ 00010 */ 00011 00012 #ifndef SWIG 00013 #include <string> 00014 #endif 00015 00016 /** Possible PCM Audio formats for the mixer */ 00017 enum AUDIO_FORMAT { 00018 AF_Default, ///< Default format (Int16) 00019 AF_Float32, ///< 32-bit floats 00020 AF_Int16, ///< 16-bit signed ints 00021 AF_Int32, ///< 32-bit signed ints 00022 AF_Int24, ///< NFI - not supported 00023 AF_PackedInt24, ///< NFI - not supported 00024 AF_Int8, ///< 8-bit signed ints 00025 AF_UInt8, ///< 8-bit unsigned ints (not supported) 00026 AF_CustomFormat ///< Some custom format (not supported) 00027 }; 00028 00029 /** 00030 * Possible file encodings. For loading, many others will magically 00031 * work by using the magic bytes at the start of the file (and thanks 00032 * to libsndfile). However for now, these are all I've been bothered 00033 * to do mappings for when saving. 00034 */ 00035 enum FILE_ENCODING { 00036 AF_ENC_WAV, ///< WAV File (defaults to PCM) 00037 AF_ENC_RAW, ///< RAW format (PCM) 00038 AF_ENC_OGG, ///< OGG File -- not yet implemented 00039 AF_ENC_FLAC, ///< Compressed, lossless FLAC 00040 AF_ENC_AU, ///< AU File (defaults to PCM) 00041 AF_ENC_AIFF, ///< AIFF File 00042 AF_ENC_CAF, ///< Apple CAF File 00043 AF_MASK_FILE = 0x00ff, ///< Mask for file type 00044 AF_SHIFT_FILE = 0, ///< right bit-shift for file (header) type 00045 00046 /* the encodings below must be OR-ed with a header format above */ 00047 AF_ENC_PCM = 0x0000, ///< PCM encoding (default) 00048 AF_ENC_MLAW = 0x0100, ///< mu-law encoding 00049 AF_ENC_ALAW = 0x0200, ///< A-law encoding 00050 AF_ENC_ADPCM = 0x0300, ///< ADPCM -- WAV or AU only, valid qualities are 24 (default), 32 or 40 (kbps) 00051 AF_ENC_DWVW = 0x0400, ///< DWVW -- AIFF or RAW only 00052 AF_ENC_VORBIS = 0x0500, ///< Vorbis encoding (ogg) -- not yet implemented 00053 AF_ENC_SPEEX = 0x0600, ///< Speex encoding (ogg) -- not yet implemented 00054 AF_MASK_ENCODING = 0x0f00, ///< Mask for encoding 00055 AF_SHIFT_ENCODING = 8, ///< right bit-shift for encoding 00056 00057 /* use the encodings below to force a PCM format other than that of the audio system */ 00058 AF_ENC_PCM_AUDIOSYS = 0x0000, ///< Use the same audio format as the currently running AudioSystem 00059 AF_ENC_PCM_UNSIGNED = 0x1000, ///< Unsigned 8-bit -- WAV, AIFF and RAW only 00060 AF_ENC_PCM_8 = 0x2000, ///< Signed 8-bit integer -- all except WAV 00061 AF_ENC_PCM_16 = 0x3000, ///< Signed 16-bit integer 00062 AF_ENC_PCM_24 = 0x5000, ///< Signed 24-bit integer 00063 AF_ENC_PCM_32 = 0x6000, ///< Signed 32-bit integer 00064 AF_ENC_PCM_FLOAT = 0x7000, ///< 32-bit floating point 00065 AF_ENC_PCM_DOUBLE = 0x8000, ///< 64-bit floating point 00066 AF_MASK_PCM_FORMAT = 0xf000, ///< Mask for PCM format 00067 AF_SHIFT_PCM_FORMAT = 12, ///< right bit-shift for pcm format 00068 00069 AF_MASK_FILE_ENCODING = 0xffff ///< Mask for file and encoding description 00070 }; 00071 00072 /** Audio backends */ 00073 enum AUDIO_BACKEND { 00074 AF_NOAUDIO = 0, ///< Use a dummy backend 00075 AF_PORTAUDIO = 1, ///< Use Portaudio backend (default host) 00076 AF_JACKAUDIO = 2, ///< Use JACK Audio Connection Toolkit backend 00077 AF_PORTAUDIO_OSS = 5, 00078 AF_PORTAUDIO_ALSA = 9, 00079 AF_PORTAUDIO_JACK = 13, 00080 AF_PORTAUDIO_MME = 17, 00081 AF_PORTAUDIO_ASIO = 21, 00082 AF_PORTAUDIO_AL = 25, 00083 AF_PORTAUDIO_BEOS = 29, 00084 AF_PORTAUDIO_WDMKS = 33, 00085 AF_PORTAUDIO_COREAUDIO = 37, 00086 AF_PORTAUDIO_SOUNDMANAGER = 41, 00087 AF_PORTAUDIO_DIRECTSOUND = 45, 00088 AF_PORTAUDIO_ALSA_BLOCK = 49, 00089 AF_PORTAUDIO_ABSOLUTE = 53 ///< Device IDs specified for portaudio are absolute IDs 00090 /* that's all I've implemented so far.. */ 00091 }; 00092 00093 class AudioSystemImpl; //forward dec 00094 class ASSample; //forward dec 00095 00096 /** 00097 * The audio system. Only one of these may exist at a time. 00098 * You may delete the old copy and make a new one if you wish. 00099 */ 00100 class AudioSystem { 00101 public: 00102 /* configuration variables */ 00103 /** 00104 * Number of audio tracks in mixer. 00105 * - 0 will disable audio (singleton will never be created) 00106 * - 1 will use a super-fast non-mixer version 00107 * - >1 will use a stereo/mono N-track mixer 00108 * default: 32 00109 * \note track overhead (i.e. >2) is negligible (i.e. vs 2) 00110 */ 00111 static unsigned AUDIO_TRACKS; 00112 #if 0 00113 /** Default audio backend fallback order (jack, portaudio, noaudio). 00114 * \note JACK is first because Portaudio is unstable and 00115 * tends to segfault when it can't initialise 00116 */ 00117 static const AUDIO_BACKEND DEFAULT_BACKENDS[]; 00118 #endif 00119 00120 protected: 00121 ///no copying - we are a Singleton 00122 AudioSystem(const AudioSystem&);// {} 00123 ///no assignment - we are a Singleton 00124 AudioSystem& operator=(const AudioSystem&);// {return *this;} 00125 00126 AudioSystemImpl* impl; ///< The pointer implementation 00127 static AudioSystem* instance; ///< The singleton 00128 public: 00129 /** 00130 * Create the audio system. 00131 * 00132 * \param format The format to try and mix audio in (some backends may force a particular format) 00133 * \param sampleRate The sample rate to run the AudioSystem in 00134 * \param inputChannels The number of input channels (i.e. mono/stereo microphone) 00135 * \param outputChannels The number of output channels (i.e. mono/stereo/surround) 00136 * \param deviceIDin The input device identifier (usually backend-dependent, -1 is default/best, use listDevices() for a list) 00137 * \param deviceIDout The input output identifier 00138 * \param backends A fallback list of backends to attempt to initialize THIS MUST BE TERMINATED BY AF_NOAUDIO (or NULL/0) 00139 */ 00140 AudioSystem(AUDIO_FORMAT format = AF_Default, 00141 double sampleRate = 0.0, 00142 int inputChannels = 2, 00143 int outputChannels = 2, 00144 int deviceIDin = -1, 00145 int deviceIDout = -1, 00146 const AUDIO_BACKEND backends[] = NULL 00147 ); 00148 00149 /** 00150 * Get the singleton instance. Returns NULL if it has 00151 * not been created, or it has been destroyed. 00152 */ 00153 static AudioSystem* get();// {return instance;} //no good for dependent DLLs 00154 00155 /** 00156 * Returns true if the AudioSystem is running. 00157 */ 00158 static bool isRunning();// {return instance;} //no good for dependent DLLs 00159 00160 /** 00161 * Set the debugging level for the audio system. 0 for none, 00162 * higher means more messages 00163 */ 00164 static void setDebugLevel(unsigned level); 00165 00166 /** 00167 * Set the FILE* at which debugging output is sent 00168 */ 00169 static void setDebugFile(void* FILESTAR); 00170 00171 /** 00172 * Lists the device IDs to stderr 00173 */ 00174 static void listDevices(); 00175 00176 /** 00177 * Destructor destroys the singleton, allowing another to be made. 00178 */ 00179 ~AudioSystem(); 00180 00181 /** 00182 * Load a sample that will be managed by the AudioSystem. 00183 * Client code will just use the return value as a pointer 00184 * to pass back into the audio system. Most of this can occur 00185 * in a background thread .. but maybe not two at once. 00186 * 00187 * \note If \a name is not registered, it must refer to a file AND 00188 * the file must be in a format convertible to the audio system. 00189 * 00190 * \param name A filename, or the name of a sample "known" to the AudioSystem 00191 * \return a loaded sample, that can be passed back to the AudioSystem 00192 */ 00193 ASSample* loadSample(const char* name); 00194 00195 /** 00196 * Free all resources used by a sample, ONLY IF THE REFERENCE COUNT IS ZERO. 00197 * Will also remove itself from the sample registry. Only ever use this to 00198 * free a sample -- never delete() your reference. 00199 * 00200 * \param samp the sample to free 00201 * \return true if the reference count was zero and the sample was freed (i.e. success) 00202 */ 00203 bool freeSample(ASSample* samp); 00204 00205 /** 00206 * Load a raw sample from memory. Must match the format of the loaded 00207 * AudioSystem. 00208 */ 00209 ASSample* loadRawSample(const char* name, void* data, unsigned long size); 00210 00211 /** 00212 * Mix a loaded sample into the output audio stream. 00213 * \note if samp is NULL, we return false 00214 * \note if DEBUG_LEVEL > WARNING (2, i.e. 3 or more), we check to see if \a samp 00215 * is registered before playing (otherwise we assume it is valid) 00216 * 00217 * \param samp the sample to play 00218 * \param record_after if true, we will start recording when the sample is finished 00219 * \param record_size the size of the record buffer in seconds 00220 * \param vol the volume at which to mix the (output) sample 00221 * \param trackno if non-null, this will be set to the track number assigned to the sample 00222 * \returns true if there is a free track in which to play the sample 00223 */ 00224 bool mixSample(ASSample *samp, bool record_after, double record_size = 30.0, float vol = 1.0f, unsigned* trackno = 0); 00225 00226 /**\overload mixSample(samp, record_after, record_size, vol, trackno) */ 00227 bool mixSample(ASSample *samp, float vol = 1.0f, unsigned* trackno = 0); 00228 00229 /** 00230 * Loop a sample. Stop it with stopSample. 00231 * 00232 * \note it makes no sense to record after one of these 00233 * \param samp the sample to play 00234 * \param vol the volume at which to mix the sample 00235 * \param trackno if non-null, this will be set to the track number assigned to the sample 00236 * \returns true if our mixer supports looping and 00237 * there is a free track in which to play the sample 00238 */ 00239 bool loopSample(ASSample *samp, float vol = 1.0f, unsigned* trackno = 0); 00240 00241 /** 00242 * Stop playing instances of a sample. 00243 * 00244 * \param samp the sample to stop playing. 00245 * \param trackno the track (holding a playing \a samp) to stop; -1 for all 00246 * \returns the number of samples stopped 00247 */ 00248 unsigned stopSample(ASSample *samp, int trackno = -1); 00249 00250 /** 00251 * Pause playing instances of a sample. 00252 * 00253 * \param samp the sample to pause 00254 * \param trackno the track (holding a playing \a samp) to pause; -1 for all 00255 * \param setpause true to pause, false to unpause 00256 * \returns the number of samples paused 00257 */ 00258 unsigned pauseSample(ASSample *samp, int trackno = -1, bool setpause = true); 00259 00260 /** 00261 * Unpause paused instances of a sample. 00262 */ 00263 unsigned unpauseSample(ASSample *samp, int trackno = -1); 00264 00265 /** 00266 * Adjust the volume of all playing instances of a sample 00267 * 00268 * \param samp the sample to adjust 00269 * \param vol the volume to set 00270 * \param trackno the track (holding a playing \a samp) to adjust; -1 for all 00271 * \returns the number of samples adjusted 00272 */ 00273 unsigned setVolume(ASSample *samp, float vol = 1.0f, int trackno = -1); 00274 00275 /** 00276 * Start buffering data from the audio input (microphone) into 00277 * the (single) recording buffer. 00278 * 00279 * \param secondsMax the maximum amount of time we will record for (we will trim the buffer if we record less) 00280 * \return true if we were able to start recording (false if we are already recording) 00281 */ 00282 bool startRec(double secondsMax = 30.0); 00283 00284 /** 00285 * Pause the recording 00286 * 00287 * \return true if there is a current recording that was not already paused (and is now paused) 00288 */ 00289 bool pauseRec(); 00290 00291 /** 00292 * Resume the recording 00293 * 00294 * \return true if there is a currently a paused recording that has now resumed 00295 */ 00296 bool resumeRec(); 00297 00298 /** 00299 * Preview the current recording (i.e. mix it into the output stream). It doesn't need to be paused. 00300 * 00301 * \param vol the volume at which to mix the recording 00302 * \param trackno if non-null, set to the track number where the recording will be previewed 00303 * \return true if there is a current recording 00304 */ 00305 bool previewRec(float vol = 1.0, unsigned* trackno = 0); 00306 00307 /** 00308 * Returns true if we are currently recording. 00309 */ 00310 bool isRecording(); 00311 00312 /** 00313 * Stop *ALL* audio operations 00314 */ 00315 void stop(); 00316 00317 /** 00318 * Stop buffering and create a sample from the recorded audio. 00319 * 00320 * \param name if non-null use \a name to identify the sample in the registry 00321 * if null, a name will be generated based on the current time 00322 * \param save if true, the sample will be saved to disk, using \a name as the filename 00323 * \param save_in_thread if true, we will start a thread to save the data 00324 * \param enc file encoding to use (defaults to WAV) 00325 * \param quality encoding quality, where relevant 00326 */ 00327 ASSample* stopRec(const char* name = "", bool save = false, bool save_in_thread = false, 00328 FILE_ENCODING enc = AF_ENC_WAV, float quality = 2.0); 00329 #ifndef SWIG 00330 /**\overload loadRawSample(const char, void*, unsigned long) */ 00331 ASSample* loadRawSample(const std::string &name, void* data, unsigned long size); 00332 /**\overload loadSample(const char*) */ 00333 ASSample* loadSample(const std::string &name); 00334 /**\overload stopRec(const char*, bool, bool, FILE_ENCODING, float) */ 00335 ASSample* stopRec(const std::string &name, bool save = false, bool save_in_thread = false, 00336 FILE_ENCODING enc = AF_ENC_WAV, float quality = 2.0); 00337 #endif 00338 00339 /** Get the current VU level of the input buffer between 0 and 1.0 */ 00340 float inputVU() const; 00341 }; 00342 00343 /** 00344 * This is an AudioSystem Sample. Nothing to do with ample amounts of donkeys. 00345 * We can maybe move this to the cpp file... 00346 */ 00347 class ASSample { 00348 public: 00349 friend class AudioSystemImpl; ///Allow AudioSystemImpl to delete instances 00350 #ifndef SWIG_MUST_PEEK 00351 protected: 00352 #endif 00353 /** Virtual Destructor -- does nothing, but private -- 00354 * must be deleted by the audio system; NOT YOU! */ 00355 virtual ~ASSample() {} 00356 public: 00357 /** Number of non-registry references to this sample */ 00358 unsigned refs; 00359 /** Constructor (refs start at 0) */ 00360 ASSample() : refs(0) {} 00361 /** Return the number of channels in this sample */ 00362 virtual unsigned getChannels() const = 0; 00363 /** Return the format of this sample */ 00364 virtual AUDIO_FORMAT getFormat() const = 0; 00365 /** Return the number of bytes in this sample */ 00366 virtual unsigned long numBytes() const = 0; 00367 /** Return the number of frames in this sample */ 00368 virtual unsigned long numFrames() const = 0; 00369 /** Get a pointer to the first byte of this sample */ 00370 virtual const void* getBytes() const = 0; 00371 /** Return the sample rate of this sample */ 00372 virtual double getSamRate() const = 0; 00373 /** Reample to \a newrate */ 00374 virtual bool resample(double newrate, bool highquality = false) = 0; 00375 00376 /** Tell this sample that \a frames of its data were mixed by \a handle. 00377 * This function may by called at the interrupt level so cannot allocate 00378 * memory. 00379 */ 00380 virtual void mixed(unsigned long /*frames*/, void* /*handle*/ = 0, int /*channelOffset*/ = -1) {} 00381 }; 00382 00383 /** \example record_basic.cpp 00384 * Basic Recording 00385 */ 00386 00387 /** \example record.cpp 00388 * Extended Recording 00389 */ 00390 00391 /** \example volumes.cpp 00392 * Playing with given volumes 00393 */ 00394 00395 /** 00396 * \example mixing.cpp 00397 * Mixing multiple tracks 00398 */ 00399 00400 /** \example loopmix.cpp 00401 * Mixing and looping 00402 */ 00403 00404 /** \example pytests.py 00405 * Python bindings 00406 */ 00407 00408 /** \example rbtests.rb 00409 * Ruby bindings 00410 */ 00411 00412 00413 #endif