11 #include <vorbis/vorbisfile.h>
24 #include <gst/app/gstappsrc.h>
25 #include <gst/app/gstappsink.h>
26 #include <gst/app/gstappbuffer.h>
30 #ifdef HAVE_SYS_TYPES_H
31 #include <sys/types.h>
33 #ifdef HAVE_SYS_WAIT_H
52 #ifdef HAVE_PTHREAD_NP_H
53 #include <pthread_np.h>
57 typedef pthread_mutex_t CRITICAL_SECTION
;
58 static inline void EnterCriticalSection(CRITICAL_SECTION
*cs
)
61 ret
= pthread_mutex_lock(cs
);
64 static inline void LeaveCriticalSection(CRITICAL_SECTION
*cs
)
67 ret
= pthread_mutex_unlock(cs
);
70 static inline void InitializeCriticalSection(CRITICAL_SECTION
*cs
)
72 pthread_mutexattr_t attrib
;
75 ret
= pthread_mutexattr_init(&attrib
);
78 ret
= pthread_mutexattr_settype(&attrib
, PTHREAD_MUTEX_RECURSIVE
);
79 #ifdef HAVE_PTHREAD_NP_H
81 ret
= pthread_mutexattr_setkind_np(&attrib
, PTHREAD_MUTEX_RECURSIVE
);
84 ret
= pthread_mutex_init(cs
, &attrib
);
87 pthread_mutexattr_destroy(&attrib
);
89 static inline void DeleteCriticalSection(CRITICAL_SECTION
*cs
)
92 ret
= pthread_mutex_destroy(cs
);
107 } endian_test
= { 1 };
108 static const bool LittleEndian
= (endian_test
.b
[0] != 0);
109 static const bool BigEndian
= !LittleEndian
;
112 void SetError(const char *err
);
113 ALuint
DetectBlockAlignment(ALenum format
);
115 struct UserCallbacks
{
116 void* (*open_file
)(const ALchar
*);
117 void* (*open_mem
)(const ALubyte
*,ALuint
);
118 ALboolean (*get_fmt
)(void*,ALenum
*,ALuint
*,ALuint
*);
119 ALuint (*decode
)(void*,ALubyte
*,ALuint
);
120 ALboolean (*rewind
)(void*);
121 void (*close
)(void*);
123 extern std::map
<ALint
,UserCallbacks
> InstalledCallbacks
;
132 std::istream
*fstream
;
134 virtual bool IsValid() = 0;
135 virtual bool GetFormat(ALenum
*,ALuint
*,ALuint
*) = 0;
136 virtual ALuint
GetData(ALubyte
*,ALuint
) = 0;
137 virtual bool Rewind() = 0;
138 virtual bool SetOrder(ALuint order
)
140 if(!order
) return Rewind();
141 SetError("Invalid order for stream");
145 alureStream(std::istream
*_stream
)
146 : data(NULL
), dataChunk(NULL
), fstream(_stream
)
147 { StreamList
.push_front(this); }
148 virtual ~alureStream()
150 delete[] data
; delete[] dataChunk
;
151 StreamList
.erase(std::find(StreamList
.begin(), StreamList
.end(), this));
154 static void Clear(void)
156 while(StreamList
.size() > 0)
157 alureDestroyStream(*(StreamList
.begin()), 0, NULL
);
160 static bool Verify(alureStream
*stream
)
162 ListType::iterator i
= std::find(StreamList
.begin(), StreamList
.end(), stream
);
163 return (i
!= StreamList
.end());
167 typedef std::list
<alureStream
*> ListType
;
168 static ListType StreamList
;
170 void StopStream(alureStream
*stream
);
178 MemDataInfo() : Data(NULL
), Length(0), Pos(0)
180 MemDataInfo(const MemDataInfo
&inf
) : Data(inf
.Data
), Length(inf
.Length
),
185 class MemStreamBuf
: public std::streambuf
{
188 virtual int_type
underflow();
189 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
);
190 virtual pos_type
seekpos(pos_type pos
, std::ios_base::openmode mode
= std::ios_base::in
| std::ios_base::out
);
193 MemStreamBuf(const MemDataInfo
&data
)
196 memInfo
.Pos
/= sizeof(char_type
);
197 memInfo
.Length
/= sizeof(char_type
);
199 virtual ~MemStreamBuf() { }
203 void* (*open
)(const char *filename
, ALuint mode
);
204 void (*close
)(void *f
);
205 ALsizei (*read
)(void *f
, ALubyte
*buf
, ALuint count
);
206 ALsizei (*write
)(void *f
, const ALubyte
*buf
, ALuint count
);
207 alureInt64 (*seek
)(void *f
, alureInt64 offset
, int whence
);
209 extern UserFuncs Funcs
;
211 class FileStreamBuf
: public std::streambuf
{
217 virtual int_type
underflow();
218 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
);
219 virtual pos_type
seekpos(pos_type pos
, std::ios_base::openmode mode
= std::ios_base::in
| std::ios_base::out
);
223 { return usrFile
!= NULL
; }
225 FileStreamBuf(const char *filename
, ALint mode
)
226 : usrFile(NULL
), fio(Funcs
)
227 { usrFile
= fio
.open(filename
, mode
); }
228 virtual ~FileStreamBuf()
229 { if(usrFile
) fio
.close(usrFile
); }
232 class InStream
: public std::istream
{
234 InStream(const char *filename
)
235 : std::istream(new FileStreamBuf(filename
, 0))
237 if(!(static_cast<FileStreamBuf
*>(rdbuf())->IsOpen()))
240 InStream(const MemDataInfo
&memInfo
)
241 : std::istream(new MemStreamBuf(memInfo
))
248 struct customStream
: public alureStream
{
257 virtual bool IsValid();
258 virtual bool GetFormat(ALenum
*format
, ALuint
*frequency
, ALuint
*blockalign
);
259 virtual ALuint
GetData(ALubyte
*data
, ALuint bytes
);
260 virtual bool Rewind();
262 customStream(const char *fname
, const UserCallbacks
&callbacks
);
263 customStream(const MemDataInfo
&memData
, const UserCallbacks
&callbacks
);
264 customStream(void *userdata
, ALenum fmt
, ALuint srate
, const UserCallbacks
&callbacks
);
265 virtual ~customStream();
269 extern CRITICAL_SECTION cs_StreamPlay
;
271 alureStream
*create_stream(const char *fname
);
272 alureStream
*create_stream(const MemDataInfo
&memData
);
274 template <typename T
>
275 const T
& clamp(const T
& val
, const T
& min
, const T
& max
)
276 { return std::max(std::min(val
, max
), min
); }