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 static inline void EnterCriticalSection(CRITICAL_SECTION
*cs
)
44 ret
= pthread_mutex_lock(cs
);
47 static inline void LeaveCriticalSection(CRITICAL_SECTION
*cs
)
50 ret
= pthread_mutex_unlock(cs
);
53 static inline void InitializeCriticalSection(CRITICAL_SECTION
*cs
)
55 pthread_mutexattr_t attrib
;
58 ret
= pthread_mutexattr_init(&attrib
);
61 ret
= pthread_mutexattr_settype(&attrib
, PTHREAD_MUTEX_RECURSIVE
);
62 #ifdef HAVE_PTHREAD_NP_H
64 ret
= pthread_mutexattr_setkind_np(&attrib
, PTHREAD_MUTEX_RECURSIVE
);
67 ret
= pthread_mutex_init(cs
, &attrib
);
70 pthread_mutexattr_destroy(&attrib
);
72 static inline void DeleteCriticalSection(CRITICAL_SECTION
*cs
)
75 ret
= pthread_mutex_destroy(cs
);
92 } endian_test
= { 1 };
93 static const bool LittleEndian
= (endian_test
.b
[0] != 0);
94 static const bool BigEndian
= !LittleEndian
;
97 void *OpenLib(const char *libname
);
98 void CloseLib(void *handle
);
100 #define LOAD_FUNC(h, x) p##x = x
102 void *GetLibProc(void *handle
, const char *funcname
);
105 void LoadFunc(void *handle
, const char *funcname
, T
**funcptr
)
106 { *funcptr
= reinterpret_cast<T
*>(GetLibProc(handle
, funcname
)); }
108 #define LOAD_FUNC(h, x) LoadFunc((h), #x, &(p##x)); \
118 extern PFNALCSETTHREADCONTEXTPROC alcSetThreadContext
;
119 extern PFNALCGETTHREADCONTEXTPROC alcGetThreadContext
;
121 void SetError(const char *err
);
122 ALuint
DetectBlockAlignment(ALenum format
);
123 ALuint
DetectCompressionRate(ALenum format
);
124 ALenum
GetSampleFormat(ALuint channels
, ALuint bits
, bool isFloat
);
126 struct UserCallbacks
{
127 void* (*open_file
)(const ALchar
*);
128 void* (*open_mem
)(const ALubyte
*,ALuint
);
129 ALboolean (*get_fmt
)(void*,ALenum
*,ALuint
*,ALuint
*);
130 ALuint (*decode
)(void*,ALubyte
*,ALuint
);
131 ALboolean (*rewind
)(void*);
132 void (*close
)(void*);
134 extern std::map
<ALint
,UserCallbacks
> InstalledCallbacks
;
138 // Local copy of memory data
141 // Storage when reading chunks
142 std::vector
<ALubyte
> dataChunk
;
144 // Abstracted input stream
145 std::istream
*fstream
;
147 virtual bool IsValid() = 0;
148 virtual bool GetFormat(ALenum
*,ALuint
*,ALuint
*) = 0;
149 virtual ALuint
GetData(ALubyte
*,ALuint
) = 0;
150 virtual bool Rewind() = 0;
151 virtual bool SetOrder(ALuint order
)
153 if(!order
) return Rewind();
154 SetError("Invalid order for stream");
157 virtual bool SetPatchset(const char*)
160 alureStream(std::istream
*_stream
)
161 : data(NULL
), fstream(_stream
)
162 { StreamList
.push_front(this); }
163 virtual ~alureStream()
166 StreamList
.erase(std::find(StreamList
.begin(), StreamList
.end(), this));
169 static void Clear(void)
171 while(StreamList
.size() > 0)
172 alureDestroyStream(*(StreamList
.begin()), 0, NULL
);
175 static bool Verify(alureStream
*stream
)
177 ListType::iterator i
= std::find(StreamList
.begin(), StreamList
.end(), stream
);
178 return (i
!= StreamList
.end());
182 typedef std::list
<alureStream
*> ListType
;
183 static ListType StreamList
;
185 void StopStream(alureStream
*stream
);
193 MemDataInfo() : Data(NULL
), Length(0), Pos(0)
195 MemDataInfo(const MemDataInfo
&inf
) : Data(inf
.Data
), Length(inf
.Length
),
200 class MemStreamBuf
: public std::streambuf
{
203 virtual int_type
underflow();
204 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
);
205 virtual pos_type
seekpos(pos_type pos
, std::ios_base::openmode mode
= std::ios_base::in
| std::ios_base::out
);
208 MemStreamBuf(const MemDataInfo
&data
)
211 memInfo
.Pos
/= sizeof(char_type
);
212 memInfo
.Length
/= sizeof(char_type
);
214 virtual ~MemStreamBuf() { }
218 void* (*open
)(const char *filename
, ALuint mode
);
219 void (*close
)(void *f
);
220 ALsizei (*read
)(void *f
, ALubyte
*buf
, ALuint count
);
221 ALsizei (*write
)(void *f
, const ALubyte
*buf
, ALuint count
);
222 alureInt64 (*seek
)(void *f
, alureInt64 offset
, int whence
);
224 extern UserFuncs Funcs
;
226 class FileStreamBuf
: public std::streambuf
{
232 virtual int_type
underflow();
233 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
);
234 virtual pos_type
seekpos(pos_type pos
, std::ios_base::openmode mode
= std::ios_base::in
| std::ios_base::out
);
238 { return usrFile
!= NULL
; }
240 FileStreamBuf(const char *filename
, ALint mode
)
241 : usrFile(NULL
), fio(Funcs
)
242 { usrFile
= fio
.open(filename
, mode
); }
243 virtual ~FileStreamBuf()
244 { if(usrFile
) fio
.close(usrFile
); }
247 class InStream
: public std::istream
{
249 InStream(const char *filename
)
250 : std::istream(new FileStreamBuf(filename
, 0))
252 if(!(static_cast<FileStreamBuf
*>(rdbuf())->IsOpen()))
255 InStream(const MemDataInfo
&memInfo
)
256 : std::istream(new MemStreamBuf(memInfo
))
263 static inline ALuint
read_le32(std::istream
*file
)
266 if(!file
->read(reinterpret_cast<char*>(buffer
), 4)) return 0;
267 return buffer
[0] | (buffer
[1]<<8) | (buffer
[2]<<16) | (buffer
[3]<<24);
270 static inline ALushort
read_le16(std::istream
*file
)
273 if(!file
->read(reinterpret_cast<char*>(buffer
), 2)) return 0;
274 return buffer
[0] | (buffer
[1]<<8);
277 static inline ALuint
read_be32(std::istream
*file
)
280 if(!file
->read(reinterpret_cast<char*>(buffer
), 4)) return 0;
281 return (buffer
[0]<<24) | (buffer
[1]<<16) | (buffer
[2]<<8) | buffer
[3];
284 static inline ALushort
read_be16(std::istream
*file
)
287 if(!file
->read(reinterpret_cast<char*>(buffer
), 2)) return 0;
288 return (buffer
[0]<<8) | buffer
[1];
291 static inline ALuint
read_be80extended(std::istream
*file
)
294 if(!file
->read(reinterpret_cast<char*>(buffer
), 10)) return 0;
295 ALuint mantissa
, last
= 0;
296 ALubyte exp
= buffer
[1];
298 mantissa
= (buffer
[2]<<24) | (buffer
[3]<<16) | (buffer
[4]<<8) | buffer
[5];
304 if((last
&1)) mantissa
++;
309 extern CRITICAL_SECTION cs_StreamPlay
;
311 alureStream
*create_stream(const char *fname
);
312 alureStream
*create_stream(const MemDataInfo
&memData
);
313 alureStream
*create_stream(ALvoid
*userdata
, ALenum format
, ALuint rate
, const UserCallbacks
&cb
);
315 template <typename T
>
316 const T
& clamp(const T
& val
, const T
& min
, const T
& max
)
317 { return std::max(std::min(val
, max
), min
); }
319 template <typename T
>
320 void swap(T
&val1
, T
&val2
)
328 template<typename T1
, typename T2
>
329 T1
SearchSecond(T1 start
, T1 end
, T2 val
)
331 while(start
!= end
&& start
->second
!= val
)
337 typedef std::auto_ptr
<alureStream
>(*FactoryType
)(std::istream
*);
338 typedef std::multimap
<ALint
,FactoryType
> ListType
;
340 static const ListType
& GetList();
343 static ListType
& AddList(FactoryType func
=NULL
, ALint prio
=0);
346 template<typename T
, ALint prio
>
347 struct DecoderDecl
: public Decoder
{
351 AddList(Factory
, prio
);
355 ListType
&list
= AddList();
356 list
.erase(SearchSecond(list
.begin(), list
.end(), Factory
));
361 static std::auto_ptr
<alureStream
> Factory(std::istream
*file
)
363 std::auto_ptr
<alureStream
> ret(new T(file
));
364 if(ret
->IsValid()) return ret
;
365 return std::auto_ptr
<alureStream
>();
369 Decoder
&alure_init_wav(void);
370 Decoder
&alure_init_aiff(void);
371 Decoder
&alure_init_vorbisfile(void);
372 Decoder
&alure_init_flac(void);
373 Decoder
&alure_init_sndfile(void);
374 Decoder
&alure_init_fluidsynth(void);
375 Decoder
&alure_init_dumb(void);
376 Decoder
&alure_init_modplug(void);
377 Decoder
&alure_init_mpg123(void);