2021-04-17 23:35:25 -04:00
/**
* Original code : automated SDL audio test written by Edgar Simo " bobbens "
* New / updated tests : aschiffler at ferzkopp dot net
*/
/* quiet windows compiler warnings */
# define _CRT_SECURE_NO_WARNINGS
# include <stdio.h>
# include <string.h>
# include "SDL.h"
# include "SDL_test.h"
/* ================= Test Case Implementation ================== */
/* Fixture */
void
_audioSetUp ( void * arg )
{
/* Start SDL audio subsystem */
int ret = SDL_InitSubSystem ( SDL_INIT_AUDIO ) ;
SDLTest_AssertPass ( " Call to SDL_InitSubSystem(SDL_INIT_AUDIO) " ) ;
SDLTest_AssertCheck ( ret = = 0 , " Check result from SDL_InitSubSystem(SDL_INIT_AUDIO) " ) ;
if ( ret ! = 0 ) {
SDLTest_LogError ( " %s " , SDL_GetError ( ) ) ;
}
}
void
_audioTearDown ( void * arg )
{
/* Remove a possibly created file from SDL disk writer audio driver; ignore errors */
remove ( " sdlaudio.raw " ) ;
SDLTest_AssertPass ( " Cleanup of test files completed " ) ;
}
/* Global counter for callback invocation */
int _audio_testCallbackCounter ;
/* Global accumulator for total callback length */
int _audio_testCallbackLength ;
/* Test callback function */
void SDLCALL _audio_testCallback ( void * userdata , Uint8 * stream , int len )
{
/* track that callback was called */
_audio_testCallbackCounter + + ;
_audio_testCallbackLength + = len ;
}
/* Test case functions */
/**
* \ brief Stop and restart audio subsystem
*
* \ sa https : //wiki.libsdl.org/SDL_QuitSubSystem
* \ sa https : //wiki.libsdl.org/SDL_InitSubSystem
*/
int audio_quitInitAudioSubSystem ( )
{
/* Stop SDL audio subsystem */
SDL_QuitSubSystem ( SDL_INIT_AUDIO ) ;
SDLTest_AssertPass ( " Call to SDL_QuitSubSystem(SDL_INIT_AUDIO) " ) ;
/* Restart audio again */
_audioSetUp ( NULL ) ;
return TEST_COMPLETED ;
}
/**
* \ brief Start and stop audio directly
*
* \ sa https : //wiki.libsdl.org/SDL_InitAudio
* \ sa https : //wiki.libsdl.org/SDL_QuitAudio
*/
int audio_initQuitAudio ( )
{
int result ;
int i , iMax ;
const char * audioDriver ;
/* Stop SDL audio subsystem */
SDL_QuitSubSystem ( SDL_INIT_AUDIO ) ;
SDLTest_AssertPass ( " Call to SDL_QuitSubSystem(SDL_INIT_AUDIO) " ) ;
/* Loop over all available audio drivers */
iMax = SDL_GetNumAudioDrivers ( ) ;
SDLTest_AssertPass ( " Call to SDL_GetNumAudioDrivers() " ) ;
SDLTest_AssertCheck ( iMax > 0 , " Validate number of audio drivers; expected: >0 got: %d " , iMax ) ;
for ( i = 0 ; i < iMax ; i + + ) {
audioDriver = SDL_GetAudioDriver ( i ) ;
SDLTest_AssertPass ( " Call to SDL_GetAudioDriver(%d) " , i ) ;
SDLTest_AssertCheck ( audioDriver ! = NULL , " Audio driver name is not NULL " ) ;
SDLTest_AssertCheck ( audioDriver [ 0 ] ! = ' \0 ' , " Audio driver name is not empty; got: %s " , audioDriver ) ;
/* Call Init */
result = SDL_AudioInit ( audioDriver ) ;
SDLTest_AssertPass ( " Call to SDL_AudioInit('%s') " , audioDriver ) ;
SDLTest_AssertCheck ( result = = 0 , " Validate result value; expected: 0 got: %d " , result ) ;
/* Call Quit */
SDL_AudioQuit ( ) ;
SDLTest_AssertPass ( " Call to SDL_AudioQuit() " ) ;
}
/* NULL driver specification */
audioDriver = NULL ;
/* Call Init */
result = SDL_AudioInit ( audioDriver ) ;
SDLTest_AssertPass ( " Call to SDL_AudioInit(NULL) " ) ;
SDLTest_AssertCheck ( result = = 0 , " Validate result value; expected: 0 got: %d " , result ) ;
/* Call Quit */
SDL_AudioQuit ( ) ;
SDLTest_AssertPass ( " Call to SDL_AudioQuit() " ) ;
/* Restart audio again */
_audioSetUp ( NULL ) ;
return TEST_COMPLETED ;
}
/**
* \ brief Start , open , close and stop audio
*
* \ sa https : //wiki.libsdl.org/SDL_InitAudio
* \ sa https : //wiki.libsdl.org/SDL_OpenAudio
* \ sa https : //wiki.libsdl.org/SDL_CloseAudio
* \ sa https : //wiki.libsdl.org/SDL_QuitAudio
*/
int audio_initOpenCloseQuitAudio ( )
{
int result , expectedResult ;
int i , iMax , j , k ;
const char * audioDriver ;
SDL_AudioSpec desired ;
/* Stop SDL audio subsystem */
SDL_QuitSubSystem ( SDL_INIT_AUDIO ) ;
SDLTest_AssertPass ( " Call to SDL_QuitSubSystem(SDL_INIT_AUDIO) " ) ;
/* Loop over all available audio drivers */
iMax = SDL_GetNumAudioDrivers ( ) ;
SDLTest_AssertPass ( " Call to SDL_GetNumAudioDrivers() " ) ;
SDLTest_AssertCheck ( iMax > 0 , " Validate number of audio drivers; expected: >0 got: %d " , iMax ) ;
for ( i = 0 ; i < iMax ; i + + ) {
audioDriver = SDL_GetAudioDriver ( i ) ;
SDLTest_AssertPass ( " Call to SDL_GetAudioDriver(%d) " , i ) ;
SDLTest_AssertCheck ( audioDriver ! = NULL , " Audio driver name is not NULL " ) ;
SDLTest_AssertCheck ( audioDriver [ 0 ] ! = ' \0 ' , " Audio driver name is not empty; got: %s " , audioDriver ) ;
/* Change specs */
for ( j = 0 ; j < 2 ; j + + ) {
/* Call Init */
result = SDL_AudioInit ( audioDriver ) ;
SDLTest_AssertPass ( " Call to SDL_AudioInit('%s') " , audioDriver ) ;
SDLTest_AssertCheck ( result = = 0 , " Validate result value; expected: 0 got: %d " , result ) ;
/* Set spec */
SDL_memset ( & desired , 0 , sizeof ( desired ) ) ;
switch ( j ) {
case 0 :
/* Set standard desired spec */
desired . freq = 22050 ;
desired . format = AUDIO_S16SYS ;
desired . channels = 2 ;
desired . samples = 4096 ;
desired . callback = _audio_testCallback ;
desired . userdata = NULL ;
case 1 :
/* Set custom desired spec */
desired . freq = 48000 ;
desired . format = AUDIO_F32SYS ;
desired . channels = 2 ;
desired . samples = 2048 ;
desired . callback = _audio_testCallback ;
desired . userdata = NULL ;
break ;
}
/* Call Open (maybe multiple times) */
for ( k = 0 ; k < = j ; k + + ) {
result = SDL_OpenAudio ( & desired , NULL ) ;
SDLTest_AssertPass ( " Call to SDL_OpenAudio(desired_spec_%d, NULL), call %d " , j , k + 1 ) ;
expectedResult = ( k = = 0 ) ? 0 : - 1 ;
SDLTest_AssertCheck ( result = = expectedResult , " Verify return value; expected: %d, got: %d " , expectedResult , result ) ;
}
/* Call Close (maybe multiple times) */
for ( k = 0 ; k < = j ; k + + ) {
SDL_CloseAudio ( ) ;
SDLTest_AssertPass ( " Call to SDL_CloseAudio(), call %d " , k + 1 ) ;
}
/* Call Quit (maybe multiple times) */
for ( k = 0 ; k < = j ; k + + ) {
SDL_AudioQuit ( ) ;
SDLTest_AssertPass ( " Call to SDL_AudioQuit(), call %d " , k + 1 ) ;
}
} /* spec loop */
} /* driver loop */
/* Restart audio again */
_audioSetUp ( NULL ) ;
return TEST_COMPLETED ;
}
/**
* \ brief Pause and unpause audio
*
* \ sa https : //wiki.libsdl.org/SDL_PauseAudio
*/
int audio_pauseUnpauseAudio ( )
{
int result ;
int i , iMax , j , k , l ;
int totalDelay ;
int pause_on ;
int originalCounter ;
const char * audioDriver ;
SDL_AudioSpec desired ;
/* Stop SDL audio subsystem */
SDL_QuitSubSystem ( SDL_INIT_AUDIO ) ;
SDLTest_AssertPass ( " Call to SDL_QuitSubSystem(SDL_INIT_AUDIO) " ) ;
/* Loop over all available audio drivers */
iMax = SDL_GetNumAudioDrivers ( ) ;
SDLTest_AssertPass ( " Call to SDL_GetNumAudioDrivers() " ) ;
SDLTest_AssertCheck ( iMax > 0 , " Validate number of audio drivers; expected: >0 got: %d " , iMax ) ;
for ( i = 0 ; i < iMax ; i + + ) {
audioDriver = SDL_GetAudioDriver ( i ) ;
SDLTest_AssertPass ( " Call to SDL_GetAudioDriver(%d) " , i ) ;
SDLTest_AssertCheck ( audioDriver ! = NULL , " Audio driver name is not NULL " ) ;
SDLTest_AssertCheck ( audioDriver [ 0 ] ! = ' \0 ' , " Audio driver name is not empty; got: %s " , audioDriver ) ;
/* Change specs */
for ( j = 0 ; j < 2 ; j + + ) {
/* Call Init */
result = SDL_AudioInit ( audioDriver ) ;
SDLTest_AssertPass ( " Call to SDL_AudioInit('%s') " , audioDriver ) ;
SDLTest_AssertCheck ( result = = 0 , " Validate result value; expected: 0 got: %d " , result ) ;
/* Set spec */
SDL_memset ( & desired , 0 , sizeof ( desired ) ) ;
switch ( j ) {
case 0 :
/* Set standard desired spec */
desired . freq = 22050 ;
desired . format = AUDIO_S16SYS ;
desired . channels = 2 ;
desired . samples = 4096 ;
desired . callback = _audio_testCallback ;
desired . userdata = NULL ;
case 1 :
/* Set custom desired spec */
desired . freq = 48000 ;
desired . format = AUDIO_F32SYS ;
desired . channels = 2 ;
desired . samples = 2048 ;
desired . callback = _audio_testCallback ;
desired . userdata = NULL ;
break ;
}
/* Call Open */
result = SDL_OpenAudio ( & desired , NULL ) ;
SDLTest_AssertPass ( " Call to SDL_OpenAudio(desired_spec_%d, NULL) " , j ) ;
SDLTest_AssertCheck ( result = = 0 , " Verify return value; expected: 0 got: %d " , result ) ;
/* Start and stop audio multiple times */
for ( l = 0 ; l < 3 ; l + + ) {
SDLTest_Log ( " Pause/Unpause iteration: %d " , l + 1 ) ;
/* Reset callback counters */
_audio_testCallbackCounter = 0 ;
_audio_testCallbackLength = 0 ;
/* Un-pause audio to start playing (maybe multiple times) */
pause_on = 0 ;
for ( k = 0 ; k < = j ; k + + ) {
SDL_PauseAudio ( pause_on ) ;
SDLTest_AssertPass ( " Call to SDL_PauseAudio(%d), call %d " , pause_on , k + 1 ) ;
}
/* Wait for callback */
totalDelay = 0 ;
do {
SDL_Delay ( 10 ) ;
totalDelay + = 10 ;
}
while ( _audio_testCallbackCounter = = 0 & & totalDelay < 1000 ) ;
SDLTest_AssertCheck ( _audio_testCallbackCounter > 0 , " Verify callback counter; expected: >0 got: %d " , _audio_testCallbackCounter ) ;
SDLTest_AssertCheck ( _audio_testCallbackLength > 0 , " Verify callback length; expected: >0 got: %d " , _audio_testCallbackLength ) ;
/* Pause audio to stop playing (maybe multiple times) */
for ( k = 0 ; k < = j ; k + + ) {
pause_on = ( k = = 0 ) ? 1 : SDLTest_RandomIntegerInRange ( 99 , 9999 ) ;
SDL_PauseAudio ( pause_on ) ;
SDLTest_AssertPass ( " Call to SDL_PauseAudio(%d), call %d " , pause_on , k + 1 ) ;
}
/* Ensure callback is not called again */
originalCounter = _audio_testCallbackCounter ;
SDL_Delay ( totalDelay + 10 ) ;
SDLTest_AssertCheck ( originalCounter = = _audio_testCallbackCounter , " Verify callback counter; expected: %d, got: %d " , originalCounter , _audio_testCallbackCounter ) ;
}
/* Call Close */
SDL_CloseAudio ( ) ;
SDLTest_AssertPass ( " Call to SDL_CloseAudio() " ) ;
/* Call Quit */
SDL_AudioQuit ( ) ;
SDLTest_AssertPass ( " Call to SDL_AudioQuit() " ) ;
} /* spec loop */
} /* driver loop */
/* Restart audio again */
_audioSetUp ( NULL ) ;
return TEST_COMPLETED ;
}
/**
* \ brief Enumerate and name available audio devices ( output and capture ) .
*
* \ sa https : //wiki.libsdl.org/SDL_GetNumAudioDevices
* \ sa https : //wiki.libsdl.org/SDL_GetAudioDeviceName
*/
int audio_enumerateAndNameAudioDevices ( )
{
int t , tt ;
int i , n , nn ;
const char * name , * nameAgain ;
/* Iterate over types: t=0 output device, t=1 input/capture device */
for ( t = 0 ; t < 2 ; t + + ) {
/* Get number of devices. */
n = SDL_GetNumAudioDevices ( t ) ;
SDLTest_AssertPass ( " Call to SDL_GetNumAudioDevices(%i) " , t ) ;
SDLTest_Log ( " Number of %s devices < 0, reported as %i " , ( t ) ? " capture " : " output " , n ) ;
SDLTest_AssertCheck ( n > = 0 , " Validate result is >= 0, got: %i " , n ) ;
/* Variation of non-zero type */
if ( t = = 1 ) {
tt = t + SDLTest_RandomIntegerInRange ( 1 , 10 ) ;
nn = SDL_GetNumAudioDevices ( tt ) ;
SDLTest_AssertCheck ( n = = nn , " Verify result from SDL_GetNumAudioDevices(%i), expected same number of audio devices %i, got %i " , tt , n , nn ) ;
nn = SDL_GetNumAudioDevices ( - tt ) ;
SDLTest_AssertCheck ( n = = nn , " Verify result from SDL_GetNumAudioDevices(%i), expected same number of audio devices %i, got %i " , - tt , n , nn ) ;
}
/* List devices. */
if ( n > 0 ) {
for ( i = 0 ; i < n ; i + + ) {
name = SDL_GetAudioDeviceName ( i , t ) ;
SDLTest_AssertPass ( " Call to SDL_GetAudioDeviceName(%i, %i) " , i , t ) ;
SDLTest_AssertCheck ( name ! = NULL , " Verify result from SDL_GetAudioDeviceName(%i, %i) is not NULL " , i , t ) ;
if ( name ! = NULL ) {
SDLTest_AssertCheck ( name [ 0 ] ! = ' \0 ' , " verify result from SDL_GetAudioDeviceName(%i, %i) is not empty, got: '%s' " , i , t , name ) ;
if ( t = = 1 ) {
/* Also try non-zero type */
tt = t + SDLTest_RandomIntegerInRange ( 1 , 10 ) ;
nameAgain = SDL_GetAudioDeviceName ( i , tt ) ;
SDLTest_AssertCheck ( nameAgain ! = NULL , " Verify result from SDL_GetAudioDeviceName(%i, %i) is not NULL " , i , tt ) ;
if ( nameAgain ! = NULL ) {
SDLTest_AssertCheck ( nameAgain [ 0 ] ! = ' \0 ' , " Verify result from SDL_GetAudioDeviceName(%i, %i) is not empty, got: '%s' " , i , tt , nameAgain ) ;
SDLTest_AssertCheck ( SDL_strcmp ( name , nameAgain ) = = 0 ,
" Verify SDL_GetAudioDeviceName(%i, %i) and SDL_GetAudioDeviceName(%i %i) return the same string " ,
i , t , i , tt ) ;
}
}
}
}
}
}
return TEST_COMPLETED ;
}
/**
* \ brief Negative tests around enumeration and naming of audio devices .
*
* \ sa https : //wiki.libsdl.org/SDL_GetNumAudioDevices
* \ sa https : //wiki.libsdl.org/SDL_GetAudioDeviceName
*/
int audio_enumerateAndNameAudioDevicesNegativeTests ( )
{
int t ;
int i , j , no , nc ;
const char * name ;
/* Get number of devices. */
no = SDL_GetNumAudioDevices ( 0 ) ;
SDLTest_AssertPass ( " Call to SDL_GetNumAudioDevices(0) " ) ;
nc = SDL_GetNumAudioDevices ( 1 ) ;
SDLTest_AssertPass ( " Call to SDL_GetNumAudioDevices(1) " ) ;
/* Invalid device index when getting name */
for ( t = 0 ; t < 2 ; t + + ) {
/* Negative device index */
i = SDLTest_RandomIntegerInRange ( - 10 , - 1 ) ;
name = SDL_GetAudioDeviceName ( i , t ) ;
SDLTest_AssertPass ( " Call to SDL_GetAudioDeviceName(%i, %i) " , i , t ) ;
SDLTest_AssertCheck ( name = = NULL , " Check SDL_GetAudioDeviceName(%i, %i) result NULL, expected NULL, got: %s " , i , t , ( name = = NULL ) ? " NULL " : name ) ;
/* Device index past range */
for ( j = 0 ; j < 3 ; j + + ) {
i = ( t ) ? nc + j : no + j ;
name = SDL_GetAudioDeviceName ( i , t ) ;
SDLTest_AssertPass ( " Call to SDL_GetAudioDeviceName(%i, %i) " , i , t ) ;
SDLTest_AssertCheck ( name = = NULL , " Check SDL_GetAudioDeviceName(%i, %i) result, expected: NULL, got: %s " , i , t , ( name = = NULL ) ? " NULL " : name ) ;
}
/* Capture index past capture range but within output range */
if ( ( no > 0 ) & & ( no > nc ) & & ( t = = 1 ) ) {
i = no - 1 ;
name = SDL_GetAudioDeviceName ( i , t ) ;
SDLTest_AssertPass ( " Call to SDL_GetAudioDeviceName(%i, %i) " , i , t ) ;
SDLTest_AssertCheck ( name = = NULL , " Check SDL_GetAudioDeviceName(%i, %i) result, expected: NULL, got: %s " , i , t , ( name = = NULL ) ? " NULL " : name ) ;
}
}
return TEST_COMPLETED ;
}
/**
* \ brief Checks available audio driver names .
*
* \ sa https : //wiki.libsdl.org/SDL_GetNumAudioDrivers
* \ sa https : //wiki.libsdl.org/SDL_GetAudioDriver
*/
int audio_printAudioDrivers ( )
{
int i , n ;
const char * name ;
/* Get number of drivers */
n = SDL_GetNumAudioDrivers ( ) ;
SDLTest_AssertPass ( " Call to SDL_GetNumAudioDrivers() " ) ;
SDLTest_AssertCheck ( n > = 0 , " Verify number of audio drivers >= 0, got: %i " , n ) ;
/* List drivers. */
if ( n > 0 )
{
for ( i = 0 ; i < n ; i + + ) {
name = SDL_GetAudioDriver ( i ) ;
SDLTest_AssertPass ( " Call to SDL_GetAudioDriver(%i) " , i ) ;
SDLTest_AssertCheck ( name ! = NULL , " Verify returned name is not NULL " ) ;
if ( name ! = NULL ) {
SDLTest_AssertCheck ( name [ 0 ] ! = ' \0 ' , " Verify returned name is not empty, got: '%s' " , name ) ;
}
}
}
return TEST_COMPLETED ;
}
/**
* \ brief Checks current audio driver name with initialized audio .
*
* \ sa https : //wiki.libsdl.org/SDL_GetCurrentAudioDriver
*/
int audio_printCurrentAudioDriver ( )
{
/* Check current audio driver */
const char * name = SDL_GetCurrentAudioDriver ( ) ;
SDLTest_AssertPass ( " Call to SDL_GetCurrentAudioDriver() " ) ;
SDLTest_AssertCheck ( name ! = NULL , " Verify returned name is not NULL " ) ;
if ( name ! = NULL ) {
SDLTest_AssertCheck ( name [ 0 ] ! = ' \0 ' , " Verify returned name is not empty, got: '%s' " , name ) ;
}
return TEST_COMPLETED ;
}
/* Definition of all formats, channels, and frequencies used to test audio conversions */
const int _numAudioFormats = 18 ;
SDL_AudioFormat _audioFormats [ ] = { AUDIO_S8 , AUDIO_U8 , AUDIO_S16LSB , AUDIO_S16MSB , AUDIO_S16SYS , AUDIO_S16 , AUDIO_U16LSB ,
AUDIO_U16MSB , AUDIO_U16SYS , AUDIO_U16 , AUDIO_S32LSB , AUDIO_S32MSB , AUDIO_S32SYS , AUDIO_S32 ,
AUDIO_F32LSB , AUDIO_F32MSB , AUDIO_F32SYS , AUDIO_F32 } ;
2021-12-06 20:20:09 -05:00
const char * _audioFormatsVerbose [ ] = { " AUDIO_S8 " , " AUDIO_U8 " , " AUDIO_S16LSB " , " AUDIO_S16MSB " , " AUDIO_S16SYS " , " AUDIO_S16 " , " AUDIO_U16LSB " ,
2021-04-17 23:35:25 -04:00
" AUDIO_U16MSB " , " AUDIO_U16SYS " , " AUDIO_U16 " , " AUDIO_S32LSB " , " AUDIO_S32MSB " , " AUDIO_S32SYS " , " AUDIO_S32 " ,
" AUDIO_F32LSB " , " AUDIO_F32MSB " , " AUDIO_F32SYS " , " AUDIO_F32 " } ;
const int _numAudioChannels = 4 ;
Uint8 _audioChannels [ ] = { 1 , 2 , 4 , 6 } ;
const int _numAudioFrequencies = 4 ;
int _audioFrequencies [ ] = { 11025 , 22050 , 44100 , 48000 } ;
/**
* \ brief Builds various audio conversion structures
*
* \ sa https : //wiki.libsdl.org/SDL_BuildAudioCVT
*/
int audio_buildAudioCVT ( )
{
int result ;
SDL_AudioCVT cvt ;
SDL_AudioSpec spec1 ;
SDL_AudioSpec spec2 ;
int i , ii , j , jj , k , kk ;
/* No conversion needed */
spec1 . format = AUDIO_S16LSB ;
spec1 . channels = 2 ;
spec1 . freq = 22050 ;
result = SDL_BuildAudioCVT ( & cvt , spec1 . format , spec1 . channels , spec1 . freq ,
spec1 . format , spec1 . channels , spec1 . freq ) ;
SDLTest_AssertPass ( " Call to SDL_BuildAudioCVT(spec1 ==> spec1) " ) ;
SDLTest_AssertCheck ( result = = 0 , " Verify result value; expected: 0, got: %i " , result ) ;
/* Typical conversion */
spec1 . format = AUDIO_S8 ;
spec1 . channels = 1 ;
spec1 . freq = 22050 ;
spec2 . format = AUDIO_S16LSB ;
spec2 . channels = 2 ;
spec2 . freq = 44100 ;
result = SDL_BuildAudioCVT ( & cvt , spec1 . format , spec1 . channels , spec1 . freq ,
spec2 . format , spec2 . channels , spec2 . freq ) ;
SDLTest_AssertPass ( " Call to SDL_BuildAudioCVT(spec1 ==> spec2) " ) ;
SDLTest_AssertCheck ( result = = 1 , " Verify result value; expected: 1, got: %i " , result ) ;
/* All source conversions with random conversion targets, allow 'null' conversions */
for ( i = 0 ; i < _numAudioFormats ; i + + ) {
for ( j = 0 ; j < _numAudioChannels ; j + + ) {
for ( k = 0 ; k < _numAudioFrequencies ; k + + ) {
spec1 . format = _audioFormats [ i ] ;
spec1 . channels = _audioChannels [ j ] ;
spec1 . freq = _audioFrequencies [ k ] ;
ii = SDLTest_RandomIntegerInRange ( 0 , _numAudioFormats - 1 ) ;
jj = SDLTest_RandomIntegerInRange ( 0 , _numAudioChannels - 1 ) ;
kk = SDLTest_RandomIntegerInRange ( 0 , _numAudioFrequencies - 1 ) ;
spec2 . format = _audioFormats [ ii ] ;
spec2 . channels = _audioChannels [ jj ] ;
spec2 . freq = _audioFrequencies [ kk ] ;
result = SDL_BuildAudioCVT ( & cvt , spec1 . format , spec1 . channels , spec1 . freq ,
spec2 . format , spec2 . channels , spec2 . freq ) ;
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) " ,
i , _audioFormatsVerbose [ i ] , spec1 . format , j , spec1 . channels , k , spec1 . freq , ii , _audioFormatsVerbose [ ii ] , spec2 . format , jj , spec2 . channels , kk , spec2 . freq ) ;
SDLTest_AssertCheck ( result = = 0 | | result = = 1 , " Verify result value; expected: 0 or 1, got: %i " , result ) ;
if ( result < 0 ) {
SDLTest_LogError ( " %s " , SDL_GetError ( ) ) ;
} else {
SDLTest_AssertCheck ( cvt . len_mult > 0 , " Verify that cvt.len_mult value; expected: >0, got: %i " , cvt . len_mult ) ;
}
}
}
}
return TEST_COMPLETED ;
}
/**
* \ brief Checkes calls with invalid input to SDL_BuildAudioCVT
*
* \ sa https : //wiki.libsdl.org/SDL_BuildAudioCVT
*/
int audio_buildAudioCVTNegative ( )
{
const char * expectedError = " Parameter 'cvt' is invalid " ;
const char * error ;
int result ;
SDL_AudioCVT cvt ;
SDL_AudioSpec spec1 ;
SDL_AudioSpec spec2 ;
int i ;
char message [ 256 ] ;
/* Valid format */
spec1 . format = AUDIO_S8 ;
spec1 . channels = 1 ;
spec1 . freq = 22050 ;
spec2 . format = AUDIO_S16LSB ;
spec2 . channels = 2 ;
spec2 . freq = 44100 ;
SDL_ClearError ( ) ;
SDLTest_AssertPass ( " Call to SDL_ClearError() " ) ;
/* NULL input for CVT buffer */
result = SDL_BuildAudioCVT ( ( SDL_AudioCVT * ) NULL , spec1 . format , spec1 . channels , spec1 . freq ,
spec2 . format , spec2 . channels , spec2 . freq ) ;
SDLTest_AssertPass ( " Call to SDL_BuildAudioCVT(NULL,...) " ) ;
SDLTest_AssertCheck ( result = = - 1 , " Verify result value; expected: -1, got: %i " , result ) ;
error = SDL_GetError ( ) ;
SDLTest_AssertPass ( " Call to SDL_GetError() " ) ;
SDLTest_AssertCheck ( error ! = NULL , " Validate that error message was not NULL " ) ;
if ( error ! = NULL ) {
SDLTest_AssertCheck ( SDL_strcmp ( error , expectedError ) = = 0 ,
" Validate error message, expected: '%s', got: '%s' " , expectedError , error ) ;
}
/* Invalid conversions */
for ( i = 1 ; i < 64 ; i + + ) {
/* Valid format to start with */
spec1 . format = AUDIO_S8 ;
spec1 . channels = 1 ;
spec1 . freq = 22050 ;
spec2 . format = AUDIO_S16LSB ;
spec2 . channels = 2 ;
spec2 . freq = 44100 ;
SDL_ClearError ( ) ;
SDLTest_AssertPass ( " Call to SDL_ClearError() " ) ;
/* Set various invalid format inputs */
SDL_strlcpy ( message , " Invalid: " , 256 ) ;
if ( i & 1 ) {
SDL_strlcat ( message , " spec1.format " , 256 ) ;
spec1 . format = 0 ;
}
if ( i & 2 ) {
SDL_strlcat ( message , " spec1.channels " , 256 ) ;
spec1 . channels = 0 ;
}
if ( i & 4 ) {
SDL_strlcat ( message , " spec1.freq " , 256 ) ;
spec1 . freq = 0 ;
}
if ( i & 8 ) {
SDL_strlcat ( message , " spec2.format " , 256 ) ;
spec2 . format = 0 ;
}
if ( i & 16 ) {
SDL_strlcat ( message , " spec2.channels " , 256 ) ;
spec2 . channels = 0 ;
}
if ( i & 32 ) {
SDL_strlcat ( message , " spec2.freq " , 256 ) ;
spec2 . freq = 0 ;
}
SDLTest_Log ( " %s " , message ) ;
result = SDL_BuildAudioCVT ( & cvt , spec1 . format , spec1 . channels , spec1 . freq ,
spec2 . format , spec2 . channels , spec2 . freq ) ;
SDLTest_AssertPass ( " Call to SDL_BuildAudioCVT(spec1 ==> spec2) " ) ;
SDLTest_AssertCheck ( result = = - 1 , " Verify result value; expected: -1, got: %i " , result ) ;
error = SDL_GetError ( ) ;
SDLTest_AssertPass ( " Call to SDL_GetError() " ) ;
SDLTest_AssertCheck ( error ! = NULL & & error [ 0 ] ! = ' \0 ' , " Validate that error message was not NULL or empty " ) ;
}
SDL_ClearError ( ) ;
SDLTest_AssertPass ( " Call to SDL_ClearError() " ) ;
return TEST_COMPLETED ;
}
/**
* \ brief Checks current audio status .
*
* \ sa https : //wiki.libsdl.org/SDL_GetAudioStatus
*/
int audio_getAudioStatus ( )
{
SDL_AudioStatus result ;
/* Check current audio status */
result = SDL_GetAudioStatus ( ) ;
SDLTest_AssertPass ( " Call to SDL_GetAudioStatus() " ) ;
SDLTest_AssertCheck ( result = = SDL_AUDIO_STOPPED | | result = = SDL_AUDIO_PLAYING | | result = = SDL_AUDIO_PAUSED ,
" Verify returned value; expected: STOPPED (%i) | PLAYING (%i) | PAUSED (%i), got: %i " ,
SDL_AUDIO_STOPPED , SDL_AUDIO_PLAYING , SDL_AUDIO_PAUSED , result ) ;
return TEST_COMPLETED ;
}
/**
* \ brief Opens , checks current audio status , and closes a device .
*
* \ sa https : //wiki.libsdl.org/SDL_GetAudioStatus
*/
int audio_openCloseAndGetAudioStatus ( )
{
SDL_AudioStatus result ;
int i ;
int count ;
2021-12-06 20:20:09 -05:00
const char * device ;
2021-04-17 23:35:25 -04:00
SDL_AudioDeviceID id ;
SDL_AudioSpec desired , obtained ;
/* Get number of devices. */
count = SDL_GetNumAudioDevices ( 0 ) ;
SDLTest_AssertPass ( " Call to SDL_GetNumAudioDevices(0) " ) ;
if ( count > 0 ) {
for ( i = 0 ; i < count ; i + + ) {
/* Get device name */
2021-12-06 20:20:09 -05:00
device = SDL_GetAudioDeviceName ( i , 0 ) ;
2021-04-17 23:35:25 -04:00
SDLTest_AssertPass ( " SDL_GetAudioDeviceName(%i,0) " , i ) ;
SDLTest_AssertCheck ( device ! = NULL , " Validate device name is not NULL; got: %s " , ( device ! = NULL ) ? device : " NULL " ) ;
if ( device = = NULL ) return TEST_ABORTED ;
/* Set standard desired spec */
desired . freq = 22050 ;
desired . format = AUDIO_S16SYS ;
desired . channels = 2 ;
desired . samples = 4096 ;
desired . callback = _audio_testCallback ;
desired . userdata = NULL ;
/* Open device */
2021-12-06 20:20:09 -05:00
id = SDL_OpenAudioDevice ( device , 0 , & desired , & obtained , SDL_AUDIO_ALLOW_ANY_CHANGE ) ;
2021-04-17 23:35:25 -04:00
SDLTest_AssertPass ( " SDL_OpenAudioDevice('%s',...) " , device ) ;
SDLTest_AssertCheck ( id > 1 , " Validate device ID; expected: >=2, got: %i " , id ) ;
if ( id > 1 ) {
/* Check device audio status */
result = SDL_GetAudioDeviceStatus ( id ) ;
SDLTest_AssertPass ( " Call to SDL_GetAudioDeviceStatus() " ) ;
SDLTest_AssertCheck ( result = = SDL_AUDIO_STOPPED | | result = = SDL_AUDIO_PLAYING | | result = = SDL_AUDIO_PAUSED ,
" Verify returned value; expected: STOPPED (%i) | PLAYING (%i) | PAUSED (%i), got: %i " ,
SDL_AUDIO_STOPPED , SDL_AUDIO_PLAYING , SDL_AUDIO_PAUSED , result ) ;
/* Close device again */
SDL_CloseAudioDevice ( id ) ;
SDLTest_AssertPass ( " Call to SDL_CloseAudioDevice() " ) ;
}
}
} else {
SDLTest_Log ( " No devices to test with " ) ;
}
return TEST_COMPLETED ;
}
/**
* \ brief Locks and unlocks open audio device .
*
* \ sa https : //wiki.libsdl.org/SDL_LockAudioDevice
* \ sa https : //wiki.libsdl.org/SDL_UnlockAudioDevice
*/
int audio_lockUnlockOpenAudioDevice ( )
{
int i ;
int count ;
2021-12-06 20:20:09 -05:00
const char * device ;
2021-04-17 23:35:25 -04:00
SDL_AudioDeviceID id ;
SDL_AudioSpec desired , obtained ;
/* Get number of devices. */
count = SDL_GetNumAudioDevices ( 0 ) ;
SDLTest_AssertPass ( " Call to SDL_GetNumAudioDevices(0) " ) ;
if ( count > 0 ) {
for ( i = 0 ; i < count ; i + + ) {
/* Get device name */
2021-12-06 20:20:09 -05:00
device = SDL_GetAudioDeviceName ( i , 0 ) ;
2021-04-17 23:35:25 -04:00
SDLTest_AssertPass ( " SDL_GetAudioDeviceName(%i,0) " , i ) ;
SDLTest_AssertCheck ( device ! = NULL , " Validate device name is not NULL; got: %s " , ( device ! = NULL ) ? device : " NULL " ) ;
if ( device = = NULL ) return TEST_ABORTED ;
/* Set standard desired spec */
desired . freq = 22050 ;
desired . format = AUDIO_S16SYS ;
desired . channels = 2 ;
desired . samples = 4096 ;
desired . callback = _audio_testCallback ;
desired . userdata = NULL ;
/* Open device */
2021-12-06 20:20:09 -05:00
id = SDL_OpenAudioDevice ( device , 0 , & desired , & obtained , SDL_AUDIO_ALLOW_ANY_CHANGE ) ;
2021-04-17 23:35:25 -04:00
SDLTest_AssertPass ( " SDL_OpenAudioDevice('%s',...) " , device ) ;
SDLTest_AssertCheck ( id > 1 , " Validate device ID; expected: >=2, got: %i " , id ) ;
if ( id > 1 ) {
/* Lock to protect callback */
SDL_LockAudioDevice ( id ) ;
SDLTest_AssertPass ( " SDL_LockAudioDevice(%i) " , id ) ;
/* Simulate callback processing */
SDL_Delay ( 10 ) ;
SDLTest_Log ( " Simulate callback processing - delay " ) ;
/* Unlock again */
SDL_UnlockAudioDevice ( id ) ;
SDLTest_AssertPass ( " SDL_UnlockAudioDevice(%i) " , id ) ;
/* Close device again */
SDL_CloseAudioDevice ( id ) ;
SDLTest_AssertPass ( " Call to SDL_CloseAudioDevice() " ) ;
}
}
} else {
SDLTest_Log ( " No devices to test with " ) ;
}
return TEST_COMPLETED ;
}
/**
* \ brief Convert audio using various conversion structures
*
* \ sa https : //wiki.libsdl.org/SDL_BuildAudioCVT
* \ sa https : //wiki.libsdl.org/SDL_ConvertAudio
*/
int audio_convertAudio ( )
{
int result ;
SDL_AudioCVT cvt ;
SDL_AudioSpec spec1 ;
SDL_AudioSpec spec2 ;
int c ;
char message [ 128 ] ;
int i , ii , j , jj , k , kk , l , ll ;
/* Iterate over bitmask that determines which parameters are modified in the conversion */
for ( c = 1 ; c < 8 ; c + + ) {
SDL_strlcpy ( message , " Changing: " , 128 ) ;
if ( c & 1 ) {
SDL_strlcat ( message , " Format " , 128 ) ;
}
if ( c & 2 ) {
SDL_strlcat ( message , " Channels " , 128 ) ;
}
if ( c & 4 ) {
SDL_strlcat ( message , " Frequencies " , 128 ) ;
}
SDLTest_Log ( " %s " , message ) ;
/* All source conversions with random conversion targets */
for ( i = 0 ; i < _numAudioFormats ; i + + ) {
for ( j = 0 ; j < _numAudioChannels ; j + + ) {
for ( k = 0 ; k < _numAudioFrequencies ; k + + ) {
spec1 . format = _audioFormats [ i ] ;
spec1 . channels = _audioChannels [ j ] ;
spec1 . freq = _audioFrequencies [ k ] ;
/* Ensure we have a different target format */
do {
if ( c & 1 ) {
ii = SDLTest_RandomIntegerInRange ( 0 , _numAudioFormats - 1 ) ;
} else {
ii = 1 ;
}
if ( c & 2 ) {
jj = SDLTest_RandomIntegerInRange ( 0 , _numAudioChannels - 1 ) ;
} else {
jj = j ;
}
if ( c & 4 ) {
kk = SDLTest_RandomIntegerInRange ( 0 , _numAudioFrequencies - 1 ) ;
} else {
kk = k ;
}
} while ( ( i = = ii ) & & ( j = = jj ) & & ( k = = kk ) ) ;
spec2 . format = _audioFormats [ ii ] ;
spec2 . channels = _audioChannels [ jj ] ;
spec2 . freq = _audioFrequencies [ kk ] ;
result = SDL_BuildAudioCVT ( & cvt , spec1 . format , spec1 . channels , spec1 . freq ,
spec2 . format , spec2 . channels , spec2 . freq ) ;
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) " ,
i , _audioFormatsVerbose [ i ] , spec1 . format , j , spec1 . channels , k , spec1 . freq , ii , _audioFormatsVerbose [ ii ] , spec2 . format , jj , spec2 . channels , kk , spec2 . freq ) ;
SDLTest_AssertCheck ( result = = 1 , " Verify result value; expected: 1, got: %i " , result ) ;
if ( result ! = 1 ) {
SDLTest_LogError ( " %s " , SDL_GetError ( ) ) ;
} else {
SDLTest_AssertCheck ( cvt . len_mult > 0 , " Verify that cvt.len_mult value; expected: >0, got: %i " , cvt . len_mult ) ;
if ( cvt . len_mult < 1 ) return TEST_ABORTED ;
/* Create some random data to convert */
l = 64 ;
ll = l * cvt . len_mult ;
SDLTest_Log ( " Creating dummy sample buffer of %i length (%i bytes) " , l , ll ) ;
cvt . len = l ;
cvt . buf = ( Uint8 * ) SDL_malloc ( ll ) ;
SDLTest_AssertCheck ( cvt . buf ! = NULL , " Check data buffer to convert is not NULL " ) ;
if ( cvt . buf = = NULL ) return TEST_ABORTED ;
/* Convert the data */
result = SDL_ConvertAudio ( & cvt ) ;
SDLTest_AssertPass ( " Call to SDL_ConvertAudio() " ) ;
SDLTest_AssertCheck ( result = = 0 , " Verify result value; expected: 0; got: %i " , result ) ;
SDLTest_AssertCheck ( cvt . buf ! = NULL , " Verify conversion buffer is not NULL " ) ;
SDLTest_AssertCheck ( cvt . len_ratio > 0.0 , " Verify conversion length ratio; expected: >0; got: %f " , cvt . len_ratio ) ;
/* Free converted buffer */
SDL_free ( cvt . buf ) ;
cvt . buf = NULL ;
}
}
}
}
}
return TEST_COMPLETED ;
}
/**
* \ brief Opens , checks current connected status , and closes a device .
*
* \ sa https : //wiki.libsdl.org/SDL_AudioDeviceConnected
*/
int audio_openCloseAudioDeviceConnected ( )
{
int result = - 1 ;
int i ;
int count ;
2021-12-06 20:20:09 -05:00
const char * device ;
2021-04-17 23:35:25 -04:00
SDL_AudioDeviceID id ;
SDL_AudioSpec desired , obtained ;
/* Get number of devices. */
count = SDL_GetNumAudioDevices ( 0 ) ;
SDLTest_AssertPass ( " Call to SDL_GetNumAudioDevices(0) " ) ;
if ( count > 0 ) {
for ( i = 0 ; i < count ; i + + ) {
/* Get device name */
2021-12-06 20:20:09 -05:00
device = SDL_GetAudioDeviceName ( i , 0 ) ;
2021-04-17 23:35:25 -04:00
SDLTest_AssertPass ( " SDL_GetAudioDeviceName(%i,0) " , i ) ;
SDLTest_AssertCheck ( device ! = NULL , " Validate device name is not NULL; got: %s " , ( device ! = NULL ) ? device : " NULL " ) ;
if ( device = = NULL ) return TEST_ABORTED ;
/* Set standard desired spec */
desired . freq = 22050 ;
desired . format = AUDIO_S16SYS ;
desired . channels = 2 ;
desired . samples = 4096 ;
desired . callback = _audio_testCallback ;
desired . userdata = NULL ;
/* Open device */
2021-12-06 20:20:09 -05:00
id = SDL_OpenAudioDevice ( device , 0 , & desired , & obtained , SDL_AUDIO_ALLOW_ANY_CHANGE ) ;
2021-04-17 23:35:25 -04:00
SDLTest_AssertPass ( " SDL_OpenAudioDevice('%s',...) " , device ) ;
SDLTest_AssertCheck ( id > 1 , " Validate device ID; expected: >1, got: %i " , id ) ;
if ( id > 1 ) {
/* TODO: enable test code when function is available in SDL2 */
# ifdef AUDIODEVICECONNECTED_DEFINED
/* Get connected status */
result = SDL_AudioDeviceConnected ( id ) ;
SDLTest_AssertPass ( " Call to SDL_AudioDeviceConnected() " ) ;
# endif
SDLTest_AssertCheck ( result = = 1 , " Verify returned value; expected: 1; got: %i " , result ) ;
/* Close device again */
SDL_CloseAudioDevice ( id ) ;
SDLTest_AssertPass ( " Call to SDL_CloseAudioDevice() " ) ;
}
}
} else {
SDLTest_Log ( " No devices to test with " ) ;
}
return TEST_COMPLETED ;
}
/* ================= Test Case References ================== */
/* Audio test cases */
static const SDLTest_TestCaseReference audioTest1 =
{ ( SDLTest_TestCaseFp ) audio_enumerateAndNameAudioDevices , " audio_enumerateAndNameAudioDevices " , " Enumerate and name available audio devices (output and capture) " , TEST_ENABLED } ;
static const SDLTest_TestCaseReference audioTest2 =
{ ( SDLTest_TestCaseFp ) audio_enumerateAndNameAudioDevicesNegativeTests , " audio_enumerateAndNameAudioDevicesNegativeTests " , " Negative tests around enumeration and naming of audio devices. " , TEST_ENABLED } ;
static const SDLTest_TestCaseReference audioTest3 =
{ ( SDLTest_TestCaseFp ) audio_printAudioDrivers , " audio_printAudioDrivers " , " Checks available audio driver names. " , TEST_ENABLED } ;
static const SDLTest_TestCaseReference audioTest4 =
{ ( SDLTest_TestCaseFp ) audio_printCurrentAudioDriver , " audio_printCurrentAudioDriver " , " Checks current audio driver name with initialized audio. " , TEST_ENABLED } ;
static const SDLTest_TestCaseReference audioTest5 =
{ ( SDLTest_TestCaseFp ) audio_buildAudioCVT , " audio_buildAudioCVT " , " Builds various audio conversion structures. " , TEST_ENABLED } ;
static const SDLTest_TestCaseReference audioTest6 =
{ ( SDLTest_TestCaseFp ) audio_buildAudioCVTNegative , " audio_buildAudioCVTNegative " , " Checks calls with invalid input to SDL_BuildAudioCVT " , TEST_ENABLED } ;
static const SDLTest_TestCaseReference audioTest7 =
{ ( SDLTest_TestCaseFp ) audio_getAudioStatus , " audio_getAudioStatus " , " Checks current audio status. " , TEST_ENABLED } ;
static const SDLTest_TestCaseReference audioTest8 =
{ ( SDLTest_TestCaseFp ) audio_openCloseAndGetAudioStatus , " audio_openCloseAndGetAudioStatus " , " Opens and closes audio device and get audio status. " , TEST_ENABLED } ;
static const SDLTest_TestCaseReference audioTest9 =
{ ( SDLTest_TestCaseFp ) audio_lockUnlockOpenAudioDevice , " audio_lockUnlockOpenAudioDevice " , " Locks and unlocks an open audio device. " , TEST_ENABLED } ;
/* TODO: enable test when SDL_ConvertAudio segfaults on cygwin have been fixed. */
/* For debugging, test case can be run manually using --filter audio_convertAudio */
static const SDLTest_TestCaseReference audioTest10 =
{ ( SDLTest_TestCaseFp ) audio_convertAudio , " audio_convertAudio " , " Convert audio using available formats. " , TEST_DISABLED } ;
/* TODO: enable test when SDL_AudioDeviceConnected has been implemented. */
static const SDLTest_TestCaseReference audioTest11 =
{ ( SDLTest_TestCaseFp ) audio_openCloseAudioDeviceConnected , " audio_openCloseAudioDeviceConnected " , " Opens and closes audio device and get connected status. " , TEST_DISABLED } ;
static const SDLTest_TestCaseReference audioTest12 =
{ ( SDLTest_TestCaseFp ) audio_quitInitAudioSubSystem , " audio_quitInitAudioSubSystem " , " Quit and re-init audio subsystem. " , TEST_ENABLED } ;
static const SDLTest_TestCaseReference audioTest13 =
{ ( SDLTest_TestCaseFp ) audio_initQuitAudio , " audio_initQuitAudio " , " Init and quit audio drivers directly. " , TEST_ENABLED } ;
static const SDLTest_TestCaseReference audioTest14 =
{ ( SDLTest_TestCaseFp ) audio_initOpenCloseQuitAudio , " audio_initOpenCloseQuitAudio " , " Cycle through init, open, close and quit with various audio specs. " , TEST_ENABLED } ;
static const SDLTest_TestCaseReference audioTest15 =
{ ( SDLTest_TestCaseFp ) audio_pauseUnpauseAudio , " audio_pauseUnpauseAudio " , " Pause and Unpause audio for various audio specs while testing callback. " , TEST_ENABLED } ;
/* Sequence of Audio test cases */
static const SDLTest_TestCaseReference * audioTests [ ] = {
& audioTest1 , & audioTest2 , & audioTest3 , & audioTest4 , & audioTest5 , & audioTest6 ,
& audioTest7 , & audioTest8 , & audioTest9 , & audioTest10 , & audioTest11 ,
& audioTest12 , & audioTest13 , & audioTest14 , & audioTest15 , NULL
} ;
/* Audio test suite (global) */
SDLTest_TestSuiteReference audioTestSuite = {
" Audio " ,
_audioSetUp ,
audioTests ,
_audioTearDown
} ;