testautomation_audio.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893
  1. /**
  2. * Original code: automated SDL audio test written by Edgar Simo "bobbens"
  3. * New/updated tests: aschiffler at ferzkopp dot net
  4. */
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include "SDL.h"
  8. #include "SDL_test.h"
  9. /* ================= Test Case Implementation ================== */
  10. /* Fixture */
  11. void
  12. _audioSetUp(void *arg)
  13. {
  14. /* Start SDL audio subsystem */
  15. int ret = SDL_InitSubSystem( SDL_INIT_AUDIO );
  16. SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_AUDIO)");
  17. SDLTest_AssertCheck(ret==0, "Check result from SDL_InitSubSystem(SDL_INIT_AUDIO)");
  18. if (ret != 0) {
  19. SDLTest_LogError("%s", SDL_GetError());
  20. }
  21. }
  22. /* Test callback function */
  23. void _audio_testCallback(void *userdata, Uint8 *stream, int len)
  24. {
  25. /* TODO: add tracking if callback was called */
  26. }
  27. /* Test case functions */
  28. /**
  29. * \brief Stop and restart audio subsystem
  30. *
  31. * \sa http://wiki.libsdl.org/moin.cgi/SDL_QuitSubSystem
  32. * \sa http://wiki.libsdl.org/moin.cgi/SDL_InitSubSystem
  33. */
  34. int audio_quitInitAudioSubSystem()
  35. {
  36. /* Stop SDL audio subsystem */
  37. SDL_QuitSubSystem( SDL_INIT_AUDIO );
  38. SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");
  39. /* Restart audio again */
  40. _audioSetUp(NULL);
  41. return TEST_COMPLETED;
  42. }
  43. /**
  44. * \brief Start and stop audio directly
  45. *
  46. * \sa http://wiki.libsdl.org/moin.cgi/SDL_InitAudio
  47. * \sa http://wiki.libsdl.org/moin.cgi/SDL_QuitAudio
  48. */
  49. int audio_initQuitAudio()
  50. {
  51. int result;
  52. int i, iMax;
  53. const char* audioDriver;
  54. /* Stop SDL audio subsystem */
  55. SDL_QuitSubSystem( SDL_INIT_AUDIO );
  56. SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");
  57. /* Loop over all available audio drivers */
  58. iMax = SDL_GetNumAudioDrivers();
  59. SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers");
  60. SDLTest_AssertCheck(iMax > 0, "Validate number of audio drivers; expected: >0 got: %d", iMax);
  61. for (i = 0; i < iMax; i++) {
  62. audioDriver = SDL_GetAudioDriver(i);
  63. SDLTest_AssertPass("Call to SDL_GetAudioDriver(%d)", i);
  64. SDLTest_AssertCheck(audioDriver != NULL, "Audio driver name is not NULL");
  65. SDLTest_AssertCheck(audioDriver[0] != '\0', "Audio driver name is not empty; got: %s", audioDriver);
  66. /* Call Init */
  67. result = SDL_AudioInit(audioDriver);
  68. SDLTest_AssertPass("Call to SDL_AudioInit('%s')", audioDriver);
  69. SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result);
  70. /* Call Quit */
  71. SDL_AudioQuit();
  72. SDLTest_AssertPass("Call to SDL_AudioQuit()");
  73. }
  74. /* NULL driver specification */
  75. audioDriver = NULL;
  76. /* Call Init */
  77. result = SDL_AudioInit(audioDriver);
  78. SDLTest_AssertPass("Call to SDL_AudioInit(NULL)");
  79. SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result);
  80. /* Call Quit */
  81. SDL_AudioQuit();
  82. SDLTest_AssertPass("Call to SDL_AudioQuit()");
  83. /* Restart audio again */
  84. _audioSetUp(NULL);
  85. return TEST_COMPLETED;
  86. }
  87. /**
  88. * \brief Start, open, close and stop audio
  89. *
  90. * \sa http://wiki.libsdl.org/moin.cgi/SDL_InitAudio
  91. * \sa http://wiki.libsdl.org/moin.cgi/SDL_OpenAudio
  92. * \sa http://wiki.libsdl.org/moin.cgi/SDL_CloseAudio
  93. * \sa http://wiki.libsdl.org/moin.cgi/SDL_QuitAudio
  94. */
  95. int audio_initOpenCloseQuitAudio()
  96. {
  97. int result;
  98. int i, iMax, j;
  99. const char* audioDriver;
  100. SDL_AudioSpec desired;
  101. /* Stop SDL audio subsystem */
  102. SDL_QuitSubSystem( SDL_INIT_AUDIO );
  103. SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");
  104. /* Loop over all available audio drivers */
  105. iMax = SDL_GetNumAudioDrivers();
  106. SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers");
  107. SDLTest_AssertCheck(iMax > 0, "Validate number of audio drivers; expected: >0 got: %d", iMax);
  108. for (i = 0; i < iMax; i++) {
  109. audioDriver = SDL_GetAudioDriver(i);
  110. SDLTest_AssertPass("Call to SDL_GetAudioDriver(%d)", i);
  111. SDLTest_AssertCheck(audioDriver != NULL, "Audio driver name is not NULL");
  112. SDLTest_AssertCheck(audioDriver[0] != '\0', "Audio driver name is not empty; got: %s", audioDriver);
  113. /* Change specs */
  114. for (j = 0; j < 2; j++) {
  115. /* Call Init */
  116. result = SDL_AudioInit(audioDriver);
  117. SDLTest_AssertPass("Call to SDL_AudioInit('%s')", audioDriver);
  118. SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result);
  119. /* Set spec */
  120. SDL_memset(&desired, 0, sizeof(desired));
  121. switch (j) {
  122. case 0:
  123. /* Set standard desired spec */
  124. desired.freq = 22050;
  125. desired.format = AUDIO_S16SYS;
  126. desired.channels = 2;
  127. desired.samples = 4096;
  128. desired.callback = _audio_testCallback;
  129. desired.userdata = NULL;
  130. case 1:
  131. /* Set custom desired spec */
  132. desired.freq = 48000;
  133. desired.format = AUDIO_F32SYS;
  134. desired.channels = 2;
  135. desired.samples = 2048;
  136. desired.callback = _audio_testCallback;
  137. desired.userdata = NULL;
  138. break;
  139. }
  140. /* Call Open */
  141. result = SDL_OpenAudio(&desired, NULL);
  142. SDLTest_AssertPass("Call to SDL_OpenAudio(desired_spec_%d, NULL)", j);
  143. SDLTest_AssertCheck(result == 0, "Verify return value; expected: 0 got: %d", result);
  144. /* Call Close */
  145. SDL_CloseAudio();
  146. SDLTest_AssertPass("Call to SDL_CloseAudio()");
  147. /* Call Quit */
  148. SDL_AudioQuit();
  149. SDLTest_AssertPass("Call to SDL_AudioQuit()");
  150. } /* spec loop */
  151. } /* driver loop */
  152. /* Restart audio again */
  153. _audioSetUp(NULL);
  154. return TEST_COMPLETED;
  155. }
  156. /**
  157. * \brief Enumerate and name available audio devices (output and capture).
  158. *
  159. * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetNumAudioDevices
  160. * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetAudioDeviceName
  161. */
  162. int audio_enumerateAndNameAudioDevices()
  163. {
  164. int t, tt;
  165. int i, n, nn;
  166. const char *name, *nameAgain;
  167. /* Iterate over types: t=0 output device, t=1 input/capture device */
  168. for (t=0; t<2; t++) {
  169. /* Get number of devices. */
  170. n = SDL_GetNumAudioDevices(t);
  171. SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(%i)", t);
  172. SDLTest_Log("Number of %s devices < 0, reported as %i", (t) ? "capture" : "output", n);
  173. SDLTest_AssertCheck(n >= 0, "Validate result is >= 0, got: %i", n);
  174. /* Variation of non-zero type */
  175. if (t==1) {
  176. tt = t + SDLTest_RandomIntegerInRange(1,10);
  177. nn = SDL_GetNumAudioDevices(tt);
  178. SDLTest_AssertCheck(n==nn, "Verify result from SDL_GetNumAudioDevices(%i), expected same number of audio devices %i, got %i", tt, n, nn);
  179. nn = SDL_GetNumAudioDevices(-tt);
  180. SDLTest_AssertCheck(n==nn, "Verify result from SDL_GetNumAudioDevices(%i), expected same number of audio devices %i, got %i", -tt, n, nn);
  181. }
  182. /* List devices. */
  183. if (n>0) {
  184. for (i=0; i<n; i++) {
  185. name = SDL_GetAudioDeviceName(i, t);
  186. SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i, %i)", i, t);
  187. SDLTest_AssertCheck(name != NULL, "Verify result from SDL_GetAudioDeviceName(%i, %i) is not NULL", i, t);
  188. if (name != NULL) {
  189. SDLTest_AssertCheck(name[0] != '\0', "verify result from SDL_GetAudioDeviceName(%i, %i) is not empty, got: '%s'", i, t, name);
  190. if (t==1) {
  191. /* Also try non-zero type */
  192. tt = t + SDLTest_RandomIntegerInRange(1,10);
  193. nameAgain = SDL_GetAudioDeviceName(i, tt);
  194. SDLTest_AssertCheck(nameAgain != NULL, "Verify result from SDL_GetAudioDeviceName(%i, %i) is not NULL", i, tt);
  195. if (nameAgain != NULL) {
  196. SDLTest_AssertCheck(nameAgain[0] != '\0', "Verify result from SDL_GetAudioDeviceName(%i, %i) is not empty, got: '%s'", i, tt, nameAgain);
  197. SDLTest_AssertCheck(SDL_strcmp(name, nameAgain)==0,
  198. "Verify SDL_GetAudioDeviceName(%i, %i) and SDL_GetAudioDeviceName(%i %i) return the same string",
  199. i, t, i, tt);
  200. }
  201. }
  202. }
  203. }
  204. }
  205. }
  206. return TEST_COMPLETED;
  207. }
  208. /**
  209. * \brief Negative tests around enumeration and naming of audio devices.
  210. *
  211. * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetNumAudioDevices
  212. * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetAudioDeviceName
  213. */
  214. int audio_enumerateAndNameAudioDevicesNegativeTests()
  215. {
  216. int t;
  217. int i, j, no, nc;
  218. const char *name;
  219. /* Get number of devices. */
  220. no = SDL_GetNumAudioDevices(0);
  221. SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)");
  222. nc = SDL_GetNumAudioDevices(1);
  223. SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(1)");
  224. /* Invalid device index when getting name */
  225. for (t=0; t<2; t++) {
  226. /* Negative device index */
  227. i = SDLTest_RandomIntegerInRange(-10,-1);
  228. name = SDL_GetAudioDeviceName(i, t);
  229. SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i, %i)", i, t);
  230. SDLTest_AssertCheck(name == NULL, "Check SDL_GetAudioDeviceName(%i, %i) result NULL, expected NULL, got: %s", i, t, (name == NULL) ? "NULL" : name);
  231. /* Device index past range */
  232. for (j=0; j<3; j++) {
  233. i = (t) ? nc+j : no+j;
  234. name = SDL_GetAudioDeviceName(i, t);
  235. SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i, %i)", i, t);
  236. SDLTest_AssertCheck(name == NULL, "Check SDL_GetAudioDeviceName(%i, %i) result, expected: NULL, got: %s", i, t, (name == NULL) ? "NULL" : name);
  237. }
  238. /* Capture index past capture range but within output range */
  239. if ((no>0) && (no>nc) && (t==1)) {
  240. i = no-1;
  241. name = SDL_GetAudioDeviceName(i, t);
  242. SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i, %i)", i, t);
  243. SDLTest_AssertCheck(name == NULL, "Check SDL_GetAudioDeviceName(%i, %i) result, expected: NULL, got: %s", i, t, (name == NULL) ? "NULL" : name);
  244. }
  245. }
  246. return TEST_COMPLETED;
  247. }
  248. /**
  249. * \brief Checks available audio driver names.
  250. *
  251. * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetNumAudioDrivers
  252. * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetAudioDriver
  253. */
  254. int audio_printAudioDrivers()
  255. {
  256. int i, n;
  257. const char *name;
  258. /* Get number of drivers */
  259. n = SDL_GetNumAudioDrivers();
  260. SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers()");
  261. SDLTest_AssertCheck(n>=0, "Verify number of audio drivers >= 0, got: %i", n);
  262. /* List drivers. */
  263. if (n>0)
  264. {
  265. for (i=0; i<n; i++) {
  266. name = SDL_GetAudioDriver(i);
  267. SDLTest_AssertPass("Call to SDL_GetAudioDriver(%i)", i);
  268. SDLTest_AssertCheck(name != NULL, "Verify returned name is not NULL");
  269. if (name != NULL) {
  270. SDLTest_AssertCheck(name[0] != '\0', "Verify returned name is not empty, got: '%s'", name);
  271. }
  272. }
  273. }
  274. return TEST_COMPLETED;
  275. }
  276. /**
  277. * \brief Checks current audio driver name with initialized audio.
  278. *
  279. * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetCurrentAudioDriver
  280. */
  281. int audio_printCurrentAudioDriver()
  282. {
  283. /* Check current audio driver */
  284. const char *name = SDL_GetCurrentAudioDriver();
  285. SDLTest_AssertPass("Call to SDL_GetCurrentAudioDriver()");
  286. SDLTest_AssertCheck(name != NULL, "Verify returned name is not NULL");
  287. if (name != NULL) {
  288. SDLTest_AssertCheck(name[0] != '\0', "Verify returned name is not empty, got: '%s'", name);
  289. }
  290. return TEST_COMPLETED;
  291. }
  292. /* Definition of all formats, channels, and frequencies used to test audio conversions */
  293. const int _numAudioFormats = 18;
  294. SDL_AudioFormat _audioFormats[] = { AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S16SYS, AUDIO_S16, AUDIO_U16LSB,
  295. AUDIO_U16MSB, AUDIO_U16SYS, AUDIO_U16, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_S32SYS, AUDIO_S32,
  296. AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_F32SYS, AUDIO_F32 };
  297. char *_audioFormatsVerbose[] = { "AUDIO_S8", "AUDIO_U8", "AUDIO_S16LSB", "AUDIO_S16MSB", "AUDIO_S16SYS", "AUDIO_S16", "AUDIO_U16LSB",
  298. "AUDIO_U16MSB", "AUDIO_U16SYS", "AUDIO_U16", "AUDIO_S32LSB", "AUDIO_S32MSB", "AUDIO_S32SYS", "AUDIO_S32",
  299. "AUDIO_F32LSB", "AUDIO_F32MSB", "AUDIO_F32SYS", "AUDIO_F32" };
  300. const int _numAudioChannels = 4;
  301. Uint8 _audioChannels[] = { 1, 2, 4, 6 };
  302. const int _numAudioFrequencies = 4;
  303. int _audioFrequencies[] = { 11025, 22050, 44100, 48000 };
  304. /**
  305. * \brief Builds various audio conversion structures
  306. *
  307. * \sa http://wiki.libsdl.org/moin.cgi/SDL_BuildAudioCVT
  308. */
  309. int audio_buildAudioCVT()
  310. {
  311. int result;
  312. SDL_AudioCVT cvt;
  313. SDL_AudioSpec spec1;
  314. SDL_AudioSpec spec2;
  315. int i, ii, j, jj, k, kk;
  316. /* No conversion needed */
  317. spec1.format = AUDIO_S16LSB;
  318. spec1.channels = 2;
  319. spec1.freq = 22050;
  320. result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq,
  321. spec1.format, spec1.channels, spec1.freq);
  322. SDLTest_AssertPass("Call to SDL_BuildAudioCVT(spec1 ==> spec1)");
  323. SDLTest_AssertCheck(result == 0, "Verify result value; expected: 0, got: %i", result);
  324. /* Typical conversion */
  325. spec1.format = AUDIO_S8;
  326. spec1.channels = 1;
  327. spec1.freq = 22050;
  328. spec2.format = AUDIO_S16LSB;
  329. spec2.channels = 2;
  330. spec2.freq = 44100;
  331. result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq,
  332. spec2.format, spec2.channels, spec2.freq);
  333. SDLTest_AssertPass("Call to SDL_BuildAudioCVT(spec1 ==> spec2)");
  334. SDLTest_AssertCheck(result == 1, "Verify result value; expected: 1, got: %i", result);
  335. /* All source conversions with random conversion targets, allow 'null' conversions */
  336. for (i = 0; i < _numAudioFormats; i++) {
  337. for (j = 0; j < _numAudioChannels; j++) {
  338. for (k = 0; k < _numAudioFrequencies; k++) {
  339. spec1.format = _audioFormats[i];
  340. spec1.channels = _audioChannels[j];
  341. spec1.freq = _audioFrequencies[k];
  342. ii = SDLTest_RandomIntegerInRange(0, _numAudioFormats - 1);
  343. jj = SDLTest_RandomIntegerInRange(0, _numAudioChannels - 1);
  344. kk = SDLTest_RandomIntegerInRange(0, _numAudioFrequencies - 1);
  345. spec2.format = _audioFormats[ii];
  346. spec2.channels = _audioChannels[jj];
  347. spec2.freq = _audioFrequencies[kk];
  348. result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq,
  349. spec2.format, spec2.channels, spec2.freq);
  350. SDLTest_AssertPass("Call to SDL_BuildAudioCVT(format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i ==> format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i)",
  351. i, _audioFormatsVerbose[i], spec1.format, j, spec1.channels, k, spec1.freq, ii, _audioFormatsVerbose[ii], spec2.format, jj, spec2.channels, kk, spec2.freq);
  352. SDLTest_AssertCheck(result == 0 || result == 1, "Verify result value; expected: 0 or 1, got: %i", result);
  353. if (result<0) {
  354. SDLTest_LogError(SDL_GetError());
  355. } else {
  356. SDLTest_AssertCheck(cvt.len_mult > 0, "Verify that cvt.len_mult value; expected: >0, got: %i", cvt.len_mult);
  357. }
  358. }
  359. }
  360. }
  361. return TEST_COMPLETED;
  362. }
  363. /**
  364. * \brief Checkes calls with invalid input to SDL_BuildAudioCVT
  365. *
  366. * \sa http://wiki.libsdl.org/moin.cgi/SDL_BuildAudioCVT
  367. */
  368. int audio_buildAudioCVTNegative()
  369. {
  370. const char *expectedError = "Parameter 'cvt' is invalid";
  371. const char *error;
  372. int result;
  373. SDL_AudioCVT cvt;
  374. SDL_AudioSpec spec1;
  375. SDL_AudioSpec spec2;
  376. int i;
  377. char message[256];
  378. /* Valid format */
  379. spec1.format = AUDIO_S8;
  380. spec1.channels = 1;
  381. spec1.freq = 22050;
  382. spec2.format = AUDIO_S16LSB;
  383. spec2.channels = 2;
  384. spec2.freq = 44100;
  385. SDL_ClearError();
  386. SDLTest_AssertPass("Call to SDL_ClearError()");
  387. /* NULL input for CVT buffer */
  388. result = SDL_BuildAudioCVT((SDL_AudioCVT *)NULL, spec1.format, spec1.channels, spec1.freq,
  389. spec2.format, spec2.channels, spec2.freq);
  390. SDLTest_AssertPass("Call to SDL_BuildAudioCVT(NULL,...)");
  391. SDLTest_AssertCheck(result == -1, "Verify result value; expected: -1, got: %i", result);
  392. error = SDL_GetError();
  393. SDLTest_AssertPass("Call to SDL_GetError()");
  394. SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL");
  395. if (error != NULL) {
  396. SDLTest_AssertCheck(SDL_strcmp(error, expectedError) == 0,
  397. "Validate error message, expected: '%s', got: '%s'", expectedError, error);
  398. }
  399. /* Invalid conversions */
  400. for (i = 1; i < 64; i++) {
  401. /* Valid format to start with */
  402. spec1.format = AUDIO_S8;
  403. spec1.channels = 1;
  404. spec1.freq = 22050;
  405. spec2.format = AUDIO_S16LSB;
  406. spec2.channels = 2;
  407. spec2.freq = 44100;
  408. SDL_ClearError();
  409. SDLTest_AssertPass("Call to SDL_ClearError()");
  410. /* Set various invalid format inputs */
  411. SDL_strlcpy(message, "Invalid: ", 256);
  412. if (i & 1) {
  413. SDL_strlcat(message, " spec1.format", 256);
  414. spec1.format = 0;
  415. }
  416. if (i & 2) {
  417. SDL_strlcat(message, " spec1.channels", 256);
  418. spec1.channels = 0;
  419. }
  420. if (i & 4) {
  421. SDL_strlcat(message, " spec1.freq", 256);
  422. spec1.freq = 0;
  423. }
  424. if (i & 8) {
  425. SDL_strlcat(message, " spec2.format", 256);
  426. spec2.format = 0;
  427. }
  428. if (i & 16) {
  429. SDL_strlcat(message, " spec2.channels", 256);
  430. spec2.channels = 0;
  431. }
  432. if (i & 32) {
  433. SDL_strlcat(message, " spec2.freq", 256);
  434. spec2.freq = 0;
  435. }
  436. SDLTest_Log(message);
  437. result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq,
  438. spec2.format, spec2.channels, spec2.freq);
  439. SDLTest_AssertPass("Call to SDL_BuildAudioCVT(spec1 ==> spec2)");
  440. SDLTest_AssertCheck(result == -1, "Verify result value; expected: -1, got: %i", result);
  441. error = SDL_GetError();
  442. SDLTest_AssertPass("Call to SDL_GetError()");
  443. SDLTest_AssertCheck(error != NULL && error[0] != '\0', "Validate that error message was not NULL or empty");
  444. }
  445. SDL_ClearError();
  446. SDLTest_AssertPass("Call to SDL_ClearError()");
  447. return TEST_COMPLETED;
  448. }
  449. /**
  450. * \brief Checks current audio status.
  451. *
  452. * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetAudioStatus
  453. */
  454. int audio_getAudioStatus()
  455. {
  456. SDL_AudioStatus result;
  457. /* Check current audio status */
  458. result = SDL_GetAudioStatus();
  459. SDLTest_AssertPass("Call to SDL_GetAudioStatus()");
  460. SDLTest_AssertCheck(result == SDL_AUDIO_STOPPED || result == SDL_AUDIO_PLAYING || result == SDL_AUDIO_PAUSED,
  461. "Verify returned value; expected: STOPPED (%i) | PLAYING (%i) | PAUSED (%i), got: %i",
  462. SDL_AUDIO_STOPPED, SDL_AUDIO_PLAYING, SDL_AUDIO_PAUSED, result);
  463. return TEST_COMPLETED;
  464. }
  465. /**
  466. * \brief Opens, checks current audio status, and closes a device.
  467. *
  468. * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetAudioStatus
  469. */
  470. int audio_openCloseAndGetAudioStatus()
  471. {
  472. SDL_AudioStatus result;
  473. int i;
  474. int count;
  475. char *device;
  476. SDL_AudioDeviceID id;
  477. SDL_AudioSpec desired, obtained;
  478. /* Get number of devices. */
  479. count = SDL_GetNumAudioDevices(0);
  480. SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)");
  481. if (count > 0) {
  482. for (i = 0; i < count; i++) {
  483. /* Get device name */
  484. device = (char *)SDL_GetAudioDeviceName(i, 0);
  485. SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i);
  486. SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL");
  487. if (device == NULL) return TEST_ABORTED;
  488. /* Set standard desired spec */
  489. desired.freq=22050;
  490. desired.format=AUDIO_S16SYS;
  491. desired.channels=2;
  492. desired.samples=4096;
  493. desired.callback=_audio_testCallback;
  494. desired.userdata=NULL;
  495. /* Open device */
  496. id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE);
  497. SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device);
  498. SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >=2, got: %i", id);
  499. if (id > 1) {
  500. /* Check device audio status */
  501. result = SDL_GetAudioDeviceStatus(id);
  502. SDLTest_AssertPass("Call to SDL_GetAudioDeviceStatus()");
  503. SDLTest_AssertCheck(result == SDL_AUDIO_STOPPED || result == SDL_AUDIO_PLAYING || result == SDL_AUDIO_PAUSED,
  504. "Verify returned value; expected: STOPPED (%i) | PLAYING (%i) | PAUSED (%i), got: %i",
  505. SDL_AUDIO_STOPPED, SDL_AUDIO_PLAYING, SDL_AUDIO_PAUSED, result);
  506. /* Close device again */
  507. SDL_CloseAudioDevice(id);
  508. SDLTest_AssertPass("Call to SDL_CloseAudioDevice()");
  509. }
  510. }
  511. } else {
  512. SDLTest_Log("No devices to test with");
  513. }
  514. return TEST_COMPLETED;
  515. }
  516. /**
  517. * \brief Locks and unlocks open audio device.
  518. *
  519. * \sa http://wiki.libsdl.org/moin.cgi/SDL_LockAudioDevice
  520. * \sa http://wiki.libsdl.org/moin.cgi/SDL_UnlockAudioDevice
  521. */
  522. int audio_lockUnlockOpenAudioDevice()
  523. {
  524. int i;
  525. int count;
  526. char *device;
  527. SDL_AudioDeviceID id;
  528. SDL_AudioSpec desired, obtained;
  529. /* Get number of devices. */
  530. count = SDL_GetNumAudioDevices(0);
  531. SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)");
  532. if (count > 0) {
  533. for (i = 0; i < count; i++) {
  534. /* Get device name */
  535. device = (char *)SDL_GetAudioDeviceName(i, 0);
  536. SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i);
  537. SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL");
  538. if (device == NULL) return TEST_ABORTED;
  539. /* Set standard desired spec */
  540. desired.freq=22050;
  541. desired.format=AUDIO_S16SYS;
  542. desired.channels=2;
  543. desired.samples=4096;
  544. desired.callback=_audio_testCallback;
  545. desired.userdata=NULL;
  546. /* Open device */
  547. id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE);
  548. SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device);
  549. SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >=2, got: %i", id);
  550. if (id > 1) {
  551. /* Lock to protect callback */
  552. SDL_LockAudioDevice(id);
  553. SDLTest_AssertPass("SDL_LockAudioDevice(%i)", id);
  554. /* Simulate callback processing */
  555. SDL_Delay(10);
  556. SDLTest_Log("Simulate callback processing - delay");
  557. /* Unlock again */
  558. SDL_UnlockAudioDevice(id);
  559. SDLTest_AssertPass("SDL_UnlockAudioDevice(%i)", id);
  560. /* Close device again */
  561. SDL_CloseAudioDevice(id);
  562. SDLTest_AssertPass("Call to SDL_CloseAudioDevice()");
  563. }
  564. }
  565. } else {
  566. SDLTest_Log("No devices to test with");
  567. }
  568. return TEST_COMPLETED;
  569. }
  570. /**
  571. * \brief Convert audio using various conversion structures
  572. *
  573. * \sa http://wiki.libsdl.org/moin.cgi/SDL_BuildAudioCVT
  574. * \sa http://wiki.libsdl.org/moin.cgi/SDL_ConvertAudio
  575. */
  576. int audio_convertAudio()
  577. {
  578. int result;
  579. SDL_AudioCVT cvt;
  580. SDL_AudioSpec spec1;
  581. SDL_AudioSpec spec2;
  582. int c;
  583. char message[128];
  584. int i, ii, j, jj, k, kk, l, ll;
  585. /* Iterate over bitmask that determines which parameters are modified in the conversion */
  586. for (c = 1; c < 8; c++) {
  587. SDL_strlcpy(message, "Changing:", 128);
  588. if (c & 1) {
  589. SDL_strlcat(message, " Format", 128);
  590. }
  591. if (c & 2) {
  592. SDL_strlcat(message, " Channels", 128);
  593. }
  594. if (c & 4) {
  595. SDL_strlcat(message, " Frequencies", 128);
  596. }
  597. SDLTest_Log(message);
  598. /* All source conversions with random conversion targets */
  599. for (i = 0; i < _numAudioFormats; i++) {
  600. for (j = 0; j < _numAudioChannels; j++) {
  601. for (k = 0; k < _numAudioFrequencies; k++) {
  602. spec1.format = _audioFormats[i];
  603. spec1.channels = _audioChannels[j];
  604. spec1.freq = _audioFrequencies[k];
  605. /* Ensure we have a different target format */
  606. do {
  607. if (c & 1) {
  608. ii = SDLTest_RandomIntegerInRange(0, _numAudioFormats - 1);
  609. } else {
  610. ii = 1;
  611. }
  612. if (c & 2) {
  613. jj = SDLTest_RandomIntegerInRange(0, _numAudioChannels - 1);
  614. } else {
  615. jj= j;
  616. }
  617. if (c & 4) {
  618. kk = SDLTest_RandomIntegerInRange(0, _numAudioFrequencies - 1);
  619. } else {
  620. kk = k;
  621. }
  622. } while ((i == ii) && (j == jj) && (k == kk));
  623. spec2.format = _audioFormats[ii];
  624. spec2.channels = _audioChannels[jj];
  625. spec2.freq = _audioFrequencies[kk];
  626. result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq,
  627. spec2.format, spec2.channels, spec2.freq);
  628. SDLTest_AssertPass("Call to SDL_BuildAudioCVT(format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i ==> format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i)",
  629. i, _audioFormatsVerbose[i], spec1.format, j, spec1.channels, k, spec1.freq, ii, _audioFormatsVerbose[ii], spec2.format, jj, spec2.channels, kk, spec2.freq);
  630. SDLTest_AssertCheck(result == 1, "Verify result value; expected: 1, got: %i", result);
  631. if (result != 1) {
  632. SDLTest_LogError(SDL_GetError());
  633. } else {
  634. SDLTest_AssertCheck(cvt.len_mult > 0, "Verify that cvt.len_mult value; expected: >0, got: %i", cvt.len_mult);
  635. if (cvt.len_mult < 1) return TEST_ABORTED;
  636. /* Create some random data to convert */
  637. l = 64;
  638. ll = l * cvt.len_mult;
  639. SDLTest_Log("Creating dummy sample buffer of %i length (%i bytes)", l, ll);
  640. cvt.len = l;
  641. cvt.buf = (Uint8 *)SDL_malloc(ll);
  642. SDLTest_AssertCheck(cvt.buf != NULL, "Check data buffer to convert is not NULL");
  643. if (cvt.buf == NULL) return TEST_ABORTED;
  644. /* Convert the data */
  645. result = SDL_ConvertAudio(&cvt);
  646. SDLTest_AssertPass("Call to SDL_ConvertAudio()");
  647. SDLTest_AssertCheck(result == 0, "Verify result value; expected: 0; got: %i", result);
  648. SDLTest_AssertCheck(cvt.buf != NULL, "Verify conversion buffer is not NULL");
  649. SDLTest_AssertCheck(cvt.len_ratio > 0.0, "Verify conversion length ratio; expected: >0; got: %f", cvt.len_ratio);
  650. /* Free converted buffer */
  651. SDL_free(cvt.buf);
  652. cvt.buf = NULL;
  653. }
  654. }
  655. }
  656. }
  657. }
  658. return TEST_COMPLETED;
  659. }
  660. /**
  661. * \brief Opens, checks current connected status, and closes a device.
  662. *
  663. * \sa http://wiki.libsdl.org/moin.cgi/SDL_AudioDeviceConnected
  664. */
  665. int audio_openCloseAudioDeviceConnected()
  666. {
  667. int result = -1;
  668. int i;
  669. int count;
  670. char *device;
  671. SDL_AudioDeviceID id;
  672. SDL_AudioSpec desired, obtained;
  673. /* Get number of devices. */
  674. count = SDL_GetNumAudioDevices(0);
  675. SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)");
  676. if (count > 0) {
  677. for (i = 0; i < count; i++) {
  678. /* Get device name */
  679. device = (char *)SDL_GetAudioDeviceName(i, 0);
  680. SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i);
  681. SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL");
  682. if (device == NULL) return TEST_ABORTED;
  683. /* Set standard desired spec */
  684. desired.freq=22050;
  685. desired.format=AUDIO_S16SYS;
  686. desired.channels=2;
  687. desired.samples=4096;
  688. desired.callback=_audio_testCallback;
  689. desired.userdata=NULL;
  690. /* Open device */
  691. id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE);
  692. SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device);
  693. SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >1, got: %i", id);
  694. if (id > 1) {
  695. /* TODO: enable test code when function is available in SDL2 */
  696. #ifdef AUDIODEVICECONNECTED_DEFINED
  697. /* Get connected status */
  698. result = SDL_AudioDeviceConnected(id);
  699. SDLTest_AssertPass("Call to SDL_AudioDeviceConnected()");
  700. #endif
  701. SDLTest_AssertCheck(result == 1, "Verify returned value; expected: 1; got: %i", result);
  702. /* Close device again */
  703. SDL_CloseAudioDevice(id);
  704. SDLTest_AssertPass("Call to SDL_CloseAudioDevice()");
  705. }
  706. }
  707. } else {
  708. SDLTest_Log("No devices to test with");
  709. }
  710. return TEST_COMPLETED;
  711. }
  712. /* ================= Test Case References ================== */
  713. /* Audio test cases */
  714. static const SDLTest_TestCaseReference audioTest1 =
  715. { (SDLTest_TestCaseFp)audio_enumerateAndNameAudioDevices, "audio_enumerateAndNameAudioDevices", "Enumerate and name available audio devices (output and capture)", TEST_ENABLED };
  716. static const SDLTest_TestCaseReference audioTest2 =
  717. { (SDLTest_TestCaseFp)audio_enumerateAndNameAudioDevicesNegativeTests, "audio_enumerateAndNameAudioDevicesNegativeTests", "Negative tests around enumeration and naming of audio devices.", TEST_ENABLED };
  718. static const SDLTest_TestCaseReference audioTest3 =
  719. { (SDLTest_TestCaseFp)audio_printAudioDrivers, "audio_printAudioDrivers", "Checks available audio driver names.", TEST_ENABLED };
  720. static const SDLTest_TestCaseReference audioTest4 =
  721. { (SDLTest_TestCaseFp)audio_printCurrentAudioDriver, "audio_printCurrentAudioDriver", "Checks current audio driver name with initialized audio.", TEST_ENABLED };
  722. static const SDLTest_TestCaseReference audioTest5 =
  723. { (SDLTest_TestCaseFp)audio_buildAudioCVT, "audio_buildAudioCVT", "Builds various audio conversion structures.", TEST_ENABLED };
  724. static const SDLTest_TestCaseReference audioTest6 =
  725. { (SDLTest_TestCaseFp)audio_buildAudioCVTNegative, "audio_buildAudioCVTNegative", "Checks calls with invalid input to SDL_BuildAudioCVT", TEST_ENABLED };
  726. static const SDLTest_TestCaseReference audioTest7 =
  727. { (SDLTest_TestCaseFp)audio_getAudioStatus, "audio_getAudioStatus", "Checks current audio status.", TEST_ENABLED };
  728. static const SDLTest_TestCaseReference audioTest8 =
  729. { (SDLTest_TestCaseFp)audio_openCloseAndGetAudioStatus, "audio_openCloseAndGetAudioStatus", "Opens and closes audio device and get audio status.", TEST_ENABLED };
  730. static const SDLTest_TestCaseReference audioTest9 =
  731. { (SDLTest_TestCaseFp)audio_lockUnlockOpenAudioDevice, "audio_lockUnlockOpenAudioDevice", "Locks and unlocks an open audio device.", TEST_ENABLED };
  732. /* TODO: enable test when SDL_ConvertAudio segfaults on cygwin have been fixed. */
  733. /* For debugging, test case can be run manually using --filter audio_convertAudio */
  734. static const SDLTest_TestCaseReference audioTest10 =
  735. { (SDLTest_TestCaseFp)audio_convertAudio, "audio_convertAudio", "Convert audio using available formats.", TEST_DISABLED };
  736. /* TODO: enable test when SDL_AudioDeviceConnected has been implemented. */
  737. static const SDLTest_TestCaseReference audioTest11 =
  738. { (SDLTest_TestCaseFp)audio_openCloseAudioDeviceConnected, "audio_openCloseAudioDeviceConnected", "Opens and closes audio device and get connected status.", TEST_DISABLED };
  739. static const SDLTest_TestCaseReference audioTest12 =
  740. { (SDLTest_TestCaseFp)audio_quitInitAudioSubSystem, "audio_quitInitAudioSubSystem", "Quit and re-init audio subsystem.", TEST_ENABLED };
  741. /* TODO: enable when bugs 1343 and 1396 are fixed. */
  742. /* For debugging, test case can be run manually using --filter audio_initQuitAudio */
  743. static const SDLTest_TestCaseReference audioTest13 =
  744. { (SDLTest_TestCaseFp)audio_initQuitAudio, "audio_initQuitAudio", "Init and quit audio drivers directly.", TEST_DISABLED };
  745. /* TODO: enable when bugs 1343 and 1396 are fixed. */
  746. /* For debugging, test case can be run manually using --filter audio_initOpenCloseQuitAudio */
  747. static const SDLTest_TestCaseReference audioTest14 =
  748. { (SDLTest_TestCaseFp)audio_initOpenCloseQuitAudio, "audio_initOpenCloseQuitAudio", "Cycle through init, open, close and quit with various audio specs.", TEST_DISABLED };
  749. /* Sequence of Audio test cases */
  750. static const SDLTest_TestCaseReference *audioTests[] = {
  751. &audioTest1, &audioTest2, &audioTest3, &audioTest4, &audioTest5, &audioTest6,
  752. &audioTest7, &audioTest8, &audioTest9, &audioTest10, &audioTest11,
  753. &audioTest12, &audioTest13, &audioTest14, NULL
  754. };
  755. /* Audio test suite (global) */
  756. SDLTest_TestSuiteReference audioTestSuite = {
  757. "Audio",
  758. _audioSetUp,
  759. audioTests,
  760. NULL
  761. };