11 #include <vorbis/vorbisfile.h>
26 #include <fluidsynth.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
);
109 } endian_test
= { 1 };
110 static const bool LittleEndian
= (endian_test
.b
[0] != 0);
111 static const bool BigEndian
= !LittleEndian
;
114 void *OpenLib(const char *libname
);
115 void CloseLib(void *handle
);
117 #define LOAD_FUNC(h, x) p##x = x
119 void *GetLibProc(void *handle
, const char *funcname
);
122 void LoadFunc(void *handle
, const char *funcname
, T
**funcptr
)
123 { *funcptr
= reinterpret_cast<T
*>(GetLibProc(handle
, funcname
)); }
125 #define LOAD_FUNC(h, x) LoadFunc((h), #x, &(p##x)); \
135 extern void *vorbisfile_handle
;
136 extern void *flac_handle
;
137 extern void *dumb_handle
;
138 extern void *mod_handle
;
139 extern void *mp123_handle
;
140 extern void *sndfile_handle
;
141 extern void *fsynth_handle
;
143 #define MAKE_FUNC(x) extern typeof(x)* p##x
144 #ifdef HAS_VORBISFILE
147 MAKE_FUNC(ov_open_callbacks
);
148 MAKE_FUNC(ov_pcm_seek
);
152 MAKE_FUNC(FLAC__stream_decoder_get_state
);
153 MAKE_FUNC(FLAC__stream_decoder_finish
);
154 MAKE_FUNC(FLAC__stream_decoder_new
);
155 MAKE_FUNC(FLAC__stream_decoder_seek_absolute
);
156 MAKE_FUNC(FLAC__stream_decoder_delete
);
157 MAKE_FUNC(FLAC__stream_decoder_process_single
);
158 MAKE_FUNC(FLAC__stream_decoder_init_stream
);
161 MAKE_FUNC(dumbfile_open_ex
);
162 MAKE_FUNC(dumbfile_close
);
163 MAKE_FUNC(dumb_read_mod
);
164 MAKE_FUNC(dumb_read_s3m
);
165 MAKE_FUNC(dumb_read_xm
);
166 MAKE_FUNC(dumb_read_it
);
167 MAKE_FUNC(dumb_silence
);
168 MAKE_FUNC(duh_sigrenderer_generate_samples
);
169 MAKE_FUNC(duh_get_it_sigrenderer
);
170 MAKE_FUNC(duh_end_sigrenderer
);
171 MAKE_FUNC(unload_duh
);
172 MAKE_FUNC(dumb_it_start_at_order
);
173 MAKE_FUNC(dumb_it_set_loop_callback
);
174 MAKE_FUNC(dumb_it_sr_get_speed
);
175 MAKE_FUNC(dumb_it_sr_set_speed
);
178 MAKE_FUNC(ModPlug_Load
);
179 MAKE_FUNC(ModPlug_Unload
);
180 MAKE_FUNC(ModPlug_Read
);
181 MAKE_FUNC(ModPlug_SeekOrder
);
184 MAKE_FUNC(mpg123_read
);
185 MAKE_FUNC(mpg123_init
);
186 MAKE_FUNC(mpg123_open_feed
);
187 MAKE_FUNC(mpg123_new
);
188 MAKE_FUNC(mpg123_delete
);
189 MAKE_FUNC(mpg123_feed
);
190 MAKE_FUNC(mpg123_exit
);
191 MAKE_FUNC(mpg123_getformat
);
192 MAKE_FUNC(mpg123_format_none
);
193 MAKE_FUNC(mpg123_decode
);
194 MAKE_FUNC(mpg123_format
);
198 MAKE_FUNC(sf_open_virtual
);
199 MAKE_FUNC(sf_readf_short
);
202 #ifdef HAS_FLUIDSYNTH
203 MAKE_FUNC(fluid_settings_setstr
);
204 MAKE_FUNC(fluid_synth_program_change
);
205 MAKE_FUNC(fluid_synth_sfload
);
206 MAKE_FUNC(fluid_settings_setnum
);
207 MAKE_FUNC(fluid_synth_sysex
);
208 MAKE_FUNC(fluid_synth_cc
);
209 MAKE_FUNC(fluid_synth_pitch_bend
);
210 MAKE_FUNC(fluid_synth_channel_pressure
);
211 MAKE_FUNC(fluid_synth_write_float
);
212 MAKE_FUNC(new_fluid_synth
);
213 MAKE_FUNC(delete_fluid_settings
);
214 MAKE_FUNC(delete_fluid_synth
);
215 MAKE_FUNC(fluid_synth_program_reset
);
216 MAKE_FUNC(fluid_settings_setint
);
217 MAKE_FUNC(new_fluid_settings
);
218 MAKE_FUNC(fluid_synth_write_s16
);
219 MAKE_FUNC(fluid_synth_noteoff
);
220 MAKE_FUNC(fluid_synth_sfunload
);
221 MAKE_FUNC(fluid_synth_noteon
);
225 void SetError(const char *err
);
226 ALuint
DetectBlockAlignment(ALenum format
);
227 ALuint
DetectCompressionRate(ALenum format
);
228 ALenum
GetSampleFormat(ALuint channels
, ALuint bits
, bool isFloat
);
230 struct UserCallbacks
{
231 void* (*open_file
)(const ALchar
*);
232 void* (*open_mem
)(const ALubyte
*,ALuint
);
233 ALboolean (*get_fmt
)(void*,ALenum
*,ALuint
*,ALuint
*);
234 ALuint (*decode
)(void*,ALubyte
*,ALuint
);
235 ALboolean (*rewind
)(void*);
236 void (*close
)(void*);
238 extern std::map
<ALint
,UserCallbacks
> InstalledCallbacks
;
242 // Local copy of memory data
245 // Storage when reading chunks
246 std::vector
<ALubyte
> dataChunk
;
248 // Abstracted input stream
249 std::istream
*fstream
;
251 virtual bool IsValid() = 0;
252 virtual bool GetFormat(ALenum
*,ALuint
*,ALuint
*) = 0;
253 virtual ALuint
GetData(ALubyte
*,ALuint
) = 0;
254 virtual bool Rewind() = 0;
255 virtual bool SetOrder(ALuint order
)
257 if(!order
) return Rewind();
258 SetError("Invalid order for stream");
261 virtual bool SetPatchset(const char*)
264 alureStream(std::istream
*_stream
)
265 : data(NULL
), fstream(_stream
)
266 { StreamList
.push_front(this); }
267 virtual ~alureStream()
270 StreamList
.erase(std::find(StreamList
.begin(), StreamList
.end(), this));
273 static void Clear(void)
275 while(StreamList
.size() > 0)
276 alureDestroyStream(*(StreamList
.begin()), 0, NULL
);
279 static bool Verify(alureStream
*stream
)
281 ListType::iterator i
= std::find(StreamList
.begin(), StreamList
.end(), stream
);
282 return (i
!= StreamList
.end());
286 typedef std::list
<alureStream
*> ListType
;
287 static ListType StreamList
;
289 void StopStream(alureStream
*stream
);
297 MemDataInfo() : Data(NULL
), Length(0), Pos(0)
299 MemDataInfo(const MemDataInfo
&inf
) : Data(inf
.Data
), Length(inf
.Length
),
304 class MemStreamBuf
: public std::streambuf
{
307 virtual int_type
underflow();
308 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
);
309 virtual pos_type
seekpos(pos_type pos
, std::ios_base::openmode mode
= std::ios_base::in
| std::ios_base::out
);
312 MemStreamBuf(const MemDataInfo
&data
)
315 memInfo
.Pos
/= sizeof(char_type
);
316 memInfo
.Length
/= sizeof(char_type
);
318 virtual ~MemStreamBuf() { }
322 void* (*open
)(const char *filename
, ALuint mode
);
323 void (*close
)(void *f
);
324 ALsizei (*read
)(void *f
, ALubyte
*buf
, ALuint count
);
325 ALsizei (*write
)(void *f
, const ALubyte
*buf
, ALuint count
);
326 alureInt64 (*seek
)(void *f
, alureInt64 offset
, int whence
);
328 extern UserFuncs Funcs
;
330 class FileStreamBuf
: public std::streambuf
{
336 virtual int_type
underflow();
337 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
);
338 virtual pos_type
seekpos(pos_type pos
, std::ios_base::openmode mode
= std::ios_base::in
| std::ios_base::out
);
342 { return usrFile
!= NULL
; }
344 FileStreamBuf(const char *filename
, ALint mode
)
345 : usrFile(NULL
), fio(Funcs
)
346 { usrFile
= fio
.open(filename
, mode
); }
347 virtual ~FileStreamBuf()
348 { if(usrFile
) fio
.close(usrFile
); }
351 class InStream
: public std::istream
{
353 InStream(const char *filename
)
354 : std::istream(new FileStreamBuf(filename
, 0))
356 if(!(static_cast<FileStreamBuf
*>(rdbuf())->IsOpen()))
359 InStream(const MemDataInfo
&memInfo
)
360 : std::istream(new MemStreamBuf(memInfo
))
367 extern CRITICAL_SECTION cs_StreamPlay
;
369 alureStream
*create_stream(const char *fname
);
370 alureStream
*create_stream(const MemDataInfo
&memData
);
371 alureStream
*create_stream(ALvoid
*userdata
, ALenum format
, ALuint rate
, const UserCallbacks
&cb
);
373 template <typename T
>
374 const T
& clamp(const T
& val
, const T
& min
, const T
& max
)
375 { return std::max(std::min(val
, max
), min
); }
377 template <typename T
>
378 void swap(T
&val1
, T
&val2
)
387 typedef std::auto_ptr
<alureStream
>(*FactoryType
)(std::istream
*);
388 typedef std::vector
<FactoryType
> ListType
;
390 static const ListType
& GetList();
393 static ListType
& AddList(FactoryType func
);
397 struct DecoderDecl
: public Decoder
{
398 DecoderDecl() { AddList(Factory
); }
401 ListType
&list
= AddList(NULL
);
402 list
.erase(std::find(list
.begin(), list
.end(), Factory
));
406 static std::auto_ptr
<alureStream
> Factory(std::istream
*file
)
408 std::auto_ptr
<alureStream
> ret(new T(file
));
409 if(ret
->IsValid()) return ret
;
410 return std::auto_ptr
<alureStream
>();