taptaudio.h

Go to the documentation of this file.
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

Generated on Fri Aug 5 19:43:10 2005 for TaptAudio by  doxygen 1.4.3