MPMA Framework 0.4
Source.h
Go to the documentation of this file.
00001 
00002 //Luke Lenhart, 2008-2011
00003 //See /docs/License.txt for details on how this code may be used.
00004 
00005 #pragma once
00006 
00007 #include "../base/Setup.h"
00008 
00009 #ifdef MPMA_COMPILE_AUDIO
00010 
00011 #include "../base/Types.h"
00012 #include "../base/ReferenceCount.h"
00013 #include "../base/Locks.h"
00014 
00015 #include <string>
00016 #include <memory>
00017 #include <vector>
00018 
00019 //forward declarations
00020 struct OggVorbis_File;
00021 
00022 namespace AUDIO
00023 {
00025     const nuint FINITE_DATA=(nuint)(0-2);
00027     const nuint INFINITE_DATA=(nuint)(0-1);
00028 
00030     class Source
00031     {
00032     public:
00033         Source();
00034         virtual ~Source();
00035 
00037         virtual nuint FillData(void *data, nuint maxSamples)=0;
00038 
00040         virtual nuint GetRemainingSamples() const=0;
00041 
00043         virtual bool IsStereo() const=0;
00044 
00046         virtual nuint GetSampleRate() const=0;
00047 
00049         virtual void Seek(nuint sampleNumber=0);
00050 
00052         inline nuint GetSampleSize() const
00053             { return IsStereo()?4:2; }
00054     };
00055 
00056 
00057     // -- below are a several convenient implementations of Source
00058 
00060     class WavFileSource: public Source
00061     {
00062     public:
00064         WavFileSource(const std::string &filename);
00065         virtual ~WavFileSource();
00066 
00068         inline bool IsLoaded() const
00069             { return fileHandle!=0; }
00070 
00071         virtual nuint FillData(void *data, nuint maxSamples);
00072         virtual nuint GetRemainingSamples() const;
00073         virtual bool IsStereo() const;
00074         virtual nuint GetSampleRate() const;
00075         virtual void Seek(nuint sampleNumber=0);
00076 
00077     private:
00078         void LoadFailed();
00079 
00080         void *fileHandle;
00081         std::string filename;
00082         nuint rate;
00083         nuint sourceBits;
00084         bool isStereo;
00085         nuint dataStartSeekPos;
00086 
00087         bool hitEof;
00088 
00089         Source *bad; //bad source to use if we failed to load
00090         MPMA::SpinLock lock;
00091     };
00092 
00093 #ifdef AUDIO_OGG_VORBIS_ENABLED
00094 
00095     class VorbisFileSource: public Source
00096     {
00097     public:
00099         VorbisFileSource(const std::string &filename);
00101         VorbisFileSource(const void *pFileInMemory, uint32 memoryLength);
00102         virtual ~VorbisFileSource();
00103 
00105         inline bool IsLoaded() const
00106             { return vorbisFile!=0; }
00107 
00108         virtual nuint FillData(void *data, nuint maxSamples);
00109         virtual nuint GetRemainingSamples() const;
00110         virtual bool IsStereo() const;
00111         virtual nuint GetSampleRate() const;
00112         virtual void Seek(nuint sampleNumber=0);
00113 
00114     private:
00115         OggVorbis_File *vorbisFile;
00116         std::string filename;
00117         nuint rate;
00118         nuint sourceBits;
00119         bool isStereo;
00120 
00121         bool hitEof;
00122 
00123         Source *bad; //bad source to use if we failed to load
00124         MPMA::SpinLock lock;
00125 
00126         //things for reading directly from memory rather than a file
00127         struct VorbisMemoryData
00128         {
00129             inline VorbisMemoryData(): Cursor(0) {}
00130 
00131             std::vector<unsigned char> Data;
00132             uint32 Cursor;
00133         } vorbisInMemory;
00134 
00135         static size_t VorbisMemoryRead(void *ptr, size_t size, size_t nmemb, void *datasource);
00136         static int VorbisMemorySeek(void *datasource, sint64 offset, int whence);
00137         static int VorbisMemoryClose(void *datasource);
00138         static long VorbisMemoryTell(void *datasource);
00139 
00140     };
00141 #endif
00142 
00143 #ifdef AUDIO_OGG_FLAC_ENABLED
00144     class InternalMpmaFlacDecoder;
00145 
00147     class FlacFileSource: public Source
00148     {
00149     public:
00151         FlacFileSource(const std::string &filename);
00152         virtual ~FlacFileSource();
00153 
00155         inline bool IsLoaded() const
00156             { return flac!=0; }
00157 
00158         virtual nuint FillData(void *data, nuint maxSamples);
00159         virtual nuint GetRemainingSamples() const;
00160         virtual bool IsStereo() const;
00161         virtual nuint GetSampleRate() const;
00162         virtual void Seek(nuint sampleNumber=0);
00163 
00164     private:
00165         InternalMpmaFlacDecoder *flac;
00166         std::string filename;
00167 
00168         bool hitEof;
00169 
00170         Source *bad; //bad source to use if we failed to load
00171         MPMA::SpinLock lock;
00172     };
00173 #endif
00174 
00176     class LoopSource: public Source
00177     {
00178     public:
00180         LoopSource(std::shared_ptr<Source> source, nuint loopStartSample=0, nuint loopEndSample=~0);
00181 
00182         virtual nuint FillData(void *data, nuint maxSamples);
00183         inline nuint GetRemainingSamples() const { return INFINITE_DATA; }
00184         inline bool IsStereo() const { return source->IsStereo(); }
00185         inline nuint GetSampleRate() const { return source->GetSampleRate(); }
00186 
00187     private:
00188         std::shared_ptr<Source> source;
00189         nuint loopStart;
00190         nuint loopEnd;
00191         nuint currentSample;
00192     };
00193 
00195     class MonoToStereoSource: public Source
00196     {
00197     public:
00199         MonoToStereoSource(std::shared_ptr<Source> sourceLeft, std::shared_ptr<Source> sourceRight);
00200 
00201         virtual nuint FillData(void *data, nuint maxSamples);
00202         virtual nuint GetRemainingSamples() const;
00203         virtual bool IsStereo() const;
00204         virtual nuint GetSampleRate() const;
00205         virtual void Seek(nuint sampleNumber=0);
00206 
00207     private:
00208         std::shared_ptr<Source> sourceL, sourceR;
00209     };
00210 
00212     class EmptySource: public Source
00213     {
00214     public:
00215         virtual nuint FillData(void *data, nuint maxSamples);
00216         virtual nuint GetRemainingSamples() const;
00217         virtual bool IsStereo() const;
00218         virtual nuint GetSampleRate() const;
00219     };
00220 
00222     class WhiteNoiseSource: public Source
00223     {
00224     public:
00226         WhiteNoiseSource(float seconds=0, nuint sampleRate=44100, int quietLevel=0);
00227 
00228         virtual nuint FillData(void *data, nuint maxSamples);
00229         virtual nuint GetRemainingSamples() const;
00230         virtual bool IsStereo() const;
00231         virtual nuint GetSampleRate() const;
00232         virtual void Seek(nuint sampleNumber=0);
00233 
00234     private:
00235         nuint samplesRemaining;
00236         nuint rate;
00237         float origTimeLeft;
00238         uint32 lastSample;
00239         int quietness;
00240     };
00241 }
00242 
00243 #endif //#ifdef MPMA_COMPILE_AUDIO
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends