src/audio/SDL_audiocvt.c
changeset 10843 31c9dede7b9c
parent 10842 30b37eaf3b3c
child 10844 936e8095db14
equal deleted inserted replaced
10842:30b37eaf3b3c 10843:31c9dede7b9c
   867     SDL_AudioCVT cvt_before_resampling;
   867     SDL_AudioCVT cvt_before_resampling;
   868     SDL_AudioCVT cvt_after_resampling;
   868     SDL_AudioCVT cvt_after_resampling;
   869     SDL_DataQueue *queue;
   869     SDL_DataQueue *queue;
   870     Uint8 *work_buffer;
   870     Uint8 *work_buffer;
   871     int work_buffer_len;
   871     int work_buffer_len;
   872     Uint8 *resample_buffer;
       
   873     int resample_buffer_len;
       
   874     int src_sample_frame_size;
   872     int src_sample_frame_size;
   875     SDL_AudioFormat src_format;
   873     SDL_AudioFormat src_format;
   876     Uint8 src_channels;
   874     Uint8 src_channels;
   877     int src_rate;
   875     int src_rate;
   878     int dst_sample_frame_size;
   876     int dst_sample_frame_size;
  1143 
  1141 
  1144 int
  1142 int
  1145 SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, const Uint32 _buflen)
  1143 SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, const Uint32 _buflen)
  1146 {
  1144 {
  1147     int buflen = (int) _buflen;
  1145     int buflen = (int) _buflen;
       
  1146     SDL_bool copied = SDL_FALSE;
  1148 
  1147 
  1149     if (!stream) {
  1148     if (!stream) {
  1150         return SDL_InvalidParamError("stream");
  1149         return SDL_InvalidParamError("stream");
  1151     } else if (!buf) {
  1150     } else if (!buf) {
  1152         return SDL_InvalidParamError("buf");
  1151         return SDL_InvalidParamError("buf");
  1160         const int workbuflen = buflen * stream->cvt_before_resampling.len_mult;  /* will be "* 1" if not needed */
  1159         const int workbuflen = buflen * stream->cvt_before_resampling.len_mult;  /* will be "* 1" if not needed */
  1161         Uint8 *workbuf = EnsureBufferSize(&stream->work_buffer, &stream->work_buffer_len, workbuflen);
  1160         Uint8 *workbuf = EnsureBufferSize(&stream->work_buffer, &stream->work_buffer_len, workbuflen);
  1162         if (workbuf == NULL) {
  1161         if (workbuf == NULL) {
  1163             return -1;  /* probably out of memory. */
  1162             return -1;  /* probably out of memory. */
  1164         }
  1163         }
       
  1164         copied = SDL_TRUE;
  1165         SDL_memcpy(workbuf, buf, buflen);
  1165         SDL_memcpy(workbuf, buf, buflen);
  1166         stream->cvt_before_resampling.buf = workbuf;
  1166         stream->cvt_before_resampling.buf = workbuf;
  1167         stream->cvt_before_resampling.len = buflen;
  1167         stream->cvt_before_resampling.len = buflen;
  1168         if (SDL_ConvertAudio(&stream->cvt_before_resampling) == -1) {
  1168         if (SDL_ConvertAudio(&stream->cvt_before_resampling) == -1) {
  1169             return -1;   /* uhoh! */
  1169             return -1;   /* uhoh! */
  1172         buflen = stream->cvt_before_resampling.len_cvt;
  1172         buflen = stream->cvt_before_resampling.len_cvt;
  1173     }
  1173     }
  1174 
  1174 
  1175     if (stream->dst_rate != stream->src_rate) {
  1175     if (stream->dst_rate != stream->src_rate) {
  1176         const int workbuflen = buflen * ((int) SDL_ceil(stream->rate_incr));
  1176         const int workbuflen = buflen * ((int) SDL_ceil(stream->rate_incr));
  1177         void *workbuf = EnsureBufferSize(&stream->resample_buffer, &stream->resample_buffer_len, workbuflen);
  1177         void *workbuf = EnsureBufferSize(&stream->work_buffer, &stream->work_buffer_len, workbuflen);
  1178         if (workbuf == NULL) {
  1178         if (workbuf == NULL) {
  1179             return -1;  /* probably out of memory. */
  1179             return -1;  /* probably out of memory. */
  1180         }
  1180         }
  1181         buflen = stream->resampler_func(stream, buf, buflen, workbuf, workbuflen);
  1181         if (!copied) {
       
  1182             SDL_memcpy(workbuf, buf, buflen);
       
  1183             copied = SDL_TRUE;
       
  1184         }
       
  1185         buflen = stream->resampler_func(stream, workbuf, buflen, workbuf, workbuflen);
  1182         buf = workbuf;
  1186         buf = workbuf;
  1183     }
  1187     }
  1184 
  1188 
  1185     if (stream->cvt_after_resampling.needed) {
  1189     if (stream->cvt_after_resampling.needed) {
  1186         const int workbuflen = buflen * stream->cvt_after_resampling.len_mult;  /* will be "* 1" if not needed */
  1190         const int workbuflen = buflen * stream->cvt_after_resampling.len_mult;  /* will be "* 1" if not needed */
  1187         Uint8 *workbuf;
  1191         Uint8 *workbuf = EnsureBufferSize(&stream->work_buffer, &stream->work_buffer_len, workbuflen);
  1188 
       
  1189         if (buf == stream->resample_buffer) {
       
  1190             workbuf = EnsureBufferSize(&stream->resample_buffer, &stream->resample_buffer_len, workbuflen);
       
  1191         } else {
       
  1192             const int inplace = (buf == stream->work_buffer);
       
  1193             workbuf = EnsureBufferSize(&stream->work_buffer, &stream->work_buffer_len, workbuflen);
       
  1194             if (workbuf && !inplace) {
       
  1195                 SDL_memcpy(workbuf, buf, buflen);
       
  1196             }
       
  1197         }
       
  1198 
       
  1199         if (workbuf == NULL) {
  1192         if (workbuf == NULL) {
  1200             return -1;  /* probably out of memory. */
  1193             return -1;  /* probably out of memory. */
       
  1194         }
       
  1195         if (!copied) {
       
  1196             SDL_memcpy(workbuf, buf, buflen);
       
  1197             copied = SDL_TRUE;
  1201         }
  1198         }
  1202 
  1199 
  1203         stream->cvt_after_resampling.buf = workbuf;
  1200         stream->cvt_after_resampling.buf = workbuf;
  1204         stream->cvt_after_resampling.len = buflen;
  1201         stream->cvt_after_resampling.len = buflen;
  1205         if (SDL_ConvertAudio(&stream->cvt_after_resampling) == -1) {
  1202         if (SDL_ConvertAudio(&stream->cvt_after_resampling) == -1) {
  1258         if (stream->cleanup_resampler_func) {
  1255         if (stream->cleanup_resampler_func) {
  1259             stream->cleanup_resampler_func(stream);
  1256             stream->cleanup_resampler_func(stream);
  1260         }
  1257         }
  1261         SDL_FreeDataQueue(stream->queue);
  1258         SDL_FreeDataQueue(stream->queue);
  1262         SDL_free(stream->work_buffer);
  1259         SDL_free(stream->work_buffer);
  1263         SDL_free(stream->resample_buffer);
       
  1264         SDL_free(stream);
  1260         SDL_free(stream);
  1265     }
  1261     }
  1266 }
  1262 }
  1267 
  1263 
  1268 /* vi: set ts=4 sw=4 expandtab: */
  1264 /* vi: set ts=4 sw=4 expandtab: */