Cleaned up IRIX audio driver, added float32 support and fallbacks when
authorRyan C. Gordon <icculus@icculus.org>
Fri, 01 Sep 2006 00:04:07 +0000
changeset 20027590aaf89a60
parent 2001 02108bfd6550
child 2003 506851d3efa4
Cleaned up IRIX audio driver, added float32 support and fallbacks when
a specific audiospec isn't supported or the hardware fails.

Usual disclaimer: No IRIX box, so this may not even compile.
src/audio/dmedia/SDL_irixaudio.c
     1.1 --- a/src/audio/dmedia/SDL_irixaudio.c	Thu Aug 31 23:16:48 2006 +0000
     1.2 +++ b/src/audio/dmedia/SDL_irixaudio.c	Fri Sep 01 00:04:07 2006 +0000
     1.3 @@ -19,6 +19,7 @@
     1.4      Sam Lantinga
     1.5      slouken@libsdl.org
     1.6  */
     1.7 +#include <errno.h>
     1.8  #include "SDL_config.h"
     1.9  
    1.10  /* Allow access to a raw mixing buffer (For IRIX 6.5 and higher) */
    1.11 @@ -149,71 +150,100 @@
    1.12  static int
    1.13  AL_OpenAudio(_THIS, SDL_AudioSpec * spec)
    1.14  {
    1.15 -    ALconfig audio_config;
    1.16 +    SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
    1.17 +    long width = 0;
    1.18 +    long fmt = 0;
    1.19 +    int valid = 0;
    1.20 +
    1.21  #ifdef OLD_IRIX_AUDIO
    1.22 -    long audio_param[2];
    1.23 +    {
    1.24 +        long audio_param[2];
    1.25 +        audio_param[0] = AL_OUTPUT_RATE;
    1.26 +        audio_param[1] = spec->freq;
    1.27 +        valid = (ALsetparams(AL_DEFAULT_DEVICE, audio_param, 2) < 0);
    1.28 +    }
    1.29  #else
    1.30 -    ALpv audio_param;
    1.31 +    {
    1.32 +        ALpv audio_param;
    1.33 +        audio_param.param = AL_RATE;
    1.34 +        audio_param.value.i = spec->freq;
    1.35 +        valid = (alSetParams(AL_DEFAULT_OUTPUT, &audio_param, 1) < 0);
    1.36 +    }
    1.37  #endif
    1.38 -    int width;
    1.39  
    1.40 -    /* Determine the audio parameters from the AudioSpec */
    1.41 -    switch (spec->format & 0xFF) {
    1.42 +    while ((!valid) && (test_format)) {
    1.43 +        valid = 1;
    1.44 +        spec->format = test_format;
    1.45  
    1.46 -    case 8:
    1.47 -        {                       /* Signed 8 bit audio data */
    1.48 -            spec->format = AUDIO_S8;
    1.49 -            width = AL_SAMPLE_8;
    1.50 +        switch (test_format) {
    1.51 +            case AUDIO_S8:
    1.52 +                width = AL_SAMPLE_8;
    1.53 +                fmt = AL_SAMPFMT_TWOSCOMP;
    1.54 +                break;
    1.55 +
    1.56 +            case AUDIO_S16SYS:
    1.57 +                width = AL_SAMPLE_16;
    1.58 +                fmt = AL_SAMPFMT_TWOSCOMP;
    1.59 +                break;
    1.60 +
    1.61 +            case AUDIO_F32SYS:
    1.62 +                width = 0;  /* not used here... */
    1.63 +                fmt = AL_SAMPFMT_FLOAT;
    1.64 +                break;
    1.65 +
    1.66 +            /* Docs say there is int24, but not int32.... */
    1.67 +
    1.68 +            default:
    1.69 +                valid = 0;
    1.70 +                test_format = SDL_NextAudioFormat();
    1.71 +                break;
    1.72          }
    1.73 -        break;
    1.74  
    1.75 -    case 16:
    1.76 -        {                       /* Signed 16 bit audio data */
    1.77 -            spec->format = AUDIO_S16MSB;
    1.78 -            width = AL_SAMPLE_16;
    1.79 +        if (valid) {
    1.80 +            ALconfig audio_config = alNewConfig();
    1.81 +            valid = 0;
    1.82 +            if (audio_config) {
    1.83 +                if (alSetChannels(audio_config, spec->channels) < 0) {
    1.84 +                    if (spec->channels > 2) {  /* can't handle > stereo? */
    1.85 +                        spec->channels = 2;  /* try again below. */
    1.86 +                    }
    1.87 +                }
    1.88 +
    1.89 +                if ((alSetSampFmt(audio_config, fmt) >= 0) &&
    1.90 +                    ((!width) || (alSetWidth(audio_config, width) >= 0)) &&
    1.91 +                    (alSetQueueSize(audio_config, spec->samples * 2) >= 0) &&
    1.92 +                    (alSetChannels(audio_config, spec->channels) >= 0)) {
    1.93 +
    1.94 +                    audio_port = alOpenPort("SDL audio", "w", audio_config);
    1.95 +                    if (audio_port == NULL) {
    1.96 +                        /* docs say AL_BAD_CHANNELS happens here, too. */
    1.97 +                        int err = oserror();
    1.98 +                        if (err == AL_BAD_CHANNELS) {
    1.99 +                            spec->channels = 2;
   1.100 +                            alSetChannels(audio_config, spec->channels);
   1.101 +                            audio_port = alOpenPort("SDL audio", "w",
   1.102 +                                                    audio_config);
   1.103 +                        }
   1.104 +                    }
   1.105 +
   1.106 +                    if (audio_port != NULL) {
   1.107 +                        valid = 1;
   1.108 +                    }
   1.109 +                }
   1.110 +
   1.111 +                alFreeConfig(audio_config);
   1.112 +            }
   1.113          }
   1.114 -        break;
   1.115 +    }
   1.116  
   1.117 -    default:
   1.118 -        {
   1.119 -            SDL_SetError("Unsupported audio format");
   1.120 -            return (-1);
   1.121 -        }
   1.122 +    if (!valid) {
   1.123 +        SDL_SetError("Unsupported audio format");
   1.124 +        return (-1);
   1.125      }
   1.126  
   1.127      /* Update the fragment size as size in bytes */
   1.128      SDL_CalculateAudioSpec(spec);
   1.129  
   1.130 -    /* Set output frequency */
   1.131 -#ifdef OLD_IRIX_AUDIO
   1.132 -    audio_param[0] = AL_OUTPUT_RATE;
   1.133 -    audio_param[1] = spec->freq;
   1.134 -    if (ALsetparams(AL_DEFAULT_DEVICE, audio_param, 2) < 0) {
   1.135 -#else
   1.136 -    audio_param.param = AL_RATE;
   1.137 -    audio_param.value.i = spec->freq;
   1.138 -    if (alSetParams(AL_DEFAULT_OUTPUT, &audio_param, 1) < 0) {
   1.139 -#endif
   1.140 -        SDL_SetError("alSetParams failed");
   1.141 -        return (-1);
   1.142 -    }
   1.143 -
   1.144 -    /* Open the audio port with the requested frequency */
   1.145 -    audio_port = NULL;
   1.146 -    audio_config = alNewConfig();
   1.147 -    if (audio_config &&
   1.148 -        (alSetSampFmt(audio_config, AL_SAMPFMT_TWOSCOMP) >= 0) &&
   1.149 -        (alSetWidth(audio_config, width) >= 0) &&
   1.150 -        (alSetQueueSize(audio_config, spec->samples * 2) >= 0) &&
   1.151 -        (alSetChannels(audio_config, spec->channels) >= 0)) {
   1.152 -        audio_port = alOpenPort("SDL audio", "w", audio_config);
   1.153 -    }
   1.154 -    alFreeConfig(audio_config);
   1.155 -    if (audio_port == NULL) {
   1.156 -        SDL_SetError("Unable to open audio port");
   1.157 -        return (-1);
   1.158 -    }
   1.159 -
   1.160      /* Allocate mixing buffer */
   1.161      mixbuf = (Uint8 *) SDL_AllocAudioMem(spec->size);
   1.162      if (mixbuf == NULL) {