src/audio/SDL_audiocvt.c
changeset 10844 936e8095db14
parent 10843 31c9dede7b9c
child 10846 32efb3bc4db5
     1.1 --- a/src/audio/SDL_audiocvt.c	Tue Jan 24 00:17:40 2017 -0500
     1.2 +++ b/src/audio/SDL_audiocvt.c	Tue Jan 24 00:51:33 2017 -0500
     1.3 @@ -867,7 +867,8 @@
     1.4      SDL_AudioCVT cvt_before_resampling;
     1.5      SDL_AudioCVT cvt_after_resampling;
     1.6      SDL_DataQueue *queue;
     1.7 -    Uint8 *work_buffer;
     1.8 +    Uint8 *work_buffer;  /* always aligned to 16 bytes. */
     1.9 +    Uint8 *work_buffer_base;  /* maybe unaligned pointer from SDL_realloc(). */
    1.10      int work_buffer_len;
    1.11      int src_sample_frame_size;
    1.12      SDL_AudioFormat src_format;
    1.13 @@ -1125,18 +1126,21 @@
    1.14  }
    1.15  
    1.16  static Uint8 *
    1.17 -EnsureBufferSize(Uint8 **buf, int *len, const int newlen)
    1.18 +EnsureStreamBufferSize(SDL_AudioStream *stream, const int newlen)
    1.19  {
    1.20 -    if (*len < newlen) {
    1.21 -        void *ptr = SDL_realloc(*buf, newlen);
    1.22 +    if (stream->work_buffer_len < newlen) {
    1.23 +        Uint8 *ptr = (Uint8 *) SDL_realloc(stream->work_buffer_base, newlen + 32);
    1.24 +        const size_t offset = ((size_t) ptr) & 15;
    1.25          if (!ptr) {
    1.26              SDL_OutOfMemory();
    1.27              return NULL;
    1.28          }
    1.29 -        *buf = (Uint8 *) ptr;
    1.30 -        *len = newlen;
    1.31 +        /* Make sure we're aligned to 16 bytes for SIMD code. */
    1.32 +        stream->work_buffer = offset ? ptr + (16 - offset) : ptr;
    1.33 +        stream->work_buffer_base = ptr;
    1.34 +        stream->work_buffer_len = newlen;
    1.35      }
    1.36 -    return *buf;
    1.37 +    return stream->work_buffer;
    1.38  }
    1.39  
    1.40  int
    1.41 @@ -1145,6 +1149,14 @@
    1.42      int buflen = (int) _buflen;
    1.43      SDL_bool copied = SDL_FALSE;
    1.44  
    1.45 +    /* !!! FIXME: several converters can take advantage of SIMD, but only
    1.46 +       !!! FIXME:  if the data is aligned to 16 bytes. EnsureStreamBufferSize()
    1.47 +       !!! FIXME:  guarantees the buffer will align, but the
    1.48 +       !!! FIXME:  converters will iterate over the data backwards if
    1.49 +       !!! FIXME:  the output grows, and this means we won't align if buflen
    1.50 +       !!! FIXME:  isn't a multiple of 16. In these cases, we should chop off
    1.51 +       !!! FIXME:  a few samples at the end and convert them separately. */
    1.52 +
    1.53      if (!stream) {
    1.54          return SDL_InvalidParamError("stream");
    1.55      } else if (!buf) {
    1.56 @@ -1157,7 +1169,7 @@
    1.57  
    1.58      if (stream->cvt_before_resampling.needed) {
    1.59          const int workbuflen = buflen * stream->cvt_before_resampling.len_mult;  /* will be "* 1" if not needed */
    1.60 -        Uint8 *workbuf = EnsureBufferSize(&stream->work_buffer, &stream->work_buffer_len, workbuflen);
    1.61 +        Uint8 *workbuf = EnsureStreamBufferSize(stream, workbuflen);
    1.62          if (workbuf == NULL) {
    1.63              return -1;  /* probably out of memory. */
    1.64          }
    1.65 @@ -1174,7 +1186,7 @@
    1.66  
    1.67      if (stream->dst_rate != stream->src_rate) {
    1.68          const int workbuflen = buflen * ((int) SDL_ceil(stream->rate_incr));
    1.69 -        void *workbuf = EnsureBufferSize(&stream->work_buffer, &stream->work_buffer_len, workbuflen);
    1.70 +        Uint8 *workbuf = EnsureStreamBufferSize(stream, workbuflen);
    1.71          if (workbuf == NULL) {
    1.72              return -1;  /* probably out of memory. */
    1.73          }
    1.74 @@ -1188,7 +1200,7 @@
    1.75  
    1.76      if (stream->cvt_after_resampling.needed) {
    1.77          const int workbuflen = buflen * stream->cvt_after_resampling.len_mult;  /* will be "* 1" if not needed */
    1.78 -        Uint8 *workbuf = EnsureBufferSize(&stream->work_buffer, &stream->work_buffer_len, workbuflen);
    1.79 +        Uint8 *workbuf = EnsureStreamBufferSize(stream, workbuflen);
    1.80          if (workbuf == NULL) {
    1.81              return -1;  /* probably out of memory. */
    1.82          }
    1.83 @@ -1256,7 +1268,7 @@
    1.84              stream->cleanup_resampler_func(stream);
    1.85          }
    1.86          SDL_FreeDataQueue(stream->queue);
    1.87 -        SDL_free(stream->work_buffer);
    1.88 +        SDL_free(stream->work_buffer_base);
    1.89          SDL_free(stream);
    1.90      }
    1.91  }