OLD | NEW |
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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 } else if (frame->num_channels_ == 2 && number_of_channels == 1) { | 66 } else if (frame->num_channels_ == 2 && number_of_channels == 1) { |
67 AudioFrameOperations::StereoToMono(frame); | 67 AudioFrameOperations::StereoToMono(frame); |
68 } | 68 } |
69 } | 69 } |
70 | 70 |
71 // Mix |frame| into |mixed_frame|, with saturation protection and upmixing. | 71 // Mix |frame| into |mixed_frame|, with saturation protection and upmixing. |
72 // These effects are applied to |frame| itself prior to mixing. Assumes that | 72 // These effects are applied to |frame| itself prior to mixing. Assumes that |
73 // |mixed_frame| always has at least as many channels as |frame|. Supports | 73 // |mixed_frame| always has at least as many channels as |frame|. Supports |
74 // stereo at most. | 74 // stereo at most. |
75 // | 75 // |
76 // TODO(andrew): consider not modifying |frame| here. | |
77 void MixFrames(AudioFrame* mixed_frame, AudioFrame* frame, bool use_limiter) { | 76 void MixFrames(AudioFrame* mixed_frame, AudioFrame* frame, bool use_limiter) { |
78 RTC_DCHECK_GE(mixed_frame->num_channels_, frame->num_channels_); | 77 RTC_DCHECK_GE(mixed_frame->num_channels_, frame->num_channels_); |
79 if (use_limiter) { | 78 if (use_limiter) { |
80 // Divide by two to avoid saturation in the mixing. | 79 // Divide by two to avoid saturation in the mixing. |
81 // This is only meaningful if the limiter will be used. | 80 // This is only meaningful if the limiter will be used. |
82 *frame >>= 1; | 81 *frame >>= 1; |
83 } | 82 } |
84 RTC_DCHECK_EQ(frame->num_channels_, mixed_frame->num_channels_); | 83 RTC_DCHECK_EQ(frame->num_channels_, mixed_frame->num_channels_); |
85 *mixed_frame += *frame; | 84 *mixed_frame += *frame; |
86 } | 85 } |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 for (FrameAndMuteInfo& frame_and_mute : additionalFramesList) { | 229 for (FrameAndMuteInfo& frame_and_mute : additionalFramesList) { |
231 RemixFrame(frame_and_mute.frame, number_of_channels); | 230 RemixFrame(frame_and_mute.frame, number_of_channels); |
232 } | 231 } |
233 | 232 |
234 audio_frame_for_mixing->UpdateFrame( | 233 audio_frame_for_mixing->UpdateFrame( |
235 -1, time_stamp_, NULL, 0, output_frequency_, AudioFrame::kNormalSpeech, | 234 -1, time_stamp_, NULL, 0, output_frequency_, AudioFrame::kNormalSpeech, |
236 AudioFrame::kVadPassive, number_of_channels); | 235 AudioFrame::kVadPassive, number_of_channels); |
237 | 236 |
238 time_stamp_ += static_cast<uint32_t>(sample_size_); | 237 time_stamp_ += static_cast<uint32_t>(sample_size_); |
239 | 238 |
240 use_limiter_ = num_mixed_audio_sources_ > 1 && | 239 use_limiter_ = num_mixed_audio_sources_ > 1; |
241 output_frequency_ <= AudioProcessing::kMaxNativeSampleRateHz; | |
242 | 240 |
243 // We only use the limiter if it supports the output sample rate and | 241 // We only use the limiter if it supports the output sample rate and |
244 // we're actually mixing multiple streams. | 242 // we're actually mixing multiple streams. |
245 MixFromList(audio_frame_for_mixing, mixList, id_, use_limiter_); | 243 MixFromList(audio_frame_for_mixing, mixList, id_, use_limiter_); |
246 | 244 |
247 { | 245 { |
248 CriticalSectionScoped cs(crit_.get()); | 246 CriticalSectionScoped cs(crit_.get()); |
249 MixAnonomouslyFromList(audio_frame_for_mixing, additionalFramesList); | 247 MixAnonomouslyFromList(audio_frame_for_mixing, additionalFramesList); |
250 | 248 |
251 if (audio_frame_for_mixing->samples_per_channel_ == 0) { | 249 if (audio_frame_for_mixing->samples_per_channel_ == 0) { |
252 // Nothing was mixed, set the audio samples to silence. | 250 // Nothing was mixed, set the audio samples to silence. |
253 audio_frame_for_mixing->samples_per_channel_ = sample_size_; | 251 audio_frame_for_mixing->samples_per_channel_ = sample_size_; |
254 audio_frame_for_mixing->Mute(); | 252 audio_frame_for_mixing->Mute(); |
255 } else { | 253 } else { |
256 // Only call the limiter if we have something to mix. | 254 // Only call the limiter if we have something to mix. |
257 LimitMixedAudio(audio_frame_for_mixing); | 255 LimitMixedAudio(audio_frame_for_mixing); |
258 } | 256 } |
259 } | 257 } |
| 258 |
| 259 // Pass the final result to the level indicator. |
| 260 audio_level_.ComputeLevel(*audio_frame_for_mixing); |
| 261 |
260 return; | 262 return; |
261 } | 263 } |
262 | 264 |
263 int32_t NewAudioConferenceMixerImpl::SetOutputFrequency( | 265 int32_t NewAudioConferenceMixerImpl::SetOutputFrequency( |
264 const Frequency& frequency) { | 266 const Frequency& frequency) { |
265 CriticalSectionScoped cs(crit_.get()); | 267 CriticalSectionScoped cs(crit_.get()); |
266 | 268 |
267 output_frequency_ = frequency; | 269 output_frequency_ = frequency; |
268 sample_size_ = | 270 sample_size_ = |
269 static_cast<size_t>((output_frequency_ * kProcessPeriodicityInMs) / 1000); | 271 static_cast<size_t>((output_frequency_ * kProcessPeriodicityInMs) / 1000); |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 *mixedAudio += *mixedAudio; | 586 *mixedAudio += *mixedAudio; |
585 | 587 |
586 if (error != limiter_->kNoError) { | 588 if (error != limiter_->kNoError) { |
587 WEBRTC_TRACE(kTraceError, kTraceAudioMixerServer, id_, | 589 WEBRTC_TRACE(kTraceError, kTraceAudioMixerServer, id_, |
588 "Error from AudioProcessing: %d", error); | 590 "Error from AudioProcessing: %d", error); |
589 RTC_NOTREACHED(); | 591 RTC_NOTREACHED(); |
590 return false; | 592 return false; |
591 } | 593 } |
592 return true; | 594 return true; |
593 } | 595 } |
| 596 |
| 597 uint32_t NewAudioConferenceMixerImpl::GetAudioOutputLevel() { |
| 598 int8_t current_level = audio_level_.Level(); |
| 599 uint32_t level = static_cast<uint32_t>(current_level); |
| 600 WEBRTC_TRACE(kTraceStateInfo, kTraceAudioMixerServer, id_, |
| 601 "GetAudioOutputLevel() => level=%u", level); |
| 602 return level; |
| 603 } |
| 604 |
| 605 uint32_t NewAudioConferenceMixerImpl::GetAudioOutputLevelFullRange() { |
| 606 int16_t current_level = audio_level_.LevelFullRange(); |
| 607 uint32_t level = static_cast<uint32_t>(current_level); |
| 608 WEBRTC_TRACE(kTraceStateInfo, kTraceAudioMixerServer, id_, |
| 609 "GetAudioOutputLevelFullRange() => level=%u", level); |
| 610 return level; |
| 611 } |
594 } // namespace webrtc | 612 } // namespace webrtc |
OLD | NEW |