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

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

Issue 2302483002: Style changes in Audio Mixer (Closed)
Patch Set: Rebase. 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
« no previous file with comments | « webrtc/modules/audio_mixer/audio_mixer_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <utility> 15 #include <utility>
16 16
17 #include "webrtc/base/thread_annotations.h"
18 #include "webrtc/modules/audio_mixer/audio_frame_manipulator.h" 17 #include "webrtc/modules/audio_mixer/audio_frame_manipulator.h"
19 #include "webrtc/modules/audio_mixer/audio_mixer_defines.h"
20 #include "webrtc/modules/audio_processing/include/audio_processing.h"
21 #include "webrtc/modules/utility/include/audio_frame_operations.h" 18 #include "webrtc/modules/utility/include/audio_frame_operations.h"
22 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
23 #include "webrtc/system_wrappers/include/trace.h" 19 #include "webrtc/system_wrappers/include/trace.h"
24 20
25 namespace webrtc { 21 namespace webrtc {
26 namespace { 22 namespace {
27 23
28 class SourceFrame { 24 class SourceFrame {
29 public: 25 public:
30 SourceFrame(MixerAudioSource* p, AudioFrame* a, bool m, bool was_mixed_before) 26 SourceFrame(MixerAudioSource* p, AudioFrame* a, bool m, bool was_mixed_before)
31 : audio_source_(p), 27 : audio_source_(p),
32 audio_frame_(a), 28 audio_frame_(a),
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 } 77 }
82 } 78 }
83 79
84 void Ramp(const std::vector<SourceFrame>& mixed_sources_and_frames) { 80 void Ramp(const std::vector<SourceFrame>& mixed_sources_and_frames) {
85 for (const auto& source_frame : mixed_sources_and_frames) { 81 for (const auto& source_frame : mixed_sources_and_frames) {
86 // Ramp in previously unmixed. 82 // Ramp in previously unmixed.
87 if (!source_frame.was_mixed_before_) { 83 if (!source_frame.was_mixed_before_) {
88 NewMixerRampIn(source_frame.audio_frame_); 84 NewMixerRampIn(source_frame.audio_frame_);
89 } 85 }
90 86
91 const bool is_mixed = source_frame.audio_source_->mix_history_->IsMixed(); 87 const bool is_mixed = source_frame.audio_source_->IsMixed();
92 // Ramp out currently unmixed. 88 // Ramp out currently unmixed.
93 if (source_frame.was_mixed_before_ && !is_mixed) { 89 if (source_frame.was_mixed_before_ && !is_mixed) {
94 NewMixerRampOut(source_frame.audio_frame_); 90 NewMixerRampOut(source_frame.audio_frame_);
95 } 91 }
96 } 92 }
97 } 93 }
98 94
95 // Mix the AudioFrames stored in audioFrameList into mixed_audio.
96 int32_t MixFromList(AudioFrame* mixed_audio,
97 const AudioFrameList& audio_frame_list,
98 int32_t id,
99 bool use_limiter) {
100 WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, id,
101 "MixFromList(mixed_audio, audio_frame_list)");
102 if (audio_frame_list.empty())
103 return 0;
104
105 if (audio_frame_list.size() == 1) {
106 mixed_audio->timestamp_ = audio_frame_list.front()->timestamp_;
107 mixed_audio->elapsed_time_ms_ = audio_frame_list.front()->elapsed_time_ms_;
108 } else {
109 // TODO(wu): Issue 3390.
110 // Audio frame timestamp is only supported in one channel case.
111 mixed_audio->timestamp_ = 0;
112 mixed_audio->elapsed_time_ms_ = -1;
113 }
114
115 for (const auto& frame : audio_frame_list) {
116 RTC_DCHECK_EQ(mixed_audio->sample_rate_hz_, frame->sample_rate_hz_);
117 RTC_DCHECK_EQ(
118 frame->samples_per_channel_,
119 static_cast<size_t>((mixed_audio->sample_rate_hz_ *
120 webrtc::AudioMixerImpl::kFrameDurationInMs) /
121 1000));
122
123 // Mix |f.frame| into |mixed_audio|, with saturation protection.
124 // These effect is applied to |f.frame| itself prior to mixing.
125 if (use_limiter) {
126 // Divide by two to avoid saturation in the mixing.
127 // This is only meaningful if the limiter will be used.
128 *frame >>= 1;
129 }
130 RTC_DCHECK_EQ(frame->num_channels_, mixed_audio->num_channels_);
131 *mixed_audio += *frame;
132 }
133 return 0;
134 }
135
99 } // namespace 136 } // namespace
100 137
101 MixerAudioSource::MixerAudioSource() : mix_history_(new NewMixHistory()) {}
102
103 MixerAudioSource::~MixerAudioSource() {
104 delete mix_history_;
105 }
106
107 bool MixerAudioSource::IsMixed() const {
108 return mix_history_->IsMixed();
109 }
110
111 NewMixHistory::NewMixHistory() : is_mixed_(0) {}
112
113 NewMixHistory::~NewMixHistory() {}
114
115 bool NewMixHistory::IsMixed() const {
116 return is_mixed_;
117 }
118
119 bool NewMixHistory::WasMixed() const {
120 // Was mixed is the same as is mixed depending on perspective. This function
121 // is for the perspective of NewAudioConferenceMixerImpl.
122 return IsMixed();
123 }
124
125 int32_t NewMixHistory::SetIsMixed(const bool mixed) {
126 is_mixed_ = mixed;
127 return 0;
128 }
129
130 void NewMixHistory::ResetMixedStatus() {
131 is_mixed_ = false;
132 }
133
134 std::unique_ptr<AudioMixer> AudioMixer::Create(int id) { 138 std::unique_ptr<AudioMixer> AudioMixer::Create(int id) {
135 return AudioMixerImpl::Create(id); 139 return AudioMixerImpl::Create(id);
136 } 140 }
137 141
138 AudioMixerImpl::AudioMixerImpl(int id, std::unique_ptr<AudioProcessing> limiter) 142 AudioMixerImpl::AudioMixerImpl(int id, std::unique_ptr<AudioProcessing> limiter)
139 : id_(id), 143 : id_(id),
140 audio_source_list_(), 144 audio_source_list_(),
141 additional_audio_source_list_(), 145 additional_audio_source_list_(),
142 num_mixed_audio_sources_(0), 146 num_mixed_audio_sources_(0),
143 use_limiter_(true), 147 use_limiter_(true),
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 RTC_NOTREACHED(); 196 RTC_NOTREACHED();
193 return; 197 return;
194 } 198 }
195 199
196 if (OutputFrequency() != sample_rate) { 200 if (OutputFrequency() != sample_rate) {
197 SetOutputFrequency(static_cast<Frequency>(sample_rate)); 201 SetOutputFrequency(static_cast<Frequency>(sample_rate));
198 } 202 }
199 203
200 AudioFrameList mix_list; 204 AudioFrameList mix_list;
201 AudioFrameList anonymous_mix_list; 205 AudioFrameList anonymous_mix_list;
202 int num_mixed_audio_sources; 206 size_t num_mixed_audio_sources;
203 { 207 {
204 rtc::CritScope lock(&crit_); 208 rtc::CritScope lock(&crit_);
205 mix_list = GetNonAnonymousAudio(); 209 mix_list = GetNonAnonymousAudio();
206 anonymous_mix_list = GetAnonymousAudio(); 210 anonymous_mix_list = GetAnonymousAudio();
207 num_mixed_audio_sources = static_cast<int>(num_mixed_audio_sources_); 211 num_mixed_audio_sources = num_mixed_audio_sources_;
208 } 212 }
209 213
210 mix_list.insert(mix_list.begin(), anonymous_mix_list.begin(), 214 mix_list.insert(mix_list.begin(), anonymous_mix_list.begin(),
211 anonymous_mix_list.end()); 215 anonymous_mix_list.end());
212 216
213 for (const auto& frame : mix_list) { 217 for (const auto& frame : mix_list) {
214 RemixFrame(frame, number_of_channels); 218 RemixFrame(frame, number_of_channels);
215 } 219 }
216 220
217 audio_frame_for_mixing->UpdateFrame( 221 audio_frame_for_mixing->UpdateFrame(
(...skipping 18 matching lines...) Expand all
236 240
237 // Pass the final result to the level indicator. 241 // Pass the final result to the level indicator.
238 audio_level_.ComputeLevel(*audio_frame_for_mixing); 242 audio_level_.ComputeLevel(*audio_frame_for_mixing);
239 243
240 return; 244 return;
241 } 245 }
242 246
243 int32_t AudioMixerImpl::SetOutputFrequency(const Frequency& frequency) { 247 int32_t AudioMixerImpl::SetOutputFrequency(const Frequency& frequency) {
244 RTC_DCHECK_RUN_ON(&thread_checker_); 248 RTC_DCHECK_RUN_ON(&thread_checker_);
245 output_frequency_ = frequency; 249 output_frequency_ = frequency;
246 sample_size_ = 250 sample_size_ = (output_frequency_ * kFrameDurationInMs) / 1000;
247 static_cast<size_t>((output_frequency_ * kFrameDurationInMs) / 1000);
248 251
249 return 0; 252 return 0;
250 } 253 }
251 254
252 AudioMixer::Frequency AudioMixerImpl::OutputFrequency() const { 255 AudioMixer::Frequency AudioMixerImpl::OutputFrequency() const {
253 RTC_DCHECK_RUN_ON(&thread_checker_); 256 RTC_DCHECK_RUN_ON(&thread_checker_);
254 return output_frequency_; 257 return output_frequency_;
255 } 258 }
256 259
257 int32_t AudioMixerImpl::SetMixabilityStatus(MixerAudioSource* audio_source, 260 int32_t AudioMixerImpl::SetMixabilityStatus(MixerAudioSource* audio_source,
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 AudioFrame* audio_source_audio_frame = audio_frame_with_info.audio_frame; 361 AudioFrame* audio_source_audio_frame = audio_frame_with_info.audio_frame;
359 362
360 if (audio_frame_info == MixerAudioSource::AudioFrameInfo::kError) { 363 if (audio_frame_info == MixerAudioSource::AudioFrameInfo::kError) {
361 WEBRTC_TRACE(kTraceWarning, kTraceAudioMixerServer, id_, 364 WEBRTC_TRACE(kTraceWarning, kTraceAudioMixerServer, id_,
362 "failed to GetAudioFrameWithMuted() from participant"); 365 "failed to GetAudioFrameWithMuted() from participant");
363 continue; 366 continue;
364 } 367 }
365 audio_source_mixing_data_list.emplace_back( 368 audio_source_mixing_data_list.emplace_back(
366 audio_source, audio_source_audio_frame, 369 audio_source, audio_source_audio_frame,
367 audio_frame_info == MixerAudioSource::AudioFrameInfo::kMuted, 370 audio_frame_info == MixerAudioSource::AudioFrameInfo::kMuted,
368 audio_source->mix_history_->WasMixed()); 371 audio_source->WasMixed());
369 } 372 }
370 373
371 // Sort frames by sorting function. 374 // Sort frames by sorting function.
372 std::sort(audio_source_mixing_data_list.begin(), 375 std::sort(audio_source_mixing_data_list.begin(),
373 audio_source_mixing_data_list.end(), 376 audio_source_mixing_data_list.end(),
374 std::mem_fn(&SourceFrame::shouldMixBefore)); 377 std::mem_fn(&SourceFrame::shouldMixBefore));
375 378
376 int max_audio_frame_counter = kMaximumAmountOfMixedAudioSources; 379 int max_audio_frame_counter = kMaximumAmountOfMixedAudioSources;
377 380
378 // Go through list in order and put unmuted frames in result list. 381 // Go through list in order and put unmuted frames in result list.
379 for (const SourceFrame& p : audio_source_mixing_data_list) { 382 for (const SourceFrame& p : audio_source_mixing_data_list) {
380 // Filter muted. 383 // Filter muted.
381 if (p.muted_) { 384 if (p.muted_) {
382 p.audio_source_->mix_history_->SetIsMixed(false); 385 p.audio_source_->SetIsMixed(false);
383 continue; 386 continue;
384 } 387 }
385 388
386 // Add frame to result vector for mixing. 389 // Add frame to result vector for mixing.
387 bool is_mixed = false; 390 bool is_mixed = false;
388 if (max_audio_frame_counter > 0) { 391 if (max_audio_frame_counter > 0) {
389 --max_audio_frame_counter; 392 --max_audio_frame_counter;
390 result.push_back(p.audio_frame_); 393 result.push_back(p.audio_frame_);
391 ramp_list.emplace_back(p.audio_source_, p.audio_frame_, false, 394 ramp_list.emplace_back(p.audio_source_, p.audio_frame_, false,
392 p.was_mixed_before_, -1); 395 p.was_mixed_before_, -1);
393 is_mixed = true; 396 is_mixed = true;
394 } 397 }
395 p.audio_source_->mix_history_->SetIsMixed(is_mixed); 398 p.audio_source_->SetIsMixed(is_mixed);
396 } 399 }
397 Ramp(ramp_list); 400 Ramp(ramp_list);
398 return result; 401 return result;
399 } 402 }
400 403
401 AudioFrameList AudioMixerImpl::GetAnonymousAudio() const { 404 AudioFrameList AudioMixerImpl::GetAnonymousAudio() const {
402 RTC_DCHECK_RUN_ON(&thread_checker_); 405 RTC_DCHECK_RUN_ON(&thread_checker_);
403 WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, id_, 406 WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, id_,
404 "GetAnonymousAudio()"); 407 "GetAnonymousAudio()");
405 // The GetAudioFrameWithMuted() callback may result in the audio source being 408 // The GetAudioFrameWithMuted() callback may result in the audio source being
(...skipping 13 matching lines...) Expand all
419 const auto ret = audio_frame_with_info.audio_frame_info; 422 const auto ret = audio_frame_with_info.audio_frame_info;
420 AudioFrame* audio_frame = audio_frame_with_info.audio_frame; 423 AudioFrame* audio_frame = audio_frame_with_info.audio_frame;
421 if (ret == MixerAudioSource::AudioFrameInfo::kError) { 424 if (ret == MixerAudioSource::AudioFrameInfo::kError) {
422 WEBRTC_TRACE(kTraceWarning, kTraceAudioMixerServer, id_, 425 WEBRTC_TRACE(kTraceWarning, kTraceAudioMixerServer, id_,
423 "failed to GetAudioFrameWithMuted() from audio_source"); 426 "failed to GetAudioFrameWithMuted() from audio_source");
424 continue; 427 continue;
425 } 428 }
426 if (ret != MixerAudioSource::AudioFrameInfo::kMuted) { 429 if (ret != MixerAudioSource::AudioFrameInfo::kMuted) {
427 result.push_back(audio_frame); 430 result.push_back(audio_frame);
428 ramp_list.emplace_back(audio_source, audio_frame, false, 431 ramp_list.emplace_back(audio_source, audio_frame, false,
429 audio_source->mix_history_->IsMixed(), 0); 432 audio_source->IsMixed(), 0);
430 audio_source->mix_history_->SetIsMixed(true); 433 audio_source->SetIsMixed(true);
431 } 434 }
432 } 435 }
433 Ramp(ramp_list); 436 Ramp(ramp_list);
434 return result; 437 return result;
435 } 438 }
436 439
437 bool AudioMixerImpl::IsAudioSourceInList( 440 bool AudioMixerImpl::IsAudioSourceInList(
438 const MixerAudioSource& audio_source, 441 const MixerAudioSource& audio_source,
439 const MixerAudioSourceList& audio_source_list) const { 442 const MixerAudioSourceList& audio_source_list) const {
440 WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, id_, 443 WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, id_,
441 "IsAudioSourceInList(audio_source,audio_source_list)"); 444 "IsAudioSourceInList(audio_source,audio_source_list)");
442 return std::find(audio_source_list.begin(), audio_source_list.end(), 445 return std::find(audio_source_list.begin(), audio_source_list.end(),
443 &audio_source) != audio_source_list.end(); 446 &audio_source) != audio_source_list.end();
444 } 447 }
445 448
446 bool AudioMixerImpl::AddAudioSourceToList( 449 bool AudioMixerImpl::AddAudioSourceToList(
447 MixerAudioSource* audio_source, 450 MixerAudioSource* audio_source,
448 MixerAudioSourceList* audio_source_list) const { 451 MixerAudioSourceList* audio_source_list) const {
449 WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, id_, 452 WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, id_,
450 "AddAudioSourceToList(audio_source, audio_source_list)"); 453 "AddAudioSourceToList(audio_source, audio_source_list)");
451 audio_source_list->push_back(audio_source); 454 audio_source_list->push_back(audio_source);
452 // Make sure that the mixed status is correct for new MixerAudioSource. 455 // Make sure that the mixed status is correct for new MixerAudioSource.
453 audio_source->mix_history_->ResetMixedStatus(); 456 audio_source->ResetMixedStatus();
454 return true; 457 return true;
455 } 458 }
456 459
457 bool AudioMixerImpl::RemoveAudioSourceFromList( 460 bool AudioMixerImpl::RemoveAudioSourceFromList(
458 MixerAudioSource* audio_source, 461 MixerAudioSource* audio_source,
459 MixerAudioSourceList* audio_source_list) const { 462 MixerAudioSourceList* audio_source_list) const {
460 WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, id_, 463 WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, id_,
461 "RemoveAudioSourceFromList(audio_source, audio_source_list)"); 464 "RemoveAudioSourceFromList(audio_source, audio_source_list)");
462 const auto iter = std::find(audio_source_list->begin(), 465 const auto iter = std::find(audio_source_list->begin(),
463 audio_source_list->end(), audio_source); 466 audio_source_list->end(), audio_source);
464 if (iter != audio_source_list->end()) { 467 if (iter != audio_source_list->end()) {
465 audio_source_list->erase(iter); 468 audio_source_list->erase(iter);
466 // AudioSource is no longer mixed, reset to default. 469 // AudioSource is no longer mixed, reset to default.
467 audio_source->mix_history_->ResetMixedStatus(); 470 audio_source->ResetMixedStatus();
468 return true; 471 return true;
469 } else { 472 } else {
470 return false; 473 return false;
471 } 474 }
472 } 475 }
473 476
474 int32_t AudioMixerImpl::MixFromList(AudioFrame* mixed_audio,
475 const AudioFrameList& audio_frame_list,
476 int32_t id,
477 bool use_limiter) {
478 WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, id,
479 "MixFromList(mixed_audio, audio_frame_list)");
480 if (audio_frame_list.empty())
481 return 0;
482
483 if (audio_frame_list.size() == 1) {
484 mixed_audio->timestamp_ = audio_frame_list.front()->timestamp_;
485 mixed_audio->elapsed_time_ms_ = audio_frame_list.front()->elapsed_time_ms_;
486 } else {
487 // TODO(wu): Issue 3390.
488 // Audio frame timestamp is only supported in one channel case.
489 mixed_audio->timestamp_ = 0;
490 mixed_audio->elapsed_time_ms_ = -1;
491 }
492
493 for (const auto& frame : audio_frame_list) {
494 RTC_DCHECK_EQ(mixed_audio->sample_rate_hz_, frame->sample_rate_hz_);
495 RTC_DCHECK_EQ(
496 frame->samples_per_channel_,
497 static_cast<size_t>(
498 (mixed_audio->sample_rate_hz_ * kFrameDurationInMs) / 1000));
499
500 // Mix |f.frame| into |mixed_audio|, with saturation protection.
501 // These effect is applied to |f.frame| itself prior to mixing.
502 if (use_limiter) {
503 // Divide by two to avoid saturation in the mixing.
504 // This is only meaningful if the limiter will be used.
505 *frame >>= 1;
506 }
507 RTC_DCHECK_EQ(frame->num_channels_, mixed_audio->num_channels_);
508 *mixed_audio += *frame;
509 }
510 return 0;
511 }
512
513 bool AudioMixerImpl::LimitMixedAudio(AudioFrame* mixed_audio) const { 477 bool AudioMixerImpl::LimitMixedAudio(AudioFrame* mixed_audio) const {
514 RTC_DCHECK_RUN_ON(&thread_checker_); 478 RTC_DCHECK_RUN_ON(&thread_checker_);
515 if (!use_limiter_) { 479 if (!use_limiter_) {
516 return true; 480 return true;
517 } 481 }
518 482
519 // Smoothly limit the mixed frame. 483 // Smoothly limit the mixed frame.
520 const int error = limiter_->ProcessStream(mixed_audio); 484 const int error = limiter_->ProcessStream(mixed_audio);
521 485
522 // And now we can safely restore the level. This procedure results in 486 // And now we can safely restore the level. This procedure results in
(...skipping 26 matching lines...) Expand all
549 } 513 }
550 514
551 int AudioMixerImpl::GetOutputAudioLevelFullRange() { 515 int AudioMixerImpl::GetOutputAudioLevelFullRange() {
552 RTC_DCHECK_RUN_ON(&thread_checker_); 516 RTC_DCHECK_RUN_ON(&thread_checker_);
553 const int level = audio_level_.LevelFullRange(); 517 const int level = audio_level_.LevelFullRange();
554 WEBRTC_TRACE(kTraceStateInfo, kTraceAudioMixerServer, id_, 518 WEBRTC_TRACE(kTraceStateInfo, kTraceAudioMixerServer, id_,
555 "GetAudioOutputLevelFullRange() => level=%d", level); 519 "GetAudioOutputLevelFullRange() => level=%d", level);
556 return level; 520 return level;
557 } 521 }
558 } // namespace webrtc 522 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_mixer/audio_mixer_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698