MPMA Framework 0.4
|
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