1 /+ 2 + Copyright 2022 – 2023 Aya Partridge 3 + Copyright 2018 - 2022 Michael D. Parker 4 + Distributed under the Boost Software License, Version 1.0. 5 + (See accompanying file LICENSE_1_0.txt or copy at 6 + http://www.boost.org/LICENSE_1_0.txt) 7 +/ 8 module sdl.audio; 9 10 import bindbc.sdl.config; 11 import bindbc.sdl.codegen; 12 13 import sdl.rwops; 14 15 enum: ushort{ 16 SDL_AUDIO_MASK_BITSIZE = 0xFF, 17 SDL_AUDIO_MASK_DATATYPE = 1<<8, 18 SDL_AUDIO_MASK_ENDIAN = 1<<12, 19 SDL_AUDIO_MASK_SIGNED = 1<<15, 20 } 21 22 pragma(inline, true) nothrow @nogc pure @safe{ 23 SDL_AudioFormat SDL_AUDIO_BITSIZE(SDL_AudioFormat x){ return cast(SDL_AudioFormat)(x & SDL_AUDIO_MASK_BITSIZE); } 24 SDL_AudioFormat SDL_AUDIO_ISFLOAT(SDL_AudioFormat x){ return cast(SDL_AudioFormat)(x & SDL_AUDIO_MASK_DATATYPE); } 25 SDL_AudioFormat SDL_AUDIO_ISBIGENDIAN(SDL_AudioFormat x){ return cast(SDL_AudioFormat)(x & SDL_AUDIO_MASK_ENDIAN); } 26 SDL_AudioFormat SDL_AUDIO_ISSIGNED(SDL_AudioFormat x){ return cast(SDL_AudioFormat)(x & SDL_AUDIO_MASK_SIGNED); } 27 bool SDL_AUDIO_ISINT(SDL_AudioFormat x){ return !SDL_AUDIO_ISFLOAT(x); } 28 bool SDL_AUDIO_ISLITTLEENDIAN(SDL_AudioFormat x){ return !SDL_AUDIO_ISBIGENDIAN(x); } 29 bool SDL_AUDIO_ISUNSIGNED(SDL_AudioFormat x){ return !SDL_AUDIO_ISSIGNED(x); } 30 } 31 deprecated("Please use the non-template variant instead"){ 32 enum SDL_AUDIO_BITSIZE(SDL_AudioFormat x) = x & SDL_AUDIO_MASK_BITSIZE; 33 enum SDL_AUDIO_ISFLOAT(SDL_AudioFormat x) = x & SDL_AUDIO_MASK_DATATYPE; 34 enum SDL_AUDIO_ISBIGENDIAN(SDL_AudioFormat x) = x & SDL_AUDIO_MASK_ENDIAN; 35 enum SDL_AUDIO_ISSIGNED(SDL_AudioFormat x) = x & SDL_AUDIO_MASK_SIGNED; 36 enum SDL_AUDIO_ISINT(SDL_AudioFormat x) = !SDL_AUDIO_ISFLOAT(x); 37 enum SDL_AUDIO_ISLITTLEENDIAN(SDL_AudioFormat x) = !SDL_AUDIO_ISBIGENDIAN(x); 38 enum SDL_AUDIO_ISUNSIGNED(SDL_AudioFormat x) = !SDL_AUDIO_ISSIGNED(x); 39 } 40 41 alias SDL_AudioFormat = ushort; 42 enum: SDL_AudioFormat{ 43 AUDIO_U8 = 0x0008, 44 AUDIO_S8 = 0x8008, 45 AUDIO_U16LSB = 0x0010, 46 AUDIO_S16LSB = 0x8010, 47 AUDIO_U16MSB = 0x1010, 48 AUDIO_S16MSB = 0x9010, 49 AUDIO_U16 = AUDIO_U16LSB, 50 AUDIO_S16 = AUDIO_S16LSB, 51 AUDIO_S32LSB = 0x8020, 52 AUDIO_S32MSB = 0x9020, 53 AUDIO_S32 = AUDIO_S32LSB, 54 AUDIO_F32LSB = 0x8120, 55 AUDIO_F32MSB = 0x9120, 56 AUDIO_F32 = AUDIO_F32LSB, 57 } 58 59 version(LittleEndian){ 60 alias AUDIO_U16SYS = AUDIO_U16LSB; 61 alias AUDIO_S16SYS = AUDIO_S16LSB; 62 alias AUDIO_S32SYS = AUDIO_S32LSB; 63 alias AUDIO_F32SYS = AUDIO_F32LSB; 64 }else{ 65 alias AUDIO_U16SYS = AUDIO_U16MSB; 66 alias AUDIO_S16SYS = AUDIO_S16MSB; 67 alias AUDIO_S32SYS = AUDIO_S32MSB; 68 alias AUDIO_F32SYS = AUDIO_F32MSB; 69 } 70 71 enum{ 72 SDL_AUDIO_ALLOW_FREQUENCY_CHANGE = 0x00000001, 73 SDL_AUDIO_ALLOW_FORMAT_CHANGE = 0x00000002, 74 SDL_AUDIO_ALLOW_CHANNELS_CHANGE = 0x00000004, 75 } 76 static if(sdlSupport >= SDLSupport.v2_0_9) 77 enum{ 78 SDL_AUDIO_ALLOW_SAMPLES_CHANGE = 0x00000008, 79 SDL_AUDIO_ALLOW_ANY_CHANGE = 80 SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_FORMAT_CHANGE | 81 SDL_AUDIO_ALLOW_CHANNELS_CHANGE | SDL_AUDIO_ALLOW_SAMPLES_CHANGE, 82 } 83 else 84 enum{ 85 SDL_AUDIO_ALLOW_ANY_CHANGE = 86 SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_FORMAT_CHANGE | 87 SDL_AUDIO_ALLOW_CHANNELS_CHANGE, 88 } 89 90 alias SDL_AudioCallback = extern(C) void function(void* userdata, ubyte* stream, int len) nothrow; 91 92 struct SDL_AudioSpec{ 93 int freq; 94 SDL_AudioFormat format; 95 ubyte channels; 96 ubyte silence; 97 ushort samples; 98 ushort padding; 99 uint size; 100 SDL_AudioCallback callback; 101 void* userdata; 102 } 103 104 // Declared in 2.0.6, but doesn't hurt to use here 105 enum SDL_AUDIOCVT_MAX_FILTERS = 9; 106 107 alias SDL_AudioFilter = extern(C) void function(SDL_AudioCVT* cvt, SDL_AudioFormat format) nothrow; 108 109 struct SDL_AudioCVT{ 110 int needed; 111 SDL_AudioFormat src_format; 112 SDL_AudioFormat dst_format; 113 double rate_incr; 114 ubyte* buf; 115 int len; 116 int len_cvt; 117 int len_mult; 118 double len_ratio; 119 SDL_AudioFilter[SDL_AUDIOCVT_MAX_FILTERS + 1] filters; 120 int filter_index; 121 } 122 123 alias SDL_AudioDeviceID = uint; 124 125 alias SDL_AudioStatus = int; 126 enum: SDL_AudioStatus{ 127 SDL_AUDIO_STOPPED = 0, 128 SDL_AUDIO_PLAYING = 1, 129 SDL_AUDIO_PAUSED = 2, 130 } 131 132 pragma(inline, true) SDL_AudioSpec* SDL_LoadWAV(const(char)* file, SDL_AudioSpec* spec, ubyte** audio_buf, uint* len) @nogc nothrow{ 133 return SDL_LoadWAV_RW(SDL_RWFromFile(file, "rb"), 1, spec, audio_buf, len); 134 } 135 136 static if(sdlSupport >= SDLSupport.v2_0_7){ 137 struct SDL_AudioStream; 138 } 139 140 enum SDL_MIX_MAXVOLUME = 128; 141 142 mixin(joinFnBinds((){ 143 string[][] ret; 144 ret ~= makeFnBinds([ 145 [q{int}, q{SDL_GetNumAudioDrivers}, q{}], 146 [q{const(char)*}, q{SDL_GetAudioDriver}, q{int index}], 147 [q{int}, q{SDL_AudioInit}, q{const(char)* driver_name}], 148 [q{void}, q{SDL_AudioQuit}, q{}], 149 [q{const(char)*}, q{SDL_GetCurrentAudioDriver}, q{}], 150 [q{int}, q{SDL_OpenAudio}, q{SDL_AudioSpec* desired, SDL_AudioSpec* obtained}], 151 [q{int}, q{SDL_GetNumAudioDevices}, q{int iscapture}], 152 [q{const(char)*}, q{SDL_GetAudioDeviceName}, q{int index, int iscapture}], 153 [q{SDL_AudioDeviceID}, q{SDL_OpenAudioDevice}, q{const(char)* device, int iscapture, const(SDL_AudioSpec)* desired, SDL_AudioSpec* obtained, int allowed_changes}], 154 [q{SDL_AudioStatus}, q{SDL_GetAudioStatus}, q{}], 155 [q{SDL_AudioStatus}, q{SDL_GetAudioDeviceStatus}, q{SDL_AudioDeviceID dev}], 156 [q{void}, q{SDL_PauseAudio}, q{int pause_on}], 157 [q{void}, q{SDL_PauseAudioDevice}, q{SDL_AudioDeviceID dev, int pause_on}], 158 [q{SDL_AudioSpec*}, q{SDL_LoadWAV_RW}, q{SDL_RWops* src, int freesrc, SDL_AudioSpec* spec, ubyte** audio_buf, uint* audio_len}], 159 [q{void}, q{SDL_FreeWAV}, q{ubyte* audio_buf}], 160 [q{int}, q{SDL_BuildAudioCVT}, q{SDL_AudioCVT* cvt, SDL_AudioFormat src_format, ubyte src_channels, int src_rate, SDL_AudioFormat dst_format, ubyte dst_channels, int dst_rate}], 161 [q{int}, q{SDL_ConvertAudio}, q{SDL_AudioCVT* cvt}], 162 [q{void}, q{SDL_MixAudio}, q{ubyte* dst, const(ubyte)* src, uint len, int volume}], 163 [q{void}, q{SDL_MixAudioFormat}, q{ubyte* dst, const(ubyte)* src, SDL_AudioFormat format, uint len, int volume}], 164 [q{void}, q{SDL_LockAudio}, q{}], 165 [q{void}, q{SDL_LockAudioDevice}, q{SDL_AudioDeviceID dev}], 166 [q{void}, q{SDL_UnlockAudio}, q{}], 167 [q{void}, q{SDL_UnlockAudioDevice}, q{SDL_AudioDeviceID dev}], 168 [q{void}, q{SDL_CloseAudio}, q{}], 169 [q{void}, q{SDL_CloseAudioDevice}, q{SDL_AudioDeviceID dev}], 170 ]); 171 static if(sdlSupport >= SDLSupport.v2_0_4){ 172 ret ~= makeFnBinds([ 173 [q{int}, q{SDL_QueueAudio}, q{SDL_AudioDeviceID dev, const(void)* data, uint len}], 174 [q{int}, q{SDL_ClearQueuedAudio}, q{SDL_AudioDeviceID dev}], 175 [q{int}, q{SDL_GetQueuedAudioSize}, q{SDL_AudioDeviceID dev}], 176 ]); 177 } 178 static if(sdlSupport >= SDLSupport.v2_0_5){ 179 ret ~= makeFnBinds([ 180 [q{uint}, q{SDL_DequeueAudio}, q{SDL_AudioDeviceID dev, void* data, uint len}], 181 ]); 182 } 183 static if(sdlSupport >= SDLSupport.v2_0_7){ 184 ret ~= makeFnBinds([ 185 [q{SDL_AudioStream*}, q{SDL_NewAudioStream}, q{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}], 186 [q{int}, q{SDL_AudioStreamPut}, q{SDL_AudioStream* stream, const(void)* buf, int len}], 187 [q{int}, q{SDL_AudioStreamGet}, q{SDL_AudioStream* stream, void* buf, int len}], 188 [q{int}, q{SDL_AudioStreamAvailable}, q{SDL_AudioStream* stream}], 189 [q{int}, q{SDL_AudioStreamFlush}, q{SDL_AudioStream* stream}], 190 [q{void}, q{SDL_AudioStreamClear}, q{SDL_AudioStream* stream}], 191 [q{void}, q{SDL_FreeAudioStream}, q{SDL_AudioStream* stream}], 192 ]); 193 } 194 static if(sdlSupport >= SDLSupport.v2_0_16){ 195 ret ~= makeFnBinds([ 196 [q{int}, q{SDL_GetAudioDeviceSpec}, q{int index, int iscapture, SDL_AudioSpec *spec}], 197 ]); 198 } 199 static if(sdlSupport >= SDLSupport.v2_24){ 200 ret ~= makeFnBinds([ 201 [q{int}, q{SDL_GetDefaultAudioInfo}, q{char** name, SDL_AudioSpec* spec, int iscapture}], 202 ]); 203 } 204 return ret; 205 }()));