| 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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 } | 136 } |
| 137 | 137 |
| 138 } // namespace | 138 } // namespace |
| 139 | 139 |
| 140 AudioMixerImpl::AudioMixerImpl(std::unique_ptr<AudioProcessing> limiter) | 140 AudioMixerImpl::AudioMixerImpl(std::unique_ptr<AudioProcessing> limiter) |
| 141 : audio_source_list_(), | 141 : audio_source_list_(), |
| 142 use_limiter_(true), | 142 use_limiter_(true), |
| 143 time_stamp_(0), | 143 time_stamp_(0), |
| 144 limiter_(std::move(limiter)) { | 144 limiter_(std::move(limiter)) { |
| 145 SetOutputFrequency(kDefaultFrequency); | 145 SetOutputFrequency(kDefaultFrequency); |
| 146 thread_checker_.DetachFromThread(); | |
| 147 } | 146 } |
| 148 | 147 |
| 149 AudioMixerImpl::~AudioMixerImpl() {} | 148 AudioMixerImpl::~AudioMixerImpl() {} |
| 150 | 149 |
| 151 rtc::scoped_refptr<AudioMixerImpl> AudioMixerImpl::Create() { | 150 rtc::scoped_refptr<AudioMixerImpl> AudioMixerImpl::Create() { |
| 152 Config config; | 151 Config config; |
| 153 config.Set<ExperimentalAgc>(new ExperimentalAgc(false)); | 152 config.Set<ExperimentalAgc>(new ExperimentalAgc(false)); |
| 154 std::unique_ptr<AudioProcessing> limiter(AudioProcessing::Create(config)); | 153 std::unique_ptr<AudioProcessing> limiter(AudioProcessing::Create(config)); |
| 155 if (!limiter.get()) { | 154 if (!limiter.get()) { |
| 156 return nullptr; | 155 return nullptr; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 182 } | 181 } |
| 183 | 182 |
| 184 return rtc::scoped_refptr<AudioMixerImpl>( | 183 return rtc::scoped_refptr<AudioMixerImpl>( |
| 185 new rtc::RefCountedObject<AudioMixerImpl>(std::move(limiter))); | 184 new rtc::RefCountedObject<AudioMixerImpl>(std::move(limiter))); |
| 186 } | 185 } |
| 187 | 186 |
| 188 void AudioMixerImpl::Mix(int sample_rate, | 187 void AudioMixerImpl::Mix(int sample_rate, |
| 189 size_t number_of_channels, | 188 size_t number_of_channels, |
| 190 AudioFrame* audio_frame_for_mixing) { | 189 AudioFrame* audio_frame_for_mixing) { |
| 191 RTC_DCHECK(number_of_channels == 1 || number_of_channels == 2); | 190 RTC_DCHECK(number_of_channels == 1 || number_of_channels == 2); |
| 192 RTC_DCHECK_RUN_ON(&thread_checker_); | 191 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); |
| 193 | 192 |
| 194 if (OutputFrequency() != sample_rate) { | 193 if (OutputFrequency() != sample_rate) { |
| 195 SetOutputFrequency(sample_rate); | 194 SetOutputFrequency(sample_rate); |
| 196 } | 195 } |
| 197 | 196 |
| 198 AudioFrameList mix_list; | 197 AudioFrameList mix_list; |
| 199 { | 198 { |
| 200 rtc::CritScope lock(&crit_); | 199 rtc::CritScope lock(&crit_); |
| 201 mix_list = GetAudioFromSources(); | 200 mix_list = GetAudioFromSources(); |
| 202 } | 201 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 222 audio_frame_for_mixing->Mute(); | 221 audio_frame_for_mixing->Mute(); |
| 223 } else { | 222 } else { |
| 224 // Only call the limiter if we have something to mix. | 223 // Only call the limiter if we have something to mix. |
| 225 LimitMixedAudio(audio_frame_for_mixing); | 224 LimitMixedAudio(audio_frame_for_mixing); |
| 226 } | 225 } |
| 227 | 226 |
| 228 return; | 227 return; |
| 229 } | 228 } |
| 230 | 229 |
| 231 void AudioMixerImpl::SetOutputFrequency(int frequency) { | 230 void AudioMixerImpl::SetOutputFrequency(int frequency) { |
| 232 RTC_DCHECK_RUN_ON(&thread_checker_); | 231 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); |
| 233 output_frequency_ = frequency; | 232 output_frequency_ = frequency; |
| 234 sample_size_ = (output_frequency_ * kFrameDurationInMs) / 1000; | 233 sample_size_ = (output_frequency_ * kFrameDurationInMs) / 1000; |
| 235 } | 234 } |
| 236 | 235 |
| 237 int AudioMixerImpl::OutputFrequency() const { | 236 int AudioMixerImpl::OutputFrequency() const { |
| 238 RTC_DCHECK_RUN_ON(&thread_checker_); | 237 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); |
| 239 return output_frequency_; | 238 return output_frequency_; |
| 240 } | 239 } |
| 241 | 240 |
| 242 bool AudioMixerImpl::AddSource(Source* audio_source) { | 241 bool AudioMixerImpl::AddSource(Source* audio_source) { |
| 243 RTC_DCHECK(audio_source); | 242 RTC_DCHECK(audio_source); |
| 244 rtc::CritScope lock(&crit_); | 243 rtc::CritScope lock(&crit_); |
| 245 RTC_DCHECK(FindSourceInList(audio_source, &audio_source_list_) == | 244 RTC_DCHECK(FindSourceInList(audio_source, &audio_source_list_) == |
| 246 audio_source_list_.end()) | 245 audio_source_list_.end()) |
| 247 << "Source already added to mixer"; | 246 << "Source already added to mixer"; |
| 248 audio_source_list_.emplace_back(audio_source, false, 0); | 247 audio_source_list_.emplace_back(audio_source, false, 0); |
| 249 return true; | 248 return true; |
| 250 } | 249 } |
| 251 | 250 |
| 252 bool AudioMixerImpl::RemoveSource(Source* audio_source) { | 251 bool AudioMixerImpl::RemoveSource(Source* audio_source) { |
| 253 RTC_DCHECK(audio_source); | 252 RTC_DCHECK(audio_source); |
| 254 rtc::CritScope lock(&crit_); | 253 rtc::CritScope lock(&crit_); |
| 255 const auto iter = FindSourceInList(audio_source, &audio_source_list_); | 254 const auto iter = FindSourceInList(audio_source, &audio_source_list_); |
| 256 RTC_DCHECK(iter != audio_source_list_.end()) << "Source not present in mixer"; | 255 RTC_DCHECK(iter != audio_source_list_.end()) << "Source not present in mixer"; |
| 257 audio_source_list_.erase(iter); | 256 audio_source_list_.erase(iter); |
| 258 return true; | 257 return true; |
| 259 } | 258 } |
| 260 | 259 |
| 261 AudioFrameList AudioMixerImpl::GetAudioFromSources() { | 260 AudioFrameList AudioMixerImpl::GetAudioFromSources() { |
| 262 RTC_DCHECK_RUN_ON(&thread_checker_); | 261 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); |
| 263 AudioFrameList result; | 262 AudioFrameList result; |
| 264 std::vector<SourceFrame> audio_source_mixing_data_list; | 263 std::vector<SourceFrame> audio_source_mixing_data_list; |
| 265 std::vector<SourceFrame> ramp_list; | 264 std::vector<SourceFrame> ramp_list; |
| 266 | 265 |
| 267 // Get audio source audio and put it in the struct vector. | 266 // Get audio source audio and put it in the struct vector. |
| 268 for (auto& source_and_status : audio_source_list_) { | 267 for (auto& source_and_status : audio_source_list_) { |
| 269 auto audio_frame_with_info = | 268 auto audio_frame_with_info = |
| 270 source_and_status.audio_source->GetAudioFrameWithInfo( | 269 source_and_status.audio_source->GetAudioFrameWithInfo( |
| 271 static_cast<int>(OutputFrequency())); | 270 static_cast<int>(OutputFrequency())); |
| 272 | 271 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 is_mixed = true; | 304 is_mixed = true; |
| 306 } | 305 } |
| 307 p.source_status->is_mixed = is_mixed; | 306 p.source_status->is_mixed = is_mixed; |
| 308 } | 307 } |
| 309 RampAndUpdateGain(ramp_list); | 308 RampAndUpdateGain(ramp_list); |
| 310 return result; | 309 return result; |
| 311 } | 310 } |
| 312 | 311 |
| 313 | 312 |
| 314 bool AudioMixerImpl::LimitMixedAudio(AudioFrame* mixed_audio) const { | 313 bool AudioMixerImpl::LimitMixedAudio(AudioFrame* mixed_audio) const { |
| 315 RTC_DCHECK_RUN_ON(&thread_checker_); | 314 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); |
| 316 if (!use_limiter_) { | 315 if (!use_limiter_) { |
| 317 return true; | 316 return true; |
| 318 } | 317 } |
| 319 | 318 |
| 320 // Smoothly limit the mixed frame. | 319 // Smoothly limit the mixed frame. |
| 321 const int error = limiter_->ProcessStream(mixed_audio); | 320 const int error = limiter_->ProcessStream(mixed_audio); |
| 322 | 321 |
| 323 // And now we can safely restore the level. This procedure results in | 322 // And now we can safely restore the level. This procedure results in |
| 324 // some loss of resolution, deemed acceptable. | 323 // some loss of resolution, deemed acceptable. |
| 325 // | 324 // |
| 326 // It's possible to apply the gain in the AGC (with a target level of 0 dbFS | 325 // It's possible to apply the gain in the AGC (with a target level of 0 dbFS |
| 327 // and compression gain of 6 dB). However, in the transition frame when this | 326 // and compression gain of 6 dB). However, in the transition frame when this |
| 328 // is enabled (moving from one to two audio sources) it has the potential to | 327 // is enabled (moving from one to two audio sources) it has the potential to |
| 329 // create discontinuities in the mixed frame. | 328 // create discontinuities in the mixed frame. |
| 330 // | 329 // |
| 331 // Instead we double the frame (with addition since left-shifting a | 330 // Instead we double the frame (with addition since left-shifting a |
| 332 // negative value is undefined). | 331 // negative value is undefined). |
| 333 *mixed_audio += *mixed_audio; | 332 *mixed_audio += *mixed_audio; |
| 334 | 333 |
| 335 if (error != limiter_->kNoError) { | 334 if (error != limiter_->kNoError) { |
| 336 LOG_F(LS_ERROR) << "Error from AudioProcessing: " << error; | 335 LOG_F(LS_ERROR) << "Error from AudioProcessing: " << error; |
| 337 RTC_NOTREACHED(); | 336 RTC_NOTREACHED(); |
| 338 return false; | 337 return false; |
| 339 } | 338 } |
| 340 return true; | 339 return true; |
| 341 } | 340 } |
| 342 | 341 |
| 343 bool AudioMixerImpl::GetAudioSourceMixabilityStatusForTest( | 342 bool AudioMixerImpl::GetAudioSourceMixabilityStatusForTest( |
| 344 AudioMixerImpl::Source* audio_source) const { | 343 AudioMixerImpl::Source* audio_source) const { |
| 345 RTC_DCHECK_RUN_ON(&thread_checker_); | 344 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); |
| 346 rtc::CritScope lock(&crit_); | 345 rtc::CritScope lock(&crit_); |
| 347 | 346 |
| 348 const auto non_anonymous_iter = | 347 const auto non_anonymous_iter = |
| 349 FindSourceInList(audio_source, &audio_source_list_); | 348 FindSourceInList(audio_source, &audio_source_list_); |
| 350 if (non_anonymous_iter != audio_source_list_.end()) { | 349 if (non_anonymous_iter != audio_source_list_.end()) { |
| 351 return non_anonymous_iter->is_mixed; | 350 return non_anonymous_iter->is_mixed; |
| 352 } | 351 } |
| 353 | 352 |
| 354 LOG(LS_ERROR) << "Audio source unknown"; | 353 LOG(LS_ERROR) << "Audio source unknown"; |
| 355 return false; | 354 return false; |
| 356 } | 355 } |
| 357 } // namespace webrtc | 356 } // namespace webrtc |
| OLD | NEW |