7 #ifdef HAVE_SYS_TYPES_H
10 #ifdef HAVE_SYS_WAIT_H
29 #ifdef HAVE_PTHREAD_NP_H
30 #include <pthread_np.h>
34 typedef pthread_mutex_t CRITICAL_SECTION
;
35 static inline void EnterCriticalSection(CRITICAL_SECTION
*cs
)
38 ret
= pthread_mutex_lock(cs
);
41 static inline void LeaveCriticalSection(CRITICAL_SECTION
*cs
)
44 ret
= pthread_mutex_unlock(cs
);
47 static inline void InitializeCriticalSection(CRITICAL_SECTION
*cs
)
49 pthread_mutexattr_t attrib
;
52 ret
= pthread_mutexattr_init(&attrib
);
55 ret
= pthread_mutexattr_settype(&attrib
, PTHREAD_MUTEX_RECURSIVE
);
56 #ifdef HAVE_PTHREAD_NP_H
58 ret
= pthread_mutexattr_setkind_np(&attrib
, PTHREAD_MUTEX_RECURSIVE
);
61 ret
= pthread_mutex_init(cs
, &attrib
);
64 pthread_mutexattr_destroy(&attrib
);
66 static inline void DeleteCriticalSection(CRITICAL_SECTION
*cs
)
69 ret
= pthread_mutex_destroy(cs
);
86 } endian_test
= { 1 };
87 static const bool LittleEndian
= (endian_test
.b
[0] != 0);
88 static const bool BigEndian
= !LittleEndian
;
91 void *OpenLib(const char *libname
);
92 void CloseLib(void *handle
);
94 #define LOAD_FUNC(h, x) p##x = x
96 void *GetLibProc(void *handle
, const char *funcname
);
99 void LoadFunc(void *handle
, const char *funcname
, T
**funcptr
)
100 { *funcptr
= reinterpret_cast<T
*>(GetLibProc(handle
, funcname
)); }
102 #define LOAD_FUNC(h, x) LoadFunc((h), #x, &(p##x)); \
112 void SetError(const char *err
);
113 ALuint
DetectBlockAlignment(ALenum format
);
114 ALuint
DetectCompressionRate(ALenum format
);
115 ALenum
GetSampleFormat(ALuint channels
, ALuint bits
, bool isFloat
);
117 struct UserCallbacks
{
118 void* (*open_file
)(const ALchar
*);
119 void* (*open_mem
)(const ALubyte
*,ALuint
);
120 ALboolean (*get_fmt
)(void*,ALenum
*,ALuint
*,ALuint
*);
121 ALuint (*decode
)(void*,ALubyte
*,ALuint
);
122 ALboolean (*rewind
)(void*);
123 void (*close
)(void*);
125 extern std::map
<ALint
,UserCallbacks
> InstalledCallbacks
;
129 // Local copy of memory data
132 // Storage when reading chunks
133 std::vector
<ALubyte
> dataChunk
;
135 // Abstracted input stream
136 std::istream
*fstream
;
138 virtual bool IsValid() = 0;
139 virtual bool GetFormat(ALenum
*,ALuint
*,ALuint
*) = 0;
140 virtual ALuint
GetData(ALubyte
*,ALuint
) = 0;
141 virtual bool Rewind() = 0;
142 virtual bool SetOrder(ALuint order
)
144 if(!order
) return Rewind();
145 SetError("Invalid order for stream");
148 virtual bool SetPatchset(const char*)
151 alureStream(std::istream
*_stream
)
152 : data(NULL
), fstream(_stream
)
153 { StreamList
.push_front(this); }
154 virtual ~alureStream()
157 StreamList
.erase(std::find(StreamList
.begin(), StreamList
.end(), this));
160 static void Clear(void)
162 while(StreamList
.size() > 0)
163 alureDestroyStream(*(StreamList
.begin()), 0, NULL
);
166 static bool Verify(alureStream
*stream
)
168 ListType::iterator i
= std::find(StreamList
.begin(), StreamList
.end(), stream
);
169 return (i
!= StreamList
.end());
173 typedef std::list
<alureStream
*> ListType
;
174 static ListType StreamList
;
176 void StopStream(alureStream
*stream
);
184 MemDataInfo() : Data(NULL
), Length(0), Pos(0)
186 MemDataInfo(const MemDataInfo
&inf
) : Data(inf
.Data
), Length(inf
.Length
),
191 class MemStreamBuf
: public std::streambuf
{
194 virtual int_type
underflow();
195 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
);
196 virtual pos_type
seekpos(pos_type pos
, std::ios_base::openmode mode
= std::ios_base::in
| std::ios_base::out
);
199 MemStreamBuf(const MemDataInfo
&data
)
202 memInfo
.Pos
/= sizeof(char_type
);
203 memInfo
.Length
/= sizeof(char_type
);
205 virtual ~MemStreamBuf() { }
209 void* (*open
)(const char *filename
, ALuint mode
);
210 void (*close
)(void *f
);
211 ALsizei (*read
)(void *f
, ALubyte
*buf
, ALuint count
);
212 ALsizei (*write
)(void *f
, const ALubyte
*buf
, ALuint count
);
213 alureInt64 (*seek
)(void *f
, alureInt64 offset
, int whence
);
215 extern UserFuncs Funcs
;
217 class FileStreamBuf
: public std::streambuf
{
223 virtual int_type
underflow();
224 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
);
225 virtual pos_type
seekpos(pos_type pos
, std::ios_base::openmode mode
= std::ios_base::in
| std::ios_base::out
);
229 { return usrFile
!= NULL
; }
231 FileStreamBuf(const char *filename
, ALint mode
)
232 : usrFile(NULL
), fio(Funcs
)
233 { usrFile
= fio
.open(filename
, mode
); }
234 virtual ~FileStreamBuf()
235 { if(usrFile
) fio
.close(usrFile
); }
238 class InStream
: public std::istream
{
240 InStream(const char *filename
)
241 : std::istream(new FileStreamBuf(filename
, 0))
243 if(!(static_cast<FileStreamBuf
*>(rdbuf())->IsOpen()))
246 InStream(const MemDataInfo
&memInfo
)
247 : std::istream(new MemStreamBuf(memInfo
))
254 static inline ALuint
read_le32(std::istream
*file
)
257 if(!file
->read(reinterpret_cast<char*>(buffer
), 4)) return 0;
258 return buffer
[0] | (buffer
[1]<<8) | (buffer
[2]<<16) | (buffer
[3]<<24);
261 static inline ALushort
read_le16(std::istream
*file
)
264 if(!file
->read(reinterpret_cast<char*>(buffer
), 2)) return 0;
265 return buffer
[0] | (buffer
[1]<<8);
268 static inline ALuint
read_be32(std::istream
*file
)
271 if(!file
->read(reinterpret_cast<char*>(buffer
), 4)) return 0;
272 return (buffer
[0]<<24) | (buffer
[1]<<16) | (buffer
[2]<<8) | buffer
[3];
275 static inline ALushort
read_be16(std::istream
*file
)
278 if(!file
->read(reinterpret_cast<char*>(buffer
), 2)) return 0;
279 return (buffer
[0]<<8) | buffer
[1];
282 static inline ALuint
read_be80extended(std::istream
*file
)
285 if(!file
->read(reinterpret_cast<char*>(buffer
), 10)) return 0;
286 ALuint mantissa
, last
= 0;
287 ALubyte exp
= buffer
[1];
289 mantissa
= (buffer
[2]<<24) | (buffer
[3]<<16) | (buffer
[4]<<8) | buffer
[5];
295 if((last
&1)) mantissa
++;
300 extern CRITICAL_SECTION cs_StreamPlay
;
302 alureStream
*create_stream(const char *fname
);
303 alureStream
*create_stream(const MemDataInfo
&memData
);
304 alureStream
*create_stream(ALvoid
*userdata
, ALenum format
, ALuint rate
, const UserCallbacks
&cb
);
306 template <typename T
>
307 const T
& clamp(const T
& val
, const T
& min
, const T
& max
)
308 { return std::max(std::min(val
, max
), min
); }
310 template <typename T
>
311 void swap(T
&val1
, T
&val2
)
320 typedef std::auto_ptr
<alureStream
>(*FactoryType
)(std::istream
*);
321 typedef std::vector
<FactoryType
> ListType
;
323 static const ListType
& GetList();
326 static ListType
& AddList(FactoryType func
);
330 struct DecoderDecl
: public Decoder
{
338 ListType
&list
= AddList(NULL
);
339 list
.erase(std::find(list
.begin(), list
.end(), Factory
));
344 static std::auto_ptr
<alureStream
> Factory(std::istream
*file
)
346 std::auto_ptr
<alureStream
> ret(new T(file
));
347 if(ret
->IsValid()) return ret
;
348 return std::auto_ptr
<alureStream
>();