Move the appropriate lib-handling function declarations to main.h
[alure.git] / include / main.h
blobe0e2d259bac1e1e911f095ccb2d73deef39071a7
1 #ifndef MAIN_H
2 #define MAIN_H
4 #include "AL/alure.h"
5 #include "alext.h"
7 #ifdef HAS_SNDFILE
8 #include <sndfile.h>
9 #endif
10 #ifdef HAS_VORBISFILE
11 #include <vorbis/vorbisfile.h>
12 #endif
13 #ifdef HAS_FLAC
14 #include <FLAC/all.h>
15 #endif
16 #ifdef HAS_MPG123
17 #include <mpg123.h>
18 #endif
19 #ifdef HAS_DUMB
20 #include <dumb.h>
21 #endif
22 #ifdef HAS_MODPLUG
23 #include <modplug.h>
24 #endif
25 #ifdef HAS_FLUIDSYNTH
26 #include <fluidsynth.h>
27 #endif
30 #ifdef HAVE_SYS_TYPES_H
31 #include <sys/types.h>
32 #endif
33 #ifdef HAVE_SYS_WAIT_H
34 #include <sys/wait.h>
35 #endif
36 #ifdef HAVE_SIGNAL_H
37 #include <signal.h>
38 #endif
40 #ifdef HAVE_WINDOWS_H
42 #include <windows.h>
44 #else
46 #ifdef HAVE_DLFCN_H
47 #include <dlfcn.h>
48 #endif
50 #include <assert.h>
51 #include <pthread.h>
52 #ifdef HAVE_PTHREAD_NP_H
53 #include <pthread_np.h>
54 #endif
55 #include <errno.h>
57 typedef pthread_mutex_t CRITICAL_SECTION;
58 static inline void EnterCriticalSection(CRITICAL_SECTION *cs)
60 int ret;
61 ret = pthread_mutex_lock(cs);
62 assert(ret == 0);
64 static inline void LeaveCriticalSection(CRITICAL_SECTION *cs)
66 int ret;
67 ret = pthread_mutex_unlock(cs);
68 assert(ret == 0);
70 static inline void InitializeCriticalSection(CRITICAL_SECTION *cs)
72 pthread_mutexattr_t attrib;
73 int ret;
75 ret = pthread_mutexattr_init(&attrib);
76 assert(ret == 0);
78 ret = pthread_mutexattr_settype(&attrib, PTHREAD_MUTEX_RECURSIVE);
79 #ifdef HAVE_PTHREAD_NP_H
80 if(ret != 0)
81 ret = pthread_mutexattr_setkind_np(&attrib, PTHREAD_MUTEX_RECURSIVE);
82 #endif
83 assert(ret == 0);
84 ret = pthread_mutex_init(cs, &attrib);
85 assert(ret == 0);
87 pthread_mutexattr_destroy(&attrib);
89 static inline void DeleteCriticalSection(CRITICAL_SECTION *cs)
91 int ret;
92 ret = pthread_mutex_destroy(cs);
93 assert(ret == 0);
96 #endif
98 #include <map>
99 #include <streambuf>
100 #include <istream>
101 #include <list>
102 #include <algorithm>
103 #include <vector>
104 #include <memory>
106 static const union {
107 int val;
108 char b[sizeof(int)];
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);
116 #ifndef DYNLOAD
117 #define LOAD_FUNC(h, x) p##x = x
118 #else
119 void *GetLibProc(void *handle, const char *funcname);
121 template<typename T>
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)); \
126 if(!(p##x)) \
128 CloseLib((h)); \
129 (h) = NULL; \
130 break; \
132 #endif
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
145 MAKE_FUNC(ov_clear);
146 MAKE_FUNC(ov_info);
147 MAKE_FUNC(ov_open_callbacks);
148 MAKE_FUNC(ov_pcm_seek);
149 MAKE_FUNC(ov_read);
150 #endif
151 #ifdef HAS_FLAC
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);
159 #endif
160 #ifdef HAS_DUMB
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);
176 #endif
177 #ifdef HAS_MODPLUG
178 MAKE_FUNC(ModPlug_Load);
179 MAKE_FUNC(ModPlug_Unload);
180 MAKE_FUNC(ModPlug_Read);
181 MAKE_FUNC(ModPlug_SeekOrder);
182 #endif
183 #ifdef HAS_MPG123
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);
195 #endif
196 #ifdef HAS_SNDFILE
197 MAKE_FUNC(sf_close);
198 MAKE_FUNC(sf_open_virtual);
199 MAKE_FUNC(sf_readf_short);
200 MAKE_FUNC(sf_seek);
201 #endif
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);
222 #endif
223 #undef MAKE_FUNC
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;
241 struct alureStream {
242 // Local copy of memory data
243 ALubyte *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");
259 return false;
261 virtual bool SetPatchset(const char*)
262 { return true; }
264 alureStream(std::istream *_stream)
265 : data(NULL), fstream(_stream)
266 { StreamList.push_front(this); }
267 virtual ~alureStream()
269 delete[] data;
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());
285 private:
286 typedef std::list<alureStream*> ListType;
287 static ListType StreamList;
289 void StopStream(alureStream *stream);
292 struct MemDataInfo {
293 const ALubyte *Data;
294 size_t Length;
295 size_t Pos;
297 MemDataInfo() : Data(NULL), Length(0), Pos(0)
299 MemDataInfo(const MemDataInfo &inf) : Data(inf.Data), Length(inf.Length),
300 Pos(inf.Pos)
304 class MemStreamBuf : public std::streambuf {
305 MemDataInfo memInfo;
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);
311 public:
312 MemStreamBuf(const MemDataInfo &data)
313 : memInfo(data)
315 memInfo.Pos /= sizeof(char_type);
316 memInfo.Length /= sizeof(char_type);
318 virtual ~MemStreamBuf() { }
321 struct UserFuncs {
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 {
331 void *usrFile;
332 UserFuncs fio;
334 char buffer[1024];
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);
340 public:
341 bool IsOpen()
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 {
352 public:
353 InStream(const char *filename)
354 : std::istream(new FileStreamBuf(filename, 0))
356 if(!(static_cast<FileStreamBuf*>(rdbuf())->IsOpen()))
357 clear(failbit);
359 InStream(const MemDataInfo &memInfo)
360 : std::istream(new MemStreamBuf(memInfo))
362 virtual ~InStream()
363 { delete rdbuf(); }
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)
380 val1 ^= val2;
381 val2 ^= val1;
382 val1 ^= val2;
386 struct Decoder {
387 typedef std::auto_ptr<alureStream>(*FactoryType)(std::istream*);
388 typedef std::vector<FactoryType> ListType;
390 static const ListType& GetList();
392 protected:
393 static ListType& AddList(FactoryType func);
396 template<typename T>
397 struct DecoderDecl : public Decoder {
398 DecoderDecl() { AddList(Factory); }
399 ~DecoderDecl()
401 ListType &list = AddList(NULL);
402 list.erase(std::find(list.begin(), list.end(), Factory));
405 private:
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>();
414 #endif // MAIN_H