SDL: cleanup/sync the main loop of *_OpenDevice functions to pick audio format

From 2eafe4340cbaf4afe5563c1d5d66a58385ada812 Mon Sep 17 00:00:00 2001
From: pionere <[EMAIL REDACTED]>
Date: Thu, 20 Jan 2022 12:18:59 +0100
Subject: [PATCH] cleanup/sync the main loop of *_OpenDevice functions to pick
 audio format

---
 src/audio/alsa/SDL_alsa_audio.c            | 20 ++----
 src/audio/android/SDL_androidaudio.c       |  8 +--
 src/audio/arts/SDL_artsaudio.c             | 24 +++----
 src/audio/coreaudio/SDL_coreaudio.m        | 31 +++++----
 src/audio/directsound/SDL_directsound.c    | 17 ++---
 src/audio/emscripten/SDL_emscriptenaudio.c | 16 ++---
 src/audio/fusionsound/SDL_fsaudio.c        | 25 ++------
 src/audio/haiku/SDL_haikuaudio.cc          | 17 ++---
 src/audio/nas/SDL_nasaudio.c               | 55 ++++++++--------
 src/audio/netbsd/SDL_netbsdaudio.c         | 47 ++++++--------
 src/audio/openslES/SDL_openslES.c          |  7 +-
 src/audio/os2/SDL_os2audio.c               | 15 ++---
 src/audio/paudio/SDL_paudio.c              | 66 +++++++------------
 src/audio/pulseaudio/SDL_pulseaudio.c      | 35 +++++-----
 src/audio/qsa/SDL_qsa_audio.c              | 75 +++++-----------------
 src/audio/sndio/SDL_sndioaudio.c           | 12 ++--
 src/audio/wasapi/SDL_wasapi.c              |  2 +-
 src/audio/winmm/SDL_winmm.c                | 21 +++---
 18 files changed, 186 insertions(+), 307 deletions(-)

diff --git a/src/audio/alsa/SDL_alsa_audio.c b/src/audio/alsa/SDL_alsa_audio.c
index c42b73045d5..4a2eec7f052 100644
--- a/src/audio/alsa/SDL_alsa_audio.c
+++ b/src/audio/alsa/SDL_alsa_audio.c
@@ -598,10 +598,7 @@ ALSA_OpenDevice(_THIS, void *handle, const char *devname)
     }
 
     /* Try for a closest match on audio format */
-    status = -1;
-    for (test_format = SDL_FirstAudioFormat(this->spec.format);
-         test_format && (status < 0);) {
-        status = 0;             /* if we can't support a format, it'll become -1. */
+    for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
         switch (test_format) {
         case AUDIO_U8:
             format = SND_PCM_FORMAT_U8;
@@ -634,19 +631,14 @@ ALSA_OpenDevice(_THIS, void *handle, const char *devname)
             format = SND_PCM_FORMAT_FLOAT_BE;
             break;
         default:
-            status = -1;
-            break;
-        }
-        if (status >= 0) {
-            status = ALSA_snd_pcm_hw_params_set_format(pcm_handle,
-                                                       hwparams, format);
+            continue;
         }
-        if (status < 0) {
-            test_format = SDL_NextAudioFormat();
+        if (ALSA_snd_pcm_hw_params_set_format(pcm_handle, hwparams, format) >= 0) {
+            break;
         }
     }
-    if (status < 0) {
-        return SDL_SetError("ALSA: Couldn't find any hardware audio formats");
+    if (!test_format) {
+        return SDL_SetError("%s: Unsupported audio format", "alsa");
     }
     this->spec.format = test_format;
 
diff --git a/src/audio/android/SDL_androidaudio.c b/src/audio/android/SDL_androidaudio.c
index cdf494897d4..92bb5910e69 100644
--- a/src/audio/android/SDL_androidaudio.c
+++ b/src/audio/android/SDL_androidaudio.c
@@ -55,20 +55,18 @@ ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname)
         return SDL_OutOfMemory();
     }
 
-    test_format = SDL_FirstAudioFormat(this->spec.format);
-    while (test_format != 0) { /* no "UNKNOWN" constant */
+    for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
         if ((test_format == AUDIO_U8) ||
             (test_format == AUDIO_S16) ||
             (test_format == AUDIO_F32)) {
             this->spec.format = test_format;
             break;
         }
-        test_format = SDL_NextAudioFormat();
     }
 
-    if (test_format == 0) {
+    if (!test_format) {
         /* Didn't find a compatible format :( */
-        return SDL_SetError("No compatible audio format!");
+        return SDL_SetError("%s: Unsupported audio format", "android");
     }
 
     if (Android_JNI_OpenAudioDevice(iscapture, &this->spec) < 0) {
diff --git a/src/audio/arts/SDL_artsaudio.c b/src/audio/arts/SDL_artsaudio.c
index 6806b1b4a29..359eec40d56 100644
--- a/src/audio/arts/SDL_artsaudio.c
+++ b/src/audio/arts/SDL_artsaudio.c
@@ -219,8 +219,8 @@ static int
 ARTS_OpenDevice(_THIS, void *handle, const char *devname)
 {
     int rc = 0;
-    int bits = 0, frag_spec = 0;
-    SDL_AudioFormat test_format = 0, format = 0;
+    int bits, frag_spec = 0;
+    SDL_AudioFormat test_format = 0;
 
     /* Initialize all variables that we clean on shutdown */
     this->hidden = (struct SDL_PrivateAudioData *)
@@ -231,32 +231,24 @@ ARTS_OpenDevice(_THIS, void *handle, const char *devname)
     SDL_zerop(this->hidden);
 
     /* Try for a closest match on audio format */
-    for (test_format = SDL_FirstAudioFormat(this->spec.format);
-         !format && test_format;) {
+    for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
 #ifdef DEBUG_AUDIO
         fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
 #endif
         switch (test_format) {
         case AUDIO_U8:
-            bits = 8;
-            format = 1;
-            break;
         case AUDIO_S16LSB:
-            bits = 16;
-            format = 1;
             break;
         default:
-            format = 0;
-            break;
-        }
-        if (!format) {
-            test_format = SDL_NextAudioFormat();
+            continue;
         }
+        break;
     }
-    if (format == 0) {
-        return SDL_SetError("Couldn't find any hardware audio formats");
+    if (!test_format) {
+        return SDL_SetError("%s: Unsupported audio format", "arts");
     }
     this->spec.format = test_format;
+    bits = SDL_AUDIO_BITSIZE(test_format);
 
     if ((rc = SDL_NAME(arts_init) ()) != 0) {
         return SDL_SetError("Unable to initialize ARTS: %s",
diff --git a/src/audio/coreaudio/SDL_coreaudio.m b/src/audio/coreaudio/SDL_coreaudio.m
index 95823e03e32..3b0ef9d81a0 100644
--- a/src/audio/coreaudio/SDL_coreaudio.m
+++ b/src/audio/coreaudio/SDL_coreaudio.m
@@ -1018,8 +1018,8 @@ output device (in which case we'll try again). */
 COREAUDIO_OpenDevice(_THIS, void *handle, const char *devname)
 {
     AudioStreamBasicDescription *strdesc;
-    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
-    SDL_bool valid_datatype = SDL_FALSE, iscapture = this->iscapture;
+    SDL_AudioFormat test_format;
+    SDL_bool iscapture = this->iscapture;
     SDL_AudioDevice **new_open_devices;
 
     /* Initialize all variables that we clean on shutdown */
@@ -1076,8 +1076,7 @@ output device (in which case we'll try again). */
     strdesc->mSampleRate = this->spec.freq;
     strdesc->mFramesPerPacket = 1;
 
-    while ((!valid_datatype) && (test_format)) {
-        this->spec.format = test_format;
+    for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
         /* CoreAudio handles most of SDL's formats natively, but not U16, apparently. */
         switch (test_format) {
         case AUDIO_U8:
@@ -1088,26 +1087,26 @@ output device (in which case we'll try again). */
         case AUDIO_S32MSB:
         case AUDIO_F32LSB:
         case AUDIO_F32MSB:
-            valid_datatype = SDL_TRUE;
-            strdesc->mBitsPerChannel = SDL_AUDIO_BITSIZE(this->spec.format);
-            if (SDL_AUDIO_ISBIGENDIAN(this->spec.format))
-                strdesc->mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
-
-            if (SDL_AUDIO_ISFLOAT(this->spec.format))
-                strdesc->mFormatFlags |= kLinearPCMFormatFlagIsFloat;
-            else if (SDL_AUDIO_ISSIGNED(this->spec.format))
-                strdesc->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
             break;
 
         default:
-            test_format = SDL_NextAudioFormat();
-            break;
+            continue;
         }
+        break;
     }
 
-    if (!valid_datatype) {      /* shouldn't happen, but just in case... */
+    if (!test_format) {      /* shouldn't happen, but just in case... */
         return SDL_SetError("Unsupported audio format");
     }
+    this->spec.format = test_format;
+    strdesc->mBitsPerChannel = SDL_AUDIO_BITSIZE(test_format);
+    if (SDL_AUDIO_ISBIGENDIAN(test_format))
+        strdesc->mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
+
+    if (SDL_AUDIO_ISFLOAT(test_format))
+        strdesc->mFormatFlags |= kLinearPCMFormatFlagIsFloat;
+    else if (SDL_AUDIO_ISSIGNED(test_format))
+        strdesc->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
 
     strdesc->mBytesPerFrame = strdesc->mChannelsPerFrame * strdesc->mBitsPerChannel / 8;
     strdesc->mBytesPerPacket = strdesc->mBytesPerFrame * strdesc->mFramesPerPacket;
diff --git a/src/audio/directsound/SDL_directsound.c b/src/audio/directsound/SDL_directsound.c
index 11430272395..86e58a1a6ef 100644
--- a/src/audio/directsound/SDL_directsound.c
+++ b/src/audio/directsound/SDL_directsound.c
@@ -477,10 +477,9 @@ DSOUND_OpenDevice(_THIS, void *handle, const char *devname)
 {
     const DWORD numchunks = 8;
     HRESULT result;
-    SDL_bool valid_format = SDL_FALSE;
     SDL_bool tried_format = SDL_FALSE;
     SDL_bool iscapture = this->iscapture;
-    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
+    SDL_AudioFormat test_format;
     LPGUID guid = (LPGUID) handle;
     DWORD bufsize;
 
@@ -511,7 +510,7 @@ DSOUND_OpenDevice(_THIS, void *handle, const char *devname)
         }
     }
 
-    while ((!valid_format) && (test_format)) {
+    for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
         switch (test_format) {
         case AUDIO_U8:
         case AUDIO_S16:
@@ -548,19 +547,21 @@ DSOUND_OpenDevice(_THIS, void *handle, const char *devname)
                 rc = iscapture ? CreateCaptureBuffer(this, bufsize, &wfmt) : CreateSecondary(this, bufsize, &wfmt);
                 if (rc == 0) {
                     this->hidden->num_buffers = numchunks;
-                    valid_format = SDL_TRUE;
+                    break;
                 }
             }
-            break;
+            continue;
+        default:
+            continue;
         }
-        test_format = SDL_NextAudioFormat();
+        break;
     }
 
-    if (!valid_format) {
+    if (!test_format) {
         if (tried_format) {
             return -1;  /* CreateSecondary() should have called SDL_SetError(). */
         }
-        return SDL_SetError("DirectSound: Unsupported audio format");
+        return SDL_SetError("%s: Unsupported audio format", "directsound");
     }
 
     /* Playback buffers will auto-start playing in DSOUND_WaitDevice() */
diff --git a/src/audio/emscripten/SDL_emscriptenaudio.c b/src/audio/emscripten/SDL_emscriptenaudio.c
index 764c8e1b4af..157892f8fe3 100644
--- a/src/audio/emscripten/SDL_emscriptenaudio.c
+++ b/src/audio/emscripten/SDL_emscriptenaudio.c
@@ -194,7 +194,6 @@ EMSCRIPTENAUDIO_CloseDevice(_THIS)
 static int
 EMSCRIPTENAUDIO_OpenDevice(_THIS, void *handle, const char *devname)
 {
-    SDL_bool valid_format = SDL_FALSE;
     SDL_AudioFormat test_format;
     SDL_bool iscapture = this->iscapture;
     int result;
@@ -229,22 +228,21 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, void *handle, const char *devname)
         return SDL_SetError("Web Audio API is not available!");
     }
 
-    test_format = SDL_FirstAudioFormat(this->spec.format);
-    while ((!valid_format) && (test_format)) {
+    for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
         switch (test_format) {
         case AUDIO_F32: /* web audio only supports floats */
-            this->spec.format = test_format;
-
-            valid_format = SDL_TRUE;
             break;
+        default:
+            continue;
         }
-        test_format = SDL_NextAudioFormat();
+        break;
     }
 
-    if (!valid_format) {
+    if (!test_format) {
         /* Didn't find a compatible format :( */
-        return SDL_SetError("No compatible audio format!");
+        return SDL_SetError("%s: Unsupported audio format", "emscripten");
     }
+    this->spec.format = test_format;
 
     /* Initialize all variables that we clean on shutdown */
 #if 0  /* !!! FIXME: currently not used. Can we move some stuff off the SDL2 namespace? --ryan. */
diff --git a/src/audio/fusionsound/SDL_fsaudio.c b/src/audio/fusionsound/SDL_fsaudio.c
index 89affb61508..92c214ceb3d 100644
--- a/src/audio/fusionsound/SDL_fsaudio.c
+++ b/src/audio/fusionsound/SDL_fsaudio.c
@@ -177,7 +177,7 @@ static int
 SDL_FS_OpenDevice(_THIS, void *handle, const char *devname)
 {
     int bytes;
-    SDL_AudioFormat test_format = 0, format = 0;
+    SDL_AudioFormat test_format;
     FSSampleFormat fs_format;
     FSStreamDescription desc;
     DirectResult ret;
@@ -191,45 +191,34 @@ SDL_FS_OpenDevice(_THIS, void *handle, const char *devname)
     SDL_zerop(this->hidden);
 
     /* Try for a closest match on audio format */
-    for (test_format = SDL_FirstAudioFormat(this->spec.format);
-         !format && test_format;) {
+    for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
 #ifdef DEBUG_AUDIO
         fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
 #endif
         switch (test_format) {
         case AUDIO_U8:
             fs_format = FSSF_U8;
-            bytes = 1;
-            format = 1;
             break;
         case AUDIO_S16SYS:
             fs_format = FSSF_S16;
-            bytes = 2;
-            format = 1;
             break;
         case AUDIO_S32SYS:
             fs_format = FSSF_S32;
-            bytes = 4;
-            format = 1;
             break;
         case AUDIO_F32SYS:
             fs_format = FSSF_FLOAT;
-            bytes = 4;
-            format = 1;
             break;
         default:
-            format = 0;
-            break;
-        }
-        if (!format) {
-            test_format = SDL_NextAudioFormat();
+            continue;
         }
+        break;
     }
 
-    if (format == 0) {
-        return SDL_SetError("Couldn't find any hardware audio formats");
+    if (!test_format) {
+        return SDL_SetError("%s: Unsupported audio format", "fusionsound");
     }
     this->spec.format = test_format;
+    bytes = SDL_AUDIO_BITSIZE(test_format) / 8;
 
     /* Retrieve the main sound interface. */
     ret = SDL_NAME(FusionSoundCreate) (&this->hidden->fs);
diff --git a/src/audio/haiku/SDL_haikuaudio.cc b/src/audio/haiku/SDL_haikuaudio.cc
index 9e3724799b7..c23b63ec695 100644
--- a/src/audio/haiku/SDL_haikuaudio.cc
+++ b/src/audio/haiku/SDL_haikuaudio.cc
@@ -122,9 +122,8 @@ UnmaskSignals(sigset_t * omask)
 static int
 HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname)
 {
-    int valid_datatype = 0;
     media_raw_audio_format format;
-    SDL_AudioFormat test_format = SDL_FirstAudioFormat(_this->spec.format);
+    SDL_AudioFormat test_format;
 
     /* Initialize all variables that we clean on shutdown */
     _this->hidden = new SDL_PrivateAudioData;
@@ -138,9 +137,7 @@ HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname)
     format.byte_order = B_MEDIA_LITTLE_ENDIAN;
     format.frame_rate = (float) _this->spec.freq;
     format.channel_count = _this->spec.channels;        /* !!! FIXME: support > 2? */
-    while ((!valid_datatype) && (test_format)) {
-        valid_datatype = 1;
-        _this->spec.format = test_format;
+    for (test_format = SDL_FirstAudioFormat(_this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
         switch (test_format) {
         case AUDIO_S8:
             format.format = media_raw_audio_format::B_AUDIO_CHAR;
@@ -178,15 +175,15 @@ HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname)
             break;
 
         default:
-            valid_datatype = 0;
-            test_format = SDL_NextAudioFormat();
-            break;
+            continue;
         }
+        break;
     }
 
-    if (!valid_datatype) {      /* shouldn't happen, but just in case... */
-        return SDL_SetError("Unsupported audio format");
+    if (!test_format) {      /* shouldn't happen, but just in case... */
+        return SDL_SetError("%s: Unsupported audio format", "haiku");
     }
+    _this->spec.format = test_format;
 
     /* Calculate the final parameters for this audio specification */
     SDL_CalculateAudioSpec(&_this->spec);
diff --git a/src/audio/nas/SDL_nasaudio.c b/src/audio/nas/SDL_nasaudio.c
index a6ef419b38c..adedb2e4202 100644
--- a/src/audio/nas/SDL_nasaudio.c
+++ b/src/audio/nas/SDL_nasaudio.c
@@ -237,26 +237,6 @@ NAS_CloseDevice(_THIS)
     SDL_free(this->hidden);
 }
 
-static unsigned char
-sdlformat_to_auformat(unsigned int fmt)
-{
-    switch (fmt) {
-    case AUDIO_U8:
-        return AuFormatLinearUnsigned8;
-    case AUDIO_S8:
-        return AuFormatLinearSigned8;
-    case AUDIO_U16LSB:
-        return AuFormatLinearUnsigned16LSB;
-    case AUDIO_U16MSB:
-        return AuFormatLinearUnsigned16MSB;
-    case AUDIO_S16LSB:
-        return AuFormatLinearSigned16LSB;
-    case AUDIO_S16MSB:
-        return AuFormatLinearSigned16MSB;
-    }
-    return AuNone;
-}
-
 static AuBool
 event_handler(AuServer * aud, AuEvent * ev, AuEventHandlerRec * hnd)
 {
@@ -336,7 +316,7 @@ NAS_OpenDevice(_THIS, void *handle, const char *devname)
     AuElement elms[3];
     int buffer_size;
     SDL_bool iscapture = this->iscapture;
-    SDL_AudioFormat test_format, format;
+    SDL_AudioFormat test_format, format = 0;
 
     /* Initialize all variables that we clean on shutdown */
     this->hidden = (struct SDL_PrivateAudioData *)
@@ -347,16 +327,33 @@ NAS_OpenDevice(_THIS, void *handle, const char *devname)
     SDL_zerop(this->hidden);
 
     /* Try for a closest match on audio format */
-    format = 0;
-    for (test_format = SDL_FirstAudioFormat(this->spec.format);
-         !format && test_format;) {
-        format = sdlformat_to_auformat(test_format);
-        if (format == AuNone) {
-            test_format = SDL_NextAudioFormat();
+    for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
+        switch (test_format) {
+        case AUDIO_U8:
+            format = AuFormatLinearUnsigned8;
+            break;
+        case AUDIO_S8:
+            format = AuFormatLinearSigned8;
+            break;
+        case AUDIO_U16LSB:
+            format = AuFormatLinearUnsigned16LSB;
+            break;
+        case AUDIO_U16MSB:
+            format = AuFormatLinearUnsigned16MSB;
+            break;
+        case AUDIO_S16LSB:
+            format = AuFormatLinearSigned16LSB;
+            break;
+        case AUDIO_S16MSB:
+            format = AuFormatLinearSigned16MSB;
+            break;
+        default:
+            continue;
         }
+        break;
     }
-    if (format == 0) {
-        return SDL_SetError("NAS: Couldn't find any hardware audio formats");
+    if (!test_format) {
+        return SDL_SetError("%s: Unsupported audio format", "nas");
     }
     this->spec.format = test_format;
 
diff --git a/src/audio/netbsd/SDL_netbsdaudio.c b/src/audio/netbsd/SDL_netbsdaudio.c
index 13556b78365..4e710d35aed 100644
--- a/src/audio/netbsd/SDL_netbsdaudio.c
+++ b/src/audio/netbsd/SDL_netbsdaudio.c
@@ -205,7 +205,8 @@ static int
 NETBSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname)
 {
     SDL_bool iscapture = this->iscapture;
-    SDL_AudioFormat format = 0;
+    SDL_AudioFormat test_format;
+    int encoding = AUDIO_ENCODING_NONE;
     audio_info_t info, hwinfo;
     struct audio_prinfo *prinfo = iscapture ? &info.record : &info.play;
 
@@ -245,54 +246,46 @@ NETBSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname)
     }
 #endif
 
-    prinfo->encoding = AUDIO_ENCODING_NONE;
     prinfo->sample_rate = this->spec.freq;
     prinfo->channels = this->spec.channels;
 
-    for (format = SDL_FirstAudioFormat(this->spec.format); format;) {
-        switch (format) {
+    for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
+        switch (test_format) {
         case AUDIO_U8:
-            prinfo->encoding = AUDIO_ENCODING_ULINEAR;
-            prinfo->precision = 8;
+            encoding = AUDIO_ENCODING_ULINEAR;
             break;
         case AUDIO_S8:
-            prinfo->encoding = AUDIO_ENCODING_SLINEAR;
-            prinfo->precision = 8;
+            encoding = AUDIO_ENCODING_SLINEAR;
             break;
         case AUDIO_S16LSB:
-            prinfo->encoding = AUDIO_ENCODING_SLINEAR_LE;
-            prinfo->precision = 16;
+            encoding = AUDIO_ENCODING_SLINEAR_LE;
             break;
         case AUDIO_S16MSB:
-            prinfo->encoding = AUDIO_ENCODING_SLINEAR_BE;
-            prinfo->precision = 16;
+            encoding = AUDIO_ENCODING_SLINEAR_BE;
             break;
         case AUDIO_U16LSB:
-            prinfo->encoding = AUDIO_ENCODING_ULINEAR_LE;
-            prinfo->precision = 16;
+            encoding = AUDIO_ENCODING_ULINEAR_LE;
             break;
         case AUDIO_U16MSB:
-            prinfo->encoding = AUDIO_ENCODING_ULINEAR_BE;
-            prinfo->precision = 16;
+            encoding = AUDIO_ENCODING_ULINEAR_BE;
             break;
         case AUDIO_S32LSB:
-            prinfo->encoding = AUDIO_ENCODING_SLINEAR_LE;
-            prinfo->precision = 32;
+            encoding = AUDIO_ENCODING_SLINEAR_LE;
             break;
         case AUDIO_S32MSB:
-            prinfo->encoding = AUDIO_ENCODING_SLINEAR_BE;
-            prinfo->precision = 32;
+            encoding = AUDIO_ENCODING_SLINEAR_BE;
             break;
+        default:
+            continue;
         }
-        if (prinfo->encoding != AUDIO_ENCODING_NONE) {
-            break;
-        }
-        format = SDL_NextAudioFormat();
+        break;
     }
 
-    if (prinfo->encoding == AUDIO_ENCODING_NONE) {
-        return SDL_SetError("No supported encoding for 0x%x", this->spec.format);
+    if (!test_format) {
+        return SDL_SetError("%s: Unsupported audio format", "netbsd");
     }
+    prinfo->encoding = encoding;
+    prinfo->precision = SDL_AUDIO_BITSIZE(test_format);
 
     info.hiwat = 5;
     info.lowat = 3;
@@ -305,7 +298,7 @@ NETBSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname)
     }
 
     /* Final spec used for the device. */
-    this->spec.format = format;
+    this->spec.format = test_format;
     this->spec.freq = prinfo->sample_rate;
     this->spec.channels = prinfo->channels;
 
diff --git a/src/audio/openslES/SDL_openslES.c b/src/audio/openslES/SDL_openslES.c
index d0c37697cea..3190435ad02 100644
--- a/src/audio/openslES/SDL_openslES.c
+++ b/src/audio/openslES/SDL_openslES.c
@@ -418,15 +418,14 @@ openslES_CreatePCMPlayer(_THIS)
     /* Just go with signed 16-bit audio as it's the most compatible */
     this->spec.format = AUDIO_S16SYS;
 #else
-    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
-    while (test_format != 0) {
+    SDL_AudioFormat test_format;
+    for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
         if (SDL_AUDIO_ISSIGNED(test_format) && SDL_AUDIO_ISINT(test_format)) {
             break;
         }
-        test_format = SDL_NextAudioFormat();
     }
 
-    if (test_format == 0) {
+    if (!test_format) {
         /* Didn't find a compatible format : */
         LOGI( "No compatible audio format, using signed 16-bit audio" );
         test_format = AUDIO_S16SYS;
diff --git a/src/audio/os2/SDL_os2audio.c b/src/audio/os2/SDL_os2audio.c
index 9decfe9ab84..247d14aa852 100644
--- a/src/audio/os2/SDL_os2audio.c
+++ b/src/audio/os2/SDL_os2audio.c
@@ -251,7 +251,7 @@ static void OS2_CloseDevice(_THIS)
 static int OS2_OpenDevice(_THIS, void *handle, const char *devname)
 {
     SDL_PrivateAudioData *pAData;
-    SDL_AudioFormat       SDLAudioFmt;
+    SDL_AudioFormat       test_format;
     MCI_AMP_OPEN_PARMS    stMCIAmpOpen;
     MCI_BUFFER_PARMS      stMCIBuffer;
     ULONG                 ulRC;
@@ -263,14 +263,13 @@ static int OS2_OpenDevice(_THIS, void *handle, const char *devname)
     SDL_zero(stMCIAmpOpen);
     SDL_zero(stMCIBuffer);
 
-    for (SDLAudioFmt = SDL_FirstAudioFormat(_this->spec.format);
-         SDLAudioFmt != 0; SDLAudioFmt = SDL_NextAudioFormat()) {
-        if (SDLAudioFmt == AUDIO_U8 || SDLAudioFmt == AUDIO_S16)
+    for (test_format = SDL_FirstAudioFormat(_this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
+        if (test_format == AUDIO_U8 || test_format == AUDIO_S16)
             break;
     }
-    if (SDLAudioFmt == 0) {
+    if (!test_format) {
         debug_os2("Unsupported audio format, AUDIO_S16 used");
-        SDLAudioFmt = AUDIO_S16;
+        test_format = AUDIO_S16;
     }
 
     pAData = (SDL_PrivateAudioData *) SDL_calloc(1, sizeof(struct SDL_PrivateAudioData));
@@ -330,7 +329,7 @@ static int OS2_OpenDevice(_THIS, void *handle, const char *devname)
                        &stMCIAmpSet, 0);
     }
 
-    _this->spec.format = SDLAudioFmt;
+    _this->spec.format = test_format;
     _this->spec.channels = _this->spec.channels > 1 ? 2 : 1;
     if (_this->spec.freq < 8000) {
         _this->spec.freq = 8000;
@@ -342,7 +341,7 @@ static int OS2_OpenDevice(_THIS, void *handle, const char *devname)
 
     /* Setup mixer. */
     pAData->stMCIMixSetup.ulFormatTag     = MCI_WAVE_FORMAT_PCM;
-    pAData->stMCIMixSetup.ulBitsPerSample = SDL_AUDIO_BITSIZE(SDLAudioFmt);
+    pAData->stMCIMixSetup.ulBitsPerSample = SDL_AUDIO_BITSIZE(test_format);
     pAData->stMCIMixSetup.ulSamplesPerSec = _this->spec.freq;
     pAData->stMCIMixSetup.ulChannels      = _this->spec.channels;
     pAData->stMCIMixSetup.ulDeviceType    = MCI_DEVTYPE_WAVEFORM_AUDIO;
diff --git a/src/audio/paudio/SDL_paudio.c b/src/audio/paudio/SDL_paudio.c
index aaadedae80f..602aa6004c2 100644
--- a/src/audio/paudio/SDL_paudio.c
+++ b/src/audio/paudio/SDL_paudio.c
@@ -228,7 +228,7 @@ PAUDIO_OpenDevice(_THIS, void *handle, const char *devname)
     const char *workaround = SDL_getenv("SDL_DSP_NOSELECT");
     char audiodev[1024];
     const char *err = NULL;
-    int format;
+    int flags;
     int bytes_per_sample;
     SDL_AudioFormat test_format;
     audio_init paud_init;
@@ -316,63 +316,44 @@ PAUDIO_OpenDevice(_THIS, void *handle, const char *devname)
     paud_init.channels = this->spec.channels;
 
     /* Try for a closest match on audio format */
-    format = 0;
-    for (test_format = SDL_FirstAudioFormat(this->spec.format);
-         !format && test_format;) {
+    for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
 #ifdef DEBUG_AUDIO
         fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
 #endif
         switch (test_format) {
         case AUDIO_U8:
-            bytes_per_sample = 1;
-            paud_init.bits_per_sample = 8;
-            paud_init.flags = TWOS_COMPLEMENT | FIXED;
-            format = 1;
+            flags = TWOS_COMPLEMENT | FIXED;
             break;
         case AUDIO_S8:
-            bytes_per_sample = 1;
-            paud_init.bits_per_sample = 8;
-            paud_init.flags = SIGNED | TWOS_COMPLEMENT | FIXED;
-            format = 1;
+            flags = SIGNED | TWOS_COMPLEMENT | FIXED;
             break;
         case AUDIO_S16LSB:
-            bytes_per_sample = 2;
-            paud_init.bits_per_sample = 16;
-            paud_init.flags = SIGNED | TWOS_COMPLEMENT | FIXED;
-            format = 1;
+            flags = SIGNED | TWOS_COMPLEMENT | FIXED;
             break;
         case AUDIO_S16MSB:
-            bytes_per_sample = 2;
-            paud_init.bits_per_sample = 16;
-            paud_init.flags = BIG_ENDIAN | SIGNED | TWOS_COMPLEMENT | FIXED;
-            format = 1;
+            flags = BIG_ENDIAN | SIGNED | TWOS_COMPLEMENT | FIXED;
             break;
         case AUDIO_U16LSB:
-            bytes_per_sample = 2;
-            paud_init.bits_per_sample = 16;
-            paud_init.flags = TWOS_COMPLEMENT | FIXED;
-            format = 1;
+            flags = TWOS_COMPLEMENT | FIXED;
             break;
         case AUDIO_U16MSB:
-            bytes_per_sample = 2;
-            paud_init.bits_per_sample = 16;
-            paud_init.flags = BIG_ENDIAN | TWOS_COMPLEMENT | FIXED;
-            format = 1;
+            flags = BIG_ENDIAN | TWOS_COMPLEMENT | FIXED;
             break;
         default:
-            break;
-        }
-        if (!format) {
-            test_format = SDL_NextAudioFormat();
+            continue;
         }
+        break;
     }
-    if (format == 0) {
+    if (!test_format) {
 #ifdef DEBUG_AUDIO
         fprintf(stderr, "Couldn't find any hardware audio formats\n");
 #endif
-        return SDL_SetError("Couldn't find any hardware audio formats");
+        return SDL_SetError("%s: Unsupported audio format", "paud");
     }
     this->spec.format = test_format;
+    paud_init.bits_per_sample = SDL_AUDIO_BITSIZE(test_format);
+    bytes_per_sample = SDL_AUDIO_BITSIZE(test_format) / 8;
+    paud_init.flags = flags;
 
     /*
      * We know the buffer size and the max number of subsequent writes
@@ -406,28 +387,25 @@ PAUDIO_OpenDevice(_THIS, void *handle, const char *devname)
     if (ioctl(fd, AUDIO_INIT, &paud_init) < 0) {
         switch (paud_init.rc) {
         case 1:
-            err = "Couldn't set audio format: DSP can't do play requests";
+            err = "DSP can't do play requests";
             break;
         case 2:
-            err = "Couldn't set audio format: DSP can't do record requests";
+            err = "DSP can't do record requests";
             break;
         case 4:
-            err = "Couldn't set audio format: request was invalid";
+            err = "request was invalid";
             break;
         case 5:
-            err = "Couldn't set audio format: conflict with open's flags";
+            err = "conflict with open's flags";
             break;
         case 6:
-            err = "Couldn't set audio format: out of DSP MIPS or memory";
+            err = "out of DSP MIPS or memory";
             break;
         default:
-            err = "Couldn't set audio format: not documented in sys/audio.h";
+            err = "not documented in sys/audio.h";
             break;
         }
-    }
-
-    if (err != NULL) {
-        return SDL_SetError("Paudio: %s", err);
+        return SDL_SetError("paud: Couldn't set audio format (%s)", err);
     }
 
     /* Allocate mixing buffer */
diff --git a/src/audio/pulseaudio/SDL_pulseaudio.c b/src/audio/pulseaudio/SDL_pulseaudio.c
index 07825d08e6d..9f954ea86f9 100644
--- a/src/audio/pulseaudio/SDL_pulseaudio.c
+++ b/src/audio/pulseaudio/SDL_pulseaudio.c
@@ -547,14 +547,14 @@ static int
 PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname)
 {
     struct SDL_PrivateAudioData *h = NULL;
-    Uint16 test_format = 0;
+    SDL_AudioFormat test_format;
     pa_sample_spec paspec;
     pa_buffer_attr paattr;
     pa_channel_map pacmap;
     pa_stream_flags_t flags = 0;
     const char *name = NULL;
     SDL_bool iscapture = this->iscapture;
-    int state = 0;
+    int state = 0, format = PA_SAMPLE_INVALID;
     int rc = 0;
 
     /* Initialize all variables that we clean on shutdown */
@@ -565,48 +565,43 @@ PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname)
     }
     SDL_zerop(this->hidd

(Patch may be truncated, please check the link at the top of this post.)