11 #include <vorbis/vorbisfile.h>
23 #include <fluidsynth.h>
27 #ifdef HAVE_SYS_TYPES_H
28 #include <sys/types.h>
30 #ifdef HAVE_SYS_WAIT_H
49 #ifdef HAVE_PTHREAD_NP_H
50 #include <pthread_np.h>
54 typedef pthread_mutex_t CRITICAL_SECTION
;
55 static inline void EnterCriticalSection(CRITICAL_SECTION
*cs
)
58 ret
= pthread_mutex_lock(cs
);
61 static inline void LeaveCriticalSection(CRITICAL_SECTION
*cs
)
64 ret
= pthread_mutex_unlock(cs
);
67 static inline void InitializeCriticalSection(CRITICAL_SECTION
*cs
)
69 pthread_mutexattr_t attrib
;
72 ret
= pthread_mutexattr_init(&attrib
);
75 ret
= pthread_mutexattr_settype(&attrib
, PTHREAD_MUTEX_RECURSIVE
);
76 #ifdef HAVE_PTHREAD_NP_H
78 ret
= pthread_mutexattr_setkind_np(&attrib
, PTHREAD_MUTEX_RECURSIVE
);
81 ret
= pthread_mutex_init(cs
, &attrib
);
84 pthread_mutexattr_destroy(&attrib
);
86 static inline void DeleteCriticalSection(CRITICAL_SECTION
*cs
)
89 ret
= pthread_mutex_destroy(cs
);
104 } endian_test
= { 1 };
105 static const bool LittleEndian
= (endian_test
.b
[0] != 0);
106 static const bool BigEndian
= !LittleEndian
;
109 extern void *vorbisfile_handle
;
110 extern void *flac_handle
;
111 extern void *dumb_handle
;
112 extern void *mp123_handle
;
113 extern void *sndfile_handle
;
114 extern void *fsynth_handle
;
116 #define MAKE_FUNC(x) extern typeof(x)* p##x
117 #ifdef HAS_VORBISFILE
120 MAKE_FUNC(ov_open_callbacks
);
121 MAKE_FUNC(ov_pcm_seek
);
125 MAKE_FUNC(FLAC__stream_decoder_get_state
);
126 MAKE_FUNC(FLAC__stream_decoder_finish
);
127 MAKE_FUNC(FLAC__stream_decoder_new
);
128 MAKE_FUNC(FLAC__stream_decoder_seek_absolute
);
129 MAKE_FUNC(FLAC__stream_decoder_delete
);
130 MAKE_FUNC(FLAC__stream_decoder_process_single
);
131 MAKE_FUNC(FLAC__stream_decoder_init_stream
);
134 MAKE_FUNC(dumbfile_open_ex
);
135 MAKE_FUNC(dumbfile_close
);
136 MAKE_FUNC(dumb_read_mod
);
137 MAKE_FUNC(dumb_read_s3m
);
138 MAKE_FUNC(dumb_read_xm
);
139 MAKE_FUNC(dumb_read_it
);
140 MAKE_FUNC(dumb_silence
);
141 MAKE_FUNC(duh_sigrenderer_generate_samples
);
142 MAKE_FUNC(duh_get_it_sigrenderer
);
143 MAKE_FUNC(duh_end_sigrenderer
);
144 MAKE_FUNC(unload_duh
);
145 MAKE_FUNC(dumb_it_start_at_order
);
146 MAKE_FUNC(dumb_it_set_loop_callback
);
147 MAKE_FUNC(dumb_it_sr_get_speed
);
148 MAKE_FUNC(dumb_it_sr_set_speed
);
151 MAKE_FUNC(mpg123_read
);
152 MAKE_FUNC(mpg123_init
);
153 MAKE_FUNC(mpg123_open_feed
);
154 MAKE_FUNC(mpg123_new
);
155 MAKE_FUNC(mpg123_delete
);
156 MAKE_FUNC(mpg123_feed
);
157 MAKE_FUNC(mpg123_exit
);
158 MAKE_FUNC(mpg123_getformat
);
159 MAKE_FUNC(mpg123_format_none
);
160 MAKE_FUNC(mpg123_decode
);
161 MAKE_FUNC(mpg123_format
);
165 MAKE_FUNC(sf_open_virtual
);
166 MAKE_FUNC(sf_readf_short
);
169 #ifdef HAS_FLUIDSYNTH
170 MAKE_FUNC(fluid_settings_setstr
);
171 MAKE_FUNC(fluid_synth_program_change
);
172 MAKE_FUNC(fluid_synth_sfload
);
173 MAKE_FUNC(fluid_settings_setnum
);
174 MAKE_FUNC(fluid_synth_sysex
);
175 MAKE_FUNC(fluid_synth_cc
);
176 MAKE_FUNC(fluid_synth_pitch_bend
);
177 MAKE_FUNC(fluid_synth_channel_pressure
);
178 MAKE_FUNC(fluid_synth_write_float
);
179 MAKE_FUNC(new_fluid_synth
);
180 MAKE_FUNC(delete_fluid_settings
);
181 MAKE_FUNC(delete_fluid_synth
);
182 MAKE_FUNC(fluid_synth_program_reset
);
183 MAKE_FUNC(fluid_settings_setint
);
184 MAKE_FUNC(new_fluid_settings
);
185 MAKE_FUNC(fluid_synth_write_s16
);
186 MAKE_FUNC(fluid_synth_noteoff
);
187 MAKE_FUNC(fluid_synth_sfunload
);
188 MAKE_FUNC(fluid_synth_noteon
);
192 void SetError(const char *err
);
193 ALuint
DetectBlockAlignment(ALenum format
);
194 ALuint
DetectCompressionRate(ALenum format
);
195 ALenum
GetSampleFormat(ALuint channels
, ALuint bits
, bool isFloat
);
197 struct UserCallbacks
{
198 void* (*open_file
)(const ALchar
*);
199 void* (*open_mem
)(const ALubyte
*,ALuint
);
200 ALboolean (*get_fmt
)(void*,ALenum
*,ALuint
*,ALuint
*);
201 ALuint (*decode
)(void*,ALubyte
*,ALuint
);
202 ALboolean (*rewind
)(void*);
203 void (*close
)(void*);
205 extern std::map
<ALint
,UserCallbacks
> InstalledCallbacks
;
214 std::istream
*fstream
;
216 virtual bool IsValid() = 0;
217 virtual bool GetFormat(ALenum
*,ALuint
*,ALuint
*) = 0;
218 virtual ALuint
GetData(ALubyte
*,ALuint
) = 0;
219 virtual bool Rewind() = 0;
220 virtual bool SetOrder(ALuint order
)
222 if(!order
) return Rewind();
223 SetError("Invalid order for stream");
227 alureStream(std::istream
*_stream
)
228 : data(NULL
), dataChunk(NULL
), fstream(_stream
)
229 { StreamList
.push_front(this); }
230 virtual ~alureStream()
232 delete[] data
; delete[] dataChunk
;
233 StreamList
.erase(std::find(StreamList
.begin(), StreamList
.end(), this));
236 static void Clear(void)
238 while(StreamList
.size() > 0)
239 alureDestroyStream(*(StreamList
.begin()), 0, NULL
);
242 static bool Verify(alureStream
*stream
)
244 ListType::iterator i
= std::find(StreamList
.begin(), StreamList
.end(), stream
);
245 return (i
!= StreamList
.end());
249 typedef std::list
<alureStream
*> ListType
;
250 static ListType StreamList
;
252 void StopStream(alureStream
*stream
);
260 MemDataInfo() : Data(NULL
), Length(0), Pos(0)
262 MemDataInfo(const MemDataInfo
&inf
) : Data(inf
.Data
), Length(inf
.Length
),
267 class MemStreamBuf
: public std::streambuf
{
270 virtual int_type
underflow();
271 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
);
272 virtual pos_type
seekpos(pos_type pos
, std::ios_base::openmode mode
= std::ios_base::in
| std::ios_base::out
);
275 MemStreamBuf(const MemDataInfo
&data
)
278 memInfo
.Pos
/= sizeof(char_type
);
279 memInfo
.Length
/= sizeof(char_type
);
281 virtual ~MemStreamBuf() { }
285 void* (*open
)(const char *filename
, ALuint mode
);
286 void (*close
)(void *f
);
287 ALsizei (*read
)(void *f
, ALubyte
*buf
, ALuint count
);
288 ALsizei (*write
)(void *f
, const ALubyte
*buf
, ALuint count
);
289 alureInt64 (*seek
)(void *f
, alureInt64 offset
, int whence
);
291 extern UserFuncs Funcs
;
293 class FileStreamBuf
: public std::streambuf
{
299 virtual int_type
underflow();
300 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
);
301 virtual pos_type
seekpos(pos_type pos
, std::ios_base::openmode mode
= std::ios_base::in
| std::ios_base::out
);
305 { return usrFile
!= NULL
; }
307 FileStreamBuf(const char *filename
, ALint mode
)
308 : usrFile(NULL
), fio(Funcs
)
309 { usrFile
= fio
.open(filename
, mode
); }
310 virtual ~FileStreamBuf()
311 { if(usrFile
) fio
.close(usrFile
); }
314 class InStream
: public std::istream
{
316 InStream(const char *filename
)
317 : std::istream(new FileStreamBuf(filename
, 0))
319 if(!(static_cast<FileStreamBuf
*>(rdbuf())->IsOpen()))
322 InStream(const MemDataInfo
&memInfo
)
323 : std::istream(new MemStreamBuf(memInfo
))
330 extern CRITICAL_SECTION cs_StreamPlay
;
332 alureStream
*create_stream(const char *fname
);
333 alureStream
*create_stream(const MemDataInfo
&memData
);
334 alureStream
*create_stream(ALvoid
*userdata
, ALenum format
, ALuint rate
, const UserCallbacks
&cb
);
336 template <typename T
>
337 const T
& clamp(const T
& val
, const T
& min
, const T
& max
)
338 { return std::max(std::min(val
, max
), min
); }
340 template <typename T
>
341 void swap(T
&val1
, T
&val2
)