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        = 11,
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 };
89 
90 struct _Mix_Music {}
91 alias _Mix_Music Mix_Music;
92 
93 enum
94 {
95     MIX_CHANNELS              = 8,
96     MIX_DEFAULT_FREQUENCY     = 22050,
97     MIX_DEFAULT_CHANNELS      = 2,
98     MIX_MAX_VOLUME            = 128,
99     MIX_CHANNEL_POST          = -2,
100 }
101 
102 version (LittleEndian) {
103     enum { MIX_DEFAULT_FORMAT = AUDIO_S16LSB }
104 } else {
105     enum { MIX_DEFAULT_FORMAT = AUDIO_S16MSB }
106 }
107 
108 string MIX_EFFECTSMAXSPEED = "MIX_EFFECTSMAXSPEED";
109 
110 extern(C)
111 {
112     alias void function(int chan, void* stream, int len, void* udata) Mix_EffectFunc_t;
113     alias void function(int chan, void* udata) Mix_EffectDone_t;
114 }
115 
116 void SDL_MIXER_VERSION(SDL_version* X)
117 {
118     X.major = SDL_MIXER_MAJOR_VERSION;
119     X.minor = SDL_MIXER_MINOR_VERSION;
120     X.patch = SDL_MIXER_PATCHLEVEL;
121 }
122 alias SDL_MIXER_VERSION MIX_VERSION;
123 
124 
125 Mix_Chunk* Mix_LoadWAV(string file)
126 {
127     return Mix_LoadWAV_RW(SDL_RWFromFile(toCString(file), toCString("rb")), 1);
128 }
129 
130 int Mix_PlayChannel(int channel, Mix_Chunk* chunk, int loops)
131 {
132     return Mix_PlayChannelTimed(channel, chunk, loops, -1);
133 }
134 
135 int Mix_FadeInChannel(int channel, Mix_Chunk* chunk, int loops, int ms)
136 {
137     return Mix_FadeInChannelTimed(channel, chunk, loops, ms, -1);
138 }
139 
140 extern (C)
141 {
142     alias CSDLVERPTR function() da_Mix_Linked_Version;
143     alias int function(int) da_Mix_Init;
144     alias void function() da_Mix_Quit;
145     alias int function (int, Uint16, int, int) da_Mix_OpenAudio;
146     alias int function(int) da_Mix_AllocateChannels;
147     alias int function(int*, Uint16*, int*) da_Mix_QuerySpec;
148     alias Mix_Chunk* function(SDL_RWops*, int) da_Mix_LoadWAV_RW;
149     alias Mix_Music* function(in char*) da_Mix_LoadMUS;
150     alias Mix_Music* function(SDL_RWops*) da_Mix_LoadMUS_RW;
151     alias Mix_Chunk* function(Uint8*) da_Mix_QuickLoad_WAV;
152     alias Mix_Chunk* function(Uint8*, Uint32) da_Mix_QuickLoad_RAW;
153     alias void function(Mix_Chunk*) da_Mix_FreeChunk;
154     alias void function(Mix_Music*) da_Mix_FreeMusic;
155     alias int function() da_Mix_GetNumChunkDecoders;
156     alias CCPTR function(int) da_Mix_GetChunkDecoder;
157     alias int function() da_Mix_GetNumMusicDecoders;
158     alias CCPTR function() da_Mix_GetMusicDecoder;
159     alias Mix_MusicType function(in Mix_Music*) da_Mix_GetMusicType;
160     alias void function(void function(void*, Uint8*, int) da_Mix_func, void*) da_Mix_SetPostMix;
161     alias void function(void function(void*, Uint8*, int) da_Mix_func, void*) da_Mix_HookMusic;
162     alias void function(void function() music_finished) da_Mix_HookMusicFinished;
163     alias void*  function() da_Mix_GetMusicHookData;
164     alias void function(void function(int channel) channel_finished) da_Mix_ChannelFinished;
165     alias int function(int, Mix_EffectFunc_t, Mix_EffectDone_t, void*) da_Mix_RegisterEffect;
166     alias int function(int, Mix_EffectFunc_t) da_Mix_UnregisterEffect;
167     alias int function(int) da_Mix_UnregisterAllEffects;
168     alias int function(int, Uint8, Uint8) da_Mix_SetPanning;
169     alias int function(int, Sint16, Uint8) da_Mix_SetPosition;
170     alias int function(int, Uint8) da_Mix_SetDistance;
171     // alias int function(int, Uint8) da_Mix_SetReverb;
172     alias int function(int, int) da_Mix_SetReverseStereo;
173     alias int function(int) da_Mix_ReserveChannels;
174     alias int function(int, int) da_Mix_GroupChannel;
175     alias int function(int, int, int) da_Mix_GroupChannels;
176     alias int function(int) da_Mix_GroupAvailable;
177     alias int function(int) da_Mix_GroupCount;
178     alias int function(int) da_Mix_GroupOldest;
179     alias int function(int) da_Mix_GroupNewer;
180     alias int function(int, Mix_Chunk*, int, int) da_Mix_PlayChannelTimed;
181     alias int function(Mix_Music*, int) da_Mix_PlayMusic;
182     alias int function(Mix_Music*, int, int) da_Mix_FadeInMusic;
183     alias int function(Mix_Music*, int, int, double) da_Mix_FadeInMusicPos;
184     alias int function(int, Mix_Chunk*, int, int, int) da_Mix_FadeInChannelTimed;
185     alias int function(int, int) da_Mix_Volume;
186     alias int function(Mix_Chunk*, int) da_Mix_VolumeChunk;
187     alias int function(int) da_Mix_VolumeMusic;
188     alias int function(int) da_Mix_HaltChannel;
189     alias int function(int) da_Mix_HaltGroup;
190     alias int function() da_Mix_HaltMusic;
191     alias int function(int, int) da_Mix_ExpireChannel;
192     alias int function(int, int) da_Mix_FadeOutChannel;
193     alias int function(int, int) da_Mix_FadeOutGroup;
194     alias int function(int) da_Mix_FadeOutMusic;
195     alias Mix_Fading function() da_Mix_FadingMusic;
196     alias Mix_Fading function(int) da_Mix_FadingChannel;
197     alias void function(int) da_Mix_Pause;
198     alias void function(int) da_Mix_Resume;
199     alias int function(int) da_Mix_Paused;
200     alias void function() da_Mix_PauseMusic;
201     alias void function() da_Mix_ResumeMusic;
202     alias void function() da_Mix_RewindMusic;
203     alias int function() da_Mix_PausedMusic;
204     alias int function(double) da_Mix_SetMusicPosition;
205     alias int function(int) da_Mix_Playing;
206     alias int function() da_Mix_PlayingMusic;
207     alias int function(in char*) da_Mix_SetMusicCMD;
208     alias int function(int) da_Mix_SetSynchroValue;
209     alias int function() da_Mix_GetSynchroValue;
210     alias Mix_Chunk* function(int) da_Mix_GetChunk;
211     alias void function() da_Mix_CloseAudio;
212 }
213 
214 mixin(gsharedString!() ~
215 "
216 da_Mix_Linked_Version Mix_Linked_Version;
217 da_Mix_Init Mix_Init;
218 da_Mix_Quit Mix_Quit;
219 da_Mix_OpenAudio Mix_OpenAudio;
220 da_Mix_AllocateChannels Mix_AllocateChannels;
221 da_Mix_QuerySpec Mix_QuerySpec;
222 da_Mix_LoadWAV_RW Mix_LoadWAV_RW;
223 da_Mix_LoadMUS Mix_LoadMUS;
224 da_Mix_LoadMUS_RW Mix_LoadMUS_RW;
225 da_Mix_QuickLoad_WAV Mix_QuickLoad_WAV;
226 da_Mix_QuickLoad_RAW Mix_QuickLoad_RAW;
227 da_Mix_FreeChunk Mix_FreeChunk;
228 da_Mix_FreeMusic Mix_FreeMusic;
229 da_Mix_GetNumChunkDecoders Mix_GetNumChunkDecoders;
230 da_Mix_GetChunkDecoder Mix_GetChunkDecoder;
231 da_Mix_GetNumMusicDecoders Mix_GetNumMusicDecoders;
232 da_Mix_GetMusicDecoder Mix_GetMusicDecoder;
233 da_Mix_GetMusicType Mix_GetMusicType;
234 da_Mix_SetPostMix Mix_SetPostMix;
235 da_Mix_HookMusic Mix_HookMusic;
236 da_Mix_HookMusicFinished Mix_HookMusicFinished;
237 da_Mix_GetMusicHookData Mix_GetMusicHookData;
238 da_Mix_ChannelFinished Mix_ChannelFinished;
239 da_Mix_RegisterEffect Mix_RegisterEffect;
240 da_Mix_UnregisterEffect Mix_UnregisterEffect;
241 da_Mix_UnregisterAllEffects Mix_UnregisterAllEffects;
242 da_Mix_SetPanning Mix_SetPanning;
243 da_Mix_SetPosition Mix_SetPosition;
244 da_Mix_SetDistance Mix_SetDistance;
245 // da_ Mix_SetReverb;
246 da_Mix_SetReverseStereo Mix_SetReverseStereo;
247 da_Mix_ReserveChannels Mix_ReserveChannels;
248 da_Mix_GroupChannel Mix_GroupChannel;
249 da_Mix_GroupChannels Mix_GroupChannels;
250 da_Mix_GroupAvailable Mix_GroupAvailable;
251 da_Mix_GroupCount Mix_GroupCount;
252 da_Mix_GroupOldest Mix_GroupOldest;
253 da_Mix_GroupNewer Mix_GroupNewer;
254 da_Mix_PlayChannelTimed Mix_PlayChannelTimed;
255 da_Mix_PlayMusic Mix_PlayMusic;
256 da_Mix_FadeInMusic Mix_FadeInMusic;
257 da_Mix_FadeInMusicPos Mix_FadeInMusicPos;
258 da_Mix_FadeInChannelTimed Mix_FadeInChannelTimed;
259 da_Mix_Volume Mix_Volume;
260 da_Mix_VolumeChunk Mix_VolumeChunk;
261 da_Mix_VolumeMusic Mix_VolumeMusic;
262 da_Mix_HaltChannel Mix_HaltChannel;
263 da_Mix_HaltGroup Mix_HaltGroup;
264 da_Mix_HaltMusic Mix_HaltMusic;
265 da_Mix_ExpireChannel Mix_ExpireChannel;
266 da_Mix_FadeOutChannel Mix_FadeOutChannel;
267 da_Mix_FadeOutGroup Mix_FadeOutGroup;
268 da_Mix_FadeOutMusic Mix_FadeOutMusic;
269 da_Mix_FadingMusic Mix_FadingMusic;
270 da_Mix_FadingChannel Mix_FadingChannel;
271 da_Mix_Pause Mix_Pause;
272 da_Mix_Resume Mix_Resume;
273 da_Mix_Paused Mix_Paused;
274 da_Mix_PauseMusic Mix_PauseMusic;
275 da_Mix_ResumeMusic Mix_ResumeMusic;
276 da_Mix_RewindMusic Mix_RewindMusic;
277 da_Mix_PausedMusic Mix_PausedMusic;
278 da_Mix_SetMusicPosition Mix_SetMusicPosition;
279 da_Mix_Playing Mix_Playing;
280 da_Mix_PlayingMusic Mix_PlayingMusic;
281 da_Mix_SetMusicCMD Mix_SetMusicCMD;
282 da_Mix_SetSynchroValue Mix_SetSynchroValue;
283 da_Mix_GetSynchroValue Mix_GetSynchroValue;
284 da_Mix_GetChunk Mix_GetChunk;
285 da_Mix_CloseAudio Mix_CloseAudio;
286 ");
287 
288 class DerelictSDLMixerLoader : SharedLibLoader
289 {
290 public:
291     this()
292     {
293         super(
294             "SDL_mixer.dll",
295             "libSDL_mixer.so, libSDL_mixer-1.2.so, libSDL_mixer-1.2.so.0",
296             "../Frameworks/SDL_mixer.framework/SDL_mixer, /Library/Frameworks/SDL_mixer.framework/SDL_mixer, /System/Library/Frameworks/SDL_mixer.framework/SDL_mixer"
297         );
298     }
299 
300 protected:
301     override void loadSymbols()
302     {
303         if(!DerelictSDL.isLoaded)
304         {
305             throw new SharedLibLoadException("DerelictSDL must be loaded before attempting to load DerelictSDLMixer!");
306         }
307 
308         bindFunc(cast(void**)&Mix_Linked_Version, "Mix_Linked_Version");
309         bindFunc(cast(void**)&Mix_Init, "Mix_Init");
310         bindFunc(cast(void**)&Mix_Quit, "Mix_Quit");
311         bindFunc(cast(void**)&Mix_OpenAudio, "Mix_OpenAudio");
312         bindFunc(cast(void**)&Mix_AllocateChannels, "Mix_AllocateChannels");
313         bindFunc(cast(void**)&Mix_QuerySpec, "Mix_QuerySpec");
314         bindFunc(cast(void**)&Mix_LoadWAV_RW, "Mix_LoadWAV_RW");
315         bindFunc(cast(void**)&Mix_LoadMUS, "Mix_LoadMUS");
316         bindFunc(cast(void**)&Mix_LoadMUS_RW, "Mix_LoadMUS_RW");
317         bindFunc(cast(void**)&Mix_QuickLoad_WAV, "Mix_QuickLoad_WAV");
318         bindFunc(cast(void**)&Mix_QuickLoad_RAW, "Mix_QuickLoad_RAW");
319         bindFunc(cast(void**)&Mix_FreeChunk, "Mix_FreeChunk");
320         bindFunc(cast(void**)&Mix_FreeMusic, "Mix_FreeMusic");
321         bindFunc(cast(void**)&Mix_GetNumChunkDecoders, "Mix_GetNumChunkDecoders");
322         bindFunc(cast(void**)&Mix_GetChunkDecoder, "Mix_GetChunkDecoder");
323         bindFunc(cast(void**)&Mix_GetNumMusicDecoders, "Mix_GetNumMusicDecoders");
324         bindFunc(cast(void**)&Mix_GetMusicDecoder, "Mix_GetMusicDecoder");
325         bindFunc(cast(void**)&Mix_GetMusicType, "Mix_GetMusicType");
326         bindFunc(cast(void**)&Mix_SetPostMix, "Mix_SetPostMix");
327         bindFunc(cast(void**)&Mix_HookMusic, "Mix_HookMusic");
328         bindFunc(cast(void**)&Mix_HookMusicFinished, "Mix_HookMusicFinished");
329         bindFunc(cast(void**)&Mix_GetMusicHookData, "Mix_GetMusicHookData");
330         bindFunc(cast(void**)&Mix_ChannelFinished, "Mix_ChannelFinished");
331         bindFunc(cast(void**)&Mix_RegisterEffect, "Mix_RegisterEffect");
332         bindFunc(cast(void**)&Mix_UnregisterEffect, "Mix_UnregisterEffect");
333         bindFunc(cast(void**)&Mix_UnregisterAllEffects, "Mix_UnregisterAllEffects");
334         bindFunc(cast(void**)&Mix_SetPanning, "Mix_SetPanning");
335         bindFunc(cast(void**)&Mix_SetPosition, "Mix_SetPosition");
336         bindFunc(cast(void**)&Mix_SetDistance, "Mix_SetDistance");
337         // bindFunc(cast(void**)&Mix_SetReverb, "Mix_SetReverb");
338         bindFunc(cast(void**)&Mix_SetReverseStereo, "Mix_SetReverseStereo");
339         bindFunc(cast(void**)&Mix_ReserveChannels, "Mix_ReserveChannels");
340         bindFunc(cast(void**)&Mix_GroupChannel, "Mix_GroupChannel");
341         bindFunc(cast(void**)&Mix_GroupChannels, "Mix_GroupChannels");
342         bindFunc(cast(void**)&Mix_GroupAvailable, "Mix_GroupAvailable");
343         bindFunc(cast(void**)&Mix_GroupCount, "Mix_GroupCount");
344         bindFunc(cast(void**)&Mix_GroupOldest, "Mix_GroupOldest");
345         bindFunc(cast(void**)&Mix_GroupNewer, "Mix_GroupNewer");
346         bindFunc(cast(void**)&Mix_PlayChannelTimed, "Mix_PlayChannelTimed");
347         bindFunc(cast(void**)&Mix_PlayMusic, "Mix_PlayMusic");
348         bindFunc(cast(void**)&Mix_FadeInMusic, "Mix_FadeInMusic");
349         bindFunc(cast(void**)&Mix_FadeInMusicPos, "Mix_FadeInMusicPos");
350         bindFunc(cast(void**)&Mix_FadeInChannelTimed, "Mix_FadeInChannelTimed");
351         bindFunc(cast(void**)&Mix_Volume, "Mix_Volume");
352         bindFunc(cast(void**)&Mix_VolumeChunk, "Mix_VolumeChunk");
353         bindFunc(cast(void**)&Mix_VolumeMusic, "Mix_VolumeMusic");
354         bindFunc(cast(void**)&Mix_HaltChannel, "Mix_HaltChannel");
355         bindFunc(cast(void**)&Mix_HaltGroup, "Mix_HaltGroup");
356         bindFunc(cast(void**)&Mix_HaltMusic, "Mix_HaltMusic");
357         bindFunc(cast(void**)&Mix_ExpireChannel, "Mix_ExpireChannel");
358         bindFunc(cast(void**)&Mix_FadeOutChannel, "Mix_FadeOutChannel");
359         bindFunc(cast(void**)&Mix_FadeOutGroup, "Mix_FadeOutGroup");
360         bindFunc(cast(void**)&Mix_FadeOutMusic, "Mix_FadeOutMusic");
361         bindFunc(cast(void**)&Mix_FadingMusic, "Mix_FadingMusic");
362         bindFunc(cast(void**)&Mix_FadingChannel, "Mix_FadingChannel");
363         bindFunc(cast(void**)&Mix_Pause, "Mix_Pause");
364         bindFunc(cast(void**)&Mix_Resume, "Mix_Resume");
365         bindFunc(cast(void**)&Mix_Paused, "Mix_Paused");
366         bindFunc(cast(void**)&Mix_PauseMusic, "Mix_PauseMusic");
367         bindFunc(cast(void**)&Mix_ResumeMusic, "Mix_ResumeMusic");
368         bindFunc(cast(void**)&Mix_RewindMusic, "Mix_RewindMusic");
369         bindFunc(cast(void**)&Mix_PausedMusic, "Mix_PausedMusic");
370         bindFunc(cast(void**)&Mix_SetMusicPosition, "Mix_SetMusicPosition");
371         bindFunc(cast(void**)&Mix_Playing, "Mix_Playing");
372         bindFunc(cast(void**)&Mix_PlayingMusic, "Mix_PlayingMusic");
373         bindFunc(cast(void**)&Mix_SetMusicCMD, "Mix_SetMusicCMD");
374         bindFunc(cast(void**)&Mix_SetSynchroValue, "Mix_SetSynchroValue");
375         bindFunc(cast(void**)&Mix_GetSynchroValue, "Mix_GetSynchroValue");
376         bindFunc(cast(void**)&Mix_GetChunk, "Mix_GetChunk");
377         bindFunc(cast(void**)&Mix_CloseAudio, "Mix_CloseAudio");
378     }
379 }
380 
381 DerelictSDLMixerLoader DerelictSDLMixer;
382 
383 static this()
384 {
385     DerelictSDLMixer = new DerelictSDLMixerLoader();
386 }
387 
388 static ~this()
389 {
390     if(SharedLibLoader.isAutoUnloadEnabled())
391         DerelictSDLMixer.unload();
392 }