Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: webrtc/modules/audio_mixer/audio_mixer_impl.cc

Issue 2557713006: Injectable output rate calculater for AudioMixer. (Closed)
Patch Set: stl instead of loop, renamed SetOutputFrequency. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 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/modules/audio_mixer/audio_mixer_impl.h" 11 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 #include <functional> 14 #include <functional>
15 #include <iterator>
15 #include <utility> 16 #include <utility>
16 17
17 #include "webrtc/audio/utility/audio_frame_operations.h" 18 #include "webrtc/audio/utility/audio_frame_operations.h"
18 #include "webrtc/base/logging.h" 19 #include "webrtc/base/logging.h"
19 #include "webrtc/modules/audio_mixer/audio_frame_manipulator.h" 20 #include "webrtc/modules/audio_mixer/audio_frame_manipulator.h"
21 #include "webrtc/modules/audio_mixer/default_output_rate_calculator.h"
20 22
21 namespace webrtc { 23 namespace webrtc {
22 namespace { 24 namespace {
23 25
24 struct SourceFrame { 26 struct SourceFrame {
25 SourceFrame(AudioMixerImpl::SourceStatus* source_status, 27 SourceFrame(AudioMixerImpl::SourceStatus* source_status,
26 AudioFrame* audio_frame, 28 AudioFrame* audio_frame,
27 bool muted) 29 bool muted)
28 : source_status(source_status), audio_frame(audio_frame), muted(muted) { 30 : source_status(source_status), audio_frame(audio_frame), muted(muted) {
29 RTC_DCHECK(source_status); 31 RTC_DCHECK(source_status);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 AudioMixerImpl::SourceStatusList::iterator FindSourceInList( 132 AudioMixerImpl::SourceStatusList::iterator FindSourceInList(
131 AudioMixerImpl::Source const* audio_source, 133 AudioMixerImpl::Source const* audio_source,
132 AudioMixerImpl::SourceStatusList* audio_source_list) { 134 AudioMixerImpl::SourceStatusList* audio_source_list) {
133 return std::find_if( 135 return std::find_if(
134 audio_source_list->begin(), audio_source_list->end(), 136 audio_source_list->begin(), audio_source_list->end(),
135 [audio_source](const std::unique_ptr<AudioMixerImpl::SourceStatus>& p) { 137 [audio_source](const std::unique_ptr<AudioMixerImpl::SourceStatus>& p) {
136 return p->audio_source == audio_source; 138 return p->audio_source == audio_source;
137 }); 139 });
138 } 140 }
139 141
140 // Rounds the maximal audio source frequency up to an APM-native 142 std::unique_ptr<AudioProcessing> CreateLimiter() {
141 // frequency.
142 int CalculateMixingFrequency(
143 const AudioMixerImpl::SourceStatusList& audio_source_list) {
144 if (audio_source_list.empty()) {
145 return AudioMixerImpl::kDefaultFrequency;
146 }
147 using NativeRate = AudioProcessing::NativeRate;
148 int maximal_frequency = 0;
149 for (const auto& source_status : audio_source_list) {
150 const int source_needed_frequency =
151 source_status->audio_source->PreferredSampleRate();
152 RTC_DCHECK_LE(NativeRate::kSampleRate8kHz, source_needed_frequency);
153 RTC_DCHECK_LE(source_needed_frequency, NativeRate::kSampleRate48kHz);
154 maximal_frequency = std::max(maximal_frequency, source_needed_frequency);
155 }
156
157 static constexpr NativeRate native_rates[] = {
158 NativeRate::kSampleRate8kHz, NativeRate::kSampleRate16kHz,
159 NativeRate::kSampleRate32kHz, NativeRate::kSampleRate48kHz};
160 const auto rounded_up_index = std::lower_bound(
161 std::begin(native_rates), std::end(native_rates), maximal_frequency);
162 RTC_DCHECK(rounded_up_index != std::end(native_rates));
163 return *rounded_up_index;
164 }
165
166 } // namespace
167
168 AudioMixerImpl::AudioMixerImpl(std::unique_ptr<AudioProcessing> limiter)
169 : audio_source_list_(),
170 use_limiter_(true),
171 time_stamp_(0),
172 limiter_(std::move(limiter)) {
173 SetOutputFrequency(kDefaultFrequency);
174 }
175
176 AudioMixerImpl::~AudioMixerImpl() {}
177
178 rtc::scoped_refptr<AudioMixerImpl> AudioMixerImpl::Create() {
179 Config config; 143 Config config;
180 config.Set<ExperimentalAgc>(new ExperimentalAgc(false)); 144 config.Set<ExperimentalAgc>(new ExperimentalAgc(false));
181 std::unique_ptr<AudioProcessing> limiter(AudioProcessing::Create(config)); 145 std::unique_ptr<AudioProcessing> limiter(AudioProcessing::Create(config));
182 if (!limiter.get()) { 146 if (!limiter.get()) {
183 return nullptr; 147 return nullptr;
184 } 148 }
185 149
186 if (limiter->gain_control()->set_mode(GainControl::kFixedDigital) != 150 if (limiter->gain_control()->set_mode(GainControl::kFixedDigital) !=
187 limiter->kNoError) { 151 limiter->kNoError) {
188 return nullptr; 152 return nullptr;
(...skipping 11 matching lines...) Expand all
200 return nullptr; 164 return nullptr;
201 } 165 }
202 166
203 if (limiter->gain_control()->enable_limiter(true) != limiter->kNoError) { 167 if (limiter->gain_control()->enable_limiter(true) != limiter->kNoError) {
204 return nullptr; 168 return nullptr;
205 } 169 }
206 170
207 if (limiter->gain_control()->Enable(true) != limiter->kNoError) { 171 if (limiter->gain_control()->Enable(true) != limiter->kNoError) {
208 return nullptr; 172 return nullptr;
209 } 173 }
174 return limiter;
175 }
210 176
177 } // namespace
178
179 AudioMixerImpl::AudioMixerImpl(
180 std::unique_ptr<AudioProcessing> limiter,
181 std::unique_ptr<OutputRateCalculator> output_rate_calculator)
182 : output_rate_calculator_(std::move(output_rate_calculator)),
183 output_frequency_(0),
184 sample_size_(0),
185 audio_source_list_(),
186 use_limiter_(true),
187 time_stamp_(0),
188 limiter_(std::move(limiter)) {}
189
190 AudioMixerImpl::~AudioMixerImpl() {}
191
192 rtc::scoped_refptr<AudioMixerImpl> AudioMixerImpl::Create() {
193 return CreateWithOutputRateCalculator(
194 std::unique_ptr<DefaultOutputRateCalculator>(
195 new DefaultOutputRateCalculator()));
196 }
197
198 rtc::scoped_refptr<AudioMixerImpl>
199 AudioMixerImpl::CreateWithOutputRateCalculator(
200 std::unique_ptr<OutputRateCalculator> output_rate_calculator) {
211 return rtc::scoped_refptr<AudioMixerImpl>( 201 return rtc::scoped_refptr<AudioMixerImpl>(
212 new rtc::RefCountedObject<AudioMixerImpl>(std::move(limiter))); 202 new rtc::RefCountedObject<AudioMixerImpl>(
203 CreateLimiter(), std::move(output_rate_calculator)));
213 } 204 }
214 205
215 void AudioMixerImpl::Mix(size_t number_of_channels, 206 void AudioMixerImpl::Mix(size_t number_of_channels,
216 AudioFrame* audio_frame_for_mixing) { 207 AudioFrame* audio_frame_for_mixing) {
217 RTC_DCHECK(number_of_channels == 1 || number_of_channels == 2); 208 RTC_DCHECK(number_of_channels == 1 || number_of_channels == 2);
218 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); 209 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
219 210
220 const int sample_rate = [&]() { 211 CalculateOutputFrequency();
221 rtc::CritScope lock(&crit_);
222 return CalculateMixingFrequency(audio_source_list_);
223 }();
224
225 if (OutputFrequency() != sample_rate) {
226 SetOutputFrequency(sample_rate);
227 }
228 212
229 AudioFrameList mix_list; 213 AudioFrameList mix_list;
230 { 214 {
231 rtc::CritScope lock(&crit_); 215 rtc::CritScope lock(&crit_);
232 mix_list = GetAudioFromSources(); 216 mix_list = GetAudioFromSources();
233 217
234 for (const auto& frame : mix_list) { 218 for (const auto& frame : mix_list) {
235 RemixFrame(number_of_channels, frame); 219 RemixFrame(number_of_channels, frame);
236 } 220 }
237 221
(...skipping 14 matching lines...) Expand all
252 audio_frame_for_mixing->samples_per_channel_ = sample_size_; 236 audio_frame_for_mixing->samples_per_channel_ = sample_size_;
253 AudioFrameOperations::Mute(audio_frame_for_mixing); 237 AudioFrameOperations::Mute(audio_frame_for_mixing);
254 } else { 238 } else {
255 // Only call the limiter if we have something to mix. 239 // Only call the limiter if we have something to mix.
256 LimitMixedAudio(audio_frame_for_mixing); 240 LimitMixedAudio(audio_frame_for_mixing);
257 } 241 }
258 242
259 return; 243 return;
260 } 244 }
261 245
262 void AudioMixerImpl::SetOutputFrequency(int frequency) { 246 void AudioMixerImpl::CalculateOutputFrequency() {
263 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); 247 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
264 output_frequency_ = frequency; 248 rtc::CritScope lock(&crit_);
249
250 std::vector<int> preferred_rates;
251 std::transform(audio_source_list_.begin(), audio_source_list_.end(),
252 std::back_inserter(preferred_rates),
253 [&](std::unique_ptr<SourceStatus>& a) {
254 return a->audio_source->PreferredSampleRate();
255 });
256
257 output_frequency_ =
258 output_rate_calculator_->CalculateOutputRate(preferred_rates);
265 sample_size_ = (output_frequency_ * kFrameDurationInMs) / 1000; 259 sample_size_ = (output_frequency_ * kFrameDurationInMs) / 1000;
266 } 260 }
267 261
268 int AudioMixerImpl::OutputFrequency() const { 262 int AudioMixerImpl::OutputFrequency() const {
269 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); 263 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
270 return output_frequency_; 264 return output_frequency_;
271 } 265 }
272 266
273 bool AudioMixerImpl::AddSource(Source* audio_source) { 267 bool AudioMixerImpl::AddSource(Source* audio_source) {
274 RTC_DCHECK(audio_source); 268 RTC_DCHECK(audio_source);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 368
375 const auto iter = FindSourceInList(audio_source, &audio_source_list_); 369 const auto iter = FindSourceInList(audio_source, &audio_source_list_);
376 if (iter != audio_source_list_.end()) { 370 if (iter != audio_source_list_.end()) {
377 return (*iter)->is_mixed; 371 return (*iter)->is_mixed;
378 } 372 }
379 373
380 LOG(LS_ERROR) << "Audio source unknown"; 374 LOG(LS_ERROR) << "Audio source unknown";
381 return false; 375 return false;
382 } 376 }
383 } // namespace webrtc 377 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_mixer/audio_mixer_impl.h ('k') | webrtc/modules/audio_mixer/audio_mixer_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698