| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "webrtc/common_audio/audio_converter.h" | 11 #include "webrtc/common_audio/audio_converter.h" |
| 12 | 12 |
| 13 #include <cstring> | 13 #include <cstring> |
| 14 #include <memory> |
| 14 #include <utility> | 15 #include <utility> |
| 16 #include <vector> |
| 15 | 17 |
| 16 #include "webrtc/base/checks.h" | 18 #include "webrtc/base/checks.h" |
| 17 #include "webrtc/base/safe_conversions.h" | 19 #include "webrtc/base/safe_conversions.h" |
| 18 #include "webrtc/common_audio/channel_buffer.h" | 20 #include "webrtc/common_audio/channel_buffer.h" |
| 19 #include "webrtc/common_audio/resampler/push_sinc_resampler.h" | 21 #include "webrtc/common_audio/resampler/push_sinc_resampler.h" |
| 20 #include "webrtc/system_wrappers/include/scoped_vector.h" | |
| 21 | 22 |
| 22 using rtc::checked_cast; | 23 using rtc::checked_cast; |
| 23 | 24 |
| 24 namespace webrtc { | 25 namespace webrtc { |
| 25 | 26 |
| 26 class CopyConverter : public AudioConverter { | 27 class CopyConverter : public AudioConverter { |
| 27 public: | 28 public: |
| 28 CopyConverter(size_t src_channels, size_t src_frames, size_t dst_channels, | 29 CopyConverter(size_t src_channels, size_t src_frames, size_t dst_channels, |
| 29 size_t dst_frames) | 30 size_t dst_frames) |
| 30 : AudioConverter(src_channels, src_frames, dst_channels, dst_frames) {} | 31 : AudioConverter(src_channels, src_frames, dst_channels, dst_frames) {} |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 } | 80 } |
| 80 }; | 81 }; |
| 81 | 82 |
| 82 class ResampleConverter : public AudioConverter { | 83 class ResampleConverter : public AudioConverter { |
| 83 public: | 84 public: |
| 84 ResampleConverter(size_t src_channels, size_t src_frames, size_t dst_channels, | 85 ResampleConverter(size_t src_channels, size_t src_frames, size_t dst_channels, |
| 85 size_t dst_frames) | 86 size_t dst_frames) |
| 86 : AudioConverter(src_channels, src_frames, dst_channels, dst_frames) { | 87 : AudioConverter(src_channels, src_frames, dst_channels, dst_frames) { |
| 87 resamplers_.reserve(src_channels); | 88 resamplers_.reserve(src_channels); |
| 88 for (size_t i = 0; i < src_channels; ++i) | 89 for (size_t i = 0; i < src_channels; ++i) |
| 89 resamplers_.push_back(new PushSincResampler(src_frames, dst_frames)); | 90 resamplers_.push_back(std::unique_ptr<PushSincResampler>( |
| 91 new PushSincResampler(src_frames, dst_frames))); |
| 90 } | 92 } |
| 91 ~ResampleConverter() override {}; | 93 ~ResampleConverter() override {}; |
| 92 | 94 |
| 93 void Convert(const float* const* src, size_t src_size, float* const* dst, | 95 void Convert(const float* const* src, size_t src_size, float* const* dst, |
| 94 size_t dst_capacity) override { | 96 size_t dst_capacity) override { |
| 95 CheckSizes(src_size, dst_capacity); | 97 CheckSizes(src_size, dst_capacity); |
| 96 for (size_t i = 0; i < resamplers_.size(); ++i) | 98 for (size_t i = 0; i < resamplers_.size(); ++i) |
| 97 resamplers_[i]->Resample(src[i], src_frames(), dst[i], dst_frames()); | 99 resamplers_[i]->Resample(src[i], src_frames(), dst[i], dst_frames()); |
| 98 } | 100 } |
| 99 | 101 |
| 100 private: | 102 private: |
| 101 ScopedVector<PushSincResampler> resamplers_; | 103 std::vector<std::unique_ptr<PushSincResampler>> resamplers_; |
| 102 }; | 104 }; |
| 103 | 105 |
| 104 // Apply a vector of converters in serial, in the order given. At least two | 106 // Apply a vector of converters in serial, in the order given. At least two |
| 105 // converters must be provided. | 107 // converters must be provided. |
| 106 class CompositionConverter : public AudioConverter { | 108 class CompositionConverter : public AudioConverter { |
| 107 public: | 109 public: |
| 108 CompositionConverter(ScopedVector<AudioConverter> converters) | 110 CompositionConverter(std::vector<std::unique_ptr<AudioConverter>> converters) |
| 109 : converters_(std::move(converters)) { | 111 : converters_(std::move(converters)) { |
| 110 RTC_CHECK_GE(converters_.size(), 2u); | 112 RTC_CHECK_GE(converters_.size(), 2u); |
| 111 // We need an intermediate buffer after every converter. | 113 // We need an intermediate buffer after every converter. |
| 112 for (auto it = converters_.begin(); it != converters_.end() - 1; ++it) | 114 for (auto it = converters_.begin(); it != converters_.end() - 1; ++it) |
| 113 buffers_.push_back(new ChannelBuffer<float>((*it)->dst_frames(), | 115 buffers_.push_back( |
| 114 (*it)->dst_channels())); | 116 std::unique_ptr<ChannelBuffer<float>>(new ChannelBuffer<float>( |
| 117 (*it)->dst_frames(), (*it)->dst_channels()))); |
| 115 } | 118 } |
| 116 ~CompositionConverter() override {}; | 119 ~CompositionConverter() override {}; |
| 117 | 120 |
| 118 void Convert(const float* const* src, size_t src_size, float* const* dst, | 121 void Convert(const float* const* src, size_t src_size, float* const* dst, |
| 119 size_t dst_capacity) override { | 122 size_t dst_capacity) override { |
| 120 converters_.front()->Convert(src, src_size, buffers_.front()->channels(), | 123 converters_.front()->Convert(src, src_size, buffers_.front()->channels(), |
| 121 buffers_.front()->size()); | 124 buffers_.front()->size()); |
| 122 for (size_t i = 2; i < converters_.size(); ++i) { | 125 for (size_t i = 2; i < converters_.size(); ++i) { |
| 123 auto src_buffer = buffers_[i - 2]; | 126 auto& src_buffer = buffers_[i - 2]; |
| 124 auto dst_buffer = buffers_[i - 1]; | 127 auto& dst_buffer = buffers_[i - 1]; |
| 125 converters_[i]->Convert(src_buffer->channels(), | 128 converters_[i]->Convert(src_buffer->channels(), |
| 126 src_buffer->size(), | 129 src_buffer->size(), |
| 127 dst_buffer->channels(), | 130 dst_buffer->channels(), |
| 128 dst_buffer->size()); | 131 dst_buffer->size()); |
| 129 } | 132 } |
| 130 converters_.back()->Convert(buffers_.back()->channels(), | 133 converters_.back()->Convert(buffers_.back()->channels(), |
| 131 buffers_.back()->size(), dst, dst_capacity); | 134 buffers_.back()->size(), dst, dst_capacity); |
| 132 } | 135 } |
| 133 | 136 |
| 134 private: | 137 private: |
| 135 ScopedVector<AudioConverter> converters_; | 138 std::vector<std::unique_ptr<AudioConverter>> converters_; |
| 136 ScopedVector<ChannelBuffer<float>> buffers_; | 139 std::vector<std::unique_ptr<ChannelBuffer<float>>> buffers_; |
| 137 }; | 140 }; |
| 138 | 141 |
| 139 std::unique_ptr<AudioConverter> AudioConverter::Create(size_t src_channels, | 142 std::unique_ptr<AudioConverter> AudioConverter::Create(size_t src_channels, |
| 140 size_t src_frames, | 143 size_t src_frames, |
| 141 size_t dst_channels, | 144 size_t dst_channels, |
| 142 size_t dst_frames) { | 145 size_t dst_frames) { |
| 143 std::unique_ptr<AudioConverter> sp; | 146 std::unique_ptr<AudioConverter> sp; |
| 144 if (src_channels > dst_channels) { | 147 if (src_channels > dst_channels) { |
| 145 if (src_frames != dst_frames) { | 148 if (src_frames != dst_frames) { |
| 146 ScopedVector<AudioConverter> converters; | 149 std::vector<std::unique_ptr<AudioConverter>> converters; |
| 147 converters.push_back(new DownmixConverter(src_channels, src_frames, | 150 converters.push_back(std::unique_ptr<AudioConverter>(new DownmixConverter( |
| 148 dst_channels, src_frames)); | 151 src_channels, src_frames, dst_channels, src_frames))); |
| 149 converters.push_back(new ResampleConverter(dst_channels, src_frames, | 152 converters.push_back( |
| 150 dst_channels, dst_frames)); | 153 std::unique_ptr<AudioConverter>(new ResampleConverter( |
| 154 dst_channels, src_frames, dst_channels, dst_frames))); |
| 151 sp.reset(new CompositionConverter(std::move(converters))); | 155 sp.reset(new CompositionConverter(std::move(converters))); |
| 152 } else { | 156 } else { |
| 153 sp.reset(new DownmixConverter(src_channels, src_frames, dst_channels, | 157 sp.reset(new DownmixConverter(src_channels, src_frames, dst_channels, |
| 154 dst_frames)); | 158 dst_frames)); |
| 155 } | 159 } |
| 156 } else if (src_channels < dst_channels) { | 160 } else if (src_channels < dst_channels) { |
| 157 if (src_frames != dst_frames) { | 161 if (src_frames != dst_frames) { |
| 158 ScopedVector<AudioConverter> converters; | 162 std::vector<std::unique_ptr<AudioConverter>> converters; |
| 159 converters.push_back(new ResampleConverter(src_channels, src_frames, | 163 converters.push_back( |
| 160 src_channels, dst_frames)); | 164 std::unique_ptr<AudioConverter>(new ResampleConverter( |
| 161 converters.push_back(new UpmixConverter(src_channels, dst_frames, | 165 src_channels, src_frames, src_channels, dst_frames))); |
| 162 dst_channels, dst_frames)); | 166 converters.push_back(std::unique_ptr<AudioConverter>(new UpmixConverter( |
| 167 src_channels, dst_frames, dst_channels, dst_frames))); |
| 163 sp.reset(new CompositionConverter(std::move(converters))); | 168 sp.reset(new CompositionConverter(std::move(converters))); |
| 164 } else { | 169 } else { |
| 165 sp.reset(new UpmixConverter(src_channels, src_frames, dst_channels, | 170 sp.reset(new UpmixConverter(src_channels, src_frames, dst_channels, |
| 166 dst_frames)); | 171 dst_frames)); |
| 167 } | 172 } |
| 168 } else if (src_frames != dst_frames) { | 173 } else if (src_frames != dst_frames) { |
| 169 sp.reset(new ResampleConverter(src_channels, src_frames, dst_channels, | 174 sp.reset(new ResampleConverter(src_channels, src_frames, dst_channels, |
| 170 dst_frames)); | 175 dst_frames)); |
| 171 } else { | 176 } else { |
| 172 sp.reset(new CopyConverter(src_channels, src_frames, dst_channels, | 177 sp.reset(new CopyConverter(src_channels, src_frames, dst_channels, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 192 RTC_CHECK(dst_channels == src_channels || dst_channels == 1 || | 197 RTC_CHECK(dst_channels == src_channels || dst_channels == 1 || |
| 193 src_channels == 1); | 198 src_channels == 1); |
| 194 } | 199 } |
| 195 | 200 |
| 196 void AudioConverter::CheckSizes(size_t src_size, size_t dst_capacity) const { | 201 void AudioConverter::CheckSizes(size_t src_size, size_t dst_capacity) const { |
| 197 RTC_CHECK_EQ(src_size, src_channels() * src_frames()); | 202 RTC_CHECK_EQ(src_size, src_channels() * src_frames()); |
| 198 RTC_CHECK_GE(dst_capacity, dst_channels() * dst_frames()); | 203 RTC_CHECK_GE(dst_capacity, dst_channels() * dst_frames()); |
| 199 } | 204 } |
| 200 | 205 |
| 201 } // namespace webrtc | 206 } // namespace webrtc |
| OLD | NEW |