taptaudio.h

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

Generated on Thu Mar 16 11:30:41 2006 for TaptAudio by  doxygen 1.4.6