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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 AudioMixerImpl::SourceStatusList::iterator FindSourceInList( | 130 AudioMixerImpl::SourceStatusList::iterator FindSourceInList( |
131 AudioMixerImpl::Source const* audio_source, | 131 AudioMixerImpl::Source const* audio_source, |
132 AudioMixerImpl::SourceStatusList* audio_source_list) { | 132 AudioMixerImpl::SourceStatusList* audio_source_list) { |
133 return std::find_if( | 133 return std::find_if( |
134 audio_source_list->begin(), audio_source_list->end(), | 134 audio_source_list->begin(), audio_source_list->end(), |
135 [audio_source](const std::unique_ptr<AudioMixerImpl::SourceStatus>& p) { | 135 [audio_source](const std::unique_ptr<AudioMixerImpl::SourceStatus>& p) { |
136 return p->audio_source == audio_source; | 136 return p->audio_source == audio_source; |
137 }); | 137 }); |
138 } | 138 } |
139 | 139 |
| 140 // Rounds the maximal audio source frequency up to an APM-native |
| 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 |
140 } // namespace | 166 } // namespace |
141 | 167 |
142 AudioMixerImpl::AudioMixerImpl(std::unique_ptr<AudioProcessing> limiter) | 168 AudioMixerImpl::AudioMixerImpl(std::unique_ptr<AudioProcessing> limiter) |
143 : audio_source_list_(), | 169 : audio_source_list_(), |
144 use_limiter_(true), | 170 use_limiter_(true), |
145 time_stamp_(0), | 171 time_stamp_(0), |
146 limiter_(std::move(limiter)) { | 172 limiter_(std::move(limiter)) { |
147 SetOutputFrequency(kDefaultFrequency); | 173 SetOutputFrequency(kDefaultFrequency); |
148 } | 174 } |
149 | 175 |
(...skipping 29 matching lines...) Expand all Loading... |
179 } | 205 } |
180 | 206 |
181 if (limiter->gain_control()->Enable(true) != limiter->kNoError) { | 207 if (limiter->gain_control()->Enable(true) != limiter->kNoError) { |
182 return nullptr; | 208 return nullptr; |
183 } | 209 } |
184 | 210 |
185 return rtc::scoped_refptr<AudioMixerImpl>( | 211 return rtc::scoped_refptr<AudioMixerImpl>( |
186 new rtc::RefCountedObject<AudioMixerImpl>(std::move(limiter))); | 212 new rtc::RefCountedObject<AudioMixerImpl>(std::move(limiter))); |
187 } | 213 } |
188 | 214 |
189 void AudioMixerImpl::Mix(int sample_rate, | 215 void AudioMixerImpl::Mix(size_t number_of_channels, |
190 size_t number_of_channels, | |
191 AudioFrame* audio_frame_for_mixing) { | 216 AudioFrame* audio_frame_for_mixing) { |
192 RTC_DCHECK(number_of_channels == 1 || number_of_channels == 2); | 217 RTC_DCHECK(number_of_channels == 1 || number_of_channels == 2); |
193 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); | 218 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); |
194 | 219 |
| 220 const int sample_rate = [&]() { |
| 221 rtc::CritScope lock(&crit_); |
| 222 return CalculateMixingFrequency(audio_source_list_); |
| 223 }(); |
| 224 |
195 if (OutputFrequency() != sample_rate) { | 225 if (OutputFrequency() != sample_rate) { |
196 SetOutputFrequency(sample_rate); | 226 SetOutputFrequency(sample_rate); |
197 } | 227 } |
198 | 228 |
199 AudioFrameList mix_list; | 229 AudioFrameList mix_list; |
200 { | 230 { |
201 rtc::CritScope lock(&crit_); | 231 rtc::CritScope lock(&crit_); |
202 mix_list = GetAudioFromSources(); | 232 mix_list = GetAudioFromSources(); |
203 | 233 |
204 for (const auto& frame : mix_list) { | 234 for (const auto& frame : mix_list) { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 | 375 |
346 const auto iter = FindSourceInList(audio_source, &audio_source_list_); | 376 const auto iter = FindSourceInList(audio_source, &audio_source_list_); |
347 if (iter != audio_source_list_.end()) { | 377 if (iter != audio_source_list_.end()) { |
348 return (*iter)->is_mixed; | 378 return (*iter)->is_mixed; |
349 } | 379 } |
350 | 380 |
351 LOG(LS_ERROR) << "Audio source unknown"; | 381 LOG(LS_ERROR) << "Audio source unknown"; |
352 return false; | 382 return false; |
353 } | 383 } |
354 } // namespace webrtc | 384 } // namespace webrtc |
OLD | NEW |