1 
2 //          Copyright Michael D. Parker 2018.
3 // Distributed under the Boost Software License, Version 1.0.
4 //    (See accompanying file LICENSE_1_0.txt or copy at
5 //          http://www.boost.org/LICENSE_1_0.txt)
6 
7 module bindbc.sdl.mixer;
8 
9 version(BindSDL_Mixer):
10 
11 import bindbc.sdl.config;
12 import bindbc.sdl.bind.sdlaudio : AUDIO_S16LSB, SDL_MIX_MAXVOLUME;
13 import bindbc.sdl.bind.sdlerror : SDL_GetError, SDL_SetError, SDL_ClearError;
14 import bindbc.sdl.bind.sdlrwops : SDL_RWops, SDL_RWFromFile;
15 import bindbc.sdl.bind.sdlstdinc : SDL_bool;
16 import bindbc.sdl.bind.sdlversion : SDL_version, SDL_VERSIONNUM;
17 
18 alias Mix_SetError = SDL_SetError;
19 alias Mix_GetError = SDL_GetError;
20 alias Mix_ClearError = SDL_ClearError;
21 
22 enum SDLMixerSupport {
23     noLibrary,
24     badLibrary,
25     sdlMixer200 = 200,
26     sdlMixer201 = 201,
27     sdlMixer202 = 202,
28 }
29 
30 enum ubyte SDL_MIXER_MAJOR_VERSION = 2;
31 enum ubyte SDL_MIXER_MINOR_VERSION = 0;
32 
33 version(SDL_Mixer_202) {
34     enum sdlMixerSupport = SDLMixerSupport.sdlMixer202;
35     enum ubyte SDL_MIXER_PATCHLEVEL = 2;
36 }
37 else version(SDL_Mixer_201) {
38     enum sdlMixerSupport = SDLMixerSupport.sdlMixer201;
39     enum ubyte SDL_MIXER_PATCHLEVEL = 1;
40 }
41 else {
42     enum sdlMixerSupport = SDLMixerSupport.sdlMixer200;
43     enum ubyte SDL_MIXER_PATCHLEVEL = 0;
44 }
45 
46 alias MIX_MAJOR_VERSION = SDL_MIXER_MAJOR_VERSION;
47 alias MIX_MINOR_VERSION = SDL_MIXER_MINOR_VERSION;
48 alias MIX_PATCH_LEVEL = SDL_MIXER_PATCHLEVEL;
49 
50 @nogc nothrow void SDL_MIXER_VERSION(SDL_version* X)
51 {
52     X.major     = SDL_MIXER_MAJOR_VERSION;
53     X.minor     = SDL_MIXER_MINOR_VERSION;
54     X.patch     = SDL_MIXER_PATCHLEVEL;
55 }
56 alias SDL_MIX_VERSION = SDL_MIX_MAXVOLUME;
57 
58 // These were implemented in SDL_mixer 2.0.2, but are fine for all versions.
59 enum SDL_MIXER_COMPILEDVERSION = SDL_VERSIONNUM!(SDL_MIXER_MAJOR_VERSION, SDL_MIXER_MINOR_VERSION, SDL_MIXER_PATCHLEVEL);
60 enum SDL_MIXER_VERSION_ATLEAST(ubyte X, ubyte Y, ubyte Z) = SDL_MIXER_COMPILEDVERSION >= SDL_VERSIONNUM!(X, Y, Z);
61 
62 static if(sdlMixerSupport >= SDLMixerSupport.sdlMixer202) {
63     enum Mix_InitFlags {
64         MIX_INIT_FLAC = 0x00000001,
65         MIX_INIT_MOD = 0x00000002,
66         MIX_INIT_MP3 = 0x00000008,
67         MIX_INIT_OGG = 0x00000010,
68         MIX_INIT_MID = 0x00000020,
69     }
70 }
71 else {
72     enum Mix_InitFlags {
73         MIX_INIT_FLAC = 0x00000001,
74         MIX_INIT_MOD = 0x00000002,
75         MIX_INIT_MODPLUG = 0x00000004,
76         MIX_INIT_MP3 = 0x00000008,
77         MIX_INIT_OGG = 0x00000010,
78         MIX_INIT_FLUIDSYNTH = 0x00000020,
79     }
80 }
81 mixin(expandEnum!Mix_InitFlags);
82 
83 enum {
84     MIX_CHANNELS              = 8,
85     MIX_DEFAULT_FREQUENCY     = 22050,
86     MIX_DEFAULT_CHANNELS      = 2,
87     MIX_MAX_VOLUME            = 128,
88     MIX_CHANNEL_POST          = -2,
89 }
90 
91 version(LittleEndian) {
92     enum MIX_DEFAULT_FORMAT = AUDIO_S16LSB;
93 } else {
94     enum MIX_DEFAULT_FORMAT = AUDIO_S16MSB;
95 }
96 
97 struct Mix_Chunk {
98    int allocated;
99    ubyte* abuf;
100    uint alen;
101    ubyte volume;
102 }
103 
104 enum Mix_Fading {
105    MIX_NO_FADING,
106    MIX_FADING_OUT,
107    MIX_FADING_IN
108 }
109 mixin(expandEnum!Mix_Fading);
110 
111 static if(sdlMixerSupport >= SDLMixerSupport.sdlMixer202) {
112     enum Mix_MusicType {
113        MUS_NONE,
114        MUS_CMD,
115        MUS_WAV,
116        MUS_MOD,
117        MUS_MID,
118        MUS_OGG,
119        MUS_MP3,
120        MUS_MP3_MAD_UNUSED,
121        MUS_FLAC,
122        MUS_MODPLUG_UNUSED,
123     }
124 }
125 else {
126     enum Mix_MusicType {
127        MUS_NONE,
128        MUS_CMD,
129        MUS_WAV,
130        MUS_MOD,
131        MUS_MID,
132        MUS_OGG,
133        MUS_MP3,
134        MUS_MP3_MAD,
135        MUS_FLAC,
136        MUS_MODPLUG,
137     }
138 }
139 mixin(expandEnum!Mix_MusicType);
140 
141 struct Mix_Music;
142 enum MIX_EFFECTSMAXSPEED = "MIX_EFFECTSMAXSPEED";
143 
144 extern(C) nothrow {
145     alias Mix_EffectFunc_t = void function(int,void*,int,void*);
146     alias Mix_EffectDone_t = void function(int,void*);
147 
148     // These aren't in SDL_mixer.h and are just here as a convenient and
149     // visible means to add the proper attributes these callbacks.
150     alias callbackI = void function(int);
151     alias callbackVUi8I = void function(void*,ubyte*,int);
152     alias callbackN = void function();
153 }
154 
155 @nogc nothrow {
156     Mix_Chunk* Mix_LoadWAV(const(char)* file) {
157         pragma(inline, true);
158         return Mix_LoadWAV_RW(SDL_RWFromFile(file,"rb"),1);
159     }
160 
161     int Mix_PlayChannel(int channel,Mix_Chunk* chunk,int loops) {
162         pragma(inline, true);
163         return Mix_PlayChannelTimed(channel,chunk,loops,-1);
164     }
165 
166     int Mix_FadeInChannel(int channel,Mix_Chunk* chunk,int loops,int ms) {
167         pragma(inline, true);
168         return Mix_FadeInChannelTimed(channel,chunk,loops,ms,-1);
169     }
170 }
171 
172 version(BindSDL_Static) {
173     extern(C) @nogc nothrow {
174         const(SDL_version)* Mix_Linked_Version();
175         int Mix_Init(int);
176         void Mix_Quit();
177         int Mix_OpenAudio(int,ushort,int,int);
178         int Mix_AllocateChannels(int);
179         int Mix_QuerySpec(int*,ushort*,int*);
180         Mix_Chunk* Mix_LoadWAV_RW(SDL_RWops*,int);
181         Mix_Music* Mix_LoadMUS(const(char)*);
182         Mix_Music* Mix_LoadMUS_RW(SDL_RWops*,int);
183         Mix_Music* Mix_LoadMUSType_RW(SDL_RWops*,Mix_MusicType,int);
184         Mix_Chunk* Mix_QuickLoad_WAV(ubyte*);
185         Mix_Chunk* Mix_QuickLoad_RAW(ubyte*,uint);
186         void Mix_FreeChunk(Mix_Chunk*);
187         void Mix_FreeMusic(Mix_Music*);
188         int Mix_GetNumChunkDecoders();
189         const(char)* Mix_GetChunkDecoder(int);
190         int Mix_GetNumMusicDecoders();
191         const(char)* Mix_GetMusicDecoder(int);
192         Mix_MusicType Mix_GetMusicType(const(Mix_Music)*);
193         void Mix_SetPostMix(callbackVUi8I,void*);
194         void Mix_HookMusic(callbackVUi8I,void*);
195         void Mix_HookMusicFinished(callbackN);
196         void* Mix_GetMusicHookData();
197         void Mix_ChannelFinished(callbackI);
198         int Mix_RegisterEffect(int,Mix_EffectFunc_t,Mix_EffectDone_t,void*);
199         int Mix_UnregisterEffect(int,Mix_EffectFunc_t);
200         int Mix_UnregisterAllEffects(int);
201         int Mix_SetPanning(int,ubyte,ubyte);
202         int Mix_SetPosition(int,short,ubyte);
203         int Mix_SetDistance(int,ubyte);
204         int Mix_SetReverseStereo(int,int);
205         int Mix_ReserveChannels(int);
206         int Mix_GroupChannel(int,int);
207         int Mix_GroupChannels(int,int,int);
208         int Mix_GroupAvailable(int);
209         int Mix_GroupCount(int);
210         int Mix_GroupOldest(int);
211         int Mix_GroupNewer(int);
212         int Mix_PlayChannelTimed(int,Mix_Chunk*,int,int);
213         int Mix_PlayMusic(Mix_Music*,int);
214         int Mix_FadeInMusic(Mix_Music*,int,int);
215         int Mix_FadeInMusicPos(Mix_Music*,int,int,double);
216         int Mix_FadeInChannelTimed(int,Mix_Chunk*,int,int,int);
217         int Mix_Volume(int,int);
218         int Mix_VolumeChunk(Mix_Chunk*,int);
219         int Mix_VolumeMusic(int);
220         int Mix_HaltChannel(int);
221         int Mix_HaltGroup(int);
222         int Mix_HaltMusic();
223         int Mix_ExpireChannel(int,int);
224         int Mix_FadeOutChannel(int,int);
225         int Mix_FadeOutGroup(int,int);
226         int Mix_FadeOutMusic(int);
227         Mix_Fading Mix_FadingMusic();
228         Mix_Fading Mix_FadingChannel(int);
229         void Mix_Pause(int);
230         void Mix_Resume(int);
231         int Mix_Paused(int);
232         void Mix_PauseMusic();
233         void Mix_ResumeMusic();
234         void Mix_RewindMusic();
235         int Mix_PausedMusic();
236         int Mix_SetMusicPosition(double);
237         int Mix_Playing(int);
238         int Mix_PlayingMusic();
239         int Mix_SetMusicCMD(in char*);
240         int Mix_SetSynchroValue(int);
241         int Mix_GetSynchroValue();
242         Mix_Chunk* Mix_GetChunk(int);
243         void Mix_CloseAudio();
244 
245         static if(sdlMixerSupport >= SDLMixerSupport.sdlMixer202) {
246             int Mix_OpenAudioDevice(int,ushort,int,int,const(char)*,int);
247             SDL_bool Mix_HasChunkDecoder(const(char)*);
248 
249             // Declared in SDL_mixer.h, but not implemented
250             // SDL_bool Mix_HasMusicDecoder(const(char)*);
251         }
252     }
253 }
254 else {
255     import bindbc.loader;
256 
257     extern(C) @nogc nothrow {
258         alias pMix_Linked_Version = const(SDL_version)* function();
259         alias pMix_Init = int function(int);
260         alias pMix_Quit = void function();
261         alias pMix_OpenAudio = int function(int,ushort,int,int);
262         alias pMix_AllocateChannels = int function(int);
263         alias pMix_QuerySpec = int function(int*,ushort*,int*);
264         alias pMix_LoadWAV_RW = Mix_Chunk* function(SDL_RWops*,int);
265         alias pMix_LoadMUS = Mix_Music* function(const(char)*);
266         alias pMix_LoadMUS_RW = Mix_Music* function(SDL_RWops*,int);
267         alias pMix_LoadMUSType_RW = Mix_Music* function(SDL_RWops*,Mix_MusicType,int);
268         alias pMix_QuickLoad_WAV = Mix_Chunk* function(ubyte*);
269         alias pMix_QuickLoad_RAW = Mix_Chunk* function(ubyte*,uint);
270         alias pMix_FreeChunk = void function(Mix_Chunk*);
271         alias pMix_FreeMusic = void function(Mix_Music*);
272         alias pMix_GetNumChunkDecoders = int function();
273         alias pMix_GetChunkDecoder = const(char)* function(int);
274         alias pMix_GetNumMusicDecoders = int function();
275         alias pMix_GetMusicDecoder = const(char)* function(int);
276         alias pMix_GetMusicType = Mix_MusicType function(const(Mix_Music)*);
277         alias pMix_SetPostMix = void function(callbackVUi8I,void*);
278         alias pMix_HookMusic = void function(callbackVUi8I,void*);
279         alias pMix_HookMusicFinished = void function(callbackN);
280         alias pMix_GetMusicHookData = void* function();
281         alias pMix_ChannelFinished = void function(callbackI);
282         alias pMix_RegisterEffect = int function(int,Mix_EffectFunc_t,Mix_EffectDone_t,void*);
283         alias pMix_UnregisterEffect = int function(int,Mix_EffectFunc_t);
284         alias pMix_UnregisterAllEffects = int function(int);
285         alias pMix_SetPanning = int function(int,ubyte,ubyte);
286         alias pMix_SetPosition = int function(int,short,ubyte);
287         alias pMix_SetDistance = int function(int,ubyte);
288         alias pMix_SetReverseStereo = int function(int,int);
289         alias pMix_ReserveChannels = int function(int);
290         alias pMix_GroupChannel = int function(int,int);
291         alias pMix_GroupChannels = int function(int,int,int);
292         alias pMix_GroupAvailable = int function(int);
293         alias pMix_GroupCount = int function(int);
294         alias pMix_GroupOldest = int function(int);
295         alias pMix_GroupNewer = int function(int);
296         alias pMix_PlayChannelTimed = int function(int,Mix_Chunk*,int,int);
297         alias pMix_PlayMusic = int function(Mix_Music*,int);
298         alias pMix_FadeInMusic = int function(Mix_Music*,int,int);
299         alias pMix_FadeInMusicPos = int function(Mix_Music*,int,int,double);
300         alias pMix_FadeInChannelTimed = int function(int,Mix_Chunk*,int,int,int);
301         alias pMix_Volume = int function(int,int);
302         alias pMix_VolumeChunk = int function(Mix_Chunk*,int);
303         alias pMix_VolumeMusic = int function(int);
304         alias pMix_HaltChannel = int function(int);
305         alias pMix_HaltGroup = int function(int);
306         alias pMix_HaltMusic = int function();
307         alias pMix_ExpireChannel = int function(int,int);
308         alias pMix_FadeOutChannel = int function(int,int);
309         alias pMix_FadeOutGroup = int function(int,int);
310         alias pMix_FadeOutMusic = int function(int);
311         alias pMix_FadingMusic = Mix_Fading function();
312         alias pMix_FadingChannel = Mix_Fading function(int);
313         alias pMix_Pause = void function(int);
314         alias pMix_Resume = void function(int);
315         alias pMix_Paused = int function(int);
316         alias pMix_PauseMusic = void function();
317         alias pMix_ResumeMusic = void function();
318         alias pMix_RewindMusic = void function();
319         alias pMix_PausedMusic = int function();
320         alias pMix_SetMusicPosition = int function(double);
321         alias pMix_Playing = int function(int);
322         alias pMix_PlayingMusic = int function();
323         alias pMix_SetMusicCMD = int function(in char*);
324         alias pMix_SetSynchroValue = int function(int);
325         alias pMix_GetSynchroValue = int function();
326         alias pMix_GetChunk = Mix_Chunk* function(int);
327         alias pMix_CloseAudio = void function();
328     }
329 
330     __gshared {
331         pMix_Linked_Version Mix_Linked_Version;
332         pMix_Init Mix_Init;
333         pMix_Quit Mix_Quit;
334         pMix_OpenAudio Mix_OpenAudio;
335         pMix_AllocateChannels Mix_AllocateChannels;
336         pMix_QuerySpec Mix_QuerySpec;
337         pMix_LoadWAV_RW Mix_LoadWAV_RW;
338         pMix_LoadMUS Mix_LoadMUS;
339         pMix_LoadMUS_RW Mix_LoadMUS_RW;
340         pMix_LoadMUSType_RW Mix_LoadMUSType_RW;
341         pMix_QuickLoad_WAV Mix_QuickLoad_WAV;
342         pMix_QuickLoad_RAW Mix_QuickLoad_RAW;
343         pMix_FreeChunk Mix_FreeChunk;
344         pMix_FreeMusic Mix_FreeMusic;
345         pMix_GetNumChunkDecoders Mix_GetNumChunkDecoders;
346         pMix_GetChunkDecoder Mix_GetChunkDecoder;
347         pMix_GetNumMusicDecoders Mix_GetNumMusicDecoders;
348         pMix_GetMusicDecoder Mix_GetMusicDecoder;
349         pMix_GetMusicType Mix_GetMusicType;
350         pMix_SetPostMix Mix_SetPostMix;
351         pMix_HookMusic Mix_HookMusic;
352         pMix_HookMusicFinished Mix_HookMusicFinished;
353         pMix_GetMusicHookData Mix_GetMusicHookData;
354         pMix_ChannelFinished Mix_ChannelFinished;
355         pMix_RegisterEffect Mix_RegisterEffect;
356         pMix_UnregisterEffect Mix_UnregisterEffect;
357         pMix_UnregisterAllEffects Mix_UnregisterAllEffects;
358         pMix_SetPanning Mix_SetPanning;
359         pMix_SetPosition Mix_SetPosition;
360         pMix_SetDistance Mix_SetDistance;
361         pMix_SetReverseStereo Mix_SetReverseStereo;
362         pMix_ReserveChannels Mix_ReserveChannels;
363         pMix_GroupChannel Mix_GroupChannel;
364         pMix_GroupChannels Mix_GroupChannels;
365         pMix_GroupAvailable Mix_GroupAvailable;
366         pMix_GroupCount Mix_GroupCount;
367         pMix_GroupOldest Mix_GroupOldest;
368         pMix_GroupNewer Mix_GroupNewer;
369         pMix_PlayChannelTimed Mix_PlayChannelTimed;
370         pMix_PlayMusic Mix_PlayMusic;
371         pMix_FadeInMusic Mix_FadeInMusic;
372         pMix_FadeInMusicPos Mix_FadeInMusicPos;
373         pMix_FadeInChannelTimed Mix_FadeInChannelTimed;
374         pMix_Volume Mix_Volume;
375         pMix_VolumeChunk Mix_VolumeChunk;
376         pMix_VolumeMusic Mix_VolumeMusic;
377         pMix_HaltChannel Mix_HaltChannel;
378         pMix_HaltGroup Mix_HaltGroup;
379         pMix_HaltMusic Mix_HaltMusic;
380         pMix_ExpireChannel Mix_ExpireChannel;
381         pMix_FadeOutChannel Mix_FadeOutChannel;
382         pMix_FadeOutGroup Mix_FadeOutGroup;
383         pMix_FadeOutMusic Mix_FadeOutMusic;
384         pMix_FadingMusic Mix_FadingMusic;
385         pMix_FadingChannel Mix_FadingChannel;
386         pMix_Pause Mix_Pause;
387         pMix_Resume Mix_Resume;
388         pMix_Paused Mix_Paused;
389         pMix_PauseMusic Mix_PauseMusic;
390         pMix_ResumeMusic Mix_ResumeMusic;
391         pMix_RewindMusic Mix_RewindMusic;
392         pMix_PausedMusic Mix_PausedMusic;
393         pMix_SetMusicPosition Mix_SetMusicPosition;
394         pMix_Playing Mix_Playing;
395         pMix_PlayingMusic Mix_PlayingMusic;
396         pMix_SetMusicCMD Mix_SetMusicCMD;
397         pMix_SetSynchroValue Mix_SetSynchroValue;
398         pMix_GetSynchroValue Mix_GetSynchroValue;
399         pMix_GetChunk Mix_GetChunk;
400         pMix_CloseAudio Mix_CloseAudio;
401     }
402 
403 
404     static if(sdlMixerSupport >= SDLMixerSupport.sdlMixer202) {
405         extern(C) @nogc nothrow {
406             alias pMix_OpenAudioDevice = int function(int,ushort,int,int,const(char)*,int);
407             alias pMix_HasChunkDecoder = SDL_bool function(const(char)*);
408 
409             // Declared in SDL_mixer.h, but not implemented
410             //alias pMix_HasMusicDecoder = SDL_bool function(const(char)*);
411         }
412 
413         __gshared {
414             pMix_OpenAudioDevice Mix_OpenAudioDevice;
415             pMix_HasChunkDecoder Mix_HasChunkDecoder;
416             //pMix_HasMusicDecoder Mix_HasMusicDecoder;
417         }
418     }
419 
420     private {
421         SharedLib lib;
422         SDLMixerSupport loadedVersion;
423     }
424 
425     void unloadSDLMixer()
426     {
427         if(lib != invalidHandle) {
428             lib.unload();
429         }
430     }
431 
432     SDLMixerSupport loadedSDLMixerVersion() { return loadedVersion; }
433 
434     bool isSDLMixerLoaded()
435     {
436         return  lib != invalidHandle;
437     }
438 
439 
440     SDLMixerSupport loadSDLMixer()
441     {
442         version(Windows) {
443             const(char)[][1] libNames = ["SDL2_mixer.dll"];
444         }
445         else version(OSX) {
446             const(char)[][6] libNames = [
447                 "libSDL2_mixer.dylib",
448                 "/usr/local/lib/libSDL2_mixer.dylib",
449                 "../Frameworks/SDL2_mixer.framework/SDL2_mixer",
450                 "/Library/Frameworks/SDL2_mixer.framework/SDL2_mixer",
451                 "/System/Library/Frameworks/SDL2_mixer.framework/SDL2_mixer",
452                 "/opt/local/lib/libSDL2_mixer.dylib"
453             ];
454         }
455         else version(Posix) {
456             const(char)[][6] libNames = [
457                 "libSDL2_mixer.so",
458                 "/usr/local/lib/libSDL2_mixer.so",
459                 "libSDL2-2.0_mixer.so",
460                 "/usr/local/lib/libSDL2-2.0_mixer.so",
461                 "libSDL2-2.0_mixer.so.0",
462                 "/usr/local/lib/libSDL2-2.0_mixer.so.0"
463             ];
464         }
465         else static assert(0, "bindbc-sdl is not yet supported on this platform.");
466 
467         SDLMixerSupport ret;
468         foreach(name; libNames) {
469             ret = loadSDLMixer(name.ptr);
470             if(ret != SDLMixerSupport.noLibrary) break;
471         }
472         return ret;
473     }
474 
475     SDLMixerSupport loadSDLMixer(const(char)* libName)
476     {
477         lib = load(libName);
478         if(lib == invalidHandle) {
479             return SDLMixerSupport.noLibrary;
480         }
481 
482         auto errCount = errorCount();
483         loadedVersion = SDLMixerSupport.badLibrary;
484 
485         lib.bindSymbol(cast(void**)&Mix_Linked_Version,"Mix_Linked_Version");
486         lib.bindSymbol(cast(void**)&Mix_Init,"Mix_Init");
487         lib.bindSymbol(cast(void**)&Mix_Quit,"Mix_Quit");
488         lib.bindSymbol(cast(void**)&Mix_OpenAudio,"Mix_OpenAudio");
489         lib.bindSymbol(cast(void**)&Mix_AllocateChannels,"Mix_AllocateChannels");
490         lib.bindSymbol(cast(void**)&Mix_QuerySpec,"Mix_QuerySpec");
491         lib.bindSymbol(cast(void**)&Mix_LoadWAV_RW,"Mix_LoadWAV_RW");
492         lib.bindSymbol(cast(void**)&Mix_LoadMUS,"Mix_LoadMUS");
493         lib.bindSymbol(cast(void**)&Mix_LoadMUS_RW,"Mix_LoadMUS_RW");
494         lib.bindSymbol(cast(void**)&Mix_LoadMUSType_RW,"Mix_LoadMUSType_RW");
495         lib.bindSymbol(cast(void**)&Mix_QuickLoad_WAV,"Mix_QuickLoad_WAV");
496         lib.bindSymbol(cast(void**)&Mix_QuickLoad_RAW,"Mix_QuickLoad_RAW");
497         lib.bindSymbol(cast(void**)&Mix_FreeChunk,"Mix_FreeChunk");
498         lib.bindSymbol(cast(void**)&Mix_FreeMusic,"Mix_FreeMusic");
499         lib.bindSymbol(cast(void**)&Mix_GetNumChunkDecoders,"Mix_GetNumChunkDecoders");
500         lib.bindSymbol(cast(void**)&Mix_GetChunkDecoder,"Mix_GetChunkDecoder");
501         lib.bindSymbol(cast(void**)&Mix_GetNumMusicDecoders,"Mix_GetNumMusicDecoders");
502         lib.bindSymbol(cast(void**)&Mix_GetMusicDecoder,"Mix_GetMusicDecoder");
503         lib.bindSymbol(cast(void**)&Mix_GetMusicType,"Mix_GetMusicType");
504         lib.bindSymbol(cast(void**)&Mix_SetPostMix,"Mix_SetPostMix");
505         lib.bindSymbol(cast(void**)&Mix_HookMusic,"Mix_HookMusic");
506         lib.bindSymbol(cast(void**)&Mix_HookMusicFinished,"Mix_HookMusicFinished");
507         lib.bindSymbol(cast(void**)&Mix_GetMusicHookData,"Mix_GetMusicHookData");
508         lib.bindSymbol(cast(void**)&Mix_ChannelFinished,"Mix_ChannelFinished");
509         lib.bindSymbol(cast(void**)&Mix_RegisterEffect,"Mix_RegisterEffect");
510         lib.bindSymbol(cast(void**)&Mix_UnregisterEffect,"Mix_UnregisterEffect");
511         lib.bindSymbol(cast(void**)&Mix_UnregisterAllEffects,"Mix_UnregisterAllEffects");
512         lib.bindSymbol(cast(void**)&Mix_SetPanning,"Mix_SetPanning");
513         lib.bindSymbol(cast(void**)&Mix_SetPosition,"Mix_SetPosition");
514         lib.bindSymbol(cast(void**)&Mix_SetDistance,"Mix_SetDistance");
515         lib.bindSymbol(cast(void**)&Mix_SetReverseStereo,"Mix_SetReverseStereo");
516         lib.bindSymbol(cast(void**)&Mix_ReserveChannels,"Mix_ReserveChannels");
517         lib.bindSymbol(cast(void**)&Mix_GroupChannel,"Mix_GroupChannel");
518         lib.bindSymbol(cast(void**)&Mix_GroupChannels,"Mix_GroupChannels");
519         lib.bindSymbol(cast(void**)&Mix_GroupAvailable,"Mix_GroupAvailable");
520         lib.bindSymbol(cast(void**)&Mix_GroupCount,"Mix_GroupCount");
521         lib.bindSymbol(cast(void**)&Mix_GroupOldest,"Mix_GroupOldest");
522         lib.bindSymbol(cast(void**)&Mix_GroupNewer,"Mix_GroupNewer");
523         lib.bindSymbol(cast(void**)&Mix_PlayChannelTimed,"Mix_PlayChannelTimed");
524         lib.bindSymbol(cast(void**)&Mix_PlayMusic,"Mix_PlayMusic");
525         lib.bindSymbol(cast(void**)&Mix_FadeInMusic,"Mix_FadeInMusic");
526         lib.bindSymbol(cast(void**)&Mix_FadeInMusicPos,"Mix_FadeInMusicPos");
527         lib.bindSymbol(cast(void**)&Mix_FadeInChannelTimed,"Mix_FadeInChannelTimed");
528         lib.bindSymbol(cast(void**)&Mix_Volume,"Mix_Volume");
529         lib.bindSymbol(cast(void**)&Mix_VolumeChunk,"Mix_VolumeChunk");
530         lib.bindSymbol(cast(void**)&Mix_VolumeMusic,"Mix_VolumeMusic");
531         lib.bindSymbol(cast(void**)&Mix_HaltChannel,"Mix_HaltChannel");
532         lib.bindSymbol(cast(void**)&Mix_HaltGroup,"Mix_HaltGroup");
533         lib.bindSymbol(cast(void**)&Mix_HaltMusic,"Mix_HaltMusic");
534         lib.bindSymbol(cast(void**)&Mix_ExpireChannel,"Mix_ExpireChannel");
535         lib.bindSymbol(cast(void**)&Mix_FadeOutChannel,"Mix_FadeOutChannel");
536         lib.bindSymbol(cast(void**)&Mix_FadeOutGroup,"Mix_FadeOutGroup");
537         lib.bindSymbol(cast(void**)&Mix_FadeOutMusic,"Mix_FadeOutMusic");
538         lib.bindSymbol(cast(void**)&Mix_FadingMusic,"Mix_FadingMusic");
539         lib.bindSymbol(cast(void**)&Mix_FadingChannel,"Mix_FadingChannel");
540         lib.bindSymbol(cast(void**)&Mix_Pause,"Mix_Pause");
541         lib.bindSymbol(cast(void**)&Mix_Resume,"Mix_Resume");
542         lib.bindSymbol(cast(void**)&Mix_Paused,"Mix_Paused");
543         lib.bindSymbol(cast(void**)&Mix_PauseMusic,"Mix_PauseMusic");
544         lib.bindSymbol(cast(void**)&Mix_ResumeMusic,"Mix_ResumeMusic");
545         lib.bindSymbol(cast(void**)&Mix_RewindMusic,"Mix_RewindMusic");
546         lib.bindSymbol(cast(void**)&Mix_PausedMusic,"Mix_PausedMusic");
547         lib.bindSymbol(cast(void**)&Mix_SetMusicPosition,"Mix_SetMusicPosition");
548         lib.bindSymbol(cast(void**)&Mix_Playing,"Mix_Playing");
549         lib.bindSymbol(cast(void**)&Mix_PlayingMusic,"Mix_PlayingMusic");
550         lib.bindSymbol(cast(void**)&Mix_SetMusicCMD,"Mix_SetMusicCMD");
551         lib.bindSymbol(cast(void**)&Mix_SetSynchroValue,"Mix_SetSynchroValue");
552         lib.bindSymbol(cast(void**)&Mix_GetSynchroValue,"Mix_GetSynchroValue");
553         lib.bindSymbol(cast(void**)&Mix_GetChunk,"Mix_GetChunk");
554         lib.bindSymbol(cast(void**)&Mix_CloseAudio,"Mix_CloseAudio");
555 
556         if(errorCount() != errCount) return SDLMixerSupport.badLibrary;
557         else loadedVersion = SDLMixerSupport.sdlMixer200;
558 
559         static if(sdlMixerSupport >= SDLMixerSupport.sdlMixer202) {
560             lib.bindSymbol(cast(void**)&Mix_OpenAudioDevice,"Mix_OpenAudioDevice");
561             lib.bindSymbol(cast(void**)&Mix_HasChunkDecoder,"Mix_HasChunkDecoder");
562 
563             if(errorCount() != errCount) return SDLMixerSupport.badLibrary;
564             else loadedVersion = SDLMixerSupport.sdlMixer202;
565         }
566 
567         return loadedVersion;
568     }
569 }