- /* Number of bytes left to read this time */
- int remaining = data_size;
- /* Our position in the output buffers, in bytes */
- int position = 0;
- while (remaining > 0) {
- /* How many bytes of the deinterleaved data to do this time */
- int this_time = min (remaining / _fs->audio_channels, _deinterleave_buffer_size);
- for (int i = 0; i < _fs->audio_channels; ++i) {
- for (int j = 0; j < this_time; j += sample_size) {
- for (int k = 0; k < sample_size; ++k) {
- int const to = j + k;
- int const from = position + (i * sample_size) + (j * _fs->audio_channels) + k;
- _deinterleave_buffer[to] = data[from];
- }
- }
-
- switch (_fs->audio_sample_format) {
- case AV_SAMPLE_FMT_S16:
- sf_write_short (_sound_files[i], (const short *) _deinterleave_buffer, this_time / sample_size);
- break;
- default:
- throw DecodeError ("unknown audio sample format");
- }
+#if HAVE_SWRESAMPLE
+ /* Maybe sample-rate convert */
+ if (_swr_context) {
+
+ /* Compute the resampled frames count and add 32 for luck */
+ int const max_resampled_frames = ceil (audio->frames() * _fs->target_audio_sample_rate() / _fs->audio_sample_rate()) + 32;
+
+ resampled.reset (new AudioBuffers (_fs->audio_channels(), max_resampled_frames));
+
+ /* Resample audio */
+ int const resampled_frames = swr_convert (
+ _swr_context, (uint8_t **) resampled->data(), max_resampled_frames, (uint8_t const **) audio->data(), audio->frames()
+ );
+
+ if (resampled_frames < 0) {
+ throw EncodeError ("could not run sample-rate converter");