src/audio/SDL_audiocvt.c
changeset 10793 7e657de3758d
parent 10791 64c46e09df9d
child 10799 234f71894a52
     1.1 --- a/src/audio/SDL_audiocvt.c	Sun Jan 08 14:28:44 2017 -0500
     1.2 +++ b/src/audio/SDL_audiocvt.c	Sun Jan 08 16:18:49 2017 -0500
     1.3 @@ -31,7 +31,7 @@
     1.4  
     1.5  /* Effectively mix right and left channels into a single channel */
     1.6  static void SDLCALL
     1.7 -SDL_ConvertMono(SDL_AudioCVT * cvt, SDL_AudioFormat format)
     1.8 +SDL_ConvertStereoToMono(SDL_AudioCVT * cvt, SDL_AudioFormat format)
     1.9  {
    1.10      float *dst = (float *) cvt->buf;
    1.11      const float *src = dst;
    1.12 @@ -51,20 +51,22 @@
    1.13  }
    1.14  
    1.15  
    1.16 -/* Discard top 4 channels */
    1.17 +/* Convert from 5.1 to stereo. Average left and right, discard subwoofer. */
    1.18  static void SDLCALL
    1.19 -SDL_ConvertStrip(SDL_AudioCVT * cvt, SDL_AudioFormat format)
    1.20 +SDL_Convert51ToStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format)
    1.21  {
    1.22      float *dst = (float *) cvt->buf;
    1.23      const float *src = dst;
    1.24      int i;
    1.25  
    1.26 -    LOG_DEBUG_CONVERT("6 channels", "stereo");
    1.27 +    LOG_DEBUG_CONVERT("5.1", "stereo");
    1.28      SDL_assert(format == AUDIO_F32SYS);
    1.29  
    1.30 +    /* this assumes FL+FR+FC+subwoof+BL+BR layout. */
    1.31      for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src += 6, dst += 2) {
    1.32 -        dst[0] = src[0];
    1.33 -        dst[1] = src[1];
    1.34 +        const double front_center = (double) src[2];
    1.35 +        dst[0] = (float) ((src[0] + front_center + src[4]) / 3.0);  /* left */
    1.36 +        dst[1] = (float) ((src[1] + front_center + src[5]) / 3.0);  /* right */
    1.37      }
    1.38  
    1.39      cvt->len_cvt /= 3;
    1.40 @@ -74,22 +76,25 @@
    1.41  }
    1.42  
    1.43  
    1.44 -/* Discard top 2 channels of 6 */
    1.45 +/* Convert from 5.1 to quad */
    1.46  static void SDLCALL
    1.47 -SDL_ConvertStrip_2(SDL_AudioCVT * cvt, SDL_AudioFormat format)
    1.48 +SDL_Convert51ToQuad(SDL_AudioCVT * cvt, SDL_AudioFormat format)
    1.49  {
    1.50      float *dst = (float *) cvt->buf;
    1.51      const float *src = dst;
    1.52      int i;
    1.53  
    1.54 -    LOG_DEBUG_CONVERT("6 channels", "quad");
    1.55 +    LOG_DEBUG_CONVERT("5.1", "quad");
    1.56      SDL_assert(format == AUDIO_F32SYS);
    1.57  
    1.58 +    /* assumes quad is FL+FR+BL+BR layout and 5.1 is FL+FR+FC+subwoof+BL+BR */
    1.59      for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src += 6, dst += 4) {
    1.60 -        dst[0] = src[0];
    1.61 -        dst[1] = src[1];
    1.62 -        dst[2] = src[2];
    1.63 -        dst[3] = src[3];
    1.64 +        /* FIXME: this is a good candidate for SIMD. */
    1.65 +        const double front_center = (double) src[2];
    1.66 +        dst[0] = (float) ((src[0] + front_center) * 0.5);  /* FL */
    1.67 +        dst[1] = (float) ((src[1] + front_center) * 0.5);  /* FR */
    1.68 +        dst[2] = (float) ((src[4] + front_center) * 0.5);  /* BL */
    1.69 +        dst[3] = (float) ((src[5] + front_center) * 0.5);  /* BR */
    1.70      }
    1.71  
    1.72      cvt->len_cvt /= 6;
    1.73 @@ -99,9 +104,10 @@
    1.74      }
    1.75  }
    1.76  
    1.77 +
    1.78  /* Duplicate a mono channel to both stereo channels */
    1.79  static void SDLCALL
    1.80 -SDL_ConvertStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format)
    1.81 +SDL_ConvertMonoToStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format)
    1.82  {
    1.83      const float *src = (const float *) (cvt->buf + cvt->len_cvt);
    1.84      float *dst = (float *) (cvt->buf + cvt->len_cvt * 2);
    1.85 @@ -125,7 +131,7 @@
    1.86  
    1.87  /* Duplicate a stereo channel to a pseudo-5.1 stream */
    1.88  static void SDLCALL
    1.89 -SDL_ConvertSurround(SDL_AudioCVT * cvt, SDL_AudioFormat format)
    1.90 +SDL_ConvertStereoTo51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
    1.91  {
    1.92      int i;
    1.93      float lf, rf, ce;
    1.94 @@ -140,12 +146,13 @@
    1.95          src -= 2;
    1.96          lf = src[0];
    1.97          rf = src[1];
    1.98 -        ce = (lf * 0.5f) + (rf * 0.5f);
    1.99 -        dst[0] = src[0];
   1.100 -        dst[1] = src[1];
   1.101 -        dst[2] = lf - ce;
   1.102 -        dst[3] = rf - ce;
   1.103 -        dst[4] = dst[5] = ce;
   1.104 +        ce = (lf + rf) * 0.5f;
   1.105 +        dst[0] = lf + (lf - ce);  /* FL */
   1.106 +        dst[1] = rf + (rf - ce);  /* FR */
   1.107 +        dst[2] = ce;  /* FC */
   1.108 +        dst[3] = ce;  /* !!! FIXME: wrong! This is the subwoofer. */
   1.109 +        dst[4] = lf;  /* BL */
   1.110 +        dst[5] = rf;  /* BR */
   1.111      }
   1.112  
   1.113      cvt->len_cvt *= 3;
   1.114 @@ -157,11 +164,11 @@
   1.115  
   1.116  /* Duplicate a stereo channel to a pseudo-4.0 stream */
   1.117  static void SDLCALL
   1.118 -SDL_ConvertSurround_4(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   1.119 +SDL_ConvertStereoToQuad(SDL_AudioCVT * cvt, SDL_AudioFormat format)
   1.120  {
   1.121      const float *src = (const float *) (cvt->buf + cvt->len_cvt);
   1.122      float *dst = (float *) (cvt->buf + cvt->len_cvt * 2);
   1.123 -    float lf, rf, ce;
   1.124 +    float lf, rf;
   1.125      int i;
   1.126  
   1.127      LOG_DEBUG_CONVERT("stereo", "quad");
   1.128 @@ -172,11 +179,10 @@
   1.129          src -= 2;
   1.130          lf = src[0];
   1.131          rf = src[1];
   1.132 -        ce = (lf / 2) + (rf / 2);
   1.133 -        dst[0] = src[0];
   1.134 -        dst[1] = src[1];
   1.135 -        dst[2] = lf - ce;
   1.136 -        dst[3] = rf - ce;
   1.137 +        dst[0] = lf;  /* FL */
   1.138 +        dst[1] = rf;  /* FR */
   1.139 +        dst[2] = lf;  /* BL */
   1.140 +        dst[3] = rf;  /* BR */
   1.141      }
   1.142  
   1.143      cvt->len_cvt *= 2;
   1.144 @@ -536,36 +542,36 @@
   1.145      /* Channel conversion */
   1.146      if (src_channels != dst_channels) {
   1.147          if ((src_channels == 1) && (dst_channels > 1)) {
   1.148 -            cvt->filters[cvt->filter_index++] = SDL_ConvertStereo;
   1.149 +            cvt->filters[cvt->filter_index++] = SDL_ConvertMonoToStereo;
   1.150              cvt->len_mult *= 2;
   1.151              src_channels = 2;
   1.152              cvt->len_ratio *= 2;
   1.153          }
   1.154          if ((src_channels == 2) && (dst_channels == 6)) {
   1.155 -            cvt->filters[cvt->filter_index++] = SDL_ConvertSurround;
   1.156 +            cvt->filters[cvt->filter_index++] = SDL_ConvertStereoTo51;
   1.157              src_channels = 6;
   1.158              cvt->len_mult *= 3;
   1.159              cvt->len_ratio *= 3;
   1.160          }
   1.161          if ((src_channels == 2) && (dst_channels == 4)) {
   1.162 -            cvt->filters[cvt->filter_index++] = SDL_ConvertSurround_4;
   1.163 +            cvt->filters[cvt->filter_index++] = SDL_ConvertStereoToQuad;
   1.164              src_channels = 4;
   1.165              cvt->len_mult *= 2;
   1.166              cvt->len_ratio *= 2;
   1.167          }
   1.168          while ((src_channels * 2) <= dst_channels) {
   1.169 -            cvt->filters[cvt->filter_index++] = SDL_ConvertStereo;
   1.170 +            cvt->filters[cvt->filter_index++] = SDL_ConvertMonoToStereo;
   1.171              cvt->len_mult *= 2;
   1.172              src_channels *= 2;
   1.173              cvt->len_ratio *= 2;
   1.174          }
   1.175          if ((src_channels == 6) && (dst_channels <= 2)) {
   1.176 -            cvt->filters[cvt->filter_index++] = SDL_ConvertStrip;
   1.177 +            cvt->filters[cvt->filter_index++] = SDL_Convert51ToStereo;
   1.178              src_channels = 2;
   1.179              cvt->len_ratio /= 3;
   1.180          }
   1.181          if ((src_channels == 6) && (dst_channels == 4)) {
   1.182 -            cvt->filters[cvt->filter_index++] = SDL_ConvertStrip_2;
   1.183 +            cvt->filters[cvt->filter_index++] = SDL_Convert51ToQuad;
   1.184              src_channels = 4;
   1.185              cvt->len_ratio /= 2;
   1.186          }
   1.187 @@ -575,7 +581,7 @@
   1.188           */
   1.189          while (((src_channels % 2) == 0) &&
   1.190                 ((src_channels / 2) >= dst_channels)) {
   1.191 -            cvt->filters[cvt->filter_index++] = SDL_ConvertMono;
   1.192 +            cvt->filters[cvt->filter_index++] = SDL_ConvertStereoToMono;
   1.193              src_channels /= 2;
   1.194              cvt->len_ratio /= 2;
   1.195          }