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

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

Issue 2408683002: Cleanup of the mixer interface. (Closed)
Patch Set: Added clarifying comments for adding/removing sources and threading aspects of the interface. Created 4 years, 2 months 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
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 AudioMixerImpl::Source const* audio_source, 130 AudioMixerImpl::Source const* audio_source,
131 AudioMixerImpl::SourceStatusList* audio_source_list) { 131 AudioMixerImpl::SourceStatusList* audio_source_list) {
132 return std::find_if(audio_source_list->begin(), audio_source_list->end(), 132 return std::find_if(audio_source_list->begin(), audio_source_list->end(),
133 [audio_source](const AudioMixerImpl::SourceStatus& p) { 133 [audio_source](const AudioMixerImpl::SourceStatus& p) {
134 return p.audio_source == audio_source; 134 return p.audio_source == audio_source;
135 }); 135 });
136 } 136 }
137 137
138 } // namespace 138 } // namespace
139 139
140 std::unique_ptr<AudioMixer> AudioMixer::Create() {
141 return AudioMixerImpl::Create();
142 }
143
144 AudioMixerImpl::AudioMixerImpl(std::unique_ptr<AudioProcessing> limiter) 140 AudioMixerImpl::AudioMixerImpl(std::unique_ptr<AudioProcessing> limiter)
145 : audio_source_list_(), 141 : audio_source_list_(),
146 num_mixed_audio_sources_(0),
147 use_limiter_(true), 142 use_limiter_(true),
148 time_stamp_(0), 143 time_stamp_(0),
149 limiter_(std::move(limiter)) { 144 limiter_(std::move(limiter)) {
150 SetOutputFrequency(kDefaultFrequency); 145 SetOutputFrequency(kDefaultFrequency);
151 thread_checker_.DetachFromThread(); 146 thread_checker_.DetachFromThread();
152 } 147 }
153 148
154 AudioMixerImpl::~AudioMixerImpl() {} 149 AudioMixerImpl::~AudioMixerImpl() {}
155 150
156 std::unique_ptr<AudioMixerImpl> AudioMixerImpl::Create() { 151 rtc::scoped_refptr<AudioMixerImpl> AudioMixerImpl::Create() {
157 Config config; 152 Config config;
158 config.Set<ExperimentalAgc>(new ExperimentalAgc(false)); 153 config.Set<ExperimentalAgc>(new ExperimentalAgc(false));
159 std::unique_ptr<AudioProcessing> limiter(AudioProcessing::Create(config)); 154 std::unique_ptr<AudioProcessing> limiter(AudioProcessing::Create(config));
160 if (!limiter.get()) { 155 if (!limiter.get()) {
161 return nullptr; 156 return nullptr;
162 } 157 }
163 158
164 if (limiter->gain_control()->set_mode(GainControl::kFixedDigital) != 159 if (limiter->gain_control()->set_mode(GainControl::kFixedDigital) !=
165 limiter->kNoError) { 160 limiter->kNoError) {
166 return nullptr; 161 return nullptr;
(...skipping 12 matching lines...) Expand all
179 } 174 }
180 175
181 if (limiter->gain_control()->enable_limiter(true) != limiter->kNoError) { 176 if (limiter->gain_control()->enable_limiter(true) != limiter->kNoError) {
182 return nullptr; 177 return nullptr;
183 } 178 }
184 179
185 if (limiter->gain_control()->Enable(true) != limiter->kNoError) { 180 if (limiter->gain_control()->Enable(true) != limiter->kNoError) {
186 return nullptr; 181 return nullptr;
187 } 182 }
188 183
189 return std::unique_ptr<AudioMixerImpl>( 184 return rtc::scoped_refptr<AudioMixerImpl>(
190 new AudioMixerImpl(std::move(limiter))); 185 new rtc::RefCountedObject<AudioMixerImpl>(std::move(limiter)));
191 } 186 }
192 187
193 void AudioMixerImpl::Mix(int sample_rate, 188 void AudioMixerImpl::Mix(int sample_rate,
194 size_t number_of_channels, 189 size_t number_of_channels,
195 AudioFrame* audio_frame_for_mixing) { 190 AudioFrame* audio_frame_for_mixing) {
196 RTC_DCHECK(number_of_channels == 1 || number_of_channels == 2); 191 RTC_DCHECK(number_of_channels == 1 || number_of_channels == 2);
197 RTC_DCHECK_RUN_ON(&thread_checker_); 192 RTC_DCHECK_RUN_ON(&thread_checker_);
198 193
199 if (OutputFrequency() != sample_rate) { 194 if (OutputFrequency() != sample_rate) {
200 SetOutputFrequency(sample_rate); 195 SetOutputFrequency(sample_rate);
201 } 196 }
202 197
203 AudioFrameList mix_list; 198 AudioFrameList mix_list;
204 size_t num_mixed_audio_sources;
205 { 199 {
206 rtc::CritScope lock(&crit_); 200 rtc::CritScope lock(&crit_);
207 mix_list = GetNonAnonymousAudio(); 201 mix_list = GetAudioFromSources();
208 num_mixed_audio_sources = num_mixed_audio_sources_;
209 } 202 }
210 203
211 for (const auto& frame : mix_list) { 204 for (const auto& frame : mix_list) {
212 RemixFrame(number_of_channels, frame); 205 RemixFrame(number_of_channels, frame);
213 } 206 }
214 207
215 audio_frame_for_mixing->UpdateFrame( 208 audio_frame_for_mixing->UpdateFrame(
216 -1, time_stamp_, NULL, 0, OutputFrequency(), AudioFrame::kNormalSpeech, 209 -1, time_stamp_, NULL, 0, OutputFrequency(), AudioFrame::kNormalSpeech,
217 AudioFrame::kVadPassive, number_of_channels); 210 AudioFrame::kVadPassive, number_of_channels);
218 211
219 time_stamp_ += static_cast<uint32_t>(sample_size_); 212 time_stamp_ += static_cast<uint32_t>(sample_size_);
220 213
221 use_limiter_ = num_mixed_audio_sources > 1; 214 use_limiter_ = mix_list.size() > 1;
222 215
223 // We only use the limiter if we're actually mixing multiple streams. 216 // We only use the limiter if we're actually mixing multiple streams.
224 MixFromList(audio_frame_for_mixing, mix_list, use_limiter_); 217 MixFromList(audio_frame_for_mixing, mix_list, use_limiter_);
225 218
226 if (audio_frame_for_mixing->samples_per_channel_ == 0) { 219 if (audio_frame_for_mixing->samples_per_channel_ == 0) {
227 // Nothing was mixed, set the audio samples to silence. 220 // Nothing was mixed, set the audio samples to silence.
228 audio_frame_for_mixing->samples_per_channel_ = sample_size_; 221 audio_frame_for_mixing->samples_per_channel_ = sample_size_;
229 audio_frame_for_mixing->Mute(); 222 audio_frame_for_mixing->Mute();
230 } else { 223 } else {
231 // Only call the limiter if we have something to mix. 224 // Only call the limiter if we have something to mix.
232 LimitMixedAudio(audio_frame_for_mixing); 225 LimitMixedAudio(audio_frame_for_mixing);
233 } 226 }
234 227
235 return; 228 return;
236 } 229 }
237 230
238 void AudioMixerImpl::SetOutputFrequency(int frequency) { 231 void AudioMixerImpl::SetOutputFrequency(int frequency) {
239 RTC_DCHECK_RUN_ON(&thread_checker_); 232 RTC_DCHECK_RUN_ON(&thread_checker_);
240 output_frequency_ = frequency; 233 output_frequency_ = frequency;
241 sample_size_ = (output_frequency_ * kFrameDurationInMs) / 1000; 234 sample_size_ = (output_frequency_ * kFrameDurationInMs) / 1000;
242 } 235 }
243 236
244 int AudioMixerImpl::OutputFrequency() const { 237 int AudioMixerImpl::OutputFrequency() const {
245 RTC_DCHECK_RUN_ON(&thread_checker_); 238 RTC_DCHECK_RUN_ON(&thread_checker_);
246 return output_frequency_; 239 return output_frequency_;
247 } 240 }
248 241
249 int32_t AudioMixerImpl::SetMixabilityStatus(Source* audio_source, 242 bool AudioMixerImpl::AddSource(Source* audio_source) {
250 bool mixable) { 243 RTC_DCHECK(audio_source);
251 { 244 rtc::CritScope lock(&crit_);
252 rtc::CritScope lock(&crit_); 245 RTC_DCHECK(FindSourceInList(audio_source, &audio_source_list_) ==
253 const bool is_mixed = FindSourceInList(audio_source, &audio_source_list_) != 246 audio_source_list_.end())
254 audio_source_list_.end(); 247 << "Source already added to mixer";
255 // API must be called with a new state. 248 audio_source_list_.emplace_back(audio_source, false, 0);
256 if (!(mixable ^ is_mixed)) { 249 return true;
257 return -1;
258 }
259 bool success = false;
260 if (mixable) {
261 success = AddAudioSourceToList(audio_source, &audio_source_list_);
262 } else {
263 success = RemoveAudioSourceFromList(audio_source, &audio_source_list_);
264 }
265 if (!success) {
266 RTC_NOTREACHED();
267 return -1;
268 }
269
270 size_t num_mixed_non_anonymous = audio_source_list_.size();
271 if (num_mixed_non_anonymous > kMaximumAmountOfMixedAudioSources) {
272 num_mixed_non_anonymous = kMaximumAmountOfMixedAudioSources;
273 }
274 num_mixed_audio_sources_ = num_mixed_non_anonymous;
275 }
276 return 0;
277 } 250 }
278 251
252 bool AudioMixerImpl::RemoveSource(Source* audio_source) {
253 RTC_DCHECK(audio_source);
254 rtc::CritScope lock(&crit_);
255 const auto iter = FindSourceInList(audio_source, &audio_source_list_);
256 RTC_DCHECK(iter != audio_source_list_.end()) << "Source not present in mixer";
257 audio_source_list_.erase(iter);
258 return true;
259 }
279 260
280 261 AudioFrameList AudioMixerImpl::GetAudioFromSources() {
281 AudioFrameList AudioMixerImpl::GetNonAnonymousAudio() {
282 RTC_DCHECK_RUN_ON(&thread_checker_); 262 RTC_DCHECK_RUN_ON(&thread_checker_);
283 AudioFrameList result; 263 AudioFrameList result;
284 std::vector<SourceFrame> audio_source_mixing_data_list; 264 std::vector<SourceFrame> audio_source_mixing_data_list;
285 std::vector<SourceFrame> ramp_list; 265 std::vector<SourceFrame> ramp_list;
286 266
287 // Get audio source audio and put it in the struct vector. 267 // Get audio source audio and put it in the struct vector.
288 for (auto& source_and_status : audio_source_list_) { 268 for (auto& source_and_status : audio_source_list_) {
289 auto audio_frame_with_info = 269 auto audio_frame_with_info =
290 source_and_status.audio_source->GetAudioFrameWithInfo( 270 source_and_status.audio_source->GetAudioFrameWithInfo(
291 static_cast<int>(OutputFrequency())); 271 static_cast<int>(OutputFrequency()));
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 result.push_back(p.audio_frame); 303 result.push_back(p.audio_frame);
324 ramp_list.emplace_back(p.source_status, p.audio_frame, false, -1); 304 ramp_list.emplace_back(p.source_status, p.audio_frame, false, -1);
325 is_mixed = true; 305 is_mixed = true;
326 } 306 }
327 p.source_status->is_mixed = is_mixed; 307 p.source_status->is_mixed = is_mixed;
328 } 308 }
329 RampAndUpdateGain(ramp_list); 309 RampAndUpdateGain(ramp_list);
330 return result; 310 return result;
331 } 311 }
332 312
333 bool AudioMixerImpl::AddAudioSourceToList(
334 Source* audio_source,
335 SourceStatusList* audio_source_list) const {
336 audio_source_list->emplace_back(audio_source, false, 0);
337 return true;
338 }
339
340 bool AudioMixerImpl::RemoveAudioSourceFromList(
341 Source* audio_source,
342 SourceStatusList* audio_source_list) const {
343 const auto iter = FindSourceInList(audio_source, audio_source_list);
344 if (iter != audio_source_list->end()) {
345 audio_source_list->erase(iter);
346 return true;
347 } else {
348 return false;
349 }
350 }
351 313
352 bool AudioMixerImpl::LimitMixedAudio(AudioFrame* mixed_audio) const { 314 bool AudioMixerImpl::LimitMixedAudio(AudioFrame* mixed_audio) const {
353 RTC_DCHECK_RUN_ON(&thread_checker_); 315 RTC_DCHECK_RUN_ON(&thread_checker_);
354 if (!use_limiter_) { 316 if (!use_limiter_) {
355 return true; 317 return true;
356 } 318 }
357 319
358 // Smoothly limit the mixed frame. 320 // Smoothly limit the mixed frame.
359 const int error = limiter_->ProcessStream(mixed_audio); 321 const int error = limiter_->ProcessStream(mixed_audio);
360 322
(...skipping 25 matching lines...) Expand all
386 const auto non_anonymous_iter = 348 const auto non_anonymous_iter =
387 FindSourceInList(audio_source, &audio_source_list_); 349 FindSourceInList(audio_source, &audio_source_list_);
388 if (non_anonymous_iter != audio_source_list_.end()) { 350 if (non_anonymous_iter != audio_source_list_.end()) {
389 return non_anonymous_iter->is_mixed; 351 return non_anonymous_iter->is_mixed;
390 } 352 }
391 353
392 LOG(LS_ERROR) << "Audio source unknown"; 354 LOG(LS_ERROR) << "Audio source unknown";
393 return false; 355 return false;
394 } 356 }
395 } // namespace webrtc 357 } // 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