2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
\r
4 * This file is part of CasparCG (www.casparcg.com).
\r
6 * CasparCG is free software: you can redistribute it and/or modify
\r
7 * it under the terms of the GNU General Public License as published by
\r
8 * the Free Software Foundation, either version 3 of the License, or
\r
9 * (at your option) any later version.
\r
11 * CasparCG is distributed in the hope that it will be useful,
\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 * GNU General Public License for more details.
\r
16 * You should have received a copy of the GNU General Public License
\r
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
\r
19 * Author: Robert Nagy, ronag89@gmail.com
\r
22 #include "../../StdAfx.h"
\r
24 #include "audio_resampler.h"
\r
26 #include <common/exception/exceptions.h>
\r
28 #if defined(_MSC_VER)
\r
29 #pragma warning (push)
\r
30 #pragma warning (disable : 4244)
\r
34 #include <libavcodec/avcodec.h>
\r
36 #if defined(_MSC_VER)
\r
37 #pragma warning (pop)
\r
40 namespace caspar { namespace ffmpeg {
\r
42 struct audio_resampler::implementation
\r
44 std::shared_ptr<ReSampleContext> resampler_;
\r
46 std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>> copy_buffer_;
\r
47 std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>> buffer2_;
\r
49 const size_t output_channels_;
\r
50 const AVSampleFormat output_sample_format_;
\r
52 const size_t input_channels_;
\r
53 const AVSampleFormat input_sample_format_;
\r
55 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
56 : output_channels_(output_channels)
\r
57 , output_sample_format_(output_sample_format)
\r
58 , input_channels_(input_channels)
\r
59 , input_sample_format_(input_sample_format)
\r
61 if(input_channels != output_channels ||
\r
62 input_sample_rate != output_sample_rate ||
\r
63 input_sample_format != output_sample_format)
\r
65 auto resampler = av_audio_resample_init(output_channels, input_channels,
\r
66 output_sample_rate, input_sample_rate,
\r
67 output_sample_format, input_sample_format,
\r
70 buffer2_.resize(AVCODEC_MAX_AUDIO_FRAME_SIZE*2);
\r
72 CASPAR_LOG(warning) << "Resampling." <<
\r
73 " sample_rate:" << input_sample_rate <<
\r
74 " audio_channels:" << input_channels <<
\r
75 " sample_fmt:" << input_sample_format;
\r
78 resampler_.reset(resampler, audio_resample_close);
\r
80 BOOST_THROW_EXCEPTION(caspar_exception());
\r
84 std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>> resample(std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>>&& data)
\r
86 if(resampler_ && !data.empty())
\r
88 buffer2_.resize(AVCODEC_MAX_AUDIO_FRAME_SIZE*2);
\r
89 auto ret = audio_resample(resampler_.get(),
\r
90 reinterpret_cast<short*>(buffer2_.data()),
\r
91 reinterpret_cast<short*>(data.data()),
\r
92 data.size() / (av_get_bytes_per_sample(input_sample_format_) * input_channels_));
\r
93 buffer2_.resize(ret * av_get_bytes_per_sample(output_sample_format_) * output_channels_);
\r
94 std::swap(data, buffer2_);
\r
97 return std::move(data);
\r
102 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
103 : impl_(new implementation(output_channels, input_channels, output_sample_rate, input_sample_rate, output_sample_format, input_sample_format)){}
\r
104 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