00001 /* $Id: taptaudio.h 192 2005-08-05 09:35:16Z tapted $ $URL: svn+ssh://pc-g33-9.it.usyd.edu.au/var/svn/pub/taptaudio/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: 192 $ 00009 * $Date: 2005-08-05 19:35:16 +1000 (Fri, 05 Aug 2005) $ 00010 */ 00011 00012 #ifndef SWIG 00013 #include <string> 00014 #endif 00015 00016 /** Possible PCM Audio formats */ 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 class AudioSystemImpl; //forward dec 00030 class ASSample; //forward dec 00031 00032 /** 00033 * The audio system. Only one of these may exist at a time. 00034 * You may delete the old copy and make a new one if you wish. 00035 */ 00036 class AudioSystem { 00037 public: 00038 /* configuration variables */ 00039 /** 00040 * Number of audio tracks in mixer. 00041 * - 0 will disable audio (singleton will never be created) 00042 * - 1 will use a super-fast non-mixer version 00043 * - >1 will use a stereo/mono N-track mixer 00044 * default: 32 00045 * \note track overhead is negligible 00046 */ 00047 static unsigned AUDIO_TRACKS; 00048 00049 00050 protected: 00051 ///no copying - we are a Singleton 00052 AudioSystem(const AudioSystem&) {} 00053 ///no assignment - we are a Singleton 00054 AudioSystem& operator=(const AudioSystem&) {return *this;} 00055 00056 AudioSystemImpl* impl; ///< The pointer implementation 00057 static AudioSystem* instance; ///< The singleton 00058 public: 00059 /** 00060 * Create the audio system 00061 */ 00062 AudioSystem(AUDIO_FORMAT format = AF_Default, 00063 double sampleRate = 0.0, 00064 int inputChannels = 2, 00065 int outputChannels = 2, 00066 int deviceIDin = 0, 00067 int deviceIDout = 0 00068 ); 00069 00070 /** 00071 * Get the singleton instance. Returns NULL if it has 00072 * not been created, or it has been destroyed. 00073 */ 00074 static AudioSystem* get() {return instance;} 00075 00076 /** 00077 * Returns true if the AudioSystem is running. 00078 */ 00079 static bool isRunning() {return instance;} 00080 00081 /** 00082 * Set the debugging level for the audio system. 0 for none, 00083 * higher means more messages 00084 */ 00085 static void setDebugLevel(unsigned level); 00086 00087 /** 00088 * Set the FILE* at which debugging output is sent 00089 */ 00090 static void setDebugFile(void* FILESTAR); 00091 00092 /** 00093 * Lists the device IDs to stderr 00094 */ 00095 static void listDevices(); 00096 00097 /** 00098 * Destructor destroys the singleton, allowing another to be made. 00099 */ 00100 ~AudioSystem(); 00101 00102 /** 00103 * Load a sample that will be managed by the AudioSystem. 00104 * Client code will just use the return value as a pointer 00105 * to pass back into the audio system. Most of this can occur 00106 * in a background thread .. but maybe not two at once. 00107 * 00108 * \note If \a name is not registered, it must refer to a file AND 00109 * the file must be in a format convertible to the audio system. 00110 * 00111 * \param name A filename, or the name of a sample "known" to the AudioSystem 00112 * \return a loaded sample, that can be passed back to the AudioSystem 00113 */ 00114 ASSample* loadSample(const char* name); 00115 #ifndef SWIG 00116 /**\overload */ 00117 ASSample* loadSample(const std::string &name); 00118 #endif 00119 00120 /** 00121 * Free all resources used by a sample, ONLY IF THE REFERENCE COUNT IS ZERO. 00122 * Will also remove itself from the sample registry. Only ever use this to 00123 * free a sample -- never delete() your reference. 00124 * 00125 * \param samp the sample to free 00126 * \return true if the reference count was zero and the sample was freed (i.e. success) 00127 */ 00128 bool freeSample(ASSample* samp); 00129 00130 /** 00131 * Load a raw sample from memory. Must match the format of the loaded 00132 * AudioSystem. 00133 */ 00134 ASSample* loadRawSample(const char* name, void* data, unsigned long size); 00135 #ifndef SWIG 00136 /**\overload */ 00137 ASSample* loadRawSample(const std::string &name, void* data, unsigned long size); 00138 #endif 00139 00140 /** 00141 * Mix a loaded sample into the output audio stream. 00142 * 00143 * \param samp the sample to play 00144 * \param record_after if true, we will start recording when the sample is finished 00145 * \param record_size the size of the record buffer in seconds 00146 * \param vol the volume at which to mix the (output) sample 00147 * \param trackno if non-null, this will be set to the track number assigned to the sample 00148 * \returns true if there is a free track in which to play the sample 00149 */ 00150 bool mixSample(ASSample *samp, bool record_after, double record_size = 30.0, float vol = 1.0f, unsigned* trackno = 0); 00151 00152 /**\overload */ 00153 bool mixSample(ASSample *samp, float vol = 1.0f, unsigned* trackno = 0); 00154 00155 /** 00156 * Loop a sample. Stop it with stopSample. 00157 * 00158 * \note it makes no sense to record after one of these 00159 * \param samp the sample to play 00160 * \param vol the volume at which to mix the sample 00161 * \param trackno if non-null, this will be set to the track number assigned to the sample 00162 * \returns true if our mixer supports looping and 00163 * there is a free track in which to play the sample 00164 */ 00165 bool loopSample(ASSample *samp, float vol = 1.0f, unsigned* trackno = 0); 00166 00167 /** 00168 * Stop playing instances of a sample. 00169 * 00170 * \param samp the sample to stop playing. 00171 * \param trackno the track (holding a playing \a samp) to stop; -1 for all 00172 * \returns the number of samples stopped 00173 */ 00174 unsigned stopSample(ASSample *samp, int trackno = -1); 00175 00176 /** 00177 * Adjust the volume of all playing instances of a sample 00178 * 00179 * \param samp the sample to adjust 00180 * \param vol the volume to set 00181 * \param trackno the track (holding a playing \a samp) to adjust; -1 for all 00182 * \returns the number of samples adjusted 00183 */ 00184 unsigned setVolume(ASSample *samp, float vol = 1.0f, int trackno = -1); 00185 00186 /** 00187 * Start buffering data from the audio input (microphone) into 00188 * the (single) recording buffer. 00189 * 00190 * \param secondsMax the maximum amount of time we will record for (we will trim the buffer if we record less) 00191 * \return true if we were able to start recording (false if we are already recording) 00192 */ 00193 bool startRec(double secondsMax = 30.0); 00194 00195 /** 00196 * Returns true if we are currently recording. 00197 */ 00198 bool isRecording(); 00199 00200 /** 00201 * Stop *ALL* audio operations 00202 */ 00203 void stop(); 00204 00205 /** 00206 * Stop buffering and create a sample from the recorded audio. 00207 * 00208 * \param name if non-null use \a name to identify the sample in the registry 00209 * if null, a name will be generated based on the current time 00210 * \param save if true, the sample will be saved to disk, using \a name as the filename 00211 * \param save_in_thread if true, we will start a thread to save the data 00212 */ 00213 ASSample* stopRec(const char* name = "", bool save = false, bool save_in_thread = false); 00214 #ifndef SWIG 00215 /**\overload */ 00216 ASSample* stopRec(const std::string &name = "", bool save = false, bool save_in_thread = false); 00217 #endif 00218 00219 }; 00220 00221 /** 00222 * This is an AudioSystem Sample. Nothing to do with ample amounts of donkeys. 00223 * We can maybe move this to the cpp file... 00224 */ 00225 class ASSample { 00226 public: 00227 friend class AudioSystemImpl; ///Allow AudioSystemImpl to delete instances 00228 #ifndef SWIG_MUST_PEEK 00229 protected: 00230 #endif 00231 /** Virtual Destructor -- does nothing, but private -- 00232 * must be deleted by the audio system; NOT YOU! */ 00233 virtual ~ASSample() {} 00234 public: 00235 /** Number of non-registry references to this sample */ 00236 unsigned refs; 00237 /** Constructor (refs start at 0) */ 00238 ASSample() : refs(0) {} 00239 /** Return the number of channels in this sample */ 00240 virtual unsigned getChannels() = 0; 00241 /** Return the format of this sample */ 00242 virtual AUDIO_FORMAT getFormat() = 0; 00243 /** Return the number of bytes in this sample */ 00244 virtual unsigned long numBytes() = 0; 00245 /** Get a pointer to the first byte of this sample */ 00246 virtual const void* getBytes() = 0; 00247 /** Return the sample rate of this sample */ 00248 virtual double getSamRate() = 0; 00249 /** Tell this sample that \a frames of its data were mixed by \a handle. 00250 * This function may by called at the interrupt level so cannot allocate 00251 * memory. 00252 */ 00253 virtual void mixed(unsigned long /*frames*/, void* /*handle*/ = 0) {} 00254 }; 00255 00256 /** \example record_basic.cpp 00257 * Basic Recording 00258 */ 00259 00260 /** \example record.cpp 00261 * Extended Recording 00262 */ 00263 00264 /** \example volumes.cpp 00265 * Playing with given volumes 00266 */ 00267 00268 /** 00269 * \example mixing.cpp 00270 * Mixing multiple tracks 00271 */ 00272 00273 /** \example loopmix.cpp 00274 * Mixing and looping 00275 */ 00276 00277 /** \example pytests.py 00278 * Python bindings 00279 */ 00280 00281 00282 #endif
1.4.3