7 #ifdef HAVE_SYS_TYPES_H
10 #ifdef HAVE_SYS_WAIT_H
23 #define typeof decltype
35 #ifdef HAVE_PTHREAD_NP_H
36 #include <pthread_np.h>
40 typedef pthread_mutex_t CRITICAL_SECTION;
41 void EnterCriticalSection(CRITICAL_SECTION *cs);
42 void LeaveCriticalSection(CRITICAL_SECTION *cs);
43 void InitializeCriticalSection(CRITICAL_SECTION *cs);
44 void DeleteCriticalSection(CRITICAL_SECTION *cs);
59 } endian_test = { 1 };
60 static const bool LittleEndian = (endian_test.b[0] != 0);
61 static const bool BigEndian = !LittleEndian;
65 void *OpenLib(const char *libname);
66 void CloseLib(void *handle);
67 void *GetLibProc(void *handle, const char *funcname);
70 void LoadFunc(void *handle, const char *funcname, T **funcptr)
71 { *funcptr = reinterpret_cast<T*>(GetLibProc(handle, funcname)); }
73 #define LOAD_FUNC(h, x) LoadFunc((h), #x, &(p##x)); \
83 extern PFNALCSETTHREADCONTEXTPROC palcSetThreadContext;
84 extern PFNALCGETTHREADCONTEXTPROC palcGetThreadContext;
85 #define alcSetThreadContext palcSetThreadContext
86 #define alcGetThreadContext palcGetThreadContext
88 void SetError(const char *err);
89 ALuint DetectBlockAlignment(ALenum format);
90 ALuint DetectCompressionRate(ALenum format);
91 ALenum GetSampleFormat(ALuint channels, ALuint bits, bool isFloat);
93 struct UserCallbacks {
94 void* (*open_file)(const ALchar*);
95 void* (*open_mem)(const ALubyte*,ALuint);
96 ALboolean (*get_fmt)(void*,ALenum*,ALuint*,ALuint*);
97 ALuint (*decode)(void*,ALubyte*,ALuint);
98 ALboolean (*rewind)(void*);
101 extern std::map<ALint,UserCallbacks> InstalledCallbacks;
104 void StopStream(alureStream *stream);
106 // Local copy of memory data
109 // Storage when reading chunks
110 std::vector<ALubyte> dataChunk;
112 // Abstracted input stream
113 std::istream *fstream;
115 virtual bool IsValid() = 0;
116 virtual bool GetFormat(ALenum*,ALuint*,ALuint*) = 0;
117 virtual ALuint GetData(ALubyte*,ALuint) = 0;
118 virtual bool Rewind() = 0;
119 virtual bool SetOrder(ALuint order)
121 if(!order) return Rewind();
122 SetError("Invalid order for stream");
125 virtual bool SetPatchset(const char*)
127 virtual alureInt64 GetLength()
130 alureStream(std::istream *_stream)
131 : data(NULL), fstream(_stream)
132 { StreamList.push_front(this); }
133 virtual ~alureStream()
136 StreamList.erase(std::find(StreamList.begin(), StreamList.end(), this));
139 static void Clear(void)
141 while(StreamList.size() > 0)
143 alureStream *stream = *(StreamList.begin());
145 std::istream *f = stream->fstream;
151 static bool Verify(alureStream *stream)
153 ListType::iterator i = std::find(StreamList.begin(), StreamList.end(), stream);
154 return (i != StreamList.end());
158 typedef std::list<alureStream*> ListType;
159 static ListType StreamList;
168 MemDataInfo() : Data(NULL), Length(0), Pos(0)
170 MemDataInfo(const MemDataInfo &inf) : Data(inf.Data), Length(inf.Length),
175 class MemStreamBuf : public std::streambuf {
178 virtual int_type underflow();
179 virtual pos_type seekoff(off_type offset, std::ios_base::seekdir whence, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out);
180 virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out);
183 MemStreamBuf(const MemDataInfo &data)
186 memInfo.Pos /= sizeof(char_type);
187 memInfo.Length /= sizeof(char_type);
189 virtual ~MemStreamBuf() { }
193 void* (*open)(const char *filename, ALuint mode);
194 void (*close)(void *f);
195 ALsizei (*read)(void *f, ALubyte *buf, ALuint count);
196 ALsizei (*write)(void *f, const ALubyte *buf, ALuint count);
197 alureInt64 (*seek)(void *f, alureInt64 offset, int whence);
199 extern UserFuncs Funcs;
200 extern bool UsingSTDIO;
202 class FileStreamBuf : public std::streambuf {
208 virtual int_type underflow();
209 virtual pos_type seekoff(off_type offset, std::ios_base::seekdir whence, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out);
210 virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out);
214 { return usrFile != NULL; }
216 FileStreamBuf(const char *filename, ALint mode)
217 : usrFile(NULL), fio(Funcs)
218 { usrFile = fio.open(filename, mode); }
219 virtual ~FileStreamBuf()
220 { if(usrFile) fio.close(usrFile); }
223 class InStream : public std::istream {
225 InStream(const char *filename)
226 : std::istream(new FileStreamBuf(filename, 0))
228 if(!(static_cast<FileStreamBuf*>(rdbuf())->IsOpen()))
231 InStream(const MemDataInfo &memInfo)
232 : std::istream(new MemStreamBuf(memInfo))
239 static inline ALuint read_le32(std::istream *file)
242 if(!file->read(reinterpret_cast<char*>(buffer), 4)) return 0;
243 return buffer[0] | (buffer[1]<<8) | (buffer[2]<<16) | (buffer[3]<<24);
246 static inline ALushort read_le16(std::istream *file)
249 if(!file->read(reinterpret_cast<char*>(buffer), 2)) return 0;
250 return buffer[0] | (buffer[1]<<8);
253 static inline ALuint read_be32(std::istream *file)
256 if(!file->read(reinterpret_cast<char*>(buffer), 4)) return 0;
257 return (buffer[0]<<24) | (buffer[1]<<16) | (buffer[2]<<8) | buffer[3];
260 static inline ALushort read_be16(std::istream *file)
263 if(!file->read(reinterpret_cast<char*>(buffer), 2)) return 0;
264 return (buffer[0]<<8) | buffer[1];
267 static inline ALuint read_be80extended(std::istream *file)
270 if(!file->read(reinterpret_cast<char*>(buffer), 10)) return 0;
271 ALuint mantissa, last = 0;
272 ALubyte exp = buffer[1];
274 mantissa = (buffer[2]<<24) | (buffer[3]<<16) | (buffer[4]<<8) | buffer[5];
280 if((last&1)) mantissa++;
285 extern CRITICAL_SECTION cs_StreamPlay;
287 alureStream *create_stream(const char *fname);
288 alureStream *create_stream(const MemDataInfo &memData);
289 alureStream *create_stream(ALvoid *userdata, ALenum format, ALuint rate, const UserCallbacks &cb);
291 template <typename T>
292 const T& clamp(const T& val, const T& min, const T& max)
293 { return std::max(std::min(val, max), min); }
295 template <typename T>
296 void swap(T &val1, T &val2)
304 template<typename T1, typename T2>
305 T1 SearchSecond(T1 start, T1 end, T2 val)
307 while(start != end && start->second != val)
313 typedef std::auto_ptr<alureStream>(*FactoryType)(std::istream*);
314 typedef std::multimap<ALint,FactoryType> ListType;
316 static const ListType& GetList();
319 static ListType& AddList(FactoryType func=NULL, ALint prio=0);
322 template<typename T, ALint prio>
323 struct DecoderDecl : public Decoder {
327 AddList(Factory, prio);
331 ListType &list = AddList();
332 list.erase(SearchSecond(list.begin(), list.end(), Factory));
337 static std::auto_ptr<alureStream> Factory(std::istream *file)
339 std::auto_ptr<alureStream> ret(new T(file));
340 if(ret->IsValid()) return ret;
341 return std::auto_ptr<alureStream>();
345 Decoder &alure_init_wav(void);
346 Decoder &alure_init_aiff(void);
347 Decoder &alure_init_vorbisfile(void);
348 Decoder &alure_init_flac(void);
349 Decoder &alure_init_sndfile(void);
350 Decoder &alure_init_fluidsynth(void);
351 Decoder &alure_init_dumb(void);
352 Decoder &alure_init_modplug(void);
353 Decoder &alure_init_mpg123(void);