src/audio/SDL_mixer.c
changeset 1982 3b4ce57c6215
parent 1895 c121d94672cb
child 1985 8055185ae4ed
     1.1 --- a/src/audio/SDL_mixer.c	Thu Aug 10 15:15:06 2006 +0000
     1.2 +++ b/src/audio/SDL_mixer.c	Thu Aug 24 12:10:46 2006 +0000
     1.3 @@ -92,22 +92,27 @@
     1.4  void
     1.5  SDL_MixAudio(Uint8 * dst, const Uint8 * src, Uint32 len, int volume)
     1.6  {
     1.7 -    Uint16 format;
     1.8 -
     1.9 -    if (volume == 0) {
    1.10 -        return;
    1.11 -    }
    1.12      /* Mix the user-level audio format */
    1.13      if (current_audio) {
    1.14 +        SDL_AudioFormat format;
    1.15          if (current_audio->convert.needed) {
    1.16              format = current_audio->convert.src_format;
    1.17          } else {
    1.18              format = current_audio->spec.format;
    1.19          }
    1.20 -    } else {
    1.21 -        /* HACK HACK HACK */
    1.22 -        format = AUDIO_S16;
    1.23 +        SDL_MixAudioFormat(dst, src, format, len, volume);
    1.24      }
    1.25 +}
    1.26 +
    1.27 +
    1.28 +void
    1.29 +SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
    1.30 +                   Uint32 len, int volume)
    1.31 +{
    1.32 +    if (volume == 0) {
    1.33 +        return;
    1.34 +    }
    1.35 +
    1.36      switch (format) {
    1.37  
    1.38      case AUDIO_U8:
    1.39 @@ -252,6 +257,134 @@
    1.40          }
    1.41          break;
    1.42  
    1.43 +    case AUDIO_S32LSB:
    1.44 +        {
    1.45 +            const Uint32 *src32 = (Uint32 *) src;
    1.46 +            Uint32 *dst32 = (Uint32 *) dst;
    1.47 +            Sint32 src1, src2;
    1.48 +            Sint64 dst_sample;
    1.49 +            const Sint64 max_audioval = ((((Sint64)1) << (32 - 1)) - 1);
    1.50 +            const Sint64 min_audioval = -(((Sint64)1) << (32 - 1));
    1.51 +
    1.52 +            len /= 4;
    1.53 +            while (len--) {
    1.54 +                src1 = (Sint32) SDL_SwapLE32(*src32);
    1.55 +                src32++;
    1.56 +                ADJUST_VOLUME(src1, volume);
    1.57 +                src2 = (Sint32) SDL_SwapLE32(*dst32);
    1.58 +                dst_sample = src1 + src2;
    1.59 +                if (dst_sample > max_audioval) {
    1.60 +                    dst_sample = max_audioval;
    1.61 +                } else if (dst_sample < min_audioval) {
    1.62 +                    dst_sample = min_audioval;
    1.63 +                }
    1.64 +                *(dst32++) = SDL_SwapLE32((Uint32) ((Sint32) dst_sample));
    1.65 +            }
    1.66 +        }
    1.67 +        break;
    1.68 +
    1.69 +    case AUDIO_S32MSB:
    1.70 +        {
    1.71 +            const Uint32 *src32 = (Uint32 *) src;
    1.72 +            Uint32 *dst32 = (Uint32 *) dst;
    1.73 +            Sint32 src1, src2;
    1.74 +            Sint64 dst_sample;
    1.75 +            const Sint64 max_audioval = ((((Sint64)1) << (32 - 1)) - 1);
    1.76 +            const Sint64 min_audioval = -(((Sint64)1) << (32 - 1));
    1.77 +
    1.78 +            len /= 4;
    1.79 +            while (len--) {
    1.80 +                src1 = (Sint32) SDL_SwapBE32(*src32);
    1.81 +                src32++;
    1.82 +                ADJUST_VOLUME(src1, volume);
    1.83 +                src2 = (Sint32) SDL_SwapBE32(*dst32);
    1.84 +                dst_sample = src1 + src2;
    1.85 +                if (dst_sample > max_audioval) {
    1.86 +                    dst_sample = max_audioval;
    1.87 +                } else if (dst_sample < min_audioval) {
    1.88 +                    dst_sample = min_audioval;
    1.89 +                }
    1.90 +                *(dst32++) = SDL_SwapBE32((Uint32) ((Sint32) dst_sample));
    1.91 +            }
    1.92 +        }
    1.93 +        break;
    1.94 +
    1.95 +    case AUDIO_F32LSB:
    1.96 +        {
    1.97 +            const float fmaxvolume = 1.0f / ((float) SDL_MIX_MAXVOLUME);
    1.98 +            const float fvolume = (float) volume;
    1.99 +            const float *src32 = (float *) src;
   1.100 +            float *dst32 = (float *) dst;
   1.101 +            float src1, src2;
   1.102 +            double dst_sample;
   1.103 +            /* !!! FIXME: are these right? */
   1.104 +            const double max_audioval = 3.40282347e+38F;
   1.105 +            const double min_audioval = -3.40282347e+38F;
   1.106 +
   1.107 +            /* !!! FIXME: this is a little nasty. */
   1.108 +            union { float f; Uint32 ui32; } cvt;
   1.109 +
   1.110 +            len /= 4;
   1.111 +            while (len--) {
   1.112 +                cvt.f = *(src32++);
   1.113 +                cvt.ui32 = SDL_SwapLE32(cvt.ui32);
   1.114 +                src1 = ((cvt.f * fvolume) * fmaxvolume);
   1.115 +
   1.116 +                cvt.f = *dst32;
   1.117 +                cvt.ui32 = SDL_SwapLE32(cvt.ui32);
   1.118 +                src2 = cvt.f;
   1.119 +
   1.120 +                dst_sample = src1 + src2;
   1.121 +                if (dst_sample > max_audioval) {
   1.122 +                    dst_sample = max_audioval;
   1.123 +                } else if (dst_sample < min_audioval) {
   1.124 +                    dst_sample = min_audioval;
   1.125 +                }
   1.126 +                cvt.f = ((float) dst_sample);
   1.127 +                cvt.ui32 = SDL_SwapLE32(cvt.ui32);
   1.128 +                *(dst32++) = cvt.f;
   1.129 +            }
   1.130 +        }
   1.131 +        break;
   1.132 +
   1.133 +    case AUDIO_F32MSB:
   1.134 +        {
   1.135 +            const float fmaxvolume = 1.0f / ((float) SDL_MIX_MAXVOLUME);
   1.136 +            const float fvolume = (float) volume;
   1.137 +            const float *src32 = (float *) src;
   1.138 +            float *dst32 = (float *) dst;
   1.139 +            float src1, src2;
   1.140 +            double dst_sample;
   1.141 +            /* !!! FIXME: are these right? */
   1.142 +            const double max_audioval = 3.40282347e+38F;
   1.143 +            const double min_audioval = -3.40282347e+38F;
   1.144 +
   1.145 +            /* !!! FIXME: this is a little nasty. */
   1.146 +            union { float f; Uint32 ui32; } cvt;
   1.147 +
   1.148 +            len /= 4;
   1.149 +            while (len--) {
   1.150 +                cvt.f = *(src32++);
   1.151 +                cvt.ui32 = SDL_SwapBE32(cvt.ui32);
   1.152 +                src1 = ((cvt.f * fvolume) * fmaxvolume);
   1.153 +
   1.154 +                cvt.f = *dst32;
   1.155 +                cvt.ui32 = SDL_SwapBE32(cvt.ui32);
   1.156 +                src2 = cvt.f;
   1.157 +
   1.158 +                dst_sample = src1 + src2;
   1.159 +                if (dst_sample > max_audioval) {
   1.160 +                    dst_sample = max_audioval;
   1.161 +                } else if (dst_sample < min_audioval) {
   1.162 +                    dst_sample = min_audioval;
   1.163 +                }
   1.164 +                cvt.f = ((float) dst_sample);
   1.165 +                cvt.ui32 = SDL_SwapBE32(cvt.ui32);
   1.166 +                *(dst32++) = cvt.f;
   1.167 +            }
   1.168 +        }
   1.169 +        break;
   1.170 +
   1.171      default:                   /* If this happens... FIXME! */
   1.172          SDL_SetError("SDL_MixAudio(): unknown audio format");
   1.173          return;