1 
2 //          Copyright 2018 - 2021 Michael D. Parker
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.bind.sdlaudio;
8 
9 import bindbc.sdl.config;
10 import bindbc.sdl.bind.sdlrwops;
11 
12 enum : ushort {
13     SDL_AUDIO_MASK_BITSIZE = 0xFF,
14     SDL_AUDIO_MASK_DATATYPE = 1<<8,
15     SDL_AUDIO_MASK_ENDIAN = 1<<12,
16     SDL_AUDIO_MASK_SIGNED = 1<<15,
17 }
18 
19 enum SDL_AudioFormat : ushort {
20     AUDIO_U8 = 0x0008,
21     AUDIO_S8 = 0x8008,
22     AUDIO_U16LSB = 0x0010,
23     AUDIO_S16LSB = 0x8010,
24     AUDIO_U16MSB = 0x1010,
25     AUDIO_S16MSB = 0x9010,
26     AUDIO_U16 = AUDIO_U16LSB,
27     AUDIO_S16 = AUDIO_S16LSB,
28     AUDIO_S32LSB = 0x8020,
29     AUDIO_S32MSB = 0x9020,
30     AUDIO_S32 = AUDIO_S32LSB,
31     AUDIO_F32LSB = 0x8120,
32     AUDIO_F32MSB = 0x9120,
33     AUDIO_F32 = AUDIO_F32LSB,
34 }
35 mixin(expandEnum!SDL_AudioFormat);
36 
37 version(LittleEndian) {
38     alias AUDIO_U16SYS = AUDIO_U16LSB;
39     alias AUDIO_S16SYS = AUDIO_S16LSB;
40     alias AUDIO_S32SYS = AUDIO_S32LSB;
41     alias AUDIO_F32SYS = AUDIO_F32LSB;
42 } else {
43     alias AUDIO_U16SYS = AUDIO_U16MSB;
44     alias AUDIO_S16SYS = AUDIO_S16MSB;
45     alias AUDIO_S32SYS = AUDIO_S32MSB;
46     alias AUDIO_F32SYS = AUDIO_F32MSB;
47 }
48 
49 enum SDL_AUDIO_BITSIZE(SDL_AudioFormat x) = x & SDL_AUDIO_MASK_BITSIZE;
50 enum SDL_AUDIO_ISFLOAT(SDL_AudioFormat x) = x & SDL_AUDIO_MASK_DATATYPE;
51 enum SDL_AUDIO_ISBIGENDIAN(SDL_AudioFormat x) = x & SDL_AUDIO_MASK_ENDIAN;
52 enum SDL_AUDIO_ISSIGNED(SDL_AudioFormat x) = x & SDL_AUDIO_MASK_SIGNED;
53 enum SDL_AUDIO_ISINT(SDL_AudioFormat x) = !SDL_AUDIO_ISFLOAT!x;
54 enum SDL_AUDIO_ISLITTLEENDIAN(SDL_AudioFormat x) = !SDL_AUDIO_ISBIGENDIAN!x;
55 enum SDL_AUDIO_ISUNSIGNED(SDL_AudioFormat x) = !SDL_AUDIO_ISSIGNED!x;
56 
57 static if(sdlSupport >= SDLSupport.sdl209) {
58     enum {
59         SDL_AUDIO_ALLOW_FREQUENCY_CHANGE = 0x00000001,
60         SDL_AUDIO_ALLOW_FORMAT_CHANGE = 0x00000002,
61         SDL_AUDIO_ALLOW_CHANNELS_CHANGE = 0x00000004,
62         SDL_AUDIO_ALLOW_SAMPLES_CHANGE = 0x00000008,
63         SDL_AUDIO_ALLOW_ANY_CHANGE = SDL_AUDIO_ALLOW_FREQUENCY_CHANGE |
64                                      SDL_AUDIO_ALLOW_FORMAT_CHANGE |
65                                      SDL_AUDIO_ALLOW_CHANNELS_CHANGE |
66                                      SDL_AUDIO_ALLOW_SAMPLES_CHANGE,
67     }
68 }
69 else {
70     enum {
71         SDL_AUDIO_ALLOW_FREQUENCY_CHANGE = 0x00000001,
72         SDL_AUDIO_ALLOW_FORMAT_CHANGE = 0x00000002,
73         SDL_AUDIO_ALLOW_CHANNELS_CHANGE = 0x00000004,
74         SDL_AUDIO_ALLOW_ANY_CHANGE = SDL_AUDIO_ALLOW_FREQUENCY_CHANGE |
75                                      SDL_AUDIO_ALLOW_FORMAT_CHANGE |
76                                      SDL_AUDIO_ALLOW_CHANNELS_CHANGE,
77     }
78 }
79 
80 extern(C) nothrow alias SDL_AudioCallback = void function(void* userdata, ubyte* stream, int len);
81 struct SDL_AudioSpec {
82     int freq;
83     SDL_AudioFormat format;
84     ubyte channels;
85     ubyte silence;
86     ushort samples;
87     ushort padding;
88     uint size;
89     SDL_AudioCallback callback;
90     void* userdata;
91 }
92 
93 // Declared in 2.0.6, but doesn't hurt to use here
94 enum SDL_AUDIOCVT_MAX_FILTERS = 9;
95 
96 extern(C) nothrow alias SDL_AudioFilter = void function(SDL_AudioCVT* cvt, SDL_AudioFormat format);
97 struct SDL_AudioCVT {
98     int needed;
99     SDL_AudioFormat src_format;
100     SDL_AudioFormat dst_format;
101     double rate_incr;
102     ubyte* buf;
103     int len;
104     int len_cvt;
105     int len_mult;
106     double len_ratio;
107     SDL_AudioFilter[SDL_AUDIOCVT_MAX_FILTERS + 1] filters;
108     int filter_index;
109 }
110 
111 alias SDL_AudioDeviceID = uint;
112 
113 enum SDL_AudioStatus {
114     SDL_AUDIO_STOPPED = 0,
115     SDL_AUDIO_PLAYING,
116     SDL_AUDIO_PAUSED,
117 }
118 mixin(expandEnum!SDL_AudioStatus);
119 
120 enum SDL_MIX_MAXVOLUME = 128;
121 
122 static if(sdlSupport >= SDLSupport.sdl207) {
123     struct SDL_AudioStream;
124 }
125 
126 @nogc nothrow
127 SDL_AudioSpec* SDL_LoadWAV(const(char)* file, SDL_AudioSpec* spec, ubyte** audio_buf, uint* len) {
128     pragma(inline, true);
129     return SDL_LoadWAV_RW(SDL_RWFromFile(file,"rb"),1,spec,audio_buf,len);
130 }
131 
132 static if(staticBinding) {
133     extern(C) @nogc nothrow {
134         int SDL_GetNumAudioDrivers();
135         const(char)* SDL_GetAudioDriver(int index);
136         int SDL_AudioInit(const(char)* driver_name);
137         void SDL_AudioQuit();
138         const(char)* SDL_GetCurrentAudioDriver();
139         int SDL_OpenAudio(SDL_AudioSpec* desired, SDL_AudioSpec* obtained);
140         int SDL_GetNumAudioDevices(int iscapture);
141         const(char)* SDL_GetAudioDeviceName(int index, int iscapture);
142         SDL_AudioDeviceID SDL_OpenAudioDevice(const(char)* device, int iscapture, const(SDL_AudioSpec)* desired, SDL_AudioSpec* obtained, int allowed_changes);
143         SDL_AudioStatus SDL_GetAudioStatus();
144         SDL_AudioStatus SDL_GetAudioDeviceStatus(SDL_AudioDeviceID dev);
145         void SDL_PauseAudio(int pause_on);
146         void SDL_PauseAudioDevice(SDL_AudioDeviceID dev, int pause_on);
147         SDL_AudioSpec* SDL_LoadWAV_RW(SDL_RWops* src, int freesrc, SDL_AudioSpec* spec, ubyte** audio_buf, uint* audio_len);
148         void SDL_FreeWAV(ubyte* audio_buf);
149         int SDL_BuildAudioCVT(SDL_AudioCVT* cvt, SDL_AudioFormat src_format, ubyte src_channels, int src_rate, SDL_AudioFormat dst_format, ubyte dst_channels, int dst_rate);
150         int SDL_ConvertAudio(SDL_AudioCVT* cvt);
151         void SDL_MixAudio(ubyte* dst, const(ubyte)* src, uint len, int volume);
152         void SDL_MixAudioFormat(ubyte* dst, const(ubyte)* src, SDL_AudioFormat format, uint len, int volume);
153         void SDL_LockAudio();
154         void SDL_LockAudioDevice(SDL_AudioDeviceID dev);
155         void SDL_UnlockAudio();
156         void SDL_UnlockAudioDevice(SDL_AudioDeviceID dev);
157         void SDL_CloseAudio();
158         void SDL_CloseAudioDevice(SDL_AudioDeviceID dev);
159 
160         static if(sdlSupport >= SDLSupport.sdl204) {
161             int SDL_QueueAudio(SDL_AudioDeviceID dev, const(void)* data, uint len);
162             int SDL_ClearQueuedAudio(SDL_AudioDeviceID dev);
163             int SDL_GetQueuedAudioSize(SDL_AudioDeviceID dev);
164         }
165 
166         static if(sdlSupport >= SDLSupport.sdl205) {
167             uint SDL_DequeueAudio(SDL_AudioDeviceID dev, void* data, uint len);
168         }
169 
170         static if(sdlSupport >= SDLSupport.sdl207) {
171             SDL_AudioStream* SDL_NewAudioStream(const(SDL_AudioFormat) src_format, const(ubyte) src_channels, const(int) src_rate, const(SDL_AudioFormat) dst_format, const(ubyte) dst_channels, const(int) dst_rate);
172             int SDL_AudioStreamPut(SDL_AudioStream* stream, const(void)* buf, int len);
173             int SDL_AudioStreamGet(SDL_AudioStream* stream, void* buf, int len);
174             int SDL_AudioStreamAvailable(SDL_AudioStream* stream);
175             int SDL_AudioStreamFlush(SDL_AudioStream* stream);
176             void SDL_AudioStreamClear(SDL_AudioStream* stream);
177             void SDL_FreeAudioStream(SDL_AudioStream* stream);
178         }
179     }
180 }
181 else {
182     extern(C) @nogc nothrow {
183         alias pSDL_GetNumAudioDrivers = int function();
184         alias pSDL_GetAudioDriver = const(char)* function(int index);
185         alias pSDL_AudioInit = int function(const(char)* driver_name);
186         alias pSDL_AudioQuit = void function();
187         alias pSDL_GetCurrentAudioDriver = const(char)* function();
188         alias pSDL_OpenAudio = int function(SDL_AudioSpec* desired, SDL_AudioSpec* obtained);
189         alias pSDL_GetNumAudioDevices = int function(int iscapture);
190         alias pSDL_GetAudioDeviceName = const(char)* function(int index, int iscapture);
191         alias pSDL_OpenAudioDevice = SDL_AudioDeviceID function(const(char)* device, int iscapture, const(SDL_AudioSpec)* desired, SDL_AudioSpec* obtained, int allowed_changes);
192         alias pSDL_GetAudioStatus = SDL_AudioStatus function();
193         alias pSDL_GetAudioDeviceStatus = SDL_AudioStatus function(SDL_AudioDeviceID dev);
194         alias pSDL_PauseAudio = void function(int pause_on);
195         alias pSDL_PauseAudioDevice = void function(SDL_AudioDeviceID dev, int pause_on);
196         alias pSDL_LoadWAV_RW = SDL_AudioSpec* function(SDL_RWops* src, int freesrc, SDL_AudioSpec* spec, ubyte** audio_buf, uint* audio_len);
197         alias pSDL_FreeWAV = void function(ubyte* audio_buf);
198         alias pSDL_BuildAudioCVT = int function(SDL_AudioCVT* cvt, SDL_AudioFormat src_format, ubyte src_channels, int src_rate, SDL_AudioFormat dst_format, ubyte dst_channels, int dst_rate);
199         alias pSDL_ConvertAudio = int function(SDL_AudioCVT* cvt);
200         alias pSDL_MixAudio = void function(ubyte* dst, const(ubyte)* src, uint len, int volume);
201         alias pSDL_MixAudioFormat = void function(ubyte* dst, const(ubyte)* src, SDL_AudioFormat format, uint len, int volume);
202         alias pSDL_LockAudio = void function();
203         alias pSDL_LockAudioDevice = void function(SDL_AudioDeviceID dev);
204         alias pSDL_UnlockAudio = void function();
205         alias pSDL_UnlockAudioDevice = void function(SDL_AudioDeviceID dev);
206         alias pSDL_CloseAudio = void function();
207         alias pSDL_CloseAudioDevice = void function(SDL_AudioDeviceID dev);
208     }
209 
210     __gshared {
211         pSDL_GetNumAudioDrivers SDL_GetNumAudioDrivers;
212         pSDL_GetAudioDriver SDL_GetAudioDriver;
213         pSDL_AudioInit SDL_AudioInit;
214         pSDL_AudioQuit SDL_AudioQuit;
215         pSDL_GetCurrentAudioDriver SDL_GetCurrentAudioDriver;
216         pSDL_OpenAudio SDL_OpenAudio;
217         pSDL_GetNumAudioDevices SDL_GetNumAudioDevices;
218         pSDL_GetAudioDeviceName SDL_GetAudioDeviceName;
219         pSDL_OpenAudioDevice SDL_OpenAudioDevice;
220         pSDL_GetAudioStatus SDL_GetAudioStatus;
221         pSDL_GetAudioDeviceStatus SDL_GetAudioDeviceStatus;
222         pSDL_PauseAudio SDL_PauseAudio;
223         pSDL_PauseAudioDevice SDL_PauseAudioDevice;
224         pSDL_LoadWAV_RW SDL_LoadWAV_RW;
225         pSDL_FreeWAV SDL_FreeWAV;
226         pSDL_BuildAudioCVT SDL_BuildAudioCVT;
227         pSDL_ConvertAudio SDL_ConvertAudio;
228         pSDL_MixAudio SDL_MixAudio;
229         pSDL_MixAudioFormat SDL_MixAudioFormat;
230         pSDL_LockAudio SDL_LockAudio;
231         pSDL_LockAudioDevice SDL_LockAudioDevice;
232         pSDL_UnlockAudio SDL_UnlockAudio;
233         pSDL_UnlockAudioDevice SDL_UnlockAudioDevice;
234         pSDL_CloseAudio SDL_CloseAudio;
235         pSDL_CloseAudioDevice SDL_CloseAudioDevice;
236     }
237 
238     static if(sdlSupport >= SDLSupport.sdl204) {
239         extern(C) @nogc nothrow {
240             alias pSDL_QueueAudio = int function(SDL_AudioDeviceID dev, const(void)* data, uint len);
241             alias pSDL_ClearQueuedAudio = int function(SDL_AudioDeviceID dev);
242             alias pSDL_GetQueuedAudioSize = int function(SDL_AudioDeviceID dev);
243         }
244 
245         __gshared {
246             pSDL_QueueAudio SDL_QueueAudio;
247             pSDL_ClearQueuedAudio SDL_ClearQueuedAudio;
248             pSDL_GetQueuedAudioSize SDL_GetQueuedAudioSize;
249         }
250     }
251 
252     static if(sdlSupport >= SDLSupport.sdl205) {
253         extern(C) @nogc nothrow {
254             alias pSDL_DequeueAudio = uint function(SDL_AudioDeviceID dev, void* data, uint len);
255         }
256 
257         __gshared {
258             pSDL_DequeueAudio SDL_DequeueAudio;
259         }
260     }
261 
262     static if(sdlSupport >= SDLSupport.sdl207) {
263         extern(C) @nogc nothrow {
264             alias pSDL_NewAudioStream = SDL_AudioStream* function(const(SDL_AudioFormat) src_format, const(ubyte) src_channels, const(int) src_rate, const(SDL_AudioFormat) dst_format, const(ubyte) dst_channels, const(int) dst_rate);
265             alias pSDL_AudioStreamPut = int function(SDL_AudioStream* stream, const(void)* buf, int len);
266             alias pSDL_AudioStreamGet = int function(SDL_AudioStream* stream, void* buf ,int len);
267             alias pSDL_AudioStreamAvailable = int function(SDL_AudioStream* stream);
268             alias pSDL_AudioStreamFlush = int function(SDL_AudioStream* stream);
269             alias pSDL_AudioStreamClear = void function(SDL_AudioStream* stream);
270             alias pSDL_FreeAudioStream = void function(SDL_AudioStream* stream);
271         }
272 
273         __gshared {
274             pSDL_NewAudioStream SDL_NewAudioStream;
275             pSDL_AudioStreamPut SDL_AudioStreamPut;
276             pSDL_AudioStreamGet SDL_AudioStreamGet;
277             pSDL_AudioStreamAvailable SDL_AudioStreamAvailable;
278             pSDL_AudioStreamFlush SDL_AudioStreamFlush;
279             pSDL_AudioStreamClear SDL_AudioStreamClear;
280             pSDL_FreeAudioStream SDL_FreeAudioStream;
281         }
282     }
283 }