diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-06-26 01:21:21 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-06-26 17:04:31 +0100 |
| commit | 09a9ac376db005a40a351736bcff4077f098825d (patch) | |
| tree | 64ea69741155d15d114ad96daf0f90e24b3abe28 /src/lib/resampler.cc | |
| parent | 46cd0fe7b5b514f0d9456b25f670679cc584a218 (diff) | |
Another try at sorting out the thorny question of timing.
Diffstat (limited to 'src/lib/resampler.cc')
| -rw-r--r-- | src/lib/resampler.cc | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/lib/resampler.cc b/src/lib/resampler.cc new file mode 100644 index 000000000..1235b9038 --- /dev/null +++ b/src/lib/resampler.cc @@ -0,0 +1,61 @@ +extern "C" { +#include "libavutil/channel_layout.h" +} +#include "resampler.h" +#include "audio_buffers.h" +#include "exceptions.h" + +#include "i18n.h" + +using boost::shared_ptr; + +Resampler::Resampler (int in, int out, int channels) + : _in_rate (in) + , _out_rate (out) + , _channels (channels) +{ + /* We will be using planar float data when we call the + resampler. As far as I can see, the audio channel + layout is not necessary for our purposes; it seems + only to be used get the number of channels and + decide if rematrixing is needed. It won't be, since + input and output layouts are the same. + */ + + _swr_context = swr_alloc_set_opts ( + 0, + av_get_default_channel_layout (_channels), + AV_SAMPLE_FMT_FLTP, + _out_rate, + av_get_default_channel_layout (_channels), + AV_SAMPLE_FMT_FLTP, + _in_rate, + 0, 0 + ); + + swr_init (_swr_context); +} + +Resampler::~Resampler () +{ + swr_free (&_swr_context); +} + +shared_ptr<const AudioBuffers> +Resampler::run (shared_ptr<const AudioBuffers> in) +{ + /* Compute the resampled frames count and add 32 for luck */ + int const max_resampled_frames = ceil ((double) in->frames() * _out_rate / _in_rate) + 32; + shared_ptr<AudioBuffers> resampled (new AudioBuffers (_channels, max_resampled_frames)); + + int const resampled_frames = swr_convert ( + _swr_context, (uint8_t **) resampled->data(), max_resampled_frames, (uint8_t const **) in->data(), in->frames() + ); + + if (resampled_frames < 0) { + throw EncodeError (_("could not run sample-rate converter")); + } + + resampled->set_frames (resampled_frames); + return resampled; +} |
