testautomation_audio.c 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559
  1. /**
  2. * Original code: automated SDL audio test written by Edgar Simo "bobbens"
  3. * New/updated tests: aschiffler at ferzkopp dot net
  4. */
  5. /* quiet windows compiler warnings */
  6. #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
  7. #define _CRT_SECURE_NO_WARNINGS
  8. #endif
  9. #include <math.h>
  10. #include <stdio.h>
  11. #include <SDL3/SDL.h>
  12. #include <SDL3/SDL_test.h>
  13. #include "testautomation_suites.h"
  14. /* ================= Test Case Implementation ================== */
  15. /* Fixture */
  16. static void SDLCALL audioSetUp(void **arg)
  17. {
  18. /* Start SDL audio subsystem */
  19. bool ret = SDL_InitSubSystem(SDL_INIT_AUDIO);
  20. SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_AUDIO)");
  21. SDLTest_AssertCheck(ret == true, "Check result from SDL_InitSubSystem(SDL_INIT_AUDIO)");
  22. if (!ret) {
  23. SDLTest_LogError("%s", SDL_GetError());
  24. }
  25. }
  26. static void SDLCALL audioTearDown(void *arg)
  27. {
  28. /* Remove a possibly created file from SDL disk writer audio driver; ignore errors */
  29. (void)remove("sdlaudio.raw");
  30. SDLTest_AssertPass("Cleanup of test files completed");
  31. }
  32. #if 0 /* !!! FIXME: maybe update this? */
  33. /* Global counter for callback invocation */
  34. static int g_audio_testCallbackCounter;
  35. /* Global accumulator for total callback length */
  36. static int g_audio_testCallbackLength;
  37. /* Test callback function */
  38. static void SDLCALL audio_testCallback(void *userdata, Uint8 *stream, int len)
  39. {
  40. /* track that callback was called */
  41. g_audio_testCallbackCounter++;
  42. g_audio_testCallbackLength += len;
  43. }
  44. #endif
  45. static SDL_AudioDeviceID g_audio_id = 0;
  46. /* Test case functions */
  47. /**
  48. * Stop and restart audio subsystem
  49. *
  50. * \sa SDL_QuitSubSystem
  51. * \sa SDL_InitSubSystem
  52. */
  53. static int SDLCALL audio_quitInitAudioSubSystem(void *arg)
  54. {
  55. /* Stop SDL audio subsystem */
  56. SDL_QuitSubSystem(SDL_INIT_AUDIO);
  57. SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");
  58. /* Restart audio again */
  59. audioSetUp(NULL);
  60. return TEST_COMPLETED;
  61. }
  62. /**
  63. * Start and stop audio directly
  64. *
  65. * \sa SDL_InitAudio
  66. * \sa SDL_QuitAudio
  67. */
  68. static int SDLCALL audio_initQuitAudio(void *arg)
  69. {
  70. int result;
  71. int i, iMax;
  72. const char *audioDriver;
  73. const char *hint = SDL_GetHint(SDL_HINT_AUDIO_DRIVER);
  74. /* Stop SDL audio subsystem */
  75. SDL_QuitSubSystem(SDL_INIT_AUDIO);
  76. SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");
  77. /* Loop over all available audio drivers */
  78. iMax = SDL_GetNumAudioDrivers();
  79. SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers()");
  80. SDLTest_AssertCheck(iMax > 0, "Validate number of audio drivers; expected: >0 got: %d", iMax);
  81. for (i = 0; i < iMax; i++) {
  82. audioDriver = SDL_GetAudioDriver(i);
  83. SDLTest_AssertPass("Call to SDL_GetAudioDriver(%d)", i);
  84. SDLTest_Assert(audioDriver != NULL, "Audio driver name is not NULL");
  85. SDLTest_AssertCheck(audioDriver[0] != '\0', "Audio driver name is not empty; got: %s", audioDriver); /* NOLINT(clang-analyzer-core.NullDereference): Checked for NULL above */
  86. if (hint && SDL_strcmp(audioDriver, hint) != 0) {
  87. continue;
  88. }
  89. /* Call Init */
  90. SDL_SetHint(SDL_HINT_AUDIO_DRIVER, audioDriver);
  91. result = SDL_InitSubSystem(SDL_INIT_AUDIO);
  92. SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_AUDIO) with driver='%s'", audioDriver);
  93. SDLTest_AssertCheck(result == true, "Validate result value; expected: true got: %d", result);
  94. /* Call Quit */
  95. SDL_QuitSubSystem(SDL_INIT_AUDIO);
  96. SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");
  97. }
  98. /* NULL driver specification */
  99. audioDriver = NULL;
  100. /* Call Init */
  101. SDL_SetHint(SDL_HINT_AUDIO_DRIVER, audioDriver);
  102. result = SDL_InitSubSystem(SDL_INIT_AUDIO);
  103. SDLTest_AssertPass("Call to SDL_AudioInit(NULL)");
  104. SDLTest_AssertCheck(result == true, "Validate result value; expected: true got: %d", result);
  105. /* Call Quit */
  106. SDL_QuitSubSystem(SDL_INIT_AUDIO);
  107. SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");
  108. /* Restart audio again */
  109. audioSetUp(NULL);
  110. return TEST_COMPLETED;
  111. }
  112. /**
  113. * Start, open, close and stop audio
  114. *
  115. * \sa SDL_InitAudio
  116. * \sa SDL_OpenAudioDevice
  117. * \sa SDL_CloseAudioDevice
  118. * \sa SDL_QuitAudio
  119. */
  120. static int SDLCALL audio_initOpenCloseQuitAudio(void *arg)
  121. {
  122. int result;
  123. int i, iMax, j, k;
  124. const char *audioDriver;
  125. SDL_AudioSpec desired;
  126. const char *hint = SDL_GetHint(SDL_HINT_AUDIO_DRIVER);
  127. /* Stop SDL audio subsystem */
  128. SDL_QuitSubSystem(SDL_INIT_AUDIO);
  129. SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");
  130. /* Loop over all available audio drivers */
  131. iMax = SDL_GetNumAudioDrivers();
  132. SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers()");
  133. SDLTest_AssertCheck(iMax > 0, "Validate number of audio drivers; expected: >0 got: %d", iMax);
  134. for (i = 0; i < iMax; i++) {
  135. audioDriver = SDL_GetAudioDriver(i);
  136. SDLTest_AssertPass("Call to SDL_GetAudioDriver(%d)", i);
  137. SDLTest_Assert(audioDriver != NULL, "Audio driver name is not NULL");
  138. SDLTest_AssertCheck(audioDriver[0] != '\0', "Audio driver name is not empty; got: %s", audioDriver); /* NOLINT(clang-analyzer-core.NullDereference): Checked for NULL above */
  139. if (hint && SDL_strcmp(audioDriver, hint) != 0) {
  140. continue;
  141. }
  142. /* Change specs */
  143. for (j = 0; j < 2; j++) {
  144. /* Call Init */
  145. SDL_SetHint(SDL_HINT_AUDIO_DRIVER, audioDriver);
  146. result = SDL_InitSubSystem(SDL_INIT_AUDIO);
  147. SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_AUDIO) with driver='%s'", audioDriver);
  148. SDLTest_AssertCheck(result == true, "Validate result value; expected: true got: %d", result);
  149. /* Set spec */
  150. SDL_zero(desired);
  151. switch (j) {
  152. case 0:
  153. /* Set standard desired spec */
  154. desired.freq = 22050;
  155. desired.format = SDL_AUDIO_S16;
  156. desired.channels = 2;
  157. break;
  158. case 1:
  159. /* Set custom desired spec */
  160. desired.freq = 48000;
  161. desired.format = SDL_AUDIO_F32;
  162. desired.channels = 2;
  163. break;
  164. }
  165. /* Call Open (maybe multiple times) */
  166. for (k = 0; k <= j; k++) {
  167. result = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &desired);
  168. if (k == 0) {
  169. g_audio_id = result;
  170. }
  171. SDLTest_AssertPass("Call to SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, desired_spec_%d), call %d", j, k + 1);
  172. SDLTest_AssertCheck(result > 0, "Verify return value; expected: > 0, got: %d", result);
  173. }
  174. /* Call Close (maybe multiple times) */
  175. for (k = 0; k <= j; k++) {
  176. SDL_CloseAudioDevice(g_audio_id);
  177. SDLTest_AssertPass("Call to SDL_CloseAudioDevice(), call %d", k + 1);
  178. }
  179. /* Call Quit (maybe multiple times) */
  180. for (k = 0; k <= j; k++) {
  181. SDL_QuitSubSystem(SDL_INIT_AUDIO);
  182. SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO), call %d", k + 1);
  183. }
  184. } /* spec loop */
  185. } /* driver loop */
  186. /* Restart audio again */
  187. audioSetUp(NULL);
  188. return TEST_COMPLETED;
  189. }
  190. /**
  191. * Pause and unpause audio
  192. *
  193. * \sa SDL_PauseAudioDevice
  194. * \sa SDL_PlayAudioDevice
  195. */
  196. static int SDLCALL audio_pauseUnpauseAudio(void *arg)
  197. {
  198. int iMax;
  199. int i, j /*, k, l*/;
  200. int result;
  201. const char *audioDriver;
  202. SDL_AudioSpec desired;
  203. const char *hint = SDL_GetHint(SDL_HINT_AUDIO_DRIVER);
  204. /* Stop SDL audio subsystem */
  205. SDL_QuitSubSystem(SDL_INIT_AUDIO);
  206. SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");
  207. /* Loop over all available audio drivers */
  208. iMax = SDL_GetNumAudioDrivers();
  209. SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers()");
  210. SDLTest_AssertCheck(iMax > 0, "Validate number of audio drivers; expected: >0 got: %d", iMax);
  211. for (i = 0; i < iMax; i++) {
  212. audioDriver = SDL_GetAudioDriver(i);
  213. SDLTest_AssertPass("Call to SDL_GetAudioDriver(%d)", i);
  214. SDLTest_Assert(audioDriver != NULL, "Audio driver name is not NULL");
  215. SDLTest_AssertCheck(audioDriver[0] != '\0', "Audio driver name is not empty; got: %s", audioDriver); /* NOLINT(clang-analyzer-core.NullDereference): Checked for NULL above */
  216. if (hint && SDL_strcmp(audioDriver, hint) != 0) {
  217. continue;
  218. }
  219. /* Change specs */
  220. for (j = 0; j < 2; j++) {
  221. /* Call Init */
  222. SDL_SetHint(SDL_HINT_AUDIO_DRIVER, audioDriver);
  223. result = SDL_InitSubSystem(SDL_INIT_AUDIO);
  224. SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_AUDIO) with driver='%s'", audioDriver);
  225. SDLTest_AssertCheck(result == true, "Validate result value; expected: true got: %d", result);
  226. /* Set spec */
  227. SDL_zero(desired);
  228. switch (j) {
  229. case 0:
  230. /* Set standard desired spec */
  231. desired.freq = 22050;
  232. desired.format = SDL_AUDIO_S16;
  233. desired.channels = 2;
  234. break;
  235. case 1:
  236. /* Set custom desired spec */
  237. desired.freq = 48000;
  238. desired.format = SDL_AUDIO_F32;
  239. desired.channels = 2;
  240. break;
  241. }
  242. /* Call Open */
  243. g_audio_id = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &desired);
  244. result = g_audio_id;
  245. SDLTest_AssertPass("Call to SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, desired_spec_%d)", j);
  246. SDLTest_AssertCheck(result > 0, "Verify return value; expected > 0 got: %d", result);
  247. #if 0 /* !!! FIXME: maybe update this? */
  248. /* Start and stop audio multiple times */
  249. for (l = 0; l < 3; l++) {
  250. SDLTest_Log("Pause/Unpause iteration: %d", l + 1);
  251. /* Reset callback counters */
  252. g_audio_testCallbackCounter = 0;
  253. g_audio_testCallbackLength = 0;
  254. /* Un-pause audio to start playing (maybe multiple times) */
  255. for (k = 0; k <= j; k++) {
  256. SDL_PlayAudioDevice(g_audio_id);
  257. SDLTest_AssertPass("Call to SDL_PlayAudioDevice(g_audio_id), call %d", k + 1);
  258. }
  259. /* Wait for callback */
  260. int totalDelay = 0;
  261. do {
  262. SDL_Delay(10);
  263. totalDelay += 10;
  264. } while (g_audio_testCallbackCounter == 0 && totalDelay < 1000);
  265. SDLTest_AssertCheck(g_audio_testCallbackCounter > 0, "Verify callback counter; expected: >0 got: %d", g_audio_testCallbackCounter);
  266. SDLTest_AssertCheck(g_audio_testCallbackLength > 0, "Verify callback length; expected: >0 got: %d", g_audio_testCallbackLength);
  267. /* Pause audio to stop playing (maybe multiple times) */
  268. for (k = 0; k <= j; k++) {
  269. const int pause_on = (k == 0) ? 1 : SDLTest_RandomIntegerInRange(99, 9999);
  270. if (pause_on) {
  271. SDL_PauseAudioDevice(g_audio_id);
  272. SDLTest_AssertPass("Call to SDL_PauseAudioDevice(g_audio_id), call %d", k + 1);
  273. } else {
  274. SDL_PlayAudioDevice(g_audio_id);
  275. SDLTest_AssertPass("Call to SDL_PlayAudioDevice(g_audio_id), call %d", k + 1);
  276. }
  277. }
  278. /* Ensure callback is not called again */
  279. const int originalCounter = g_audio_testCallbackCounter;
  280. SDL_Delay(totalDelay + 10);
  281. SDLTest_AssertCheck(originalCounter == g_audio_testCallbackCounter, "Verify callback counter; expected: %d, got: %d", originalCounter, g_audio_testCallbackCounter);
  282. }
  283. #endif
  284. /* Call Close */
  285. SDL_CloseAudioDevice(g_audio_id);
  286. SDLTest_AssertPass("Call to SDL_CloseAudioDevice()");
  287. /* Call Quit */
  288. SDL_QuitSubSystem(SDL_INIT_AUDIO);
  289. SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");
  290. } /* spec loop */
  291. } /* driver loop */
  292. /* Restart audio again */
  293. audioSetUp(NULL);
  294. return TEST_COMPLETED;
  295. }
  296. /**
  297. * Enumerate and name available audio devices (playback and recording).
  298. *
  299. * \sa SDL_GetNumAudioDevices
  300. * \sa SDL_GetAudioDeviceName
  301. */
  302. static int SDLCALL audio_enumerateAndNameAudioDevices(void *arg)
  303. {
  304. int t;
  305. int i, n;
  306. const char *name;
  307. SDL_AudioDeviceID *devices;
  308. /* Iterate over types: t=0 playback device, t=1 recording device */
  309. for (t = 0; t < 2; t++) {
  310. /* Get number of devices. */
  311. devices = (t) ? SDL_GetAudioRecordingDevices(&n) : SDL_GetAudioPlaybackDevices(&n);
  312. SDLTest_AssertPass("Call to SDL_GetAudio%sDevices(%i)", (t) ? "Recording" : "Playback", t);
  313. SDLTest_Log("Number of %s devices < 0, reported as %i", (t) ? "recording" : "playback", n);
  314. SDLTest_AssertCheck(n >= 0, "Validate result is >= 0, got: %i", n);
  315. /* List devices. */
  316. if (n > 0) {
  317. SDLTest_AssertCheck(devices != NULL, "Validate devices is not NULL if n > 0");
  318. for (i = 0; i < n; i++) {
  319. name = SDL_GetAudioDeviceName(devices[i]);
  320. SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i)", i);
  321. SDLTest_AssertCheck(name != NULL, "Verify result from SDL_GetAudioDeviceName(%i) is not NULL", i);
  322. if (name != NULL) {
  323. SDLTest_AssertCheck(name[0] != '\0', "verify result from SDL_GetAudioDeviceName(%i) is not empty, got: '%s'", i, name);
  324. }
  325. }
  326. }
  327. SDL_free(devices);
  328. }
  329. return TEST_COMPLETED;
  330. }
  331. /**
  332. * Negative tests around enumeration and naming of audio devices.
  333. *
  334. * \sa SDL_GetNumAudioDevices
  335. * \sa SDL_GetAudioDeviceName
  336. */
  337. static int SDLCALL audio_enumerateAndNameAudioDevicesNegativeTests(void *arg)
  338. {
  339. return TEST_COMPLETED; /* nothing in here atm since these interfaces changed in SDL3. */
  340. }
  341. /**
  342. * Checks available audio driver names.
  343. *
  344. * \sa SDL_GetNumAudioDrivers
  345. * \sa SDL_GetAudioDriver
  346. */
  347. static int SDLCALL audio_printAudioDrivers(void *arg)
  348. {
  349. int i, n;
  350. const char *name;
  351. /* Get number of drivers */
  352. n = SDL_GetNumAudioDrivers();
  353. SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers()");
  354. SDLTest_AssertCheck(n >= 0, "Verify number of audio drivers >= 0, got: %i", n);
  355. /* List drivers. */
  356. if (n > 0) {
  357. for (i = 0; i < n; i++) {
  358. name = SDL_GetAudioDriver(i);
  359. SDLTest_AssertPass("Call to SDL_GetAudioDriver(%i)", i);
  360. SDLTest_AssertCheck(name != NULL, "Verify returned name is not NULL");
  361. if (name != NULL) {
  362. SDLTest_AssertCheck(name[0] != '\0', "Verify returned name is not empty, got: '%s'", name);
  363. }
  364. }
  365. }
  366. return TEST_COMPLETED;
  367. }
  368. /**
  369. * Checks current audio driver name with initialized audio.
  370. *
  371. * \sa SDL_GetCurrentAudioDriver
  372. */
  373. static int SDLCALL audio_printCurrentAudioDriver(void *arg)
  374. {
  375. /* Check current audio driver */
  376. const char *name = SDL_GetCurrentAudioDriver();
  377. SDLTest_AssertPass("Call to SDL_GetCurrentAudioDriver()");
  378. SDLTest_AssertCheck(name != NULL, "Verify returned name is not NULL");
  379. if (name != NULL) {
  380. SDLTest_AssertCheck(name[0] != '\0', "Verify returned name is not empty, got: '%s'", name);
  381. }
  382. return TEST_COMPLETED;
  383. }
  384. /* Definition of all formats, channels, and frequencies used to test audio conversions */
  385. static SDL_AudioFormat g_audioFormats[] = {
  386. SDL_AUDIO_S8, SDL_AUDIO_U8,
  387. SDL_AUDIO_S16LE, SDL_AUDIO_S16BE,
  388. SDL_AUDIO_S32LE, SDL_AUDIO_S32BE,
  389. SDL_AUDIO_F32LE, SDL_AUDIO_F32BE
  390. };
  391. static const char *g_audioFormatsVerbose[] = {
  392. "SDL_AUDIO_S8", "SDL_AUDIO_U8",
  393. "SDL_AUDIO_S16LE", "SDL_AUDIO_S16BE",
  394. "SDL_AUDIO_S32LE", "SDL_AUDIO_S32BE",
  395. "SDL_AUDIO_F32LE", "SDL_AUDIO_F32BE"
  396. };
  397. static SDL_AudioFormat g_invalidAudioFormats[] = {
  398. (SDL_AudioFormat)SDL_DEFINE_AUDIO_FORMAT(SDL_AUDIO_MASK_SIGNED, SDL_AUDIO_MASK_BIG_ENDIAN, SDL_AUDIO_MASK_FLOAT, SDL_AUDIO_MASK_BITSIZE)
  399. };
  400. static const char *g_invalidAudioFormatsVerbose[] = {
  401. "SDL_AUDIO_UNKNOWN"
  402. };
  403. static const int g_numAudioFormats = SDL_arraysize(g_audioFormats);
  404. static const int g_numInvalidAudioFormats = SDL_arraysize(g_invalidAudioFormats);
  405. static Uint8 g_audioChannels[] = { 1, 2, 4, 6 };
  406. static const int g_numAudioChannels = SDL_arraysize(g_audioChannels);
  407. static int g_audioFrequencies[] = { 11025, 22050, 44100, 48000 };
  408. static const int g_numAudioFrequencies = SDL_arraysize(g_audioFrequencies);
  409. /* Verify the audio formats are laid out as expected */
  410. SDL_COMPILE_TIME_ASSERT(SDL_AUDIO_U8_FORMAT, SDL_AUDIO_U8 == SDL_AUDIO_BITSIZE(8));
  411. SDL_COMPILE_TIME_ASSERT(SDL_AUDIO_S8_FORMAT, SDL_AUDIO_S8 == (SDL_AUDIO_BITSIZE(8) | SDL_AUDIO_MASK_SIGNED));
  412. SDL_COMPILE_TIME_ASSERT(SDL_AUDIO_S16LE_FORMAT, SDL_AUDIO_S16LE == (SDL_AUDIO_BITSIZE(16) | SDL_AUDIO_MASK_SIGNED));
  413. SDL_COMPILE_TIME_ASSERT(SDL_AUDIO_S16BE_FORMAT, SDL_AUDIO_S16BE == (SDL_AUDIO_S16LE | SDL_AUDIO_MASK_BIG_ENDIAN));
  414. SDL_COMPILE_TIME_ASSERT(SDL_AUDIO_S32LE_FORMAT, SDL_AUDIO_S32LE == (SDL_AUDIO_BITSIZE(32) | SDL_AUDIO_MASK_SIGNED));
  415. SDL_COMPILE_TIME_ASSERT(SDL_AUDIO_S32BE_FORMAT, SDL_AUDIO_S32BE == (SDL_AUDIO_S32LE | SDL_AUDIO_MASK_BIG_ENDIAN));
  416. SDL_COMPILE_TIME_ASSERT(SDL_AUDIO_F32LE_FORMAT, SDL_AUDIO_F32LE == (SDL_AUDIO_BITSIZE(32) | SDL_AUDIO_MASK_FLOAT | SDL_AUDIO_MASK_SIGNED));
  417. SDL_COMPILE_TIME_ASSERT(SDL_AUDIO_F32BE_FORMAT, SDL_AUDIO_F32BE == (SDL_AUDIO_F32LE | SDL_AUDIO_MASK_BIG_ENDIAN));
  418. /**
  419. * Call to SDL_GetAudioFormatName
  420. *
  421. * \sa SDL_GetAudioFormatName
  422. */
  423. static int SDLCALL audio_getAudioFormatName(void *arg)
  424. {
  425. const char *error;
  426. int i;
  427. SDL_AudioFormat format;
  428. const char *result;
  429. /* audio formats */
  430. for (i = 0; i < g_numAudioFormats; i++) {
  431. format = g_audioFormats[i];
  432. SDLTest_Log("Audio Format: %s (%d)", g_audioFormatsVerbose[i], format);
  433. /* Get name of format */
  434. result = SDL_GetAudioFormatName(format);
  435. SDLTest_AssertPass("Call to SDL_GetAudioFormatName()");
  436. SDLTest_AssertCheck(result != NULL, "Verify result is not NULL");
  437. if (result != NULL) {
  438. SDLTest_AssertCheck(result[0] != '\0', "Verify result is non-empty");
  439. SDLTest_AssertCheck(SDL_strcmp(result, g_audioFormatsVerbose[i]) == 0,
  440. "Verify result text; expected: %s, got %s", g_audioFormatsVerbose[i], result);
  441. }
  442. }
  443. /* Negative cases */
  444. /* Invalid Formats */
  445. SDL_ClearError();
  446. SDLTest_AssertPass("Call to SDL_ClearError()");
  447. for (i = 0; i < g_numInvalidAudioFormats; i++) {
  448. format = g_invalidAudioFormats[i];
  449. result = SDL_GetAudioFormatName(format);
  450. SDLTest_AssertPass("Call to SDL_GetAudioFormatName(%d)", format);
  451. SDLTest_AssertCheck(result != NULL, "Verify result is not NULL");
  452. if (result != NULL) {
  453. SDLTest_AssertCheck(result[0] != '\0',
  454. "Verify result is non-empty; got: %s", result);
  455. SDLTest_AssertCheck(SDL_strcmp(result, g_invalidAudioFormatsVerbose[i]) == 0,
  456. "Validate name is UNKNOWN, expected: '%s', got: '%s'", g_invalidAudioFormatsVerbose[i], result);
  457. }
  458. error = SDL_GetError();
  459. SDLTest_AssertPass("Call to SDL_GetError()");
  460. SDLTest_AssertCheck(error == NULL || error[0] == '\0', "Validate that error message is empty");
  461. }
  462. return TEST_COMPLETED;
  463. }
  464. /**
  465. * Builds various audio conversion structures
  466. *
  467. * \sa SDL_CreateAudioStream
  468. */
  469. static int SDLCALL audio_buildAudioStream(void *arg)
  470. {
  471. SDL_AudioStream *stream;
  472. SDL_AudioSpec spec1;
  473. SDL_AudioSpec spec2;
  474. int i, ii, j, jj, k, kk;
  475. SDL_zero(spec1);
  476. SDL_zero(spec2);
  477. /* Call Quit */
  478. SDL_QuitSubSystem(SDL_INIT_AUDIO);
  479. SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");
  480. /* No conversion needed */
  481. spec1.format = SDL_AUDIO_S16LE;
  482. spec1.channels = 2;
  483. spec1.freq = 22050;
  484. stream = SDL_CreateAudioStream(&spec1, &spec1);
  485. SDLTest_AssertPass("Call to SDL_CreateAudioStream(spec1 ==> spec1)");
  486. SDLTest_AssertCheck(stream != NULL, "Verify stream value; expected: != NULL, got: %p", stream);
  487. SDL_DestroyAudioStream(stream);
  488. /* Typical conversion */
  489. spec1.format = SDL_AUDIO_S8;
  490. spec1.channels = 1;
  491. spec1.freq = 22050;
  492. spec2.format = SDL_AUDIO_S16LE;
  493. spec2.channels = 2;
  494. spec2.freq = 44100;
  495. stream = SDL_CreateAudioStream(&spec1, &spec2);
  496. SDLTest_AssertPass("Call to SDL_CreateAudioStream(spec1 ==> spec2)");
  497. SDLTest_AssertCheck(stream != NULL, "Verify stream value; expected: != NULL, got: %p", stream);
  498. SDL_DestroyAudioStream(stream);
  499. /* All source conversions with random conversion targets, allow 'null' conversions */
  500. for (i = 0; i < g_numAudioFormats; i++) {
  501. for (j = 0; j < g_numAudioChannels; j++) {
  502. for (k = 0; k < g_numAudioFrequencies; k++) {
  503. spec1.format = g_audioFormats[i];
  504. spec1.channels = g_audioChannels[j];
  505. spec1.freq = g_audioFrequencies[k];
  506. ii = SDLTest_RandomIntegerInRange(0, g_numAudioFormats - 1);
  507. jj = SDLTest_RandomIntegerInRange(0, g_numAudioChannels - 1);
  508. kk = SDLTest_RandomIntegerInRange(0, g_numAudioFrequencies - 1);
  509. spec2.format = g_audioFormats[ii];
  510. spec2.channels = g_audioChannels[jj];
  511. spec2.freq = g_audioFrequencies[kk];
  512. stream = SDL_CreateAudioStream(&spec1, &spec2);
  513. SDLTest_AssertPass("Call to SDL_CreateAudioStream(format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i ==> format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i)",
  514. i, g_audioFormatsVerbose[i], spec1.format, j, spec1.channels, k, spec1.freq, ii, g_audioFormatsVerbose[ii], spec2.format, jj, spec2.channels, kk, spec2.freq);
  515. SDLTest_AssertCheck(stream != NULL, "Verify stream value; expected: != NULL, got: %p", stream);
  516. if (stream == NULL) {
  517. SDLTest_LogError("%s", SDL_GetError());
  518. }
  519. SDL_DestroyAudioStream(stream);
  520. }
  521. }
  522. }
  523. /* Restart audio again */
  524. audioSetUp(NULL);
  525. return TEST_COMPLETED;
  526. }
  527. /**
  528. * Checks calls with invalid input to SDL_CreateAudioStream
  529. *
  530. * \sa SDL_CreateAudioStream
  531. */
  532. static int SDLCALL audio_buildAudioStreamNegative(void *arg)
  533. {
  534. const char *error;
  535. SDL_AudioStream *stream;
  536. SDL_AudioSpec spec1;
  537. SDL_AudioSpec spec2;
  538. int i;
  539. char message[256];
  540. SDL_zero(spec1);
  541. SDL_zero(spec2);
  542. /* Valid format */
  543. spec1.format = SDL_AUDIO_S8;
  544. spec1.channels = 1;
  545. spec1.freq = 22050;
  546. spec2.format = SDL_AUDIO_S16LE;
  547. spec2.channels = 2;
  548. spec2.freq = 44100;
  549. SDL_ClearError();
  550. SDLTest_AssertPass("Call to SDL_ClearError()");
  551. /* Invalid conversions */
  552. for (i = 1; i < 64; i++) {
  553. /* Valid format to start with */
  554. spec1.format = SDL_AUDIO_S8;
  555. spec1.channels = 1;
  556. spec1.freq = 22050;
  557. spec2.format = SDL_AUDIO_S16LE;
  558. spec2.channels = 2;
  559. spec2.freq = 44100;
  560. SDL_ClearError();
  561. SDLTest_AssertPass("Call to SDL_ClearError()");
  562. /* Set various invalid format inputs */
  563. SDL_strlcpy(message, "Invalid: ", 256);
  564. if (i & 1) {
  565. SDL_strlcat(message, " spec1.format", 256);
  566. spec1.format = 0;
  567. }
  568. if (i & 2) {
  569. SDL_strlcat(message, " spec1.channels", 256);
  570. spec1.channels = 0;
  571. }
  572. if (i & 4) {
  573. SDL_strlcat(message, " spec1.freq", 256);
  574. spec1.freq = 0;
  575. }
  576. if (i & 8) {
  577. SDL_strlcat(message, " spec2.format", 256);
  578. spec2.format = 0;
  579. }
  580. if (i & 16) {
  581. SDL_strlcat(message, " spec2.channels", 256);
  582. spec2.channels = 0;
  583. }
  584. if (i & 32) {
  585. SDL_strlcat(message, " spec2.freq", 256);
  586. spec2.freq = 0;
  587. }
  588. SDLTest_Log("%s", message);
  589. stream = SDL_CreateAudioStream(&spec1, &spec2);
  590. SDLTest_AssertPass("Call to SDL_CreateAudioStream(spec1 ==> spec2)");
  591. SDLTest_AssertCheck(stream == NULL, "Verify stream value; expected: NULL, got: %p", stream);
  592. error = SDL_GetError();
  593. SDLTest_AssertPass("Call to SDL_GetError()");
  594. SDLTest_AssertCheck(error != NULL && error[0] != '\0', "Validate that error message was not NULL or empty");
  595. SDL_DestroyAudioStream(stream);
  596. }
  597. SDL_ClearError();
  598. SDLTest_AssertPass("Call to SDL_ClearError()");
  599. return TEST_COMPLETED;
  600. }
  601. /**
  602. * Checks current audio status.
  603. *
  604. * \sa SDL_GetAudioDeviceStatus
  605. */
  606. static int SDLCALL audio_getAudioStatus(void *arg)
  607. {
  608. return TEST_COMPLETED; /* no longer a thing in SDL3. */
  609. }
  610. /**
  611. * Opens, checks current audio status, and closes a device.
  612. *
  613. * \sa SDL_GetAudioStatus
  614. */
  615. static int SDLCALL audio_openCloseAndGetAudioStatus(void *arg)
  616. {
  617. return TEST_COMPLETED; /* not a thing in SDL3. */
  618. }
  619. /**
  620. * Locks and unlocks open audio device.
  621. *
  622. * \sa SDL_LockAudioDevice
  623. * \sa SDL_UnlockAudioDevice
  624. */
  625. static int SDLCALL audio_lockUnlockOpenAudioDevice(void *arg)
  626. {
  627. return TEST_COMPLETED; /* not a thing in SDL3 */
  628. }
  629. /**
  630. * Convert audio using various conversion structures
  631. *
  632. * \sa SDL_CreateAudioStream
  633. */
  634. static int SDLCALL audio_convertAudio(void *arg)
  635. {
  636. SDL_AudioStream *stream;
  637. SDL_AudioSpec spec1;
  638. SDL_AudioSpec spec2;
  639. int c;
  640. char message[128];
  641. int i, ii, j, jj, k, kk;
  642. SDL_zero(spec1);
  643. SDL_zero(spec2);
  644. /* Iterate over bitmask that determines which parameters are modified in the conversion */
  645. for (c = 1; c < 8; c++) {
  646. SDL_strlcpy(message, "Changing:", 128);
  647. if (c & 1) {
  648. SDL_strlcat(message, " Format", 128);
  649. }
  650. if (c & 2) {
  651. SDL_strlcat(message, " Channels", 128);
  652. }
  653. if (c & 4) {
  654. SDL_strlcat(message, " Frequencies", 128);
  655. }
  656. SDLTest_Log("%s", message);
  657. /* All source conversions with random conversion targets */
  658. for (i = 0; i < g_numAudioFormats; i++) {
  659. for (j = 0; j < g_numAudioChannels; j++) {
  660. for (k = 0; k < g_numAudioFrequencies; k++) {
  661. spec1.format = g_audioFormats[i];
  662. spec1.channels = g_audioChannels[j];
  663. spec1.freq = g_audioFrequencies[k];
  664. /* Ensure we have a different target format */
  665. do {
  666. if (c & 1) {
  667. ii = SDLTest_RandomIntegerInRange(0, g_numAudioFormats - 1);
  668. } else {
  669. ii = 1;
  670. }
  671. if (c & 2) {
  672. jj = SDLTest_RandomIntegerInRange(0, g_numAudioChannels - 1);
  673. } else {
  674. jj = j;
  675. }
  676. if (c & 4) {
  677. kk = SDLTest_RandomIntegerInRange(0, g_numAudioFrequencies - 1);
  678. } else {
  679. kk = k;
  680. }
  681. } while ((i == ii) && (j == jj) && (k == kk));
  682. spec2.format = g_audioFormats[ii];
  683. spec2.channels = g_audioChannels[jj];
  684. spec2.freq = g_audioFrequencies[kk];
  685. stream = SDL_CreateAudioStream(&spec1, &spec2);
  686. SDLTest_AssertPass("Call to SDL_CreateAudioStream(format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i ==> format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i)",
  687. i, g_audioFormatsVerbose[i], spec1.format, j, spec1.channels, k, spec1.freq, ii, g_audioFormatsVerbose[ii], spec2.format, jj, spec2.channels, kk, spec2.freq);
  688. SDLTest_AssertCheck(stream != NULL, "Verify stream value; expected: != NULL, got: %p", stream);
  689. if (stream == NULL) {
  690. SDLTest_LogError("%s", SDL_GetError());
  691. } else {
  692. Uint8 *dst_buf = NULL, *src_buf = NULL;
  693. int dst_len = 0, src_len = 0, real_dst_len = 0;
  694. int l = 64, m;
  695. int src_framesize, dst_framesize;
  696. int src_silence, dst_silence;
  697. src_framesize = SDL_AUDIO_FRAMESIZE(spec1);
  698. dst_framesize = SDL_AUDIO_FRAMESIZE(spec2);
  699. src_len = l * src_framesize;
  700. SDLTest_Log("Creating dummy sample buffer of %i length (%i bytes)", l, src_len);
  701. src_buf = (Uint8 *)SDL_malloc(src_len);
  702. SDLTest_AssertCheck(src_buf != NULL, "Check src data buffer to convert is not NULL");
  703. if (src_buf == NULL) {
  704. SDL_DestroyAudioStream(stream);
  705. return TEST_ABORTED;
  706. }
  707. src_silence = SDL_GetSilenceValueForFormat(spec1.format);
  708. SDL_memset(src_buf, src_silence, src_len);
  709. dst_len = ((int)((((Sint64)l * spec2.freq) - 1) / spec1.freq) + 1) * dst_framesize;
  710. dst_buf = (Uint8 *)SDL_malloc(dst_len);
  711. SDLTest_AssertCheck(dst_buf != NULL, "Check dst data buffer to convert is not NULL");
  712. if (dst_buf == NULL) {
  713. SDL_DestroyAudioStream(stream);
  714. SDL_free(src_buf);
  715. return TEST_ABORTED;
  716. }
  717. real_dst_len = SDL_GetAudioStreamAvailable(stream);
  718. SDLTest_AssertCheck(0 == real_dst_len, "Verify available (pre-put); expected: %i; got: %i", 0, real_dst_len);
  719. /* Run the audio converter */
  720. if (!SDL_PutAudioStreamData(stream, src_buf, src_len) ||
  721. !SDL_FlushAudioStream(stream)) {
  722. SDL_DestroyAudioStream(stream);
  723. SDL_free(src_buf);
  724. SDL_free(dst_buf);
  725. return TEST_ABORTED;
  726. }
  727. real_dst_len = SDL_GetAudioStreamAvailable(stream);
  728. SDLTest_AssertCheck(dst_len == real_dst_len, "Verify available (post-put); expected: %i; got: %i", dst_len, real_dst_len);
  729. real_dst_len = SDL_GetAudioStreamData(stream, dst_buf, dst_len);
  730. SDLTest_AssertCheck(dst_len == real_dst_len, "Verify result value; expected: %i; got: %i", dst_len, real_dst_len);
  731. if (dst_len != real_dst_len) {
  732. SDL_DestroyAudioStream(stream);
  733. SDL_free(src_buf);
  734. SDL_free(dst_buf);
  735. return TEST_ABORTED;
  736. }
  737. real_dst_len = SDL_GetAudioStreamAvailable(stream);
  738. SDLTest_AssertCheck(0 == real_dst_len, "Verify available (post-get); expected: %i; got: %i", 0, real_dst_len);
  739. dst_silence = SDL_GetSilenceValueForFormat(spec2.format);
  740. for (m = 0; m < dst_len; ++m) {
  741. if (dst_buf[m] != dst_silence) {
  742. SDLTest_LogError("Output buffer is not silent");
  743. SDL_DestroyAudioStream(stream);
  744. SDL_free(src_buf);
  745. SDL_free(dst_buf);
  746. return TEST_ABORTED;
  747. }
  748. }
  749. SDL_DestroyAudioStream(stream);
  750. /* Free converted buffer */
  751. SDL_free(src_buf);
  752. SDL_free(dst_buf);
  753. }
  754. }
  755. }
  756. }
  757. }
  758. return TEST_COMPLETED;
  759. }
  760. /**
  761. * Opens, checks current connected status, and closes a device.
  762. *
  763. * \sa SDL_AudioDeviceConnected
  764. */
  765. static int SDLCALL audio_openCloseAudioDeviceConnected(void *arg)
  766. {
  767. return TEST_COMPLETED; /* not a thing in SDL3. */
  768. }
  769. static double sine_wave_sample(const Sint64 idx, const Sint64 rate, const Sint64 freq, const double phase)
  770. {
  771. /* Using integer modulo to avoid precision loss caused by large floating
  772. * point numbers. Sint64 is needed for the large integer multiplication.
  773. * The integers are assumed to be non-negative so that modulo is always
  774. * non-negative.
  775. * sin(i / rate * freq * 2 * PI + phase)
  776. * = sin(mod(i / rate * freq, 1) * 2 * PI + phase)
  777. * = sin(mod(i * freq, rate) / rate * 2 * PI + phase) */
  778. return SDL_sin(((double)(idx * freq % rate)) / ((double)rate) * (SDL_PI_D * 2) + phase);
  779. }
  780. /* Split the data into randomly sized chunks */
  781. static int put_audio_data_split(SDL_AudioStream* stream, const void* buf, int len)
  782. {
  783. SDL_AudioSpec spec;
  784. int frame_size;
  785. int ret = SDL_GetAudioStreamFormat(stream, &spec, NULL);
  786. if (!ret) {
  787. return -1;
  788. }
  789. frame_size = SDL_AUDIO_FRAMESIZE(spec);
  790. while (len > 0) {
  791. int n = SDLTest_RandomIntegerInRange(1, 10000) * frame_size;
  792. n = SDL_min(n, len);
  793. ret = SDL_PutAudioStreamData(stream, buf, n);
  794. if (!ret) {
  795. return -1;
  796. }
  797. buf = ((const Uint8*) buf) + n;
  798. len -= n;
  799. }
  800. return 0;
  801. }
  802. /* Read the data in randomly sized chunks */
  803. static int get_audio_data_split(SDL_AudioStream* stream, void* buf, int len) {
  804. SDL_AudioSpec spec;
  805. int frame_size;
  806. int ret = SDL_GetAudioStreamFormat(stream, NULL, &spec);
  807. int total = 0;
  808. if (!ret) {
  809. return -1;
  810. }
  811. frame_size = SDL_AUDIO_FRAMESIZE(spec);
  812. while (len > 0) {
  813. int n = SDLTest_RandomIntegerInRange(1, 10000) * frame_size;
  814. n = SDL_min(n, len);
  815. ret = SDL_GetAudioStreamData(stream, buf, n);
  816. if (ret <= 0) {
  817. return total ? total : -1;
  818. }
  819. buf = ((Uint8*) buf) + ret;
  820. total += ret;
  821. len -= ret;
  822. }
  823. return total;
  824. }
  825. /* Convert the data in chunks, putting/getting randomly sized chunks until finished */
  826. static int convert_audio_chunks(SDL_AudioStream* stream, const void* src, int srclen, void* dst, int dstlen)
  827. {
  828. SDL_AudioSpec src_spec, dst_spec;
  829. int src_frame_size, dst_frame_size;
  830. int total_in = 0, total_out = 0;
  831. int ret = SDL_GetAudioStreamFormat(stream, &src_spec, &dst_spec);
  832. if (!ret) {
  833. return -1;
  834. }
  835. src_frame_size = SDL_AUDIO_FRAMESIZE(src_spec);
  836. dst_frame_size = SDL_AUDIO_FRAMESIZE(dst_spec);
  837. while ((total_in < srclen) || (total_out < dstlen)) {
  838. /* Make sure we put in more than the padding frames so we get non-zero output */
  839. const int RESAMPLER_MAX_PADDING_FRAMES = 7; /* Should match RESAMPLER_MAX_PADDING_FRAMES in SDL */
  840. int to_put = SDLTest_RandomIntegerInRange(RESAMPLER_MAX_PADDING_FRAMES + 1, 40000) * src_frame_size;
  841. int to_get = SDLTest_RandomIntegerInRange(1, (int)((40000.0f * dst_spec.freq) / src_spec.freq)) * dst_frame_size;
  842. to_put = SDL_min(to_put, srclen - total_in);
  843. to_get = SDL_min(to_get, dstlen - total_out);
  844. if (to_put)
  845. {
  846. ret = put_audio_data_split(stream, (const Uint8*)(src) + total_in, to_put);
  847. if (ret < 0) {
  848. return total_out ? total_out : ret;
  849. }
  850. total_in += to_put;
  851. if (total_in == srclen) {
  852. ret = SDL_FlushAudioStream(stream);
  853. if (!ret) {
  854. return total_out ? total_out : -1;
  855. }
  856. }
  857. }
  858. if (to_get)
  859. {
  860. ret = get_audio_data_split(stream, (Uint8*)(dst) + total_out, to_get);
  861. if ((ret == 0) && (total_in == srclen)) {
  862. ret = -1;
  863. }
  864. if (ret < 0) {
  865. return total_out ? total_out : ret;
  866. }
  867. total_out += ret;
  868. }
  869. }
  870. return total_out;
  871. }
  872. /**
  873. * Check signal-to-noise ratio and maximum error of audio resampling.
  874. *
  875. * \sa https://wiki.libsdl.org/SDL_CreateAudioStream
  876. * \sa https://wiki.libsdl.org/SDL_DestroyAudioStream
  877. * \sa https://wiki.libsdl.org/SDL_PutAudioStreamData
  878. * \sa https://wiki.libsdl.org/SDL_FlushAudioStream
  879. * \sa https://wiki.libsdl.org/SDL_GetAudioStreamData
  880. */
  881. static int SDLCALL audio_resampleLoss(void *arg)
  882. {
  883. /* Note: always test long input time (>= 5s from experience) in some test
  884. * cases because an improper implementation may suffer from low resampling
  885. * precision with long input due to e.g. doing subtraction with large floats. */
  886. struct test_spec_t {
  887. int time;
  888. int freq;
  889. double phase;
  890. int rate_in;
  891. int rate_out;
  892. double signal_to_noise;
  893. double max_error;
  894. } test_specs[] = {
  895. { 50, 440, 0, 44100, 48000, 80, 0.0010 },
  896. { 50, 5000, SDL_PI_D / 2, 20000, 10000, 999, 0.0001 },
  897. { 50, 440, 0, 22050, 96000, 79, 0.0120 },
  898. { 50, 440, 0, 96000, 22050, 80, 0.0002 },
  899. { 0 }
  900. };
  901. int spec_idx = 0;
  902. int min_channels = 1;
  903. int max_channels = 1 /*8*/;
  904. int num_channels = min_channels;
  905. for (spec_idx = 0; test_specs[spec_idx].time > 0;) {
  906. const struct test_spec_t *spec = &test_specs[spec_idx];
  907. const int frames_in = spec->time * spec->rate_in;
  908. const int frames_target = spec->time * spec->rate_out;
  909. const int len_in = (frames_in * num_channels) * (int)sizeof(float);
  910. const int len_target = (frames_target * num_channels) * (int)sizeof(float);
  911. const int max_target = len_target * 2;
  912. SDL_AudioSpec tmpspec1, tmpspec2;
  913. Uint64 tick_beg = 0;
  914. Uint64 tick_end = 0;
  915. int i = 0;
  916. int j = 0;
  917. SDL_AudioStream *stream = NULL;
  918. float *buf_in = NULL;
  919. float *buf_out = NULL;
  920. int len_out = 0;
  921. double max_error = 0;
  922. double sum_squared_error = 0;
  923. double sum_squared_value = 0;
  924. double signal_to_noise = 0;
  925. SDL_zero(tmpspec1);
  926. SDL_zero(tmpspec2);
  927. SDLTest_AssertPass("Test resampling of %i s %i Hz %f phase sine wave from sampling rate of %i Hz to %i Hz",
  928. spec->time, spec->freq, spec->phase, spec->rate_in, spec->rate_out);
  929. tmpspec1.format = SDL_AUDIO_F32;
  930. tmpspec1.channels = num_channels;
  931. tmpspec1.freq = spec->rate_in;
  932. tmpspec2.format = SDL_AUDIO_F32;
  933. tmpspec2.channels = num_channels;
  934. tmpspec2.freq = spec->rate_out;
  935. stream = SDL_CreateAudioStream(&tmpspec1, &tmpspec2);
  936. SDLTest_AssertPass("Call to SDL_CreateAudioStream(SDL_AUDIO_F32, %i, %i, SDL_AUDIO_F32, %i, %i)", num_channels, spec->rate_in, num_channels, spec->rate_out);
  937. SDLTest_AssertCheck(stream != NULL, "Expected SDL_CreateAudioStream to succeed.");
  938. if (stream == NULL) {
  939. return TEST_ABORTED;
  940. }
  941. buf_in = (float *)SDL_malloc(len_in);
  942. SDLTest_AssertCheck(buf_in != NULL, "Expected input buffer to be created.");
  943. if (buf_in == NULL) {
  944. SDL_DestroyAudioStream(stream);
  945. return TEST_ABORTED;
  946. }
  947. for (i = 0; i < frames_in; ++i) {
  948. float f = (float)sine_wave_sample(i, spec->rate_in, spec->freq, spec->phase);
  949. for (j = 0; j < num_channels; ++j) {
  950. *(buf_in + (i * num_channels) + j) = f;
  951. }
  952. }
  953. tick_beg = SDL_GetPerformanceCounter();
  954. buf_out = (float *)SDL_malloc(max_target);
  955. SDLTest_AssertCheck(buf_out != NULL, "Expected output buffer to be created.");
  956. if (buf_out == NULL) {
  957. SDL_DestroyAudioStream(stream);
  958. SDL_free(buf_in);
  959. return TEST_ABORTED;
  960. }
  961. len_out = convert_audio_chunks(stream, buf_in, len_in, buf_out, max_target);
  962. SDLTest_AssertPass("Call to convert_audio_chunks(stream, buf_in, %i, buf_out, %i)", len_in, len_target);
  963. SDLTest_AssertCheck(len_out == len_target, "Expected output length to be %i, got %i.",
  964. len_target, len_out);
  965. SDL_free(buf_in);
  966. if (len_out != len_target) {
  967. SDL_DestroyAudioStream(stream);
  968. SDL_free(buf_out);
  969. return TEST_ABORTED;
  970. }
  971. tick_end = SDL_GetPerformanceCounter();
  972. SDLTest_Log("Resampling used %f seconds.", ((double)(tick_end - tick_beg)) / SDL_GetPerformanceFrequency());
  973. for (i = 0; i < frames_target; ++i) {
  974. const double target = sine_wave_sample(i, spec->rate_out, spec->freq, spec->phase);
  975. for (j = 0; j < num_channels; ++j) {
  976. const float output = *(buf_out + (i * num_channels) + j);
  977. const double error = SDL_fabs(target - output);
  978. max_error = SDL_max(max_error, error);
  979. sum_squared_error += error * error;
  980. sum_squared_value += target * target;
  981. }
  982. }
  983. SDL_DestroyAudioStream(stream);
  984. SDL_free(buf_out);
  985. signal_to_noise = 10 * SDL_log10(sum_squared_value / sum_squared_error); /* decibel */
  986. SDLTest_AssertCheck(ISFINITE(sum_squared_value), "Sum of squared target should be finite.");
  987. SDLTest_AssertCheck(ISFINITE(sum_squared_error), "Sum of squared error should be finite.");
  988. /* Infinity is theoretically possible when there is very little to no noise */
  989. SDLTest_AssertCheck(!ISNAN(signal_to_noise), "Signal-to-noise ratio should not be NaN.");
  990. SDLTest_AssertCheck(ISFINITE(max_error), "Maximum conversion error should be finite.");
  991. SDLTest_AssertCheck(signal_to_noise >= spec->signal_to_noise, "Conversion signal-to-noise ratio %f dB should be no less than %f dB.",
  992. signal_to_noise, spec->signal_to_noise);
  993. SDLTest_AssertCheck(max_error <= spec->max_error, "Maximum conversion error %f should be no more than %f.",
  994. max_error, spec->max_error);
  995. if (++num_channels > max_channels) {
  996. num_channels = min_channels;
  997. ++spec_idx;
  998. }
  999. }
  1000. return TEST_COMPLETED;
  1001. }
  1002. /**
  1003. * Check accuracy converting between audio formats.
  1004. *
  1005. * \sa SDL_ConvertAudioSamples
  1006. */
  1007. static int SDLCALL audio_convertAccuracy(void *arg)
  1008. {
  1009. static SDL_AudioFormat formats[] = { SDL_AUDIO_S8, SDL_AUDIO_U8, SDL_AUDIO_S16, SDL_AUDIO_S32 };
  1010. static const char* format_names[] = { "S8", "U8", "S16", "S32" };
  1011. int src_num = 65537 + 2048 + 48 + 256 + 100000;
  1012. int src_len = src_num * sizeof(float);
  1013. float* src_data = SDL_malloc(src_len);
  1014. int i, j;
  1015. SDLTest_AssertCheck(src_data != NULL, "Expected source buffer to be created.");
  1016. if (src_data == NULL) {
  1017. return TEST_ABORTED;
  1018. }
  1019. j = 0;
  1020. /* Generate a uniform range of floats between [-1.0, 1.0] */
  1021. for (i = 0; i < 65537; ++i) {
  1022. src_data[j++] = ((float)i - 32768.0f) / 32768.0f;
  1023. }
  1024. /* Generate floats close to 1.0 */
  1025. const float max_val = 16777216.0f;
  1026. for (i = 0; i < 1024; ++i) {
  1027. float f = (max_val + (float)(512 - i)) / max_val;
  1028. src_data[j++] = f;
  1029. src_data[j++] = -f;
  1030. }
  1031. for (i = 0; i < 24; ++i) {
  1032. float f = (max_val + (float)(3u << i)) / max_val;
  1033. src_data[j++] = f;
  1034. src_data[j++] = -f;
  1035. }
  1036. /* Generate floats far outside the [-1.0, 1.0] range */
  1037. for (i = 0; i < 128; ++i) {
  1038. float f = 2.0f + (float) i;
  1039. src_data[j++] = f;
  1040. src_data[j++] = -f;
  1041. }
  1042. /* Fill the rest with random floats between [-1.0, 1.0] */
  1043. for (i = 0; i < 100000; ++i) {
  1044. src_data[j++] = SDLTest_RandomSint32() / 2147483648.0f;
  1045. }
  1046. /* Shuffle the data for good measure */
  1047. for (i = src_num - 1; i > 0; --i) {
  1048. float f = src_data[i];
  1049. j = SDLTest_RandomIntegerInRange(0, i);
  1050. src_data[i] = src_data[j];
  1051. src_data[j] = f;
  1052. }
  1053. for (i = 0; i < SDL_arraysize(formats); ++i) {
  1054. SDL_AudioSpec src_spec, tmp_spec;
  1055. Uint64 convert_begin, convert_end;
  1056. Uint8 *tmp_data, *dst_data;
  1057. int tmp_len, dst_len;
  1058. int ret;
  1059. SDL_zero(src_spec);
  1060. SDL_zero(tmp_spec);
  1061. SDL_AudioFormat format = formats[i];
  1062. const char* format_name = format_names[i];
  1063. /* Formats with > 23 bits can represent every value exactly */
  1064. float min_delta = 1.0f;
  1065. float max_delta = -1.0f;
  1066. /* Subtract 1 bit to account for sign */
  1067. int bits = SDL_AUDIO_BITSIZE(format) - 1;
  1068. float target_max_delta = (bits > 23) ? 0.0f : (1.0f / (float)(1 << bits));
  1069. float target_min_delta = -target_max_delta;
  1070. src_spec.format = SDL_AUDIO_F32;
  1071. src_spec.channels = 1;
  1072. src_spec.freq = 44100;
  1073. tmp_spec.format = format;
  1074. tmp_spec.channels = 1;
  1075. tmp_spec.freq = 44100;
  1076. convert_begin = SDL_GetPerformanceCounter();
  1077. tmp_data = NULL;
  1078. tmp_len = 0;
  1079. ret = SDL_ConvertAudioSamples(&src_spec, (const Uint8*) src_data, src_len, &tmp_spec, &tmp_data, &tmp_len);
  1080. SDLTest_AssertCheck(ret == true, "Expected SDL_ConvertAudioSamples(F32->%s) to succeed", format_name);
  1081. if (!ret) {
  1082. SDL_free(src_data);
  1083. return TEST_ABORTED;
  1084. }
  1085. dst_data = NULL;
  1086. dst_len = 0;
  1087. ret = SDL_ConvertAudioSamples(&tmp_spec, tmp_data, tmp_len, &src_spec, &dst_data, &dst_len);
  1088. SDLTest_AssertCheck(ret == true, "Expected SDL_ConvertAudioSamples(%s->F32) to succeed", format_name);
  1089. if (!ret) {
  1090. SDL_free(tmp_data);
  1091. SDL_free(src_data);
  1092. return TEST_ABORTED;
  1093. }
  1094. convert_end = SDL_GetPerformanceCounter();
  1095. SDLTest_Log("Conversion via %s took %f seconds.", format_name, ((double)(convert_end - convert_begin)) / SDL_GetPerformanceFrequency());
  1096. SDL_free(tmp_data);
  1097. for (j = 0; j < src_num; ++j) {
  1098. float x = src_data[j];
  1099. float y = ((float*)dst_data)[j];
  1100. float d = SDL_clamp(x, -1.0f, 1.0f) - y;
  1101. min_delta = SDL_min(min_delta, d);
  1102. max_delta = SDL_max(max_delta, d);
  1103. }
  1104. SDLTest_AssertCheck(min_delta >= target_min_delta, "%s has min delta of %+f, should be >= %+f", format_name, min_delta, target_min_delta);
  1105. SDLTest_AssertCheck(max_delta <= target_max_delta, "%s has max delta of %+f, should be <= %+f", format_name, max_delta, target_max_delta);
  1106. SDL_free(dst_data);
  1107. }
  1108. SDL_free(src_data);
  1109. return TEST_COMPLETED;
  1110. }
  1111. /**
  1112. * Check accuracy when switching between formats
  1113. *
  1114. * \sa SDL_SetAudioStreamFormat
  1115. */
  1116. static int SDLCALL audio_formatChange(void *arg)
  1117. {
  1118. int i;
  1119. SDL_AudioSpec spec1, spec2, spec3;
  1120. int frames_1, frames_2, frames_3;
  1121. int length_1, length_2, length_3;
  1122. int result = 0;
  1123. int status = TEST_ABORTED;
  1124. float* buffer_1 = NULL;
  1125. float* buffer_2 = NULL;
  1126. float* buffer_3 = NULL;
  1127. SDL_AudioStream* stream = NULL;
  1128. double max_error = 0;
  1129. double sum_squared_error = 0;
  1130. double sum_squared_value = 0;
  1131. double signal_to_noise = 0;
  1132. double target_max_error = 0.02;
  1133. double target_signal_to_noise = 75.0;
  1134. int sine_freq = 500;
  1135. SDL_zero(spec1);
  1136. SDL_zero(spec2);
  1137. SDL_zero(spec3);
  1138. spec1.format = SDL_AUDIO_F32;
  1139. spec1.channels = 1;
  1140. spec1.freq = 20000;
  1141. spec2.format = SDL_AUDIO_F32;
  1142. spec2.channels = 1;
  1143. spec2.freq = 40000;
  1144. spec3.format = SDL_AUDIO_F32;
  1145. spec3.channels = 1;
  1146. spec3.freq = 80000;
  1147. frames_1 = spec1.freq;
  1148. frames_2 = spec2.freq;
  1149. frames_3 = spec3.freq * 2;
  1150. length_1 = (int)(frames_1 * sizeof(*buffer_1));
  1151. buffer_1 = (float*) SDL_malloc(length_1);
  1152. if (!SDLTest_AssertCheck(buffer_1 != NULL, "Expected buffer_1 to be created.")) {
  1153. goto cleanup;
  1154. }
  1155. length_2 = (int)(frames_2 * sizeof(*buffer_2));
  1156. buffer_2 = (float*) SDL_malloc(length_2);
  1157. if (!SDLTest_AssertCheck(buffer_2 != NULL, "Expected buffer_2 to be created.")) {
  1158. goto cleanup;
  1159. }
  1160. length_3 = (int)(frames_3 * sizeof(*buffer_3));
  1161. buffer_3 = (float*) SDL_malloc(length_3);
  1162. if (!SDLTest_AssertCheck(buffer_3 != NULL, "Expected buffer_3 to be created.")) {
  1163. goto cleanup;
  1164. }
  1165. for (i = 0; i < frames_1; ++i) {
  1166. buffer_1[i] = (float) sine_wave_sample(i, spec1.freq, sine_freq, 0.0f);
  1167. }
  1168. for (i = 0; i < frames_2; ++i) {
  1169. buffer_2[i] = (float) sine_wave_sample(i, spec2.freq, sine_freq, 0.0f);
  1170. }
  1171. stream = SDL_CreateAudioStream(NULL, NULL);
  1172. if (!SDLTest_AssertCheck(stream != NULL, "Expected SDL_CreateAudioStream to succeed")) {
  1173. goto cleanup;
  1174. }
  1175. result = SDL_SetAudioStreamFormat(stream, &spec1, &spec3);
  1176. if (!SDLTest_AssertCheck(result == true, "Expected SDL_SetAudioStreamFormat(spec1, spec3) to succeed")) {
  1177. goto cleanup;
  1178. }
  1179. result = SDL_GetAudioStreamAvailable(stream);
  1180. if (!SDLTest_AssertCheck(result == 0, "Expected SDL_GetAudioStreamAvailable return 0")) {
  1181. goto cleanup;
  1182. }
  1183. result = SDL_PutAudioStreamData(stream, buffer_1, length_1);
  1184. if (!SDLTest_AssertCheck(result == true, "Expected SDL_PutAudioStreamData(buffer_1) to succeed")) {
  1185. goto cleanup;
  1186. }
  1187. result = SDL_FlushAudioStream(stream);
  1188. if (!SDLTest_AssertCheck(result == true, "Expected SDL_FlushAudioStream to succeed")) {
  1189. goto cleanup;
  1190. }
  1191. result = SDL_SetAudioStreamFormat(stream, &spec2, &spec3);
  1192. if (!SDLTest_AssertCheck(result == true, "Expected SDL_SetAudioStreamFormat(spec2, spec3) to succeed")) {
  1193. goto cleanup;
  1194. }
  1195. result = SDL_PutAudioStreamData(stream, buffer_2, length_2);
  1196. if (!SDLTest_AssertCheck(result == true, "Expected SDL_PutAudioStreamData(buffer_1) to succeed")) {
  1197. goto cleanup;
  1198. }
  1199. result = SDL_FlushAudioStream(stream);
  1200. if (!SDLTest_AssertCheck(result == true, "Expected SDL_FlushAudioStream to succeed")) {
  1201. goto cleanup;
  1202. }
  1203. result = SDL_GetAudioStreamAvailable(stream);
  1204. if (!SDLTest_AssertCheck(result == length_3, "Expected SDL_GetAudioStreamAvailable to return %i, got %i", length_3, result)) {
  1205. goto cleanup;
  1206. }
  1207. result = SDL_GetAudioStreamData(stream, buffer_3, length_3);
  1208. if (!SDLTest_AssertCheck(result == length_3, "Expected SDL_GetAudioStreamData to return %i, got %i", length_3, result)) {
  1209. goto cleanup;
  1210. }
  1211. result = SDL_GetAudioStreamAvailable(stream);
  1212. if (!SDLTest_AssertCheck(result == 0, "Expected SDL_GetAudioStreamAvailable to return 0")) {
  1213. goto cleanup;
  1214. }
  1215. for (i = 0; i < frames_3; ++i) {
  1216. const float output = buffer_3[i];
  1217. const float target = (float) sine_wave_sample(i, spec3.freq, sine_freq, 0.0f);
  1218. const double error = SDL_fabs(target - output);
  1219. max_error = SDL_max(max_error, error);
  1220. sum_squared_error += error * error;
  1221. sum_squared_value += target * target;
  1222. }
  1223. signal_to_noise = 10 * SDL_log10(sum_squared_value / sum_squared_error); /* decibel */
  1224. SDLTest_AssertCheck(ISFINITE(sum_squared_value), "Sum of squared target should be finite.");
  1225. SDLTest_AssertCheck(ISFINITE(sum_squared_error), "Sum of squared error should be finite.");
  1226. /* Infinity is theoretically possible when there is very little to no noise */
  1227. SDLTest_AssertCheck(!ISNAN(signal_to_noise), "Signal-to-noise ratio should not be NaN.");
  1228. SDLTest_AssertCheck(ISFINITE(max_error), "Maximum conversion error should be finite.");
  1229. SDLTest_AssertCheck(signal_to_noise >= target_signal_to_noise, "Conversion signal-to-noise ratio %f dB should be no less than %f dB.",
  1230. signal_to_noise, target_signal_to_noise);
  1231. SDLTest_AssertCheck(max_error <= target_max_error, "Maximum conversion error %f should be no more than %f.",
  1232. max_error, target_max_error);
  1233. status = TEST_COMPLETED;
  1234. cleanup:
  1235. SDL_free(buffer_1);
  1236. SDL_free(buffer_2);
  1237. SDL_free(buffer_3);
  1238. SDL_DestroyAudioStream(stream);
  1239. return status;
  1240. }
  1241. /* ================= Test Case References ================== */
  1242. /* Audio test cases */
  1243. static const SDLTest_TestCaseReference audioTestGetAudioFormatName = {
  1244. audio_getAudioFormatName, "audio_getAudioFormatName", "Call to SDL_GetAudioFormatName", TEST_ENABLED
  1245. };
  1246. static const SDLTest_TestCaseReference audioTest1 = {
  1247. audio_enumerateAndNameAudioDevices, "audio_enumerateAndNameAudioDevices", "Enumerate and name available audio devices (playback and recording)", TEST_ENABLED
  1248. };
  1249. static const SDLTest_TestCaseReference audioTest2 = {
  1250. audio_enumerateAndNameAudioDevicesNegativeTests, "audio_enumerateAndNameAudioDevicesNegativeTests", "Negative tests around enumeration and naming of audio devices.", TEST_ENABLED
  1251. };
  1252. static const SDLTest_TestCaseReference audioTest3 = {
  1253. audio_printAudioDrivers, "audio_printAudioDrivers", "Checks available audio driver names.", TEST_ENABLED
  1254. };
  1255. static const SDLTest_TestCaseReference audioTest4 = {
  1256. audio_printCurrentAudioDriver, "audio_printCurrentAudioDriver", "Checks current audio driver name with initialized audio.", TEST_ENABLED
  1257. };
  1258. static const SDLTest_TestCaseReference audioTest5 = {
  1259. audio_buildAudioStream, "audio_buildAudioStream", "Builds various audio conversion structures.", TEST_ENABLED
  1260. };
  1261. static const SDLTest_TestCaseReference audioTest6 = {
  1262. audio_buildAudioStreamNegative, "audio_buildAudioStreamNegative", "Checks calls with invalid input to SDL_CreateAudioStream", TEST_ENABLED
  1263. };
  1264. static const SDLTest_TestCaseReference audioTest7 = {
  1265. audio_getAudioStatus, "audio_getAudioStatus", "Checks current audio status.", TEST_ENABLED
  1266. };
  1267. static const SDLTest_TestCaseReference audioTest8 = {
  1268. audio_openCloseAndGetAudioStatus, "audio_openCloseAndGetAudioStatus", "Opens and closes audio device and get audio status.", TEST_ENABLED
  1269. };
  1270. static const SDLTest_TestCaseReference audioTest9 = {
  1271. audio_lockUnlockOpenAudioDevice, "audio_lockUnlockOpenAudioDevice", "Locks and unlocks an open audio device.", TEST_ENABLED
  1272. };
  1273. static const SDLTest_TestCaseReference audioTest10 = {
  1274. audio_convertAudio, "audio_convertAudio", "Convert audio using available formats.", TEST_ENABLED
  1275. };
  1276. /* TODO: enable test when SDL_AudioDeviceConnected has been implemented. */
  1277. static const SDLTest_TestCaseReference audioTest11 = {
  1278. audio_openCloseAudioDeviceConnected, "audio_openCloseAudioDeviceConnected", "Opens and closes audio device and get connected status.", TEST_DISABLED
  1279. };
  1280. static const SDLTest_TestCaseReference audioTest12 = {
  1281. audio_quitInitAudioSubSystem, "audio_quitInitAudioSubSystem", "Quit and re-init audio subsystem.", TEST_ENABLED
  1282. };
  1283. static const SDLTest_TestCaseReference audioTest13 = {
  1284. audio_initQuitAudio, "audio_initQuitAudio", "Init and quit audio drivers directly.", TEST_ENABLED
  1285. };
  1286. static const SDLTest_TestCaseReference audioTest14 = {
  1287. audio_initOpenCloseQuitAudio, "audio_initOpenCloseQuitAudio", "Cycle through init, open, close and quit with various audio specs.", TEST_ENABLED
  1288. };
  1289. static const SDLTest_TestCaseReference audioTest15 = {
  1290. audio_pauseUnpauseAudio, "audio_pauseUnpauseAudio", "Pause and Unpause audio for various audio specs while testing callback.", TEST_ENABLED
  1291. };
  1292. static const SDLTest_TestCaseReference audioTest16 = {
  1293. audio_resampleLoss, "audio_resampleLoss", "Check signal-to-noise ratio and maximum error of audio resampling.", TEST_ENABLED
  1294. };
  1295. static const SDLTest_TestCaseReference audioTest17 = {
  1296. audio_convertAccuracy, "audio_convertAccuracy", "Check accuracy converting between audio formats.", TEST_ENABLED
  1297. };
  1298. static const SDLTest_TestCaseReference audioTest18 = {
  1299. audio_formatChange, "audio_formatChange", "Check handling of format changes.", TEST_ENABLED
  1300. };
  1301. /* Sequence of Audio test cases */
  1302. static const SDLTest_TestCaseReference *audioTests[] = {
  1303. &audioTestGetAudioFormatName,
  1304. &audioTest1, &audioTest2, &audioTest3, &audioTest4, &audioTest5, &audioTest6,
  1305. &audioTest7, &audioTest8, &audioTest9, &audioTest10, &audioTest11,
  1306. &audioTest12, &audioTest13, &audioTest14, &audioTest15, &audioTest16,
  1307. &audioTest17, &audioTest18, NULL
  1308. };
  1309. /* Audio test suite (global) */
  1310. SDLTest_TestSuiteReference audioTestSuite = {
  1311. "Audio",
  1312. audioSetUp,
  1313. audioTests,
  1314. audioTearDown
  1315. };