sample.h

Go to the documentation of this file.
00001 /* $Id: sample.h 191 2005-08-05 00:55:59Z tapted $ $URL: svn+ssh://pc-g33-9.it.usyd.edu.au/var/svn/pub/taptaudio/trunk/src/sample.h $ */
00002 #ifndef SAMPLE_DOT_AITCH
00003 #define SAMPLE_DOT_AITCH
00004 
00005 #include "taptaudio.h"
00006 
00007 /**\file sample.h
00008  * Decs for PCM Audio Samples
00009  * \author Trent Apted <tapted@it.usyd.edu.au>
00010  * $Revision: 191 $
00011  * $Date: 2005-08-05 10:55:59 +1000 (Fri, 05 Aug 2005) $
00012  */
00013 
00014 #include <SDL.h>
00015 
00016 #include "sndfile.h"
00017 #include "taptdebug.h"
00018 
00019 /** An ASSample using Pulse Code Modulation (PCM) */
00020 class PCMSample : public ASSample {
00021 protected:
00022     void *data;               ///< The audio data
00023     int channels;             ///< The number of channels in the sample
00024     unsigned long bytes_size; ///< The size of \a data
00025     double rate;              ///< The sample rate
00026     AUDIO_FORMAT fmt;         ///< The audio format
00027 
00028     /** Protected constructor for subclasses */
00029     PCMSample() : data(0) {}
00030 
00031 public:
00032     PCMSample(void* data_, unsigned channels_, unsigned long bytes_size_, double rate_, AUDIO_FORMAT fmt_)
00033         :
00034     data(data_), channels(channels_), bytes_size(bytes_size_), rate(rate_), fmt(fmt_) {}
00035 
00036     virtual unsigned getChannels() {return channels;}
00037     virtual AUDIO_FORMAT getFormat() {return fmt;}
00038     virtual unsigned long numBytes() {return bytes_size;}
00039     virtual const void* getBytes() {return data;}
00040     virtual double getSamRate() {return rate;}
00041 
00042     static void mono2stereo(void *newdata,
00043                             const void *olddata,
00044                             unsigned long olddata_bytes,
00045                             unsigned oldframesize);
00046 
00047     static void stereo2mono(Uint8 *newdata,
00048                             const Uint8 *olddata,
00049                             unsigned long olddata_bytes,
00050                             unsigned framesize);
00051 
00052 };
00053 
00054 /** A PCMSample loaded from a file (e.g. .wav)
00055  * Will always load the format that is native to the sound <em>file</em>.
00056  */
00057 class FileSample : public PCMSample {
00058 protected:
00059     virtual void load_sndfile(SNDFILE* sf, SF_INFO &sfinfo, bool forcestereo);
00060     virtual ~FileSample();
00061 public:
00062     FileSample (const std::string& path, bool forcestereo = false);
00063 //    FileSample (const Uint8* data, const Uint32 bytes);
00064 };
00065 
00066 /** A FileSample that reads from the file using the specified type (i.e. not
00067  * the native type for the file).
00068  */
00069 template <class T>
00070 class FileSampleT : public FileSample {
00071 protected:
00072     virtual ~FileSampleT();
00073     virtual void load_sndfile(SNDFILE* sf, SF_INFO &sfinfo, bool forcestereo);
00074 public:
00075     FileSampleT (const std::string& path, bool forcestereo = false)
00076     :
00077     FileSample(path, forcestereo) {}
00078 };
00079 
00080 /** A PCMSample recorded from audio input (microphone) */
00081 class Recording : public PCMSample {
00082 protected:
00083     virtual ~Recording();
00084     unsigned long reserved;
00085 public:
00086     Recording(unsigned long initial_size = 28672,
00087               unsigned chans = 2,
00088               AUDIO_FORMAT format = AF_Int16,
00089               double samplerate = 44100);
00090 
00091     /**
00092      * Append -- note that this cannot be called in the audio thread --
00093      * it occurs at a kernel interrupt level and we cannot allocate memory there!
00094      */
00095     void append(void *more, unsigned long sz);
00096 
00097     void fill(const void *more, unsigned long sz);
00098     void skipfill(const void *more, unsigned long sz, unsigned block);
00099     void trim();
00100     void fillSilence(unsigned long sz);
00101     bool save(const std::string &path);
00102 
00103     virtual bool isFull() {return false;}
00104 
00105 };
00106 
00107 
00108 /**
00109  * A templatized version of libsndfile's sf_read() -- read PCM
00110  * data from an audio file.
00111  *
00112  * \param sndfile the (opened) sound file handle
00113  * \param data the target buffer to store the data read from the file. Must
00114  *        have space allocated for at least sizeof(data)*items bytes
00115  * \param items the number of items to read
00116  */
00117 template <class T>
00118     sf_count_t lsf_read(SNDFILE *sndfile, T* data, sf_count_t items) {
00119         return sf_read_raw(sndfile, data, sizeof(T) * items);
00120     }
00121 
00122 template <>
00123     sf_count_t lsf_read(SNDFILE *sndfile, short* data, sf_count_t items);
00124 template <>
00125     sf_count_t lsf_read(SNDFILE *sndfile, int* data, sf_count_t items);
00126 template <>
00127     sf_count_t lsf_read(SNDFILE *sndfile, float* data, sf_count_t items);
00128 template <>
00129     sf_count_t lsf_read(SNDFILE *sndfile, double* data, sf_count_t items);
00130 
00131 template <class T>
00132 void FileSampleT<T>::load_sndfile(SNDFILE* sf, SF_INFO &sfinfo, bool forcestereo) {
00133     T* tdata;
00134     channels = sfinfo.channels;
00135     unsigned frame_sz = sizeof(T) * channels;
00136     bytes_size = frame_sz * sfinfo.frames;
00137     rate = sfinfo.samplerate;
00138     data = tdata = new T[sfinfo.frames * channels];
00139 
00140     sf_count_t numread = lsf_read(sf, tdata, channels * sfinfo.frames );
00141 
00142     if (numread != channels * sfinfo.frames) {
00143         //error -- do something?
00144     }
00145 
00146     if (channels == 1 && forcestereo) {
00147         T *newdata = new T[sfinfo.frames * 2];
00148         mono2stereo(newdata, data, bytes_size, frame_sz /* == sizeof(T) */);
00149         delete[] tdata;
00150         data = newdata;
00151         bytes_size *= 2;
00152         channels = 2;
00153     }
00154 }
00155 
00156 template <class T>
00157 FileSampleT<T>::~FileSampleT() {
00158     delete[] static_cast<T*>(data);
00159     data = 0;
00160 }
00161 
00162 #endif

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