testautomation_audio.c 56 KB

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