]> git.sesse.net Git - casparcg/blob - modules/ffmpeg/producer/audio/audio_resampler.cpp
baa24774ba1914385e6a97b7a58cb2593ce2a7a9
[casparcg] / modules / ffmpeg / producer / audio / audio_resampler.cpp
1 #include "../../StdAfx.h"\r
2 \r
3 #include "audio_resampler.h"\r
4 \r
5 #include <common/exception/exceptions.h>\r
6 \r
7 #if defined(_MSC_VER)\r
8 #pragma warning (push)\r
9 #pragma warning (disable : 4244)\r
10 #endif\r
11 extern "C" \r
12 {\r
13         #include <libavcodec/avcodec.h>\r
14 }\r
15 #if defined(_MSC_VER)\r
16 #pragma warning (pop)\r
17 #endif\r
18 \r
19 \r
20 namespace caspar {\r
21 \r
22 struct audio_resampler::implementation\r
23 {       \r
24         std::shared_ptr<ReSampleContext> resampler_;\r
25         \r
26         std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>> copy_buffer_;\r
27         std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>> buffer2_;\r
28 \r
29         const size_t                    output_channels_;\r
30         const AVSampleFormat    output_sample_format_;\r
31 \r
32         const size_t                    input_channels_;\r
33         const AVSampleFormat    input_sample_format_;\r
34 \r
35         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
36                 : output_channels_(output_channels)\r
37                 , output_sample_format_(output_sample_format)\r
38                 , input_channels_(input_channels)\r
39                 , input_sample_format_(input_sample_format)\r
40         {\r
41                 if(input_channels               != output_channels || \r
42                    input_sample_rate    != output_sample_rate ||\r
43                    input_sample_format  != output_sample_format)\r
44                 {       \r
45                         auto resampler = av_audio_resample_init(output_channels,                input_channels,\r
46                                                                                                         output_sample_rate,             input_sample_rate,\r
47                                                                                                         output_sample_format,   input_sample_format,\r
48                                                                                                         16, 10, 0, 0.8);\r
49 \r
50                         buffer2_.resize(AVCODEC_MAX_AUDIO_FRAME_SIZE*2);\r
51 \r
52                         CASPAR_LOG(warning) << L"Resampling." <<\r
53                                                                         L" sample_rate:" << input_channels  <<\r
54                                                                         L" audio_channels:" << input_channels  <<\r
55                                                                         L" sample_fmt:" << input_sample_format;\r
56 \r
57                         if(resampler)\r
58                                 resampler_.reset(resampler, audio_resample_close);\r
59                         else\r
60                                 BOOST_THROW_EXCEPTION(caspar_exception());\r
61                 }               \r
62         }\r
63 \r
64         std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>> resample(std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>>&& data)\r
65         {\r
66                 if(resampler_)\r
67                 {\r
68                         buffer2_.resize(AVCODEC_MAX_AUDIO_FRAME_SIZE*2);\r
69                         auto ret = audio_resample(resampler_.get(),\r
70                                                                           reinterpret_cast<short*>(buffer2_.data()), \r
71                                                                           reinterpret_cast<short*>(data.data()), \r
72                                                                           data.size() / (av_get_bytes_per_sample(input_sample_format_) * input_channels_)); \r
73                         buffer2_.resize(ret * av_get_bytes_per_sample(output_sample_format_) * output_channels_);\r
74                         std::swap(data, buffer2_);\r
75                 }\r
76 \r
77                 return std::move(data);\r
78         }\r
79 };\r
80 \r
81 \r
82 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
83                                 : impl_(new implementation(output_channels, input_channels, output_sample_rate, input_sample_rate, output_sample_format, input_sample_format)){}\r
84 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
85 \r
86 }