1 #include "../../StdAfx.h"
\r
3 #include "audio_resampler.h"
\r
5 #include <common/exception/exceptions.h>
\r
7 #if defined(_MSC_VER)
\r
8 #pragma warning (push)
\r
9 #pragma warning (disable : 4244)
\r
13 #include <libavcodec/avcodec.h>
\r
15 #if defined(_MSC_VER)
\r
16 #pragma warning (pop)
\r
19 namespace caspar { namespace ffmpeg {
\r
21 struct audio_resampler::implementation
\r
23 std::shared_ptr<ReSampleContext> resampler_;
\r
25 std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>> copy_buffer_;
\r
26 std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>> buffer2_;
\r
28 const size_t output_channels_;
\r
29 const AVSampleFormat output_sample_format_;
\r
31 const size_t input_channels_;
\r
32 const AVSampleFormat input_sample_format_;
\r
34 implementation(size_t output_channels, size_t input_channels, size_t output_sample_rate, size_t input_sample_rate, AVSampleFormat output_sample_format, AVSampleFormat input_sample_format)
\r
35 : output_channels_(output_channels)
\r
36 , output_sample_format_(output_sample_format)
\r
37 , input_channels_(input_channels)
\r
38 , input_sample_format_(input_sample_format)
\r
40 if(input_channels != output_channels ||
\r
41 input_sample_rate != output_sample_rate ||
\r
42 input_sample_format != output_sample_format)
\r
44 auto resampler = av_audio_resample_init(output_channels, input_channels,
\r
45 output_sample_rate, input_sample_rate,
\r
46 output_sample_format, input_sample_format,
\r
49 buffer2_.resize(AVCODEC_MAX_AUDIO_FRAME_SIZE*2);
\r
51 CASPAR_LOG(warning) << L"Resampling." <<
\r
52 L" sample_rate:" << input_channels <<
\r
53 L" audio_channels:" << input_channels <<
\r
54 L" sample_fmt:" << input_sample_format;
\r
57 resampler_.reset(resampler, audio_resample_close);
\r
59 BOOST_THROW_EXCEPTION(caspar_exception());
\r
63 std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>> resample(std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>>&& data)
\r
67 buffer2_.resize(AVCODEC_MAX_AUDIO_FRAME_SIZE*2);
\r
68 auto ret = audio_resample(resampler_.get(),
\r
69 reinterpret_cast<short*>(buffer2_.data()),
\r
70 reinterpret_cast<short*>(data.data()),
\r
71 data.size() / (av_get_bytes_per_sample(input_sample_format_) * input_channels_));
\r
72 buffer2_.resize(ret * av_get_bytes_per_sample(output_sample_format_) * output_channels_);
\r
73 std::swap(data, buffer2_);
\r
76 return std::move(data);
\r
81 audio_resampler::audio_resampler(size_t output_channels, size_t input_channels, size_t output_sample_rate, size_t input_sample_rate, AVSampleFormat output_sample_format, AVSampleFormat input_sample_format)
\r
82 : impl_(new implementation(output_channels, input_channels, output_sample_rate, input_sample_rate, output_sample_format, input_sample_format)){}
\r
83 std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>> audio_resampler::resample(std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>>&& data){return impl_->resample(std::move(data));}
\r