1 /*
2 
3 Boost Software License - Version 1.0 - August 17th, 2003
4 
5 Permission is hereby granted, free of charge, to any person or organization
6 obtaining a copy of the software and accompanying documentation covered by
7 this license (the "Software") to use, reproduce, display, distribute,
8 execute, and transmit the Software, and to prepare derivative works of the
9 Software, and to permit third-parties to whom the Software is furnished to
10 do so, all subject to the following:
11 
12 The copyright notices in the Software and this entire statement, including
13 the above license grant, this restriction and the following disclaimer,
14 must be included in all copies of the Software, in whole or in part, and
15 all derivative works of the Software, unless such copies or derivative
16 works are solely in the form of machine-executable object code generated by
17 a source language processor.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
22 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
23 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
24 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 DEALINGS IN THE SOFTWARE.
26 
27 */
28 module derelict.sdl.mixer;
29 
30 private
31 {
32     import derelict.util.loader;
33     import derelict.util.exception;
34     import derelict.util.compat;
35     import derelict.sdl.sdl;
36 }
37 
38 enum : Uint8
39 {
40     SDL_MIXER_MAJOR_VERSION     = 1,
41     SDL_MIXER_MINOR_VERSION     = 2,
42     SDL_MIXER_PATCHLEVEL        = 12,
43 }
44 alias SDL_MIXER_MAJOR_VERSION MIX_MAJOR_VERSION;
45 alias SDL_MIXER_MINOR_VERSION MIX_MINOR_VERSION;
46 alias SDL_MIXER_PATCHLEVEL MIX_PATCH_LEVEL;
47 
48 alias SDL_SetError Mix_SetError;
49 alias SDL_GetError Mix_GetError;
50 
51 alias int MIX_InitFlags;
52 enum : int
53 {
54     MIX_INIT_FLAC = 0x00000001,
55     MIX_INIT_MOD = 0x00000002,
56     MIX_INIT_MP3 = 0x00000004,
57     MIX_INIT_OGG = 0x00000008,
58 }
59 
60 struct Mix_Chunk
61 {
62    int allocated;
63    Uint8* abuf;
64    Uint32 alen;
65    Uint8 volume;
66 };
67 
68 alias int Mix_Fading;
69 enum : int
70 {
71    MIX_NO_FADING,
72    MIX_FADING_OUT,
73    MIX_FADING_IN
74 };
75 
76 alias int Mix_MusicType;
77 enum : int
78 {
79    MUS_NONE,
80    MUS_CMD,
81    MUS_WAV,
82    MUS_MOD,
83    MUS_MID,
84    MUS_OGG,
85    MUS_MP3,
86    MUS_MP3_MAD,
87    MUS_FLAC,
88    MUS_MODPLUG,
89 };
90 
91 struct _Mix_Music {}
92 alias _Mix_Music Mix_Music;
93 
94 enum
95 {
96     MIX_CHANNELS              = 8,
97     MIX_DEFAULT_FREQUENCY     = 22050,
98     MIX_DEFAULT_CHANNELS      = 2,
99     MIX_MAX_VOLUME            = 128,
100     MIX_CHANNEL_POST          = -2,
101 }
102 
103 version (LittleEndian) {
104     enum { MIX_DEFAULT_FORMAT = AUDIO_S16LSB }
105 } else {
106     enum { MIX_DEFAULT_FORMAT = AUDIO_S16MSB }
107 }
108 
109 string MIX_EFFECTSMAXSPEED = "MIX_EFFECTSMAXSPEED";
110 
111 extern(C)
112 {
113     alias void function(int chan, void* stream, int len, void* udata) Mix_EffectFunc_t;
114     alias void function(int chan, void* udata) Mix_EffectDone_t;
115 }
116 
117 void SDL_MIXER_VERSION(SDL_version* X)
118 {
119     X.major = SDL_MIXER_MAJOR_VERSION;
120     X.minor = SDL_MIXER_MINOR_VERSION;
121     X.patch = SDL_MIXER_PATCHLEVEL;
122 }
123 alias SDL_MIXER_VERSION MIX_VERSION;
124 
125 
126 Mix_Chunk* Mix_LoadWAV(string file)
127 {
128     return Mix_LoadWAV_RW(SDL_RWFromFile(toCString(file), toCString("rb")), 1);
129 }
130 
131 int Mix_PlayChannel(int channel, Mix_Chunk* chunk, int loops)
132 {
133     return Mix_PlayChannelTimed(channel, chunk, loops, -1);
134 }
135 
136 int Mix_FadeInChannel(int channel, Mix_Chunk* chunk, int loops, int ms)
137 {
138     return Mix_FadeInChannelTimed(channel, chunk, loops, ms, -1);
139 }
140 
141 extern (C)
142 {
143     alias CSDLVERPTR function() da_Mix_Linked_Version;
144     alias int function(int) da_Mix_Init;
145     alias void function() da_Mix_Quit;
146     alias int function (int, Uint16, int, int) da_Mix_OpenAudio;
147     alias int function(int) da_Mix_AllocateChannels;
148     alias int function(int*, Uint16*, int*) da_Mix_QuerySpec;
149     alias Mix_Chunk* function(SDL_RWops*, int) da_Mix_LoadWAV_RW;
150     alias Mix_Music* function(in char*) da_Mix_LoadMUS;
151     alias Mix_Music* function(SDL_RWops*) da_Mix_LoadMUS_RW;
152     alias Mix_Music* function(SDL_RWops*, Mix_MusicType, int) da_Mix_LoadMUSType_RW;
153     alias Mix_Chunk* function(Uint8*) da_Mix_QuickLoad_WAV;
154     alias Mix_Chunk* function(Uint8*, Uint32) da_Mix_QuickLoad_RAW;
155     alias void function(Mix_Chunk*) da_Mix_FreeChunk;
156     alias void function(Mix_Music*) da_Mix_FreeMusic;
157     alias int function() da_Mix_GetNumChunkDecoders;
158     alias CCPTR function(int) da_Mix_GetChunkDecoder;
159     alias int function() da_Mix_GetNumMusicDecoders;
160     alias CCPTR function(int) da_Mix_GetMusicDecoder;
161     alias Mix_MusicType function(in Mix_Music*) da_Mix_GetMusicType;
162     alias void function(void function(void*, Uint8*, int) da_Mix_func, void*) da_Mix_SetPostMix;
163     alias void function(void function(void*, Uint8*, int) da_Mix_func, void*) da_Mix_HookMusic;
164     alias void function(void function() music_finished) da_Mix_HookMusicFinished;
165     alias void*  function() da_Mix_GetMusicHookData;
166     alias void function(void function(int channel) channel_finished) da_Mix_ChannelFinished;
167     alias int function(int, Mix_EffectFunc_t, Mix_EffectDone_t, void*) da_Mix_RegisterEffect;
168     alias int function(int, Mix_EffectFunc_t) da_Mix_UnregisterEffect;
169     alias int function(int) da_Mix_UnregisterAllEffects;
170     alias int function(int, Uint8, Uint8) da_Mix_SetPanning;
171     alias int function(int, Sint16, Uint8) da_Mix_SetPosition;
172     alias int function(int, Uint8) da_Mix_SetDistance;
173     // alias int function(int, Uint8) da_Mix_SetReverb;
174     alias int function(int, int) da_Mix_SetReverseStereo;
175     alias int function(int) da_Mix_ReserveChannels;
176     alias int function(int, int) da_Mix_GroupChannel;
177     alias int function(int, int, int) da_Mix_GroupChannels;
178     alias int function(int) da_Mix_GroupAvailable;
179     alias int function(int) da_Mix_GroupCount;
180     alias int function(int) da_Mix_GroupOldest;
181     alias int function(int) da_Mix_GroupNewer;
182     alias int function(int, Mix_Chunk*, int, int) da_Mix_PlayChannelTimed;
183     alias int function(Mix_Music*, int) da_Mix_PlayMusic;
184     alias int function(Mix_Music*, int, int) da_Mix_FadeInMusic;
185     alias int function(Mix_Music*, int, int, double) da_Mix_FadeInMusicPos;
186     alias int function(int, Mix_Chunk*, int, int, int) da_Mix_FadeInChannelTimed;
187     alias int function(int, int) da_Mix_Volume;
188     alias int function(Mix_Chunk*, int) da_Mix_VolumeChunk;
189     alias int function(int) da_Mix_VolumeMusic;
190     alias int function(int) da_Mix_HaltChannel;
191     alias int function(int) da_Mix_HaltGroup;
192     alias int function() da_Mix_HaltMusic;
193     alias int function(int, int) da_Mix_ExpireChannel;
194     alias int function(int, int) da_Mix_FadeOutChannel;
195     alias int function(int, int) da_Mix_FadeOutGroup;
196     alias int function(int) da_Mix_FadeOutMusic;
197     alias Mix_Fading function() da_Mix_FadingMusic;
198     alias Mix_Fading function(int) da_Mix_FadingChannel;
199     alias void function(int) da_Mix_Pause;
200     alias void function(int) da_Mix_Resume;
201     alias int function(int) da_Mix_Paused;
202     alias void function() da_Mix_PauseMusic;
203     alias void function() da_Mix_ResumeMusic;
204     alias void function() da_Mix_RewindMusic;
205     alias int function() da_Mix_PausedMusic;
206     alias int function(double) da_Mix_SetMusicPosition;
207     alias int function(int) da_Mix_Playing;
208     alias int function() da_Mix_PlayingMusic;
209     alias int function(in char*) da_Mix_SetMusicCMD;
210     alias int function(int) da_Mix_SetSynchroValue;
211     alias int function() da_Mix_GetSynchroValue;
212     alias Mix_Chunk* function(int) da_Mix_GetChunk;
213     alias void function() da_Mix_CloseAudio;
214 }
215 
216 mixin(gsharedString!() ~
217 "
218 da_Mix_Linked_Version Mix_Linked_Version;
219 da_Mix_Init Mix_Init;
220 da_Mix_Quit Mix_Quit;
221 da_Mix_OpenAudio Mix_OpenAudio;
222 da_Mix_AllocateChannels Mix_AllocateChannels;
223 da_Mix_QuerySpec Mix_QuerySpec;
224 da_Mix_LoadWAV_RW Mix_LoadWAV_RW;
225 da_Mix_LoadMUS Mix_LoadMUS;
226 da_Mix_LoadMUS_RW Mix_LoadMUS_RW;
227 da_Mix_LoadMUSType_RW Mix_LoadMUSType_RW;
228 da_Mix_QuickLoad_WAV Mix_QuickLoad_WAV;
229 da_Mix_QuickLoad_RAW Mix_QuickLoad_RAW;
230 da_Mix_FreeChunk Mix_FreeChunk;
231 da_Mix_FreeMusic Mix_FreeMusic;
232 da_Mix_GetNumChunkDecoders Mix_GetNumChunkDecoders;
233 da_Mix_GetChunkDecoder Mix_GetChunkDecoder;
234 da_Mix_GetNumMusicDecoders Mix_GetNumMusicDecoders;
235 da_Mix_GetMusicDecoder Mix_GetMusicDecoder;
236 da_Mix_GetMusicType Mix_GetMusicType;
237 da_Mix_SetPostMix Mix_SetPostMix;
238 da_Mix_HookMusic Mix_HookMusic;
239 da_Mix_HookMusicFinished Mix_HookMusicFinished;
240 da_Mix_GetMusicHookData Mix_GetMusicHookData;
241 da_Mix_ChannelFinished Mix_ChannelFinished;
242 da_Mix_RegisterEffect Mix_RegisterEffect;
243 da_Mix_UnregisterEffect Mix_UnregisterEffect;
244 da_Mix_UnregisterAllEffects Mix_UnregisterAllEffects;
245 da_Mix_SetPanning Mix_SetPanning;
246 da_Mix_SetPosition Mix_SetPosition;
247 da_Mix_SetDistance Mix_SetDistance;
248 // da_ Mix_SetReverb;
249 da_Mix_SetReverseStereo Mix_SetReverseStereo;
250 da_Mix_ReserveChannels Mix_ReserveChannels;
251 da_Mix_GroupChannel Mix_GroupChannel;
252 da_Mix_GroupChannels Mix_GroupChannels;
253 da_Mix_GroupAvailable Mix_GroupAvailable;
254 da_Mix_GroupCount Mix_GroupCount;
255 da_Mix_GroupOldest Mix_GroupOldest;
256 da_Mix_GroupNewer Mix_GroupNewer;
257 da_Mix_PlayChannelTimed Mix_PlayChannelTimed;
258 da_Mix_PlayMusic Mix_PlayMusic;
259 da_Mix_FadeInMusic Mix_FadeInMusic;
260 da_Mix_FadeInMusicPos Mix_FadeInMusicPos;
261 da_Mix_FadeInChannelTimed Mix_FadeInChannelTimed;
262 da_Mix_Volume Mix_Volume;
263 da_Mix_VolumeChunk Mix_VolumeChunk;
264 da_Mix_VolumeMusic Mix_VolumeMusic;
265 da_Mix_HaltChannel Mix_HaltChannel;
266 da_Mix_HaltGroup Mix_HaltGroup;
267 da_Mix_HaltMusic Mix_HaltMusic;
268 da_Mix_ExpireChannel Mix_ExpireChannel;
269 da_Mix_FadeOutChannel Mix_FadeOutChannel;
270 da_Mix_FadeOutGroup Mix_FadeOutGroup;
271 da_Mix_FadeOutMusic Mix_FadeOutMusic;
272 da_Mix_FadingMusic Mix_FadingMusic;
273 da_Mix_FadingChannel Mix_FadingChannel;
274 da_Mix_Pause Mix_Pause;
275 da_Mix_Resume Mix_Resume;
276 da_Mix_Paused Mix_Paused;
277 da_Mix_PauseMusic Mix_PauseMusic;
278 da_Mix_ResumeMusic Mix_ResumeMusic;
279 da_Mix_RewindMusic Mix_RewindMusic;
280 da_Mix_PausedMusic Mix_PausedMusic;
281 da_Mix_SetMusicPosition Mix_SetMusicPosition;
282 da_Mix_Playing Mix_Playing;
283 da_Mix_PlayingMusic Mix_PlayingMusic;
284 da_Mix_SetMusicCMD Mix_SetMusicCMD;
285 da_Mix_SetSynchroValue Mix_SetSynchroValue;
286 da_Mix_GetSynchroValue Mix_GetSynchroValue;
287 da_Mix_GetChunk Mix_GetChunk;
288 da_Mix_CloseAudio Mix_CloseAudio;
289 ");
290 
291 class DerelictSDLMixerLoader : SharedLibLoader
292 {
293 public:
294     this()
295     {
296         super(
297             "SDL_mixer.dll",
298             "libSDL_mixer.so, libSDL_mixer-1.2.so, libSDL_mixer-1.2.so.0",
299             "../Frameworks/SDL_mixer.framework/SDL_mixer, /Library/Frameworks/SDL_mixer.framework/SDL_mixer, /System/Library/Frameworks/SDL_mixer.framework/SDL_mixer"
300         );
301     }
302 
303 protected:
304     override void loadSymbols()
305     {
306         if(!DerelictSDL.isLoaded)
307         {
308             throw new SharedLibLoadException("DerelictSDL must be loaded before attempting to load DerelictSDLMixer!");
309         }
310 
311         bindFunc(cast(void**)&Mix_Linked_Version, "Mix_Linked_Version");
312         bindFunc(cast(void**)&Mix_Init, "Mix_Init");
313         bindFunc(cast(void**)&Mix_Quit, "Mix_Quit");
314         bindFunc(cast(void**)&Mix_OpenAudio, "Mix_OpenAudio");
315         bindFunc(cast(void**)&Mix_AllocateChannels, "Mix_AllocateChannels");
316         bindFunc(cast(void**)&Mix_QuerySpec, "Mix_QuerySpec");
317         bindFunc(cast(void**)&Mix_LoadWAV_RW, "Mix_LoadWAV_RW");
318         bindFunc(cast(void**)&Mix_LoadMUS, "Mix_LoadMUS");
319         bindFunc(cast(void**)&Mix_LoadMUS_RW, "Mix_LoadMUS_RW");
320         bindFunc(cast(void**)&Mix_LoadMUSType_RW, "Mix_LoadMUSType_RW");
321         bindFunc(cast(void**)&Mix_QuickLoad_WAV, "Mix_QuickLoad_WAV");
322         bindFunc(cast(void**)&Mix_QuickLoad_RAW, "Mix_QuickLoad_RAW");
323         bindFunc(cast(void**)&Mix_FreeChunk, "Mix_FreeChunk");
324         bindFunc(cast(void**)&Mix_FreeMusic, "Mix_FreeMusic");
325         bindFunc(cast(void**)&Mix_GetNumChunkDecoders, "Mix_GetNumChunkDecoders");
326         bindFunc(cast(void**)&Mix_GetChunkDecoder, "Mix_GetChunkDecoder");
327         bindFunc(cast(void**)&Mix_GetNumMusicDecoders, "Mix_GetNumMusicDecoders");
328         bindFunc(cast(void**)&Mix_GetMusicDecoder, "Mix_GetMusicDecoder");
329         bindFunc(cast(void**)&Mix_GetMusicType, "Mix_GetMusicType");
330         bindFunc(cast(void**)&Mix_SetPostMix, "Mix_SetPostMix");
331         bindFunc(cast(void**)&Mix_HookMusic, "Mix_HookMusic");
332         bindFunc(cast(void**)&Mix_HookMusicFinished, "Mix_HookMusicFinished");
333         bindFunc(cast(void**)&Mix_GetMusicHookData, "Mix_GetMusicHookData");
334         bindFunc(cast(void**)&Mix_ChannelFinished, "Mix_ChannelFinished");
335         bindFunc(cast(void**)&Mix_RegisterEffect, "Mix_RegisterEffect");
336         bindFunc(cast(void**)&Mix_UnregisterEffect, "Mix_UnregisterEffect");
337         bindFunc(cast(void**)&Mix_UnregisterAllEffects, "Mix_UnregisterAllEffects");
338         bindFunc(cast(void**)&Mix_SetPanning, "Mix_SetPanning");
339         bindFunc(cast(void**)&Mix_SetPosition, "Mix_SetPosition");
340         bindFunc(cast(void**)&Mix_SetDistance, "Mix_SetDistance");
341         // bindFunc(cast(void**)&Mix_SetReverb, "Mix_SetReverb");
342         bindFunc(cast(void**)&Mix_SetReverseStereo, "Mix_SetReverseStereo");
343         bindFunc(cast(void**)&Mix_ReserveChannels, "Mix_ReserveChannels");
344         bindFunc(cast(void**)&Mix_GroupChannel, "Mix_GroupChannel");
345         bindFunc(cast(void**)&Mix_GroupChannels, "Mix_GroupChannels");
346         bindFunc(cast(void**)&Mix_GroupAvailable, "Mix_GroupAvailable");
347         bindFunc(cast(void**)&Mix_GroupCount, "Mix_GroupCount");
348         bindFunc(cast(void**)&Mix_GroupOldest, "Mix_GroupOldest");
349         bindFunc(cast(void**)&Mix_GroupNewer, "Mix_GroupNewer");
350         bindFunc(cast(void**)&Mix_PlayChannelTimed, "Mix_PlayChannelTimed");
351         bindFunc(cast(void**)&Mix_PlayMusic, "Mix_PlayMusic");
352         bindFunc(cast(void**)&Mix_FadeInMusic, "Mix_FadeInMusic");
353         bindFunc(cast(void**)&Mix_FadeInMusicPos, "Mix_FadeInMusicPos");
354         bindFunc(cast(void**)&Mix_FadeInChannelTimed, "Mix_FadeInChannelTimed");
355         bindFunc(cast(void**)&Mix_Volume, "Mix_Volume");
356         bindFunc(cast(void**)&Mix_VolumeChunk, "Mix_VolumeChunk");
357         bindFunc(cast(void**)&Mix_VolumeMusic, "Mix_VolumeMusic");
358         bindFunc(cast(void**)&Mix_HaltChannel, "Mix_HaltChannel");
359         bindFunc(cast(void**)&Mix_HaltGroup, "Mix_HaltGroup");
360         bindFunc(cast(void**)&Mix_HaltMusic, "Mix_HaltMusic");
361         bindFunc(cast(void**)&Mix_ExpireChannel, "Mix_ExpireChannel");
362         bindFunc(cast(void**)&Mix_FadeOutChannel, "Mix_FadeOutChannel");
363         bindFunc(cast(void**)&Mix_FadeOutGroup, "Mix_FadeOutGroup");
364         bindFunc(cast(void**)&Mix_FadeOutMusic, "Mix_FadeOutMusic");
365         bindFunc(cast(void**)&Mix_FadingMusic, "Mix_FadingMusic");
366         bindFunc(cast(void**)&Mix_FadingChannel, "Mix_FadingChannel");
367         bindFunc(cast(void**)&Mix_Pause, "Mix_Pause");
368         bindFunc(cast(void**)&Mix_Resume, "Mix_Resume");
369         bindFunc(cast(void**)&Mix_Paused, "Mix_Paused");
370         bindFunc(cast(void**)&Mix_PauseMusic, "Mix_PauseMusic");
371         bindFunc(cast(void**)&Mix_ResumeMusic, "Mix_ResumeMusic");
372         bindFunc(cast(void**)&Mix_RewindMusic, "Mix_RewindMusic");
373         bindFunc(cast(void**)&Mix_PausedMusic, "Mix_PausedMusic");
374         bindFunc(cast(void**)&Mix_SetMusicPosition, "Mix_SetMusicPosition");
375         bindFunc(cast(void**)&Mix_Playing, "Mix_Playing");
376         bindFunc(cast(void**)&Mix_PlayingMusic, "Mix_PlayingMusic");
377         bindFunc(cast(void**)&Mix_SetMusicCMD, "Mix_SetMusicCMD");
378         bindFunc(cast(void**)&Mix_SetSynchroValue, "Mix_SetSynchroValue");
379         bindFunc(cast(void**)&Mix_GetSynchroValue, "Mix_GetSynchroValue");
380         bindFunc(cast(void**)&Mix_GetChunk, "Mix_GetChunk");
381         bindFunc(cast(void**)&Mix_CloseAudio, "Mix_CloseAudio");
382     }
383 }
384 
385 DerelictSDLMixerLoader DerelictSDLMixer;
386 
387 static this()
388 {
389     DerelictSDLMixer = new DerelictSDLMixerLoader();
390 }
391 
392 static ~this()
393 {
394     if(SharedLibLoader.isAutoUnloadEnabled())
395         DerelictSDLMixer.unload();
396 }