1 /+ 2 + Copyright 2022 – 2024 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 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** audioBuf, uint* len) nothrow @nogc{ 133 return SDL_LoadWAV_RW(SDL_RWFromFile(file, "rb"), 1, spec, audioBuf, 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 FnBind[] ret = [ 144 {q{int}, q{SDL_GetNumAudioDrivers}, q{}}, 145 {q{const(char)*}, q{SDL_GetAudioDriver}, q{int index}}, 146 {q{int}, q{SDL_AudioInit}, q{const(char)* driverName}}, 147 {q{void}, q{SDL_AudioQuit}, q{}}, 148 {q{const(char)*}, q{SDL_GetCurrentAudioDriver}, q{}}, 149 {q{int}, q{SDL_OpenAudio}, q{SDL_AudioSpec* desired, SDL_AudioSpec* obtained}}, 150 {q{int}, q{SDL_GetNumAudioDevices}, q{int isCapture}}, 151 {q{const(char)*}, q{SDL_GetAudioDeviceName}, q{int index, int isCapture}}, 152 {q{SDL_AudioDeviceID}, q{SDL_OpenAudioDevice}, q{const(char)* device, int isCapture, const(SDL_AudioSpec)* desired, SDL_AudioSpec* obtained, int allowedChanges}}, 153 {q{SDL_AudioStatus}, q{SDL_GetAudioStatus}, q{}}, 154 {q{SDL_AudioStatus}, q{SDL_GetAudioDeviceStatus}, q{SDL_AudioDeviceID dev}}, 155 {q{void}, q{SDL_PauseAudio}, q{int pauseOn}}, 156 {q{void}, q{SDL_PauseAudioDevice}, q{SDL_AudioDeviceID dev, int pauseOn}}, 157 {q{SDL_AudioSpec*}, q{SDL_LoadWAV_RW}, q{SDL_RWops* src, int freeSrc, SDL_AudioSpec* spec, ubyte** audioBuf, uint* audioLen}}, 158 {q{void}, q{SDL_FreeWAV}, q{ubyte* audioBuf}}, 159 {q{int}, q{SDL_BuildAudioCVT}, q{SDL_AudioCVT* cvt, SDL_AudioFormat srcFormat, ubyte srcChannels, int srcRate, SDL_AudioFormat dstFormat, ubyte dstChannels, int dstRate}}, 160 {q{int}, q{SDL_ConvertAudio}, q{SDL_AudioCVT* cvt}}, 161 {q{void}, q{SDL_MixAudio}, q{ubyte* dst, const(ubyte)* src, uint len, int volume}}, 162 {q{void}, q{SDL_MixAudioFormat}, q{ubyte* dst, const(ubyte)* src, SDL_AudioFormat format, uint len, int volume}}, 163 {q{void}, q{SDL_LockAudio}, q{}}, 164 {q{void}, q{SDL_LockAudioDevice}, q{SDL_AudioDeviceID dev}}, 165 {q{void}, q{SDL_UnlockAudio}, q{}}, 166 {q{void}, q{SDL_UnlockAudioDevice}, q{SDL_AudioDeviceID dev}}, 167 {q{void}, q{SDL_CloseAudio}, q{}}, 168 {q{void}, q{SDL_CloseAudioDevice}, q{SDL_AudioDeviceID dev}}, 169 ]; 170 if(sdlSupport >= SDLSupport.v2_0_4){ 171 FnBind[] add = [ 172 {q{int}, q{SDL_QueueAudio}, q{SDL_AudioDeviceID dev, const(void)* data, uint len}}, 173 {q{int}, q{SDL_ClearQueuedAudio}, q{SDL_AudioDeviceID dev}}, 174 {q{int}, q{SDL_GetQueuedAudioSize}, q{SDL_AudioDeviceID dev}}, 175 ]; 176 ret ~= add; 177 } 178 if(sdlSupport >= SDLSupport.v2_0_5){ 179 FnBind[] add = [ 180 {q{uint}, q{SDL_DequeueAudio}, q{SDL_AudioDeviceID dev, void* data, uint len}}, 181 ]; 182 ret ~= add; 183 } 184 if(sdlSupport >= SDLSupport.v2_0_7){ 185 FnBind[] add = [ 186 {q{SDL_AudioStream*}, q{SDL_NewAudioStream}, q{const SDL_AudioFormat srcFormat, const ubyte srcChannels, const int srcRate, const SDL_AudioFormat dstFormat, const ubyte dstChannels, const int dstRate}}, 187 {q{int}, q{SDL_AudioStreamPut}, q{SDL_AudioStream* stream, const(void)* buf, int len}}, 188 {q{int}, q{SDL_AudioStreamGet}, q{SDL_AudioStream* stream, void* buf, int len}}, 189 {q{int}, q{SDL_AudioStreamAvailable}, q{SDL_AudioStream* stream}}, 190 {q{int}, q{SDL_AudioStreamFlush}, q{SDL_AudioStream* stream}}, 191 {q{void}, q{SDL_AudioStreamClear}, q{SDL_AudioStream* stream}}, 192 {q{void}, q{SDL_FreeAudioStream}, q{SDL_AudioStream* stream}}, 193 ]; 194 ret ~= add; 195 } 196 if(sdlSupport >= SDLSupport.v2_0_16){ 197 FnBind[] add = [ 198 {q{int}, q{SDL_GetAudioDeviceSpec}, q{int index, int isCapture, SDL_AudioSpec* spec}}, 199 ]; 200 ret ~= add; 201 } 202 if(sdlSupport >= SDLSupport.v2_24){ 203 FnBind[] add = [ 204 {q{int}, q{SDL_GetDefaultAudioInfo}, q{char** name, SDL_AudioSpec* spec, int isCapture}}, 205 ]; 206 ret ~= add; 207 } 208 return ret; 209 }()));