SDL_audio.c 79 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030
  1. /*
  2. Simple DirectMedia Layer
  3. Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
  4. This software is provided 'as-is', without any express or implied
  5. warranty. In no event will the authors be held liable for any damages
  6. arising from the use of this software.
  7. Permission is granted to anyone to use this software for any purpose,
  8. including commercial applications, and to alter it and redistribute it
  9. freely, subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented; you must not
  11. claim that you wrote the original software. If you use this software
  12. in a product, an acknowledgment in the product documentation would be
  13. appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such, and must not be
  15. misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. #include "SDL_internal.h"
  19. #include "SDL_audio_c.h"
  20. #include "SDL_sysaudio.h"
  21. #include "../thread/SDL_systhread.h"
  22. #include "../SDL_utils_c.h"
  23. // Available audio drivers
  24. static const AudioBootStrap *const bootstrap[] = {
  25. #ifdef SDL_AUDIO_DRIVER_PULSEAUDIO
  26. &PULSEAUDIO_bootstrap,
  27. #endif
  28. #ifdef SDL_AUDIO_DRIVER_ALSA
  29. &ALSA_bootstrap,
  30. #endif
  31. #ifdef SDL_AUDIO_DRIVER_SNDIO
  32. &SNDIO_bootstrap,
  33. #endif
  34. #ifdef SDL_AUDIO_DRIVER_NETBSD
  35. &NETBSDAUDIO_bootstrap,
  36. #endif
  37. #ifdef SDL_AUDIO_DRIVER_WASAPI
  38. &WASAPI_bootstrap,
  39. #endif
  40. #ifdef SDL_AUDIO_DRIVER_DSOUND
  41. &DSOUND_bootstrap,
  42. #endif
  43. #ifdef SDL_AUDIO_DRIVER_HAIKU
  44. &HAIKUAUDIO_bootstrap,
  45. #endif
  46. #ifdef SDL_AUDIO_DRIVER_COREAUDIO
  47. &COREAUDIO_bootstrap,
  48. #endif
  49. #ifdef SDL_AUDIO_DRIVER_AAUDIO
  50. &AAUDIO_bootstrap,
  51. #endif
  52. #ifdef SDL_AUDIO_DRIVER_OPENSLES
  53. &openslES_bootstrap,
  54. #endif
  55. #ifdef SDL_AUDIO_DRIVER_ANDROID
  56. &ANDROIDAUDIO_bootstrap,
  57. #endif
  58. #ifdef SDL_AUDIO_DRIVER_PS2
  59. &PS2AUDIO_bootstrap,
  60. #endif
  61. #ifdef SDL_AUDIO_DRIVER_PSP
  62. &PSPAUDIO_bootstrap,
  63. #endif
  64. #ifdef SDL_AUDIO_DRIVER_VITA
  65. &VITAAUD_bootstrap,
  66. #endif
  67. #ifdef SDL_AUDIO_DRIVER_N3DS
  68. &N3DSAUDIO_bootstrap,
  69. #endif
  70. #ifdef SDL_AUDIO_DRIVER_EMSCRIPTEN
  71. &EMSCRIPTENAUDIO_bootstrap,
  72. #endif
  73. #ifdef SDL_AUDIO_DRIVER_JACK
  74. &JACK_bootstrap,
  75. #endif
  76. #ifdef SDL_AUDIO_DRIVER_PIPEWIRE
  77. &PIPEWIRE_bootstrap,
  78. #endif
  79. #ifdef SDL_AUDIO_DRIVER_OSS
  80. &DSP_bootstrap,
  81. #endif
  82. #ifdef SDL_AUDIO_DRIVER_QNX
  83. &QSAAUDIO_bootstrap,
  84. #endif
  85. #ifdef SDL_AUDIO_DRIVER_DISK
  86. &DISKAUDIO_bootstrap,
  87. #endif
  88. #ifdef SDL_AUDIO_DRIVER_DUMMY
  89. &DUMMYAUDIO_bootstrap,
  90. #endif
  91. NULL
  92. };
  93. static SDL_AudioDriver current_audio;
  94. int SDL_GetNumAudioDrivers(void)
  95. {
  96. return SDL_arraysize(bootstrap) - 1;
  97. }
  98. const char *SDL_GetAudioDriver(int index)
  99. {
  100. if (index >= 0 && index < SDL_GetNumAudioDrivers()) {
  101. return bootstrap[index]->name;
  102. }
  103. return NULL;
  104. }
  105. const char *SDL_GetCurrentAudioDriver(void)
  106. {
  107. return current_audio.name;
  108. }
  109. static int GetDefaultSampleFramesFromFreq(const int freq)
  110. {
  111. const char *hint = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES);
  112. if (hint) {
  113. const int val = SDL_atoi(hint);
  114. if (val > 0) {
  115. return val;
  116. }
  117. }
  118. if (freq <= 22050) {
  119. return 512;
  120. } else if (freq <= 48000) {
  121. return 1024;
  122. } else if (freq <= 96000) {
  123. return 2048;
  124. } else {
  125. return 4096;
  126. }
  127. }
  128. void OnAudioStreamCreated(SDL_AudioStream *stream)
  129. {
  130. SDL_assert(stream != NULL);
  131. // NOTE that you can create an audio stream without initializing the audio subsystem,
  132. // but it will not be automatically destroyed during a later call to SDL_Quit!
  133. // You must explicitly destroy it yourself!
  134. if (current_audio.device_hash_lock) {
  135. // this isn't really part of the "device list" but it's a convenient lock to use here.
  136. SDL_LockRWLockForWriting(current_audio.device_hash_lock);
  137. if (current_audio.existing_streams) {
  138. current_audio.existing_streams->prev = stream;
  139. }
  140. stream->prev = NULL;
  141. stream->next = current_audio.existing_streams;
  142. current_audio.existing_streams = stream;
  143. SDL_UnlockRWLock(current_audio.device_hash_lock);
  144. }
  145. }
  146. void OnAudioStreamDestroy(SDL_AudioStream *stream)
  147. {
  148. SDL_assert(stream != NULL);
  149. // NOTE that you can create an audio stream without initializing the audio subsystem,
  150. // but it will not be automatically destroyed during a later call to SDL_Quit!
  151. // You must explicitly destroy it yourself!
  152. if (current_audio.device_hash_lock) {
  153. // this isn't really part of the "device list" but it's a convenient lock to use here.
  154. SDL_LockRWLockForWriting(current_audio.device_hash_lock);
  155. if (stream->prev) {
  156. stream->prev->next = stream->next;
  157. }
  158. if (stream->next) {
  159. stream->next->prev = stream->prev;
  160. }
  161. if (stream == current_audio.existing_streams) {
  162. current_audio.existing_streams = stream->next;
  163. }
  164. SDL_UnlockRWLock(current_audio.device_hash_lock);
  165. }
  166. }
  167. // device should be locked when calling this.
  168. static SDL_bool AudioDeviceCanUseSimpleCopy(SDL_AudioDevice *device)
  169. {
  170. SDL_assert(device != NULL);
  171. return (
  172. device->logical_devices && // there's a logical device
  173. !device->logical_devices->next && // there's only _ONE_ logical device
  174. !device->logical_devices->postmix && // there isn't a postmix callback
  175. device->logical_devices->bound_streams && // there's a bound stream
  176. !device->logical_devices->bound_streams->next_binding // there's only _ONE_ bound stream.
  177. ) ? SDL_TRUE : SDL_FALSE;
  178. }
  179. // should hold device->lock before calling.
  180. static void UpdateAudioStreamFormatsPhysical(SDL_AudioDevice *device)
  181. {
  182. if (!device->iscapture) { // for capture devices, we only want to move to float32 for postmix, which we'll handle elsewhere.
  183. const SDL_bool simple_copy = AudioDeviceCanUseSimpleCopy(device);
  184. SDL_AudioSpec spec;
  185. device->simple_copy = simple_copy;
  186. SDL_copyp(&spec, &device->spec);
  187. if (!simple_copy) {
  188. spec.format = SDL_AUDIO_F32; // mixing and postbuf operates in float32 format.
  189. }
  190. for (SDL_LogicalAudioDevice *logdev = device->logical_devices; logdev != NULL; logdev = logdev->next) {
  191. for (SDL_AudioStream *stream = logdev->bound_streams; stream != NULL; stream = stream->next_binding) {
  192. // set the proper end of the stream to the device's format.
  193. // SDL_SetAudioStreamFormat does a ton of validation just to memcpy an audiospec.
  194. SDL_LockMutex(stream->lock);
  195. SDL_copyp(&stream->dst_spec, &spec);
  196. SDL_UnlockMutex(stream->lock);
  197. }
  198. }
  199. }
  200. }
  201. // device management and hotplug...
  202. /* SDL_AudioDevice, in SDL3, represents a piece of physical hardware, whether it is in use or not, so these objects exist as long as
  203. the system-level device is available.
  204. Physical devices get destroyed for three reasons:
  205. - They were lost to the system (a USB cable is kicked out, etc).
  206. - They failed for some other unlikely reason at the API level (which is _also_ probably a USB cable being kicked out).
  207. - We are shutting down, so all allocated resources are being freed.
  208. They are _not_ destroyed because we are done using them (when we "close" a playing device).
  209. */
  210. static void ClosePhysicalAudioDevice(SDL_AudioDevice *device);
  211. SDL_COMPILE_TIME_ASSERT(check_lowest_audio_default_value, SDL_AUDIO_DEVICE_DEFAULT_CAPTURE < SDL_AUDIO_DEVICE_DEFAULT_OUTPUT);
  212. static SDL_AudioDeviceID AssignAudioDeviceInstanceId(SDL_bool iscapture, SDL_bool islogical)
  213. {
  214. /* Assign an instance id! Start at 2, in case there are things from the SDL2 era that still think 1 is a special value.
  215. There's no reasonable scenario where this rolls over, but just in case, we wrap it in a loop.
  216. Also, make sure we don't assign SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, etc. */
  217. // The bottom two bits of the instance id tells you if it's an output device (1<<0), and if it's a physical device (1<<1).
  218. const SDL_AudioDeviceID flags = (iscapture ? 0 : (1<<0)) | (islogical ? 0 : (1<<1));
  219. const SDL_AudioDeviceID instance_id = (((SDL_AudioDeviceID) (SDL_AtomicIncRef(&current_audio.last_device_instance_id) + 1)) << 2) | flags;
  220. SDL_assert( (instance_id >= 2) && (instance_id < SDL_AUDIO_DEVICE_DEFAULT_CAPTURE) );
  221. return instance_id;
  222. }
  223. // this assumes you hold the _physical_ device lock for this logical device! This will not unlock the lock or close the physical device!
  224. static void DestroyLogicalAudioDevice(SDL_LogicalAudioDevice *logdev)
  225. {
  226. SDL_LockRWLockForWriting(current_audio.device_hash_lock);
  227. SDL_RemoveFromHashTable(current_audio.device_hash, (const void *) (uintptr_t) logdev->instance_id);
  228. SDL_UnlockRWLock(current_audio.device_hash_lock);
  229. // remove ourselves from the physical device's list of logical devices.
  230. if (logdev->next) {
  231. logdev->next->prev = logdev->prev;
  232. }
  233. if (logdev->prev) {
  234. logdev->prev->next = logdev->next;
  235. }
  236. if (logdev->physical_device->logical_devices == logdev) {
  237. logdev->physical_device->logical_devices = logdev->next;
  238. }
  239. // unbind any still-bound streams...
  240. SDL_AudioStream *next;
  241. for (SDL_AudioStream *stream = logdev->bound_streams; stream != NULL; stream = next) {
  242. SDL_LockMutex(stream->lock);
  243. next = stream->next_binding;
  244. stream->next_binding = NULL;
  245. stream->prev_binding = NULL;
  246. stream->bound_device = NULL;
  247. SDL_UnlockMutex(stream->lock);
  248. }
  249. UpdateAudioStreamFormatsPhysical(logdev->physical_device);
  250. SDL_free(logdev);
  251. }
  252. // this must not be called while `device` is still in a device list, or while a device's audio thread is still running (except if the thread calls this while shutting down). */
  253. static void DestroyPhysicalAudioDevice(SDL_AudioDevice *device)
  254. {
  255. if (!device) {
  256. return;
  257. }
  258. // Destroy any logical devices that still exist...
  259. SDL_LockMutex(device->lock);
  260. while (device->logical_devices != NULL) {
  261. DestroyLogicalAudioDevice(device->logical_devices);
  262. }
  263. SDL_UnlockMutex(device->lock);
  264. // it's safe to not hold the lock for this (we can't anyhow, or the audio thread won't quit), because we shouldn't be in the device list at this point.
  265. ClosePhysicalAudioDevice(device);
  266. current_audio.impl.FreeDeviceHandle(device);
  267. SDL_DestroyMutex(device->lock);
  268. SDL_free(device->work_buffer);
  269. SDL_free(device->name);
  270. SDL_free(device);
  271. }
  272. static SDL_AudioDevice *CreatePhysicalAudioDevice(const char *name, SDL_bool iscapture, const SDL_AudioSpec *spec, void *handle, SDL_AtomicInt *device_count)
  273. {
  274. SDL_assert(name != NULL);
  275. SDL_LockRWLockForReading(current_audio.device_hash_lock);
  276. const int shutting_down = SDL_AtomicGet(&current_audio.shutting_down);
  277. SDL_UnlockRWLock(current_audio.device_hash_lock);
  278. if (shutting_down) {
  279. return NULL; // we're shutting down, don't add any devices that are hotplugged at the last possible moment.
  280. }
  281. SDL_AudioDevice *device = (SDL_AudioDevice *)SDL_calloc(1, sizeof(SDL_AudioDevice));
  282. if (!device) {
  283. SDL_OutOfMemory();
  284. return NULL;
  285. }
  286. device->name = SDL_strdup(name);
  287. if (!device->name) {
  288. SDL_free(device);
  289. SDL_OutOfMemory();
  290. return NULL;
  291. }
  292. device->lock = SDL_CreateMutex();
  293. if (!device->lock) {
  294. SDL_free(device->name);
  295. SDL_free(device);
  296. return NULL;
  297. }
  298. SDL_AtomicSet(&device->shutdown, 0);
  299. SDL_AtomicSet(&device->condemned, 0);
  300. SDL_AtomicSet(&device->zombie, 0);
  301. device->iscapture = iscapture;
  302. SDL_copyp(&device->spec, spec);
  303. SDL_copyp(&device->default_spec, spec);
  304. device->sample_frames = GetDefaultSampleFramesFromFreq(device->spec.freq);
  305. device->silence_value = SDL_GetSilenceValueForFormat(device->spec.format);
  306. device->handle = handle;
  307. device->instance_id = AssignAudioDeviceInstanceId(iscapture, /*islogical=*/SDL_FALSE);
  308. SDL_LockRWLockForWriting(current_audio.device_hash_lock);
  309. if (SDL_InsertIntoHashTable(current_audio.device_hash, (const void *) (uintptr_t) device->instance_id, device)) {
  310. SDL_AtomicAdd(device_count, 1);
  311. } else {
  312. SDL_free(device->name);
  313. SDL_free(device);
  314. device = NULL;
  315. }
  316. SDL_UnlockRWLock(current_audio.device_hash_lock);
  317. return device;
  318. }
  319. static SDL_AudioDevice *CreateAudioCaptureDevice(const char *name, const SDL_AudioSpec *spec, void *handle)
  320. {
  321. SDL_assert(current_audio.impl.HasCaptureSupport);
  322. return CreatePhysicalAudioDevice(name, SDL_TRUE, spec, handle, &current_audio.capture_device_count);
  323. }
  324. static SDL_AudioDevice *CreateAudioOutputDevice(const char *name, const SDL_AudioSpec *spec, void *handle)
  325. {
  326. return CreatePhysicalAudioDevice(name, SDL_FALSE, spec, handle, &current_audio.output_device_count);
  327. }
  328. // The audio backends call this when a new device is plugged in.
  329. SDL_AudioDevice *SDL_AddAudioDevice(const SDL_bool iscapture, const char *name, const SDL_AudioSpec *inspec, void *handle)
  330. {
  331. const SDL_AudioFormat default_format = iscapture ? DEFAULT_AUDIO_CAPTURE_FORMAT : DEFAULT_AUDIO_OUTPUT_FORMAT;
  332. const int default_channels = iscapture ? DEFAULT_AUDIO_CAPTURE_CHANNELS : DEFAULT_AUDIO_OUTPUT_CHANNELS;
  333. const int default_freq = iscapture ? DEFAULT_AUDIO_CAPTURE_FREQUENCY : DEFAULT_AUDIO_OUTPUT_FREQUENCY;
  334. SDL_AudioSpec spec;
  335. if (!inspec) {
  336. spec.format = default_format;
  337. spec.channels = default_channels;
  338. spec.freq = default_freq;
  339. } else {
  340. spec.format = (inspec->format != 0) ? inspec->format : default_format;
  341. spec.channels = (inspec->channels != 0) ? inspec->channels : default_channels;
  342. spec.freq = (inspec->freq != 0) ? inspec->freq : default_freq;
  343. }
  344. SDL_AudioDevice *device = iscapture ? CreateAudioCaptureDevice(name, &spec, handle) : CreateAudioOutputDevice(name, &spec, handle);
  345. if (device) {
  346. // Post the event, if desired
  347. if (SDL_EventEnabled(SDL_EVENT_AUDIO_DEVICE_ADDED)) {
  348. SDL_Event event;
  349. SDL_zero(event);
  350. event.type = SDL_EVENT_AUDIO_DEVICE_ADDED;
  351. event.adevice.which = device->instance_id;
  352. event.adevice.iscapture = iscapture;
  353. SDL_PushEvent(&event);
  354. }
  355. }
  356. return device;
  357. }
  358. // this _also_ destroys the logical device!
  359. static void DisconnectLogicalAudioDevice(SDL_LogicalAudioDevice *logdev)
  360. {
  361. SDL_assert(logdev != NULL); // currently, this is always true.
  362. const SDL_AudioDeviceID instance_id = logdev->instance_id;
  363. const SDL_bool iscapture = logdev->physical_device->iscapture;
  364. DestroyLogicalAudioDevice(logdev);
  365. if (SDL_EventEnabled(SDL_EVENT_AUDIO_DEVICE_REMOVED)) {
  366. SDL_Event event;
  367. SDL_zero(event);
  368. event.type = SDL_EVENT_AUDIO_DEVICE_REMOVED;
  369. event.adevice.which = instance_id;
  370. event.adevice.iscapture = iscapture ? 1 : 0;
  371. SDL_PushEvent(&event);
  372. }
  373. }
  374. // Called when a device is removed from the system, or it fails unexpectedly, from any thread, possibly even the audio device's thread.
  375. void SDL_AudioDeviceDisconnected(SDL_AudioDevice *device)
  376. {
  377. if (!device) {
  378. return;
  379. }
  380. // if the current default device is going down, mark it as dead but keep it around until a replacement is decided upon, so we can migrate logical devices to it.
  381. if ((device->instance_id == current_audio.default_output_device_id) || (device->instance_id == current_audio.default_capture_device_id)) {
  382. SDL_LockMutex(device->lock); // make sure nothing else is messing with the device before continuing.
  383. SDL_AtomicSet(&device->zombie, 1);
  384. SDL_AtomicSet(&device->shutdown, 1); // tell audio thread to terminate, but don't mark it condemned, so the thread won't destroy the device. We'll join on the audio thread later.
  385. // dump any logical devices that explicitly opened this device. Things that opened the system default can stay.
  386. SDL_LogicalAudioDevice *next = NULL;
  387. for (SDL_LogicalAudioDevice *logdev = device->logical_devices; logdev != NULL; logdev = next) {
  388. next = logdev->next;
  389. if (!logdev->opened_as_default) { // if opened as a default, leave it on the zombie device for later migration.
  390. DisconnectLogicalAudioDevice(logdev);
  391. }
  392. }
  393. SDL_UnlockMutex(device->lock);
  394. return; // done for now. Come back when a new default device is chosen!
  395. }
  396. SDL_bool was_live = SDL_FALSE;
  397. SDL_LockMutex(device->lock); // make sure nothing else is messing with the device before continuing.
  398. // take it out of the device list.
  399. SDL_LockRWLockForWriting(current_audio.device_hash_lock);
  400. was_live = SDL_RemoveFromHashTable(current_audio.device_hash, (const void *) (uintptr_t) device->instance_id);
  401. if (was_live) {
  402. SDL_AtomicAdd(device->iscapture ? &current_audio.capture_device_count : &current_audio.output_device_count, -1);
  403. }
  404. // Mark device as condemned now that it's not in the device list.
  405. SDL_AtomicSet(&device->condemned, 1);
  406. SDL_UnlockRWLock(current_audio.device_hash_lock);
  407. // now device is not in the list, and we own it, so no one should be able to find it again, except the audio thread, which holds a pointer!
  408. SDL_AtomicSet(&device->shutdown, 1); // tell audio thread to terminate.
  409. // disconnect each attached logical device, so apps won't find their streams still bound if they get the REMOVED event before the device thread cleans up.
  410. SDL_LogicalAudioDevice *next;
  411. for (SDL_LogicalAudioDevice *logdev = device->logical_devices; logdev != NULL; logdev = next) {
  412. next = logdev->next;
  413. DisconnectLogicalAudioDevice(logdev);
  414. }
  415. // if there's an audio thread, don't free until thread is terminating, otherwise free stuff now.
  416. const SDL_bool should_destroy = SDL_AtomicGet(&device->thread_alive) ? SDL_FALSE : SDL_TRUE;
  417. const SDL_AudioDeviceID instance_id = device->instance_id;
  418. const SDL_bool iscapture = device->iscapture;
  419. SDL_UnlockMutex(device->lock);
  420. if (should_destroy) {
  421. DestroyPhysicalAudioDevice(device);
  422. }
  423. // Post the event, if we haven't tried to before and if it's desired
  424. if (was_live && SDL_EventEnabled(SDL_EVENT_AUDIO_DEVICE_REMOVED)) {
  425. SDL_Event event;
  426. SDL_zero(event);
  427. event.type = SDL_EVENT_AUDIO_DEVICE_REMOVED;
  428. event.common.timestamp = 0;
  429. event.adevice.which = instance_id;
  430. event.adevice.iscapture = iscapture ? 1 : 0;
  431. SDL_PushEvent(&event);
  432. }
  433. }
  434. // stubs for audio drivers that don't need a specific entry point...
  435. static void SDL_AudioThreadDeinit_Default(SDL_AudioDevice *device) { /* no-op. */ }
  436. static int SDL_AudioWaitDevice_Default(SDL_AudioDevice *device) { return 0; /* no-op. */ }
  437. static int SDL_AudioPlayDevice_Default(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size) { return 0; /* no-op. */ }
  438. static int SDL_AudioWaitCaptureDevice_Default(SDL_AudioDevice *device) { return 0; /* no-op. */ }
  439. static void SDL_AudioFlushCapture_Default(SDL_AudioDevice *device) { /* no-op. */ }
  440. static void SDL_AudioCloseDevice_Default(SDL_AudioDevice *device) { /* no-op. */ }
  441. static void SDL_AudioDeinitialize_Default(void) { /* no-op. */ }
  442. static void SDL_AudioFreeDeviceHandle_Default(SDL_AudioDevice *device) { /* no-op. */ }
  443. static void SDL_AudioThreadInit_Default(SDL_AudioDevice *device)
  444. {
  445. SDL_SetThreadPriority(device->iscapture ? SDL_THREAD_PRIORITY_HIGH : SDL_THREAD_PRIORITY_TIME_CRITICAL);
  446. }
  447. static void SDL_AudioDetectDevices_Default(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture)
  448. {
  449. // you have to write your own implementation if these assertions fail.
  450. SDL_assert(current_audio.impl.OnlyHasDefaultOutputDevice);
  451. SDL_assert(current_audio.impl.OnlyHasDefaultCaptureDevice || !current_audio.impl.HasCaptureSupport);
  452. *default_output = SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, NULL, (void *)((size_t)0x1));
  453. if (current_audio.impl.HasCaptureSupport) {
  454. *default_capture = SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *)((size_t)0x2));
  455. }
  456. }
  457. static Uint8 *SDL_AudioGetDeviceBuf_Default(SDL_AudioDevice *device, int *buffer_size)
  458. {
  459. *buffer_size = 0;
  460. return NULL;
  461. }
  462. static int SDL_AudioCaptureFromDevice_Default(SDL_AudioDevice *device, void *buffer, int buflen)
  463. {
  464. return SDL_Unsupported();
  465. }
  466. static int SDL_AudioOpenDevice_Default(SDL_AudioDevice *device)
  467. {
  468. return SDL_Unsupported();
  469. }
  470. // Fill in stub functions for unused driver entry points. This lets us blindly call them without having to check for validity first.
  471. static void CompleteAudioEntryPoints(void)
  472. {
  473. #define FILL_STUB(x) if (!current_audio.impl.x) { current_audio.impl.x = SDL_Audio##x##_Default; }
  474. FILL_STUB(DetectDevices);
  475. FILL_STUB(OpenDevice);
  476. FILL_STUB(ThreadInit);
  477. FILL_STUB(ThreadDeinit);
  478. FILL_STUB(WaitDevice);
  479. FILL_STUB(PlayDevice);
  480. FILL_STUB(GetDeviceBuf);
  481. FILL_STUB(WaitCaptureDevice);
  482. FILL_STUB(CaptureFromDevice);
  483. FILL_STUB(FlushCapture);
  484. FILL_STUB(CloseDevice);
  485. FILL_STUB(FreeDeviceHandle);
  486. FILL_STUB(Deinitialize);
  487. #undef FILL_STUB
  488. }
  489. static SDL_AudioDeviceID GetFirstAddedAudioDeviceID(const SDL_bool iscapture)
  490. {
  491. SDL_AudioDeviceID retval = (SDL_AudioDeviceID) SDL_AUDIO_DEVICE_DEFAULT_OUTPUT; // According to AssignAudioDeviceInstanceId, nothing can have a value this large.
  492. // (Device IDs increase as new devices are added, so the first device added has the lowest SDL_AudioDeviceID value.)
  493. SDL_LockRWLockForReading(current_audio.device_hash_lock);
  494. const void *key;
  495. const void *value;
  496. void *iter = NULL;
  497. while (SDL_IterateHashTable(current_audio.device_hash, &key, &value, &iter)) {
  498. const SDL_AudioDeviceID devid = (SDL_AudioDeviceID) (uintptr_t) value;
  499. // bit #1 of devid is set for physical devices and unset for logical.
  500. const SDL_bool isphysical = (devid & (1<<1)) ? SDL_TRUE : SDL_FALSE;
  501. if (isphysical && (devid < retval)) {
  502. retval = devid;
  503. }
  504. }
  505. SDL_UnlockRWLock(current_audio.device_hash_lock);
  506. return (retval == SDL_AUDIO_DEVICE_DEFAULT_OUTPUT) ? 0 : retval;
  507. }
  508. static Uint32 HashAudioDeviceID(const void *key, void *data)
  509. {
  510. // shift right 2, to dump the first two bits, since these are flags
  511. // (capture vs playback, logical vs physical) and the rest are unique incrementing integers.
  512. return ((Uint32) ((uintptr_t) key)) >> 2;
  513. }
  514. static SDL_bool MatchAudioDeviceID(const void *a, const void *b, void *data)
  515. {
  516. return (a == b) ? SDL_TRUE : SDL_FALSE; // they're simple Uint32 values cast to pointers.
  517. }
  518. static void NukeAudioDeviceHashItem(const void *key, const void *value, void *data)
  519. {
  520. // no-op, keys and values in this hashtable are treated as Plain Old Data and don't get freed here.
  521. }
  522. // !!! FIXME: the video subsystem does SDL_VideoInit, not SDL_InitVideo. Make this match.
  523. int SDL_InitAudio(const char *driver_name)
  524. {
  525. if (SDL_GetCurrentAudioDriver()) {
  526. SDL_QuitAudio(); // shutdown driver if already running.
  527. }
  528. SDL_ChooseAudioConverters();
  529. SDL_SetupAudioResampler();
  530. SDL_RWLock *device_hash_lock = SDL_CreateRWLock(); // create this early, so if it fails we don't have to tear down the whole audio subsystem.
  531. if (!device_hash_lock) {
  532. return -1;
  533. }
  534. SDL_HashTable *device_hash = SDL_CreateHashTable(NULL, 8, HashAudioDeviceID, MatchAudioDeviceID, NukeAudioDeviceHashItem, SDL_FALSE);
  535. if (!device_hash) {
  536. SDL_DestroyRWLock(device_hash_lock);
  537. return -1;
  538. }
  539. // Select the proper audio driver
  540. if (driver_name == NULL) {
  541. driver_name = SDL_GetHint(SDL_HINT_AUDIO_DRIVER);
  542. }
  543. SDL_bool initialized = SDL_FALSE;
  544. SDL_bool tried_to_init = SDL_FALSE;
  545. if (driver_name != NULL && *driver_name != 0) {
  546. char *driver_name_copy = SDL_strdup(driver_name);
  547. const char *driver_attempt = driver_name_copy;
  548. if (driver_name_copy == NULL) {
  549. SDL_DestroyRWLock(device_hash_lock);
  550. SDL_DestroyHashTable(device_hash);
  551. return SDL_OutOfMemory();
  552. }
  553. while (driver_attempt != NULL && *driver_attempt != 0 && !initialized) {
  554. char *driver_attempt_end = SDL_strchr(driver_attempt, ',');
  555. if (driver_attempt_end != NULL) {
  556. *driver_attempt_end = '\0';
  557. }
  558. // SDL 1.2 uses the name "dsound", so we'll support both.
  559. if (SDL_strcmp(driver_attempt, "dsound") == 0) {
  560. driver_attempt = "directsound";
  561. } else if (SDL_strcmp(driver_attempt, "pulse") == 0) { // likewise, "pulse" was renamed to "pulseaudio"
  562. driver_attempt = "pulseaudio";
  563. }
  564. for (int i = 0; bootstrap[i]; ++i) {
  565. if (SDL_strcasecmp(bootstrap[i]->name, driver_attempt) == 0) {
  566. tried_to_init = SDL_TRUE;
  567. SDL_zero(current_audio);
  568. SDL_AtomicSet(&current_audio.last_device_instance_id, 2); // start past 1 because of SDL2's legacy interface.
  569. current_audio.device_hash_lock = device_hash_lock;
  570. current_audio.device_hash = device_hash;
  571. if (bootstrap[i]->init(&current_audio.impl)) {
  572. current_audio.name = bootstrap[i]->name;
  573. current_audio.desc = bootstrap[i]->desc;
  574. initialized = SDL_TRUE;
  575. }
  576. break;
  577. }
  578. }
  579. driver_attempt = (driver_attempt_end != NULL) ? (driver_attempt_end + 1) : NULL;
  580. }
  581. SDL_free(driver_name_copy);
  582. } else {
  583. for (int i = 0; (!initialized) && (bootstrap[i]); ++i) {
  584. if (bootstrap[i]->demand_only) {
  585. continue;
  586. }
  587. tried_to_init = SDL_TRUE;
  588. SDL_zero(current_audio);
  589. SDL_AtomicSet(&current_audio.last_device_instance_id, 2); // start past 1 because of SDL2's legacy interface.
  590. current_audio.device_hash_lock = device_hash_lock;
  591. current_audio.device_hash = device_hash;
  592. if (bootstrap[i]->init(&current_audio.impl)) {
  593. current_audio.name = bootstrap[i]->name;
  594. current_audio.desc = bootstrap[i]->desc;
  595. initialized = SDL_TRUE;
  596. }
  597. }
  598. }
  599. if (!initialized) {
  600. // specific drivers will set the error message if they fail, but otherwise we do it here.
  601. if (!tried_to_init) {
  602. if (driver_name) {
  603. SDL_SetError("Audio target '%s' not available", driver_name);
  604. } else {
  605. SDL_SetError("No available audio device");
  606. }
  607. }
  608. SDL_zero(current_audio);
  609. SDL_DestroyRWLock(device_hash_lock);
  610. SDL_DestroyHashTable(device_hash);
  611. current_audio.device_hash_lock = NULL;
  612. current_audio.device_hash = NULL;
  613. return -1; // No driver was available, so fail.
  614. }
  615. CompleteAudioEntryPoints();
  616. // Make sure we have a list of devices available at startup...
  617. SDL_AudioDevice *default_output = NULL;
  618. SDL_AudioDevice *default_capture = NULL;
  619. current_audio.impl.DetectDevices(&default_output, &default_capture);
  620. // these are only set if default_* is non-NULL, in case the backend just called SDL_DefaultAudioDeviceChanged directly during DetectDevices.
  621. if (default_output) {
  622. current_audio.default_output_device_id = default_output->instance_id;
  623. }
  624. if (default_capture) {
  625. current_audio.default_capture_device_id = default_capture->instance_id;
  626. }
  627. // If no default was _ever_ specified, just take the first device we see, if any.
  628. if (!current_audio.default_output_device_id) {
  629. current_audio.default_output_device_id = GetFirstAddedAudioDeviceID(/*iscapture=*/SDL_FALSE);
  630. }
  631. if (!current_audio.default_capture_device_id) {
  632. current_audio.default_capture_device_id = GetFirstAddedAudioDeviceID(/*iscapture=*/SDL_TRUE);
  633. }
  634. return 0;
  635. }
  636. void SDL_QuitAudio(void)
  637. {
  638. if (!current_audio.name) { // not initialized?!
  639. return;
  640. }
  641. // Destroy any audio streams that still exist...
  642. while (current_audio.existing_streams != NULL) {
  643. SDL_DestroyAudioStream(current_audio.existing_streams);
  644. }
  645. // merge device lists so we don't have to duplicate work below.
  646. SDL_LockRWLockForWriting(current_audio.device_hash_lock);
  647. SDL_AtomicSet(&current_audio.shutting_down, 1);
  648. SDL_HashTable *device_hash = current_audio.device_hash;
  649. current_audio.device_hash = NULL;
  650. SDL_AtomicSet(&current_audio.output_device_count, 0);
  651. SDL_AtomicSet(&current_audio.capture_device_count, 0);
  652. SDL_UnlockRWLock(current_audio.device_hash_lock);
  653. // mark all devices for shutdown so all threads can begin to terminate.
  654. const void *key;
  655. const void *value;
  656. void *iter = NULL;
  657. while (SDL_IterateHashTable(device_hash, &key, &value, &iter)) {
  658. SDL_AudioDevice *device = (SDL_AudioDevice *) value;
  659. SDL_AtomicSet(&device->shutdown, 1);
  660. DestroyPhysicalAudioDevice(device);
  661. }
  662. // Free the driver data
  663. current_audio.impl.Deinitialize();
  664. SDL_DestroyRWLock(current_audio.device_hash_lock);
  665. SDL_DestroyHashTable(device_hash);
  666. SDL_zero(current_audio);
  667. }
  668. void SDL_AudioThreadFinalize(SDL_AudioDevice *device)
  669. {
  670. if (SDL_AtomicGet(&device->condemned)) {
  671. if (device->thread) {
  672. SDL_DetachThread(device->thread); // no one is waiting for us, just detach ourselves.
  673. device->thread = NULL;
  674. SDL_AtomicSet(&device->thread_alive, 0);
  675. }
  676. DestroyPhysicalAudioDevice(device);
  677. }
  678. SDL_AtomicSet(&device->thread_alive, 0);
  679. }
  680. static void MixFloat32Audio(float *dst, const float *src, const int buffer_size)
  681. {
  682. if (SDL_MixAudioFormat((Uint8 *) dst, (const Uint8 *) src, SDL_AUDIO_F32, buffer_size, SDL_MIX_MAXVOLUME) < 0) {
  683. SDL_assert(!"This shouldn't happen.");
  684. }
  685. }
  686. // Output device thread. This is split into chunks, so backends that need to control this directly can use the pieces they need without duplicating effort.
  687. void SDL_OutputAudioThreadSetup(SDL_AudioDevice *device)
  688. {
  689. SDL_assert(!device->iscapture);
  690. current_audio.impl.ThreadInit(device);
  691. }
  692. SDL_bool SDL_OutputAudioThreadIterate(SDL_AudioDevice *device)
  693. {
  694. SDL_assert(!device->iscapture);
  695. SDL_LockMutex(device->lock);
  696. if (SDL_AtomicGet(&device->shutdown)) {
  697. SDL_UnlockMutex(device->lock);
  698. return SDL_FALSE; // we're done, shut it down.
  699. }
  700. SDL_bool retval = SDL_TRUE;
  701. int buffer_size = device->buffer_size;
  702. Uint8 *device_buffer = current_audio.impl.GetDeviceBuf(device, &buffer_size);
  703. if (buffer_size == 0) {
  704. // WASAPI (maybe others, later) does this to say "just abandon this iteration and try again next time."
  705. } else if (!device_buffer) {
  706. retval = SDL_FALSE;
  707. } else {
  708. SDL_assert(buffer_size <= device->buffer_size); // you can ask for less, but not more.
  709. SDL_assert(AudioDeviceCanUseSimpleCopy(device) == device->simple_copy); // make sure this hasn't gotten out of sync.
  710. // can we do a basic copy without silencing/mixing the buffer? This is an extremely likely scenario, so we special-case it.
  711. if (device->simple_copy) {
  712. SDL_LogicalAudioDevice *logdev = device->logical_devices;
  713. SDL_AudioStream *stream = logdev->bound_streams;
  714. // We should have updated this elsewhere if the format changed!
  715. SDL_assert(AUDIO_SPECS_EQUAL(stream->dst_spec, device->spec));
  716. const int br = SDL_AtomicGet(&logdev->paused) ? 0 : SDL_GetAudioStreamData(stream, device_buffer, buffer_size);
  717. if (br < 0) { // Probably OOM. Kill the audio device; the whole thing is likely dying soon anyhow.
  718. retval = SDL_FALSE;
  719. SDL_memset(device_buffer, device->silence_value, buffer_size); // just supply silence to the device before we die.
  720. } else if (br < buffer_size) {
  721. SDL_memset(device_buffer + br, device->silence_value, buffer_size - br); // silence whatever we didn't write to.
  722. }
  723. } else { // need to actually mix (or silence the buffer)
  724. float *final_mix_buffer = (float *) ((device->spec.format == SDL_AUDIO_F32) ? device_buffer : device->mix_buffer);
  725. const int needed_samples = buffer_size / SDL_AUDIO_BYTESIZE(device->spec.format);
  726. const int work_buffer_size = needed_samples * sizeof (float);
  727. SDL_AudioSpec outspec;
  728. SDL_assert(work_buffer_size <= device->work_buffer_size);
  729. outspec.format = SDL_AUDIO_F32;
  730. outspec.channels = device->spec.channels;
  731. outspec.freq = device->spec.freq;
  732. SDL_memset(final_mix_buffer, '\0', work_buffer_size); // start with silence.
  733. for (SDL_LogicalAudioDevice *logdev = device->logical_devices; logdev != NULL; logdev = logdev->next) {
  734. if (SDL_AtomicGet(&logdev->paused)) {
  735. continue; // paused? Skip this logical device.
  736. }
  737. const SDL_AudioPostmixCallback postmix = logdev->postmix;
  738. float *mix_buffer = final_mix_buffer;
  739. if (postmix) {
  740. mix_buffer = device->postmix_buffer;
  741. SDL_memset(mix_buffer, '\0', work_buffer_size); // start with silence.
  742. }
  743. for (SDL_AudioStream *stream = logdev->bound_streams; stream != NULL; stream = stream->next_binding) {
  744. // We should have updated this elsewhere if the format changed!
  745. SDL_assert(AUDIO_SPECS_EQUAL(stream->dst_spec, outspec));
  746. /* this will hold a lock on `stream` while getting. We don't explicitly lock the streams
  747. for iterating here because the binding linked list can only change while the device lock is held.
  748. (we _do_ lock the stream during binding/unbinding to make sure that two threads can't try to bind
  749. the same stream to different devices at the same time, though.) */
  750. const int br = SDL_GetAudioStreamData(stream, device->work_buffer, work_buffer_size);
  751. if (br < 0) { // Probably OOM. Kill the audio device; the whole thing is likely dying soon anyhow.
  752. retval = SDL_FALSE;
  753. break;
  754. } else if (br > 0) { // it's okay if we get less than requested, we mix what we have.
  755. MixFloat32Audio(mix_buffer, (float *) device->work_buffer, br);
  756. }
  757. }
  758. if (postmix) {
  759. SDL_assert(mix_buffer == device->postmix_buffer);
  760. postmix(logdev->postmix_userdata, &outspec, mix_buffer, work_buffer_size);
  761. MixFloat32Audio(final_mix_buffer, mix_buffer, work_buffer_size);
  762. }
  763. }
  764. if (((Uint8 *) final_mix_buffer) != device_buffer) {
  765. // !!! FIXME: we can't promise the device buf is aligned/padded for SIMD.
  766. //ConvertAudio(needed_samples * device->spec.channels, final_mix_buffer, SDL_AUDIO_F32, device->spec.channels, device_buffer, device->spec.format, device->spec.channels, device->work_buffer);
  767. ConvertAudio(needed_samples / device->spec.channels, final_mix_buffer, SDL_AUDIO_F32, device->spec.channels, device->work_buffer, device->spec.format, device->spec.channels, NULL);
  768. SDL_memcpy(device_buffer, device->work_buffer, buffer_size);
  769. }
  770. }
  771. // PlayDevice SHOULD NOT BLOCK, as we are holding a lock right now. Block in WaitDevice instead!
  772. if (current_audio.impl.PlayDevice(device, device_buffer, buffer_size) < 0) {
  773. retval = SDL_FALSE;
  774. }
  775. }
  776. SDL_UnlockMutex(device->lock);
  777. if (!retval) {
  778. SDL_AudioDeviceDisconnected(device); // doh.
  779. }
  780. return retval;
  781. }
  782. void SDL_OutputAudioThreadShutdown(SDL_AudioDevice *device)
  783. {
  784. SDL_assert(!device->iscapture);
  785. const int frames = device->buffer_size / SDL_AUDIO_FRAMESIZE(device->spec);
  786. // Wait for the audio to drain. !!! FIXME: don't bother waiting if device is lost.
  787. SDL_Delay(((frames * 1000) / device->spec.freq) * 2);
  788. current_audio.impl.ThreadDeinit(device);
  789. SDL_AudioThreadFinalize(device);
  790. }
  791. static int SDLCALL OutputAudioThread(void *devicep) // thread entry point
  792. {
  793. SDL_AudioDevice *device = (SDL_AudioDevice *)devicep;
  794. SDL_assert(device != NULL);
  795. SDL_assert(!device->iscapture);
  796. SDL_OutputAudioThreadSetup(device);
  797. do {
  798. if (current_audio.impl.WaitDevice(device) < 0) {
  799. SDL_AudioDeviceDisconnected(device); // doh.
  800. break;
  801. }
  802. } while (SDL_OutputAudioThreadIterate(device));
  803. SDL_OutputAudioThreadShutdown(device);
  804. return 0;
  805. }
  806. // Capture device thread. This is split into chunks, so backends that need to control this directly can use the pieces they need without duplicating effort.
  807. void SDL_CaptureAudioThreadSetup(SDL_AudioDevice *device)
  808. {
  809. SDL_assert(device->iscapture);
  810. current_audio.impl.ThreadInit(device);
  811. }
  812. SDL_bool SDL_CaptureAudioThreadIterate(SDL_AudioDevice *device)
  813. {
  814. SDL_assert(device->iscapture);
  815. SDL_LockMutex(device->lock);
  816. SDL_bool retval = SDL_TRUE;
  817. if (SDL_AtomicGet(&device->shutdown)) {
  818. retval = SDL_FALSE; // we're done, shut it down.
  819. } else if (device->logical_devices == NULL) {
  820. current_audio.impl.FlushCapture(device); // nothing wants data, dump anything pending.
  821. } else {
  822. // this SHOULD NOT BLOCK, as we are holding a lock right now. Block in WaitCaptureDevice!
  823. int br = current_audio.impl.CaptureFromDevice(device, device->work_buffer, device->buffer_size);
  824. if (br < 0) { // uhoh, device failed for some reason!
  825. retval = SDL_FALSE;
  826. } else if (br > 0) { // queue the new data to each bound stream.
  827. for (SDL_LogicalAudioDevice *logdev = device->logical_devices; logdev != NULL; logdev = logdev->next) {
  828. if (SDL_AtomicGet(&logdev->paused)) {
  829. continue; // paused? Skip this logical device.
  830. }
  831. void *output_buffer = device->work_buffer;
  832. // I don't know why someone would want a postmix on a capture device, but we offer it for API consistency.
  833. if (logdev->postmix) {
  834. // move to float format.
  835. SDL_AudioSpec outspec;
  836. outspec.format = SDL_AUDIO_F32;
  837. outspec.channels = device->spec.channels;
  838. outspec.freq = device->spec.freq;
  839. output_buffer = device->postmix_buffer;
  840. const int frames = br / SDL_AUDIO_FRAMESIZE(device->spec);
  841. br = frames * SDL_AUDIO_FRAMESIZE(outspec);
  842. ConvertAudio(frames, device->work_buffer, device->spec.format, outspec.channels, device->postmix_buffer, SDL_AUDIO_F32, outspec.channels, NULL);
  843. logdev->postmix(logdev->postmix_userdata, &outspec, device->postmix_buffer, br);
  844. }
  845. for (SDL_AudioStream *stream = logdev->bound_streams; stream != NULL; stream = stream->next_binding) {
  846. // We should have updated this elsewhere if the format changed!
  847. SDL_assert(stream->src_spec.format == (logdev->postmix ? SDL_AUDIO_F32 : device->spec.format));
  848. SDL_assert(stream->src_spec.channels == device->spec.channels);
  849. SDL_assert(stream->src_spec.freq == device->spec.freq);
  850. /* this will hold a lock on `stream` while putting. We don't explicitly lock the streams
  851. for iterating here because the binding linked list can only change while the device lock is held.
  852. (we _do_ lock the stream during binding/unbinding to make sure that two threads can't try to bind
  853. the same stream to different devices at the same time, though.) */
  854. if (SDL_PutAudioStreamData(stream, output_buffer, br) < 0) {
  855. // oh crud, we probably ran out of memory. This is possibly an overreaction to kill the audio device, but it's likely the whole thing is going down in a moment anyhow.
  856. retval = SDL_FALSE;
  857. break;
  858. }
  859. }
  860. }
  861. }
  862. }
  863. SDL_UnlockMutex(device->lock);
  864. if (!retval) {
  865. SDL_AudioDeviceDisconnected(device); // doh.
  866. }
  867. return retval;
  868. }
  869. void SDL_CaptureAudioThreadShutdown(SDL_AudioDevice *device)
  870. {
  871. SDL_assert(device->iscapture);
  872. current_audio.impl.FlushCapture(device);
  873. current_audio.impl.ThreadDeinit(device);
  874. SDL_AudioThreadFinalize(device);
  875. }
  876. static int SDLCALL CaptureAudioThread(void *devicep) // thread entry point
  877. {
  878. SDL_AudioDevice *device = (SDL_AudioDevice *)devicep;
  879. SDL_assert(device != NULL);
  880. SDL_assert(device->iscapture);
  881. SDL_CaptureAudioThreadSetup(device);
  882. do {
  883. if (current_audio.impl.WaitCaptureDevice(device) < 0) {
  884. SDL_AudioDeviceDisconnected(device); // doh.
  885. break;
  886. }
  887. } while (SDL_CaptureAudioThreadIterate(device));
  888. SDL_CaptureAudioThreadShutdown(device);
  889. return 0;
  890. }
  891. static SDL_AudioDeviceID *GetAudioDevices(int *reqcount, SDL_bool iscapture)
  892. {
  893. if (!SDL_GetCurrentAudioDriver()) {
  894. SDL_SetError("Audio subsystem is not initialized");
  895. return NULL;
  896. }
  897. SDL_AudioDeviceID *retval = NULL;
  898. SDL_LockRWLockForReading(current_audio.device_hash_lock);
  899. int num_devices = SDL_AtomicGet(iscapture ? &current_audio.capture_device_count : &current_audio.output_device_count);
  900. if (num_devices > 0) {
  901. retval = (SDL_AudioDeviceID *) SDL_malloc((num_devices + 1) * sizeof (SDL_AudioDeviceID));
  902. if (retval == NULL) {
  903. num_devices = 0;
  904. SDL_OutOfMemory();
  905. } else {
  906. int devs_seen = 0;
  907. const void *key;
  908. const void *value;
  909. void *iter = NULL;
  910. while (SDL_IterateHashTable(current_audio.device_hash, &key, &value, &iter)) {
  911. const SDL_AudioDeviceID devid = (SDL_AudioDeviceID) (uintptr_t) key;
  912. // bit #0 of devid is set for output devices and unset for capture.
  913. // bit #1 of devid is set for physical devices and unset for logical.
  914. const SDL_bool devid_iscapture = (devid & (1<<0)) ? SDL_FALSE : SDL_TRUE;
  915. const SDL_bool isphysical = (devid & (1<<1)) ? SDL_TRUE : SDL_FALSE;
  916. if (isphysical && (devid_iscapture == iscapture)) {
  917. SDL_assert(devs_seen < num_devices);
  918. retval[devs_seen++] = devid;
  919. }
  920. }
  921. SDL_assert(devs_seen == num_devices);
  922. retval[devs_seen] = 0; // null-terminated.
  923. }
  924. }
  925. SDL_UnlockRWLock(current_audio.device_hash_lock);
  926. if (reqcount != NULL) {
  927. *reqcount = num_devices;
  928. }
  929. return retval;
  930. }
  931. SDL_AudioDeviceID *SDL_GetAudioOutputDevices(int *count)
  932. {
  933. return GetAudioDevices(count, SDL_FALSE);
  934. }
  935. SDL_AudioDeviceID *SDL_GetAudioCaptureDevices(int *count)
  936. {
  937. return GetAudioDevices(count, SDL_TRUE);
  938. }
  939. // If found, this locks _the physical device_ this logical device is associated with, before returning.
  940. static SDL_LogicalAudioDevice *ObtainLogicalAudioDevice(SDL_AudioDeviceID devid)
  941. {
  942. if (!SDL_GetCurrentAudioDriver()) {
  943. SDL_SetError("Audio subsystem is not initialized");
  944. return NULL;
  945. }
  946. SDL_LogicalAudioDevice *logdev = NULL;
  947. // bit #1 of devid is set for physical devices and unset for logical.
  948. const SDL_bool islogical = (devid & (1<<1)) ? SDL_FALSE : SDL_TRUE;
  949. if (islogical) { // don't bother looking if it's not a logical device id value.
  950. SDL_LockRWLockForReading(current_audio.device_hash_lock);
  951. SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &logdev);
  952. SDL_UnlockRWLock(current_audio.device_hash_lock);
  953. }
  954. if (!logdev) {
  955. SDL_SetError("Invalid audio device instance ID");
  956. } else {
  957. SDL_LockMutex(logdev->physical_device->lock);
  958. }
  959. return logdev;
  960. }
  961. /* this finds the physical device associated with `devid` and locks it for use.
  962. Note that a logical device instance id will return its associated physical device! */
  963. static SDL_AudioDevice *ObtainPhysicalAudioDevice(SDL_AudioDeviceID devid)
  964. {
  965. SDL_AudioDevice *device = NULL;
  966. // bit #1 of devid is set for physical devices and unset for logical.
  967. const SDL_bool islogical = (devid & (1<<1)) ? SDL_FALSE : SDL_TRUE;
  968. if (islogical) {
  969. SDL_LogicalAudioDevice *logdev = ObtainLogicalAudioDevice(devid);
  970. if (logdev) {
  971. device = logdev->physical_device;
  972. }
  973. } else if (!SDL_GetCurrentAudioDriver()) { // (the `islogical` path, above, checks this in ObtainLogicalAudioDevice.)
  974. SDL_SetError("Audio subsystem is not initialized");
  975. } else {
  976. SDL_LockRWLockForReading(current_audio.device_hash_lock);
  977. SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &device);
  978. SDL_assert(!device || !SDL_AtomicGet(&device->condemned)); // shouldn't be in the list if pending deletion.
  979. SDL_UnlockRWLock(current_audio.device_hash_lock);
  980. if (!device) {
  981. SDL_SetError("Invalid audio device instance ID");
  982. } else {
  983. SDL_LockMutex(device->lock); // caller must unlock.
  984. }
  985. }
  986. return device;
  987. }
  988. SDL_AudioDevice *SDL_FindPhysicalAudioDeviceByCallback(SDL_bool (*callback)(SDL_AudioDevice *device, void *userdata), void *userdata)
  989. {
  990. if (!SDL_GetCurrentAudioDriver()) {
  991. SDL_SetError("Audio subsystem is not initialized");
  992. return NULL;
  993. }
  994. const void *key;
  995. const void *value;
  996. void *iter = NULL;
  997. SDL_LockRWLockForReading(current_audio.device_hash_lock);
  998. while (SDL_IterateHashTable(current_audio.device_hash, &key, &value, &iter)) {
  999. const SDL_AudioDeviceID devid = (SDL_AudioDeviceID) (uintptr_t) key;
  1000. // bit #1 of devid is set for physical devices and unset for logical.
  1001. const SDL_bool isphysical = (devid & (1<<1)) ? SDL_TRUE : SDL_FALSE;
  1002. if (isphysical) {
  1003. SDL_AudioDevice *device = (SDL_AudioDevice *) value;
  1004. SDL_assert(!SDL_AtomicGet(&device->condemned)); // shouldn't be in the list if pending deletion.
  1005. if (callback(device, userdata)) { // found it?
  1006. SDL_UnlockRWLock(current_audio.device_hash_lock);
  1007. return device;
  1008. }
  1009. }
  1010. }
  1011. SDL_UnlockRWLock(current_audio.device_hash_lock);
  1012. SDL_SetError("Device not found");
  1013. return NULL;
  1014. }
  1015. static SDL_bool TestDeviceHandleCallback(SDL_AudioDevice *device, void *handle)
  1016. {
  1017. return device->handle == handle;
  1018. }
  1019. SDL_AudioDevice *SDL_FindPhysicalAudioDeviceByHandle(void *handle)
  1020. {
  1021. return SDL_FindPhysicalAudioDeviceByCallback(TestDeviceHandleCallback, handle);
  1022. }
  1023. char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid)
  1024. {
  1025. SDL_AudioDevice *device = ObtainPhysicalAudioDevice(devid);
  1026. if (!device) {
  1027. return NULL;
  1028. }
  1029. char *retval = SDL_strdup(device->name);
  1030. if (!retval) {
  1031. SDL_OutOfMemory();
  1032. }
  1033. SDL_UnlockMutex(device->lock);
  1034. return retval;
  1035. }
  1036. int SDL_GetAudioDeviceFormat(SDL_AudioDeviceID devid, SDL_AudioSpec *spec, int *sample_frames)
  1037. {
  1038. if (!spec) {
  1039. return SDL_InvalidParamError("spec");
  1040. }
  1041. SDL_bool wants_default = SDL_FALSE;
  1042. if (devid == SDL_AUDIO_DEVICE_DEFAULT_OUTPUT) {
  1043. devid = current_audio.default_output_device_id;
  1044. wants_default = SDL_TRUE;
  1045. } else if (devid == SDL_AUDIO_DEVICE_DEFAULT_CAPTURE) {
  1046. devid = current_audio.default_capture_device_id;
  1047. wants_default = SDL_TRUE;
  1048. }
  1049. if ((devid == 0) && wants_default) {
  1050. return SDL_SetError("No default audio device available");
  1051. }
  1052. SDL_AudioDevice *device = ObtainPhysicalAudioDevice(devid);
  1053. if (!device) {
  1054. return -1;
  1055. }
  1056. SDL_copyp(spec, &device->spec);
  1057. if (sample_frames) {
  1058. *sample_frames = device->sample_frames;
  1059. }
  1060. SDL_UnlockMutex(device->lock);
  1061. return 0;
  1062. }
  1063. // this expects the device lock to be held. !!! FIXME: no it doesn't...?
  1064. static void ClosePhysicalAudioDevice(SDL_AudioDevice *device)
  1065. {
  1066. //SDL_assert(current_audio.impl.ProvidesOwnCallbackThread || ((device->thread == NULL) == (SDL_AtomicGet(&device->thread_alive) == 0)));
  1067. if (SDL_AtomicGet(&device->thread_alive)) {
  1068. SDL_AtomicSet(&device->shutdown, 1);
  1069. if (device->thread != NULL) {
  1070. SDL_WaitThread(device->thread, NULL);
  1071. device->thread = NULL;
  1072. }
  1073. SDL_AtomicSet(&device->thread_alive, 0);
  1074. }
  1075. if (device->currently_opened) {
  1076. current_audio.impl.CloseDevice(device); // if ProvidesOwnCallbackThread, this must join on any existing device thread before returning!
  1077. device->currently_opened = SDL_FALSE;
  1078. device->hidden = NULL; // just in case.
  1079. }
  1080. SDL_aligned_free(device->work_buffer);
  1081. device->work_buffer = NULL;
  1082. SDL_aligned_free(device->mix_buffer);
  1083. device->mix_buffer = NULL;
  1084. SDL_aligned_free(device->postmix_buffer);
  1085. device->postmix_buffer = NULL;
  1086. SDL_copyp(&device->spec, &device->default_spec);
  1087. device->sample_frames = 0;
  1088. device->silence_value = SDL_GetSilenceValueForFormat(device->spec.format);
  1089. SDL_AtomicSet(&device->shutdown, 0); // ready to go again.
  1090. }
  1091. void SDL_CloseAudioDevice(SDL_AudioDeviceID devid)
  1092. {
  1093. SDL_LogicalAudioDevice *logdev = ObtainLogicalAudioDevice(devid);
  1094. if (logdev) { // if NULL, maybe it was already lost?
  1095. SDL_AudioDevice *device = logdev->physical_device;
  1096. DestroyLogicalAudioDevice(logdev);
  1097. if (device->logical_devices == NULL) { // no more logical devices? Close the physical device, too.
  1098. // !!! FIXME: we _need_ to release this lock, but doing so can cause a race condition if someone opens a device while we're closing it.
  1099. SDL_UnlockMutex(device->lock); // can't hold the lock or the audio thread will deadlock while we WaitThread it.
  1100. ClosePhysicalAudioDevice(device);
  1101. } else {
  1102. SDL_UnlockMutex(device->lock); // we're set, let everything go again.
  1103. }
  1104. }
  1105. }
  1106. static SDL_AudioFormat ParseAudioFormatString(const char *string)
  1107. {
  1108. if (string) {
  1109. #define CHECK_FMT_STRING(x) if (SDL_strcmp(string, #x) == 0) { return SDL_AUDIO_##x; }
  1110. CHECK_FMT_STRING(U8);
  1111. CHECK_FMT_STRING(S8);
  1112. CHECK_FMT_STRING(S16LE);
  1113. CHECK_FMT_STRING(S16BE);
  1114. CHECK_FMT_STRING(S16);
  1115. CHECK_FMT_STRING(S32LE);
  1116. CHECK_FMT_STRING(S32BE);
  1117. CHECK_FMT_STRING(S32);
  1118. CHECK_FMT_STRING(F32LE);
  1119. CHECK_FMT_STRING(F32BE);
  1120. CHECK_FMT_STRING(F32);
  1121. #undef CHECK_FMT_STRING
  1122. }
  1123. return 0;
  1124. }
  1125. static void PrepareAudioFormat(SDL_bool iscapture, SDL_AudioSpec *spec)
  1126. {
  1127. if (spec->freq == 0) {
  1128. spec->freq = iscapture ? DEFAULT_AUDIO_CAPTURE_FREQUENCY : DEFAULT_AUDIO_OUTPUT_FREQUENCY;
  1129. const char *env = SDL_getenv("SDL_AUDIO_FREQUENCY"); // !!! FIXME: should be a hint?
  1130. if (env != NULL) {
  1131. const int val = SDL_atoi(env);
  1132. if (val > 0) {
  1133. spec->freq = val;
  1134. }
  1135. }
  1136. }
  1137. if (spec->channels == 0) {
  1138. spec->channels = iscapture ? DEFAULT_AUDIO_CAPTURE_CHANNELS : DEFAULT_AUDIO_OUTPUT_CHANNELS;;
  1139. const char *env = SDL_getenv("SDL_AUDIO_CHANNELS");
  1140. if (env != NULL) {
  1141. const int val = SDL_atoi(env);
  1142. if (val > 0) {
  1143. spec->channels = val;
  1144. }
  1145. }
  1146. }
  1147. if (spec->format == 0) {
  1148. const SDL_AudioFormat val = ParseAudioFormatString(SDL_getenv("SDL_AUDIO_FORMAT"));
  1149. spec->format = (val != 0) ? val : (iscapture ? DEFAULT_AUDIO_CAPTURE_FORMAT : DEFAULT_AUDIO_OUTPUT_FORMAT);
  1150. }
  1151. }
  1152. void SDL_UpdatedAudioDeviceFormat(SDL_AudioDevice *device)
  1153. {
  1154. device->silence_value = SDL_GetSilenceValueForFormat(device->spec.format);
  1155. device->buffer_size = device->sample_frames * SDL_AUDIO_FRAMESIZE(device->spec);
  1156. device->work_buffer_size = device->sample_frames * sizeof (float) * device->spec.channels;
  1157. device->work_buffer_size = SDL_max(device->buffer_size, device->work_buffer_size); // just in case we end up with a 64-bit audio format at some point.
  1158. }
  1159. char *SDL_GetAudioThreadName(SDL_AudioDevice *device, char *buf, size_t buflen)
  1160. {
  1161. (void)SDL_snprintf(buf, buflen, "SDLAudio%c%d", (device->iscapture) ? 'C' : 'P', (int) device->instance_id);
  1162. return buf;
  1163. }
  1164. // this expects the device lock to be held.
  1165. static int OpenPhysicalAudioDevice(SDL_AudioDevice *device, const SDL_AudioSpec *inspec)
  1166. {
  1167. SDL_assert(!device->currently_opened);
  1168. SDL_assert(device->logical_devices == NULL);
  1169. // Just pretend to open a zombie device. It can still collect logical devices on the assumption they will all migrate when the default device is officially changed.
  1170. if (SDL_AtomicGet(&device->zombie)) {
  1171. return 0; // Braaaaaaaaains.
  1172. }
  1173. SDL_AudioSpec spec;
  1174. SDL_copyp(&spec, inspec ? inspec : &device->default_spec);
  1175. PrepareAudioFormat(device->iscapture, &spec);
  1176. /* We allow the device format to change if it's better than the current settings (by various definitions of "better"). This prevents
  1177. something low quality, like an old game using S8/8000Hz audio, from ruining a music thing playing at CD quality that tries to open later.
  1178. (or some VoIP library that opens for mono output ruining your surround-sound game because it got there first).
  1179. These are just requests! The backend may change any of these values during OpenDevice method! */
  1180. device->spec.format = (SDL_AUDIO_BITSIZE(device->default_spec.format) >= SDL_AUDIO_BITSIZE(spec.format)) ? device->default_spec.format : spec.format;
  1181. device->spec.freq = SDL_max(device->default_spec.freq, spec.freq);
  1182. device->spec.channels = SDL_max(device->default_spec.channels, spec.channels);
  1183. device->sample_frames = GetDefaultSampleFramesFromFreq(device->spec.freq);
  1184. SDL_UpdatedAudioDeviceFormat(device); // start this off sane.
  1185. device->currently_opened = SDL_TRUE; // mark this true even if impl.OpenDevice fails, so we know to clean up.
  1186. if (current_audio.impl.OpenDevice(device) < 0) {
  1187. ClosePhysicalAudioDevice(device); // clean up anything the backend left half-initialized.
  1188. return -1;
  1189. }
  1190. SDL_UpdatedAudioDeviceFormat(device); // in case the backend changed things and forgot to call this.
  1191. // Allocate a scratch audio buffer
  1192. device->work_buffer = (Uint8 *)SDL_aligned_alloc(SDL_SIMDGetAlignment(), device->work_buffer_size);
  1193. if (device->work_buffer == NULL) {
  1194. ClosePhysicalAudioDevice(device);
  1195. return SDL_OutOfMemory();
  1196. }
  1197. if (device->spec.format != SDL_AUDIO_F32) {
  1198. device->mix_buffer = (Uint8 *)SDL_aligned_alloc(SDL_SIMDGetAlignment(), device->work_buffer_size);
  1199. if (device->mix_buffer == NULL) {
  1200. ClosePhysicalAudioDevice(device);
  1201. return SDL_OutOfMemory();
  1202. }
  1203. }
  1204. // Start the audio thread if necessary
  1205. SDL_AtomicSet(&device->thread_alive, 1);
  1206. if (!current_audio.impl.ProvidesOwnCallbackThread) {
  1207. const size_t stacksize = 0; // just take the system default, since audio streams might have callbacks.
  1208. char threadname[64];
  1209. SDL_GetAudioThreadName(device, threadname, sizeof (threadname));
  1210. device->thread = SDL_CreateThreadInternal(device->iscapture ? CaptureAudioThread : OutputAudioThread, threadname, stacksize, device);
  1211. if (device->thread == NULL) {
  1212. SDL_AtomicSet(&device->thread_alive, 0);
  1213. ClosePhysicalAudioDevice(device);
  1214. return SDL_SetError("Couldn't create audio thread");
  1215. }
  1216. }
  1217. return 0;
  1218. }
  1219. SDL_AudioDeviceID SDL_OpenAudioDevice(SDL_AudioDeviceID devid, const SDL_AudioSpec *spec)
  1220. {
  1221. if (!SDL_GetCurrentAudioDriver()) {
  1222. SDL_SetError("Audio subsystem is not initialized");
  1223. return 0;
  1224. }
  1225. SDL_bool wants_default = SDL_FALSE;
  1226. if (devid == SDL_AUDIO_DEVICE_DEFAULT_OUTPUT) {
  1227. devid = current_audio.default_output_device_id;
  1228. wants_default = SDL_TRUE;
  1229. } else if (devid == SDL_AUDIO_DEVICE_DEFAULT_CAPTURE) {
  1230. devid = current_audio.default_capture_device_id;
  1231. wants_default = SDL_TRUE;
  1232. }
  1233. if ((devid == 0) && wants_default) {
  1234. SDL_SetError("No default audio device available");
  1235. return 0;
  1236. }
  1237. // this will let you use a logical device to make a new logical device on the parent physical device. Could be useful?
  1238. SDL_AudioDevice *device = NULL;
  1239. const SDL_bool islogical = (devid & (1<<1)) ? SDL_FALSE : SDL_TRUE;
  1240. if (!islogical) {
  1241. device = ObtainPhysicalAudioDevice(devid);
  1242. } else {
  1243. SDL_LogicalAudioDevice *logdev = ObtainLogicalAudioDevice(devid); // this locks the physical device, too.
  1244. if (logdev) {
  1245. wants_default = logdev->opened_as_default; // was the original logical device meant to be a default? Make this one, too.
  1246. device = logdev->physical_device;
  1247. }
  1248. }
  1249. SDL_AudioDeviceID retval = 0;
  1250. if (device) {
  1251. SDL_LogicalAudioDevice *logdev = NULL;
  1252. if (!wants_default && SDL_AtomicGet(&device->zombie)) {
  1253. // uhoh, this device is undead, and just waiting for a new default device to be declared so it can hand off to it. Refuse explicit opens.
  1254. SDL_SetError("Device was already lost and can't accept new opens");
  1255. } else if ((logdev = (SDL_LogicalAudioDevice *) SDL_calloc(1, sizeof (SDL_LogicalAudioDevice))) == NULL) {
  1256. SDL_OutOfMemory();
  1257. } else if (!device->currently_opened && OpenPhysicalAudioDevice(device, spec) == -1) { // first thing using this physical device? Open at the OS level...
  1258. SDL_free(logdev);
  1259. } else {
  1260. SDL_AtomicSet(&logdev->paused, 0);
  1261. retval = logdev->instance_id = AssignAudioDeviceInstanceId(device->iscapture, /*islogical=*/SDL_TRUE);
  1262. logdev->physical_device = device;
  1263. logdev->opened_as_default = wants_default;
  1264. logdev->next = device->logical_devices;
  1265. if (device->logical_devices) {
  1266. device->logical_devices->prev = logdev;
  1267. }
  1268. device->logical_devices = logdev;
  1269. UpdateAudioStreamFormatsPhysical(device);
  1270. }
  1271. SDL_UnlockMutex(device->lock);
  1272. SDL_LockRWLockForWriting(current_audio.device_hash_lock);
  1273. const SDL_bool inserted = SDL_InsertIntoHashTable(current_audio.device_hash, (const void *) (uintptr_t) retval, logdev);
  1274. SDL_UnlockRWLock(current_audio.device_hash_lock);
  1275. if (!inserted) {
  1276. SDL_CloseAudioDevice(retval);
  1277. retval = 0;
  1278. }
  1279. }
  1280. return retval;
  1281. }
  1282. static int SetLogicalAudioDevicePauseState(SDL_AudioDeviceID devid, int value)
  1283. {
  1284. SDL_LogicalAudioDevice *logdev = ObtainLogicalAudioDevice(devid);
  1285. if (!logdev) {
  1286. return -1; // ObtainLogicalAudioDevice will have set an error.
  1287. }
  1288. SDL_AtomicSet(&logdev->paused, value);
  1289. SDL_UnlockMutex(logdev->physical_device->lock);
  1290. return 0;
  1291. }
  1292. int SDL_PauseAudioDevice(SDL_AudioDeviceID devid)
  1293. {
  1294. return SetLogicalAudioDevicePauseState(devid, 1);
  1295. }
  1296. int SDLCALL SDL_ResumeAudioDevice(SDL_AudioDeviceID devid)
  1297. {
  1298. return SetLogicalAudioDevicePauseState(devid, 0);
  1299. }
  1300. SDL_bool SDL_AudioDevicePaused(SDL_AudioDeviceID devid)
  1301. {
  1302. SDL_LogicalAudioDevice *logdev = ObtainLogicalAudioDevice(devid);
  1303. SDL_bool retval = SDL_FALSE;
  1304. if (logdev) {
  1305. if (SDL_AtomicGet(&logdev->paused)) {
  1306. retval = SDL_TRUE;
  1307. }
  1308. SDL_UnlockMutex(logdev->physical_device->lock);
  1309. }
  1310. return retval;
  1311. }
  1312. int SDL_SetAudioPostmixCallback(SDL_AudioDeviceID devid, SDL_AudioPostmixCallback callback, void *userdata)
  1313. {
  1314. SDL_LogicalAudioDevice *logdev = ObtainLogicalAudioDevice(devid);
  1315. int retval = 0;
  1316. if (logdev) {
  1317. SDL_AudioDevice *device = logdev->physical_device;
  1318. if (callback && !device->postmix_buffer) {
  1319. device->postmix_buffer = (float *)SDL_aligned_alloc(SDL_SIMDGetAlignment(), device->work_buffer_size);
  1320. if (device->postmix_buffer == NULL) {
  1321. retval = SDL_OutOfMemory();
  1322. }
  1323. }
  1324. if (retval == 0) {
  1325. logdev->postmix = callback;
  1326. logdev->postmix_userdata = userdata;
  1327. if (device->iscapture) {
  1328. for (SDL_AudioStream *stream = logdev->bound_streams; stream != NULL; stream = stream->next_binding) {
  1329. // set the proper end of the stream to the device's format.
  1330. // SDL_SetAudioStreamFormat does a ton of validation just to memcpy an audiospec.
  1331. SDL_LockMutex(stream->lock);
  1332. stream->src_spec.format = callback ? SDL_AUDIO_F32 : device->spec.format;
  1333. SDL_UnlockMutex(stream->lock);
  1334. }
  1335. }
  1336. }
  1337. UpdateAudioStreamFormatsPhysical(device);
  1338. SDL_UnlockMutex(device->lock);
  1339. }
  1340. return retval;
  1341. }
  1342. int SDL_BindAudioStreams(SDL_AudioDeviceID devid, SDL_AudioStream **streams, int num_streams)
  1343. {
  1344. const SDL_bool islogical = (devid & (1<<1)) ? SDL_FALSE : SDL_TRUE;
  1345. SDL_LogicalAudioDevice *logdev;
  1346. if (num_streams == 0) {
  1347. return 0; // nothing to do
  1348. } else if (num_streams < 0) {
  1349. return SDL_InvalidParamError("num_streams");
  1350. } else if (streams == NULL) {
  1351. return SDL_InvalidParamError("streams");
  1352. } else if (!islogical) {
  1353. return SDL_SetError("Audio streams are bound to device ids from SDL_OpenAudioDevice, not raw physical devices");
  1354. } else if ((logdev = ObtainLogicalAudioDevice(devid)) == NULL) {
  1355. return -1; // ObtainLogicalAudioDevice set the error message.
  1356. } else if (logdev->simplified) {
  1357. SDL_UnlockMutex(logdev->physical_device->lock);
  1358. return SDL_SetError("Cannot change stream bindings on device opened with SDL_OpenAudioDeviceStream");
  1359. }
  1360. // !!! FIXME: We'll set the device's side's format below, but maybe we should refuse to bind a stream if the app's side doesn't have a format set yet.
  1361. // !!! FIXME: Actually, why do we allow there to be an invalid format, again?
  1362. // make sure start of list is sane.
  1363. SDL_assert(!logdev->bound_streams || (logdev->bound_streams->prev_binding == NULL));
  1364. SDL_AudioDevice *device = logdev->physical_device;
  1365. const SDL_bool iscapture = device->iscapture;
  1366. int retval = 0;
  1367. // lock all the streams upfront, so we can verify they aren't bound elsewhere and add them all in one block, as this is intended to add everything or nothing.
  1368. for (int i = 0; i < num_streams; i++) {
  1369. SDL_AudioStream *stream = streams[i];
  1370. if (stream == NULL) {
  1371. retval = SDL_SetError("Stream #%d is NULL", i);
  1372. } else {
  1373. SDL_LockMutex(stream->lock);
  1374. SDL_assert((stream->bound_device == NULL) == ((stream->prev_binding == NULL) || (stream->next_binding == NULL)));
  1375. if (stream->bound_device) {
  1376. retval = SDL_SetError("Stream #%d is already bound to a device", i);
  1377. }
  1378. }
  1379. if (retval != 0) {
  1380. int j;
  1381. for (j = 0; j <= i; j++) {
  1382. SDL_UnlockMutex(streams[j]->lock);
  1383. }
  1384. break;
  1385. }
  1386. }
  1387. if (retval == 0) {
  1388. // Now that everything is verified, chain everything together.
  1389. for (int i = 0; i < num_streams; i++) {
  1390. SDL_AudioStream *stream = streams[i];
  1391. stream->bound_device = logdev;
  1392. stream->prev_binding = NULL;
  1393. stream->next_binding = logdev->bound_streams;
  1394. if (logdev->bound_streams) {
  1395. logdev->bound_streams->prev_binding = stream;
  1396. }
  1397. logdev->bound_streams = stream;
  1398. if (iscapture) {
  1399. stream->src_spec.format = logdev->postmix ? SDL_AUDIO_F32 : device->spec.format;
  1400. }
  1401. SDL_UnlockMutex(stream->lock);
  1402. }
  1403. }
  1404. UpdateAudioStreamFormatsPhysical(device);
  1405. SDL_UnlockMutex(device->lock);
  1406. return retval;
  1407. }
  1408. int SDL_BindAudioStream(SDL_AudioDeviceID devid, SDL_AudioStream *stream)
  1409. {
  1410. return SDL_BindAudioStreams(devid, &stream, 1);
  1411. }
  1412. void SDL_UnbindAudioStreams(SDL_AudioStream **streams, int num_streams)
  1413. {
  1414. /* to prevent deadlock when holding both locks, we _must_ lock the device first, and the stream second, as that is the order the audio thread will do it.
  1415. But this means we have an unlikely, pathological case where a stream could change its binding between when we lookup its bound device and when we lock everything,
  1416. so we double-check here. */
  1417. for (int i = 0; i < num_streams; i++) {
  1418. SDL_AudioStream *stream = streams[i];
  1419. if (!stream) {
  1420. continue; // nothing to do, it's a NULL stream.
  1421. }
  1422. while (SDL_TRUE) {
  1423. SDL_LockMutex(stream->lock); // lock to check this and then release it, in case the device isn't locked yet.
  1424. SDL_LogicalAudioDevice *bounddev = stream->bound_device;
  1425. SDL_UnlockMutex(stream->lock);
  1426. // lock in correct order.
  1427. if (bounddev) {
  1428. SDL_LockMutex(bounddev->physical_device->lock); // this requires recursive mutexes, since we're likely locking the same device multiple times.
  1429. }
  1430. SDL_LockMutex(stream->lock);
  1431. if (bounddev == stream->bound_device) {
  1432. break; // the binding didn't change in the small window where it could, so we're good.
  1433. } else {
  1434. SDL_UnlockMutex(stream->lock); // it changed bindings! Try again.
  1435. if (bounddev) {
  1436. SDL_UnlockMutex(bounddev->physical_device->lock);
  1437. }
  1438. }
  1439. }
  1440. }
  1441. // everything is locked, start unbinding streams.
  1442. for (int i = 0; i < num_streams; i++) {
  1443. SDL_AudioStream *stream = streams[i];
  1444. // don't allow unbinding from "simplified" devices (opened with SDL_OpenAudioDeviceStream). Just ignore them.
  1445. if (stream && stream->bound_device && !stream->bound_device->simplified) {
  1446. if (stream->bound_device->bound_streams == stream) {
  1447. SDL_assert(stream->prev_binding == NULL);
  1448. stream->bound_device->bound_streams = stream->next_binding;
  1449. }
  1450. if (stream->prev_binding) {
  1451. stream->prev_binding->next_binding = stream->next_binding;
  1452. }
  1453. if (stream->next_binding) {
  1454. stream->next_binding->prev_binding = stream->prev_binding;
  1455. }
  1456. stream->prev_binding = stream->next_binding = NULL;
  1457. }
  1458. }
  1459. // Finalize and unlock everything.
  1460. for (int i = 0; i < num_streams; i++) {
  1461. SDL_AudioStream *stream = streams[i];
  1462. if (stream && stream->bound_device) {
  1463. SDL_LogicalAudioDevice *logdev = stream->bound_device;
  1464. stream->bound_device = NULL;
  1465. SDL_UnlockMutex(stream->lock);
  1466. if (logdev) {
  1467. UpdateAudioStreamFormatsPhysical(logdev->physical_device);
  1468. SDL_UnlockMutex(logdev->physical_device->lock);
  1469. }
  1470. }
  1471. }
  1472. }
  1473. void SDL_UnbindAudioStream(SDL_AudioStream *stream)
  1474. {
  1475. SDL_UnbindAudioStreams(&stream, 1);
  1476. }
  1477. SDL_AudioDeviceID SDL_GetAudioStreamDevice(SDL_AudioStream *stream)
  1478. {
  1479. SDL_AudioDeviceID retval = 0;
  1480. if (stream) {
  1481. SDL_LockMutex(stream->lock);
  1482. if (stream->bound_device) {
  1483. retval = stream->bound_device->instance_id;
  1484. }
  1485. SDL_UnlockMutex(stream->lock);
  1486. }
  1487. return retval;
  1488. }
  1489. SDL_AudioStream *SDL_OpenAudioDeviceStream(SDL_AudioDeviceID devid, const SDL_AudioSpec *spec, SDL_AudioStreamCallback callback, void *userdata)
  1490. {
  1491. SDL_AudioDeviceID logdevid = SDL_OpenAudioDevice(devid, spec);
  1492. if (!logdevid) {
  1493. return NULL; // error string should already be set.
  1494. }
  1495. SDL_LogicalAudioDevice *logdev = ObtainLogicalAudioDevice(logdevid);
  1496. if (logdev == NULL) { // this shouldn't happen, but just in case.
  1497. SDL_CloseAudioDevice(logdevid);
  1498. return NULL; // error string should already be set.
  1499. }
  1500. SDL_AudioDevice *physdevice = logdev->physical_device;
  1501. SDL_assert(physdevice != NULL);
  1502. SDL_AtomicSet(&logdev->paused, 1); // start the device paused, to match SDL2.
  1503. SDL_UnlockMutex(physdevice->lock); // we don't need to hold the lock for any of this.
  1504. const SDL_bool iscapture = physdevice->iscapture;
  1505. SDL_AudioStream *stream = NULL;
  1506. if (iscapture) {
  1507. stream = SDL_CreateAudioStream(&physdevice->spec, spec);
  1508. } else {
  1509. stream = SDL_CreateAudioStream(spec, &physdevice->spec);
  1510. }
  1511. if (!stream) {
  1512. SDL_CloseAudioDevice(logdevid);
  1513. return NULL; // error string should already be set.
  1514. }
  1515. if (SDL_BindAudioStream(logdevid, stream) == -1) {
  1516. SDL_DestroyAudioStream(stream);
  1517. SDL_CloseAudioDevice(logdevid);
  1518. return NULL; // error string should already be set.
  1519. }
  1520. logdev->simplified = SDL_TRUE; // forbid further binding changes on this logical device.
  1521. stream->simplified = SDL_TRUE; // so we know to close the audio device when this is destroyed.
  1522. if (callback) {
  1523. int rc;
  1524. if (iscapture) {
  1525. rc = SDL_SetAudioStreamPutCallback(stream, callback, userdata);
  1526. } else {
  1527. rc = SDL_SetAudioStreamGetCallback(stream, callback, userdata);
  1528. }
  1529. SDL_assert(rc == 0); // should only fail if stream==NULL atm.
  1530. }
  1531. return stream; // ready to rock.
  1532. }
  1533. #define NUM_FORMATS 8
  1534. static const SDL_AudioFormat format_list[NUM_FORMATS][NUM_FORMATS + 1] = {
  1535. { SDL_AUDIO_U8, SDL_AUDIO_S8, SDL_AUDIO_S16LE, SDL_AUDIO_S16BE, SDL_AUDIO_S32LE, SDL_AUDIO_S32BE, SDL_AUDIO_F32LE, SDL_AUDIO_F32BE, 0 },
  1536. { SDL_AUDIO_S8, SDL_AUDIO_U8, SDL_AUDIO_S16LE, SDL_AUDIO_S16BE, SDL_AUDIO_S32LE, SDL_AUDIO_S32BE, SDL_AUDIO_F32LE, SDL_AUDIO_F32BE, 0 },
  1537. { SDL_AUDIO_S16LE, SDL_AUDIO_S16BE, SDL_AUDIO_S32LE, SDL_AUDIO_S32BE, SDL_AUDIO_F32LE, SDL_AUDIO_F32BE, SDL_AUDIO_U8, SDL_AUDIO_S8, 0 },
  1538. { SDL_AUDIO_S16BE, SDL_AUDIO_S16LE, SDL_AUDIO_S32BE, SDL_AUDIO_S32LE, SDL_AUDIO_F32BE, SDL_AUDIO_F32LE, SDL_AUDIO_U8, SDL_AUDIO_S8, 0 },
  1539. { SDL_AUDIO_S32LE, SDL_AUDIO_S32BE, SDL_AUDIO_F32LE, SDL_AUDIO_F32BE, SDL_AUDIO_S16LE, SDL_AUDIO_S16BE, SDL_AUDIO_U8, SDL_AUDIO_S8, 0 },
  1540. { SDL_AUDIO_S32BE, SDL_AUDIO_S32LE, SDL_AUDIO_F32BE, SDL_AUDIO_F32LE, SDL_AUDIO_S16BE, SDL_AUDIO_S16LE, SDL_AUDIO_U8, SDL_AUDIO_S8, 0 },
  1541. { SDL_AUDIO_F32LE, SDL_AUDIO_F32BE, SDL_AUDIO_S32LE, SDL_AUDIO_S32BE, SDL_AUDIO_S16LE, SDL_AUDIO_S16BE, SDL_AUDIO_U8, SDL_AUDIO_S8, 0 },
  1542. { SDL_AUDIO_F32BE, SDL_AUDIO_F32LE, SDL_AUDIO_S32BE, SDL_AUDIO_S32LE, SDL_AUDIO_S16BE, SDL_AUDIO_S16LE, SDL_AUDIO_U8, SDL_AUDIO_S8, 0 },
  1543. };
  1544. const SDL_AudioFormat *SDL_ClosestAudioFormats(SDL_AudioFormat format)
  1545. {
  1546. for (int i = 0; i < NUM_FORMATS; i++) {
  1547. if (format_list[i][0] == format) {
  1548. return &format_list[i][0];
  1549. }
  1550. }
  1551. return &format_list[0][NUM_FORMATS]; // not found; return what looks like a list with only a zero in it.
  1552. }
  1553. int SDL_GetSilenceValueForFormat(SDL_AudioFormat format)
  1554. {
  1555. return (format == SDL_AUDIO_U8) ? 0x80 : 0x00;
  1556. }
  1557. // called internally by backends when the system default device changes.
  1558. void SDL_DefaultAudioDeviceChanged(SDL_AudioDevice *new_default_device)
  1559. {
  1560. if (new_default_device == NULL) { // !!! FIXME: what should we do in this case? Maybe all devices are lost, so there _isn't_ a default?
  1561. return; // uhoh.
  1562. }
  1563. const SDL_bool iscapture = new_default_device->iscapture;
  1564. const SDL_AudioDeviceID current_devid = iscapture ? current_audio.default_capture_device_id : current_audio.default_output_device_id;
  1565. if (new_default_device->instance_id == current_devid) {
  1566. return; // this is already the default.
  1567. }
  1568. SDL_LockMutex(new_default_device->lock);
  1569. SDL_AudioDevice *current_default_device = ObtainPhysicalAudioDevice(current_devid);
  1570. /* change the official default ID over while we have locks on both devices, so if something raced to open the default during
  1571. this, it either gets the new device or is ready on the old and can be migrated. */
  1572. if (iscapture) {
  1573. current_audio.default_capture_device_id = new_default_device->instance_id;
  1574. } else {
  1575. current_audio.default_output_device_id = new_default_device->instance_id;
  1576. }
  1577. if (current_default_device) {
  1578. // migrate any logical devices that were opened as a default to the new physical device...
  1579. SDL_assert(current_default_device->iscapture == iscapture);
  1580. // See if we have to open the new physical device, and if so, find the best audiospec for it.
  1581. SDL_AudioSpec spec;
  1582. SDL_bool needs_migration = SDL_FALSE;
  1583. SDL_zero(spec);
  1584. for (SDL_LogicalAudioDevice *logdev = current_default_device->logical_devices; logdev != NULL; logdev = logdev->next) {
  1585. if (logdev->opened_as_default) {
  1586. needs_migration = SDL_TRUE;
  1587. for (SDL_AudioStream *stream = logdev->bound_streams; stream != NULL; stream = stream->next_binding) {
  1588. const SDL_AudioSpec *streamspec = iscapture ? &stream->dst_spec : &stream->src_spec;
  1589. if (SDL_AUDIO_BITSIZE(streamspec->format) > SDL_AUDIO_BITSIZE(spec.format)) {
  1590. spec.format = streamspec->format;
  1591. }
  1592. if (streamspec->channels > spec.channels) {
  1593. spec.channels = streamspec->channels;
  1594. }
  1595. if (streamspec->freq > spec.freq) {
  1596. spec.freq = streamspec->freq;
  1597. }
  1598. }
  1599. }
  1600. }
  1601. if (needs_migration) {
  1602. if (new_default_device->logical_devices == NULL) { // New default physical device not been opened yet? Open at the OS level...
  1603. if (OpenPhysicalAudioDevice(new_default_device, &spec) == -1) {
  1604. needs_migration = SDL_FALSE; // uhoh, just leave everything on the old default, nothing to be done.
  1605. }
  1606. }
  1607. }
  1608. if (needs_migration) {
  1609. const SDL_bool spec_changed = !AUDIO_SPECS_EQUAL(current_default_device->spec, new_default_device->spec);
  1610. const SDL_bool post_fmt_event = (spec_changed && SDL_EventEnabled(SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED)) ? SDL_TRUE : SDL_FALSE;
  1611. SDL_LogicalAudioDevice *next = NULL;
  1612. for (SDL_LogicalAudioDevice *logdev = current_default_device->logical_devices; logdev != NULL; logdev = next) {
  1613. next = logdev->next;
  1614. if (!logdev->opened_as_default) {
  1615. continue; // not opened as a default, leave it on the current physical device.
  1616. }
  1617. // now migrate the logical device.
  1618. if (logdev->next) {
  1619. logdev->next->prev = logdev->prev;
  1620. }
  1621. if (logdev->prev) {
  1622. logdev->prev->next = logdev->next;
  1623. }
  1624. if (current_default_device->logical_devices == logdev) {
  1625. current_default_device->logical_devices = logdev->next;
  1626. }
  1627. logdev->physical_device = new_default_device;
  1628. logdev->prev = NULL;
  1629. logdev->next = new_default_device->logical_devices;
  1630. new_default_device->logical_devices = logdev;
  1631. // Post an event for each logical device we moved.
  1632. if (post_fmt_event) {
  1633. SDL_Event event;
  1634. SDL_zero(event);
  1635. event.type = SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED;
  1636. event.common.timestamp = 0;
  1637. event.adevice.iscapture = iscapture ? 1 : 0;
  1638. event.adevice.which = logdev->instance_id;
  1639. SDL_PushEvent(&event);
  1640. }
  1641. }
  1642. UpdateAudioStreamFormatsPhysical(current_default_device);
  1643. UpdateAudioStreamFormatsPhysical(new_default_device);
  1644. if (current_default_device->logical_devices == NULL) { // nothing left on the current physical device, close it.
  1645. // !!! FIXME: we _need_ to release this lock, but doing so can cause a race condition if someone opens a device while we're closing it.
  1646. SDL_UnlockMutex(current_default_device->lock); // can't hold the lock or the audio thread will deadlock while we WaitThread it.
  1647. ClosePhysicalAudioDevice(current_default_device);
  1648. SDL_LockMutex(current_default_device->lock); // we're about to unlock this again, so make sure the locks match.
  1649. }
  1650. }
  1651. SDL_UnlockMutex(current_default_device->lock);
  1652. }
  1653. SDL_UnlockMutex(new_default_device->lock);
  1654. // was current device already dead and just kept around to migrate to a new default device? Now we can kill it. Aim for the brain.
  1655. if (current_default_device && SDL_AtomicGet(&current_default_device->zombie)) {
  1656. SDL_AudioDeviceDisconnected(current_default_device); // Call again, now that we're not the default; this will remove from device list, send removal events, and destroy the SDL_AudioDevice.
  1657. }
  1658. }
  1659. int SDL_AudioDeviceFormatChangedAlreadyLocked(SDL_AudioDevice *device, const SDL_AudioSpec *newspec, int new_sample_frames)
  1660. {
  1661. const int orig_work_buffer_size = device->work_buffer_size;
  1662. if (AUDIO_SPECS_EQUAL(device->spec, *newspec) && new_sample_frames == device->sample_frames) {
  1663. return 0; // we're already in that format.
  1664. }
  1665. SDL_copyp(&device->spec, newspec);
  1666. UpdateAudioStreamFormatsPhysical(device);
  1667. SDL_bool kill_device = SDL_FALSE;
  1668. device->sample_frames = new_sample_frames;
  1669. SDL_UpdatedAudioDeviceFormat(device);
  1670. if (device->work_buffer && (device->work_buffer_size > orig_work_buffer_size)) {
  1671. SDL_aligned_free(device->work_buffer);
  1672. device->work_buffer = (Uint8 *)SDL_aligned_alloc(SDL_SIMDGetAlignment(), device->work_buffer_size);
  1673. if (!device->work_buffer) {
  1674. kill_device = SDL_TRUE;
  1675. }
  1676. if (device->postmix_buffer) {
  1677. SDL_aligned_free(device->postmix_buffer);
  1678. device->postmix_buffer = (float *)SDL_aligned_alloc(SDL_SIMDGetAlignment(), device->work_buffer_size);
  1679. if (!device->postmix_buffer) {
  1680. kill_device = SDL_TRUE;
  1681. }
  1682. }
  1683. SDL_aligned_free(device->mix_buffer);
  1684. device->mix_buffer = NULL;
  1685. if (device->spec.format != SDL_AUDIO_F32) {
  1686. device->mix_buffer = (Uint8 *)SDL_aligned_alloc(SDL_SIMDGetAlignment(), device->work_buffer_size);
  1687. if (!device->mix_buffer) {
  1688. kill_device = SDL_TRUE;
  1689. }
  1690. }
  1691. }
  1692. // Post an event for the physical device, and each logical device on this physical device.
  1693. if (!kill_device && SDL_EventEnabled(SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED)) {
  1694. SDL_Event event;
  1695. SDL_zero(event);
  1696. event.type = SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED;
  1697. event.common.timestamp = 0;
  1698. event.adevice.iscapture = device->iscapture ? 1 : 0;
  1699. event.adevice.which = device->instance_id;
  1700. SDL_PushEvent(&event);
  1701. for (SDL_LogicalAudioDevice *logdev = device->logical_devices; logdev != NULL; logdev = logdev->next) {
  1702. event.adevice.which = logdev->instance_id;
  1703. SDL_PushEvent(&event);
  1704. }
  1705. }
  1706. return kill_device ? -1 : 0;
  1707. }
  1708. int SDL_AudioDeviceFormatChanged(SDL_AudioDevice *device, const SDL_AudioSpec *newspec, int new_sample_frames)
  1709. {
  1710. SDL_LockMutex(device->lock);
  1711. const int retval = SDL_AudioDeviceFormatChangedAlreadyLocked(device, newspec, new_sample_frames);
  1712. SDL_UnlockMutex(device->lock);
  1713. return retval;
  1714. }