Index: webrtc/modules/audio_mixer/source/new_audio_conference_mixer_impl.cc |
diff --git a/webrtc/modules/audio_mixer/source/new_audio_conference_mixer_impl.cc b/webrtc/modules/audio_mixer/source/new_audio_conference_mixer_impl.cc |
index 47eac8fff56edb5653a766ef2e345f78de64c64a..3afd9be5caba486eae818e7a3b4a79ddc74f1ef3 100644 |
--- a/webrtc/modules/audio_mixer/source/new_audio_conference_mixer_impl.cc |
+++ b/webrtc/modules/audio_mixer/source/new_audio_conference_mixer_impl.cc |
@@ -19,6 +19,7 @@ |
#include "webrtc/modules/utility/include/audio_frame_operations.h" |
#include "webrtc/system_wrappers/include/critical_section_wrapper.h" |
#include "webrtc/system_wrappers/include/trace.h" |
+#include "webrtc/voice_engine/utility.h" |
namespace webrtc { |
namespace { |
@@ -58,6 +59,16 @@ class SourceFrame { |
bool was_mixed_before_; |
}; |
+// Remixes a frame between stereo and mono. |
+void RemixFrame(AudioFrame* frame, size_t number_of_channels) { |
minyue-webrtc
2016/08/08 15:05:44
why is this call Remix?
aleloi
2016/08/08 15:14:36
IIRC, remixing means changing between mono and ste
|
+ RTC_DCHECK(number_of_channels == 1 || number_of_channels == 2); |
+ if (frame->num_channels_ == 1 && number_of_channels == 2) { |
+ AudioFrameOperations::MonoToStereo(frame); |
+ } else if (frame->num_channels_ == 2 && number_of_channels == 1) { |
+ AudioFrameOperations::StereoToMono(frame); |
+ } |
+} |
+ |
// Mix |frame| into |mixed_frame|, with saturation protection and upmixing. |
// These effects are applied to |frame| itself prior to mixing. Assumes that |
// |mixed_frame| always has at least as many channels as |frame|. Supports |
@@ -71,26 +82,10 @@ void MixFrames(AudioFrame* mixed_frame, AudioFrame* frame, bool use_limiter) { |
// This is only meaningful if the limiter will be used. |
*frame >>= 1; |
} |
- if (mixed_frame->num_channels_ > frame->num_channels_) { |
- // We only support mono-to-stereo. |
- RTC_DCHECK_EQ(mixed_frame->num_channels_, static_cast<size_t>(2)); |
- RTC_DCHECK_EQ(frame->num_channels_, static_cast<size_t>(1)); |
- AudioFrameOperations::MonoToStereo(frame); |
- } |
- |
+ RTC_DCHECK_EQ(frame->num_channels_, mixed_frame->num_channels_); |
*mixed_frame += *frame; |
} |
-// Return the max number of channels from a |list| composed of AudioFrames. |
-size_t MaxNumChannels(const AudioFrameList* list) { |
- size_t max_num_channels = 1; |
- for (AudioFrameList::const_iterator iter = list->begin(); iter != list->end(); |
- ++iter) { |
- max_num_channels = std::max(max_num_channels, (*iter).frame->num_channels_); |
- } |
- return max_num_channels; |
-} |
- |
} // namespace |
MixerAudioSource::MixerAudioSource() : _mixHistory(new NewMixHistory()) {} |
@@ -137,7 +132,6 @@ NewAudioConferenceMixer* NewAudioConferenceMixer::Create(int id) { |
NewAudioConferenceMixerImpl::NewAudioConferenceMixerImpl(int id) |
: _id(id), |
- _minimumMixingFreq(kLowestPossible), |
_outputFrequency(kDefaultFrequency), |
_sampleSize(0), |
audio_source_list_(), |
@@ -189,7 +183,10 @@ bool NewAudioConferenceMixerImpl::Init() { |
return true; |
} |
-void NewAudioConferenceMixerImpl::Mix(AudioFrame* audio_frame_for_mixing) { |
+void NewAudioConferenceMixerImpl::Mix(int sample_rate, |
+ size_t number_of_channels, |
+ AudioFrame* audio_frame_for_mixing) { |
+ RTC_DCHECK(number_of_channels == 1 || number_of_channels == 2); |
size_t remainingAudioSourcesAllowedToMix = kMaximumAmountOfMixedAudioSources; |
RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
AudioFrameList mixList; |
@@ -197,46 +194,28 @@ void NewAudioConferenceMixerImpl::Mix(AudioFrame* audio_frame_for_mixing) { |
std::map<int, MixerAudioSource*> mixedAudioSourcesMap; |
{ |
CriticalSectionScoped cs(_cbCrit.get()); |
- |
- int32_t lowFreq = GetLowestMixingFrequency(); |
- // SILK can run in 12 kHz and 24 kHz. These frequencies are not |
- // supported so use the closest higher frequency to not lose any |
- // information. |
- // TODO(aleloi): this is probably more appropriate to do in |
- // GetLowestMixingFrequency(). |
- if (lowFreq == 12000) { |
- lowFreq = 16000; |
- } else if (lowFreq == 24000) { |
- lowFreq = 32000; |
+ Frequency mixing_frequency; |
+ |
+ switch (sample_rate) { |
+ case 8000: |
+ mixing_frequency = kNbInHz; |
+ break; |
+ case 16000: |
+ mixing_frequency = kWbInHz; |
+ break; |
+ case 32000: |
+ mixing_frequency = kSwbInHz; |
+ break; |
+ case 48000: |
+ mixing_frequency = kFbInHz; |
+ break; |
+ default: |
+ RTC_NOTREACHED(); |
+ return; |
} |
- if (lowFreq <= 0) { |
- return; |
- } else { |
- switch (lowFreq) { |
- case 8000: |
- if (OutputFrequency() != kNbInHz) { |
- SetOutputFrequency(kNbInHz); |
- } |
- break; |
- case 16000: |
- if (OutputFrequency() != kWbInHz) { |
- SetOutputFrequency(kWbInHz); |
- } |
- break; |
- case 32000: |
- if (OutputFrequency() != kSwbInHz) { |
- SetOutputFrequency(kSwbInHz); |
- } |
- break; |
- case 48000: |
- if (OutputFrequency() != kFbInHz) { |
- SetOutputFrequency(kFbInHz); |
- } |
- break; |
- default: |
- RTC_NOTREACHED(); |
- return; |
- } |
+ |
+ if (OutputFrequency() != mixing_frequency) { |
+ SetOutputFrequency(mixing_frequency); |
} |
mixList = UpdateToMix(remainingAudioSourcesAllowedToMix); |
@@ -244,16 +223,16 @@ void NewAudioConferenceMixerImpl::Mix(AudioFrame* audio_frame_for_mixing) { |
GetAdditionalAudio(&additionalFramesList); |
} |
- // TODO(aleloi): it might be better to decide the number of channels |
- // with an API instead of dynamically. |
- |
- // Find the max channels over all mixing lists. |
- const size_t num_mixed_channels = |
- std::max(MaxNumChannels(&mixList), MaxNumChannels(&additionalFramesList)); |
+ for (FrameAndMuteInfo& frame_and_mute : mixList) { |
+ RemixFrame(frame_and_mute.frame, number_of_channels); |
+ } |
+ for (FrameAndMuteInfo& frame_and_mute : additionalFramesList) { |
+ RemixFrame(frame_and_mute.frame, number_of_channels); |
+ } |
audio_frame_for_mixing->UpdateFrame( |
-1, _timeStamp, NULL, 0, _outputFrequency, AudioFrame::kNormalSpeech, |
- AudioFrame::kVadPassive, num_mixed_channels); |
+ AudioFrame::kVadPassive, number_of_channels); |
_timeStamp += static_cast<uint32_t>(_sampleSize); |
@@ -390,59 +369,6 @@ bool NewAudioConferenceMixerImpl::AnonymousMixabilityStatus( |
return IsAudioSourceInList(audio_source, additional_audio_source_list_); |
} |
-int32_t NewAudioConferenceMixerImpl::SetMinimumMixingFrequency(Frequency freq) { |
- // Make sure that only allowed sampling frequencies are used. Use closest |
- // higher sampling frequency to avoid losing information. |
- if (static_cast<int>(freq) == 12000) { |
- freq = kWbInHz; |
- } else if (static_cast<int>(freq) == 24000) { |
- freq = kSwbInHz; |
- } |
- |
- if ((freq == kNbInHz) || (freq == kWbInHz) || (freq == kSwbInHz) || |
- (freq == kLowestPossible)) { |
- _minimumMixingFreq = freq; |
- return 0; |
- } else { |
- WEBRTC_TRACE(kTraceError, kTraceAudioMixerServer, _id, |
- "SetMinimumMixingFrequency incorrect frequency: %i", freq); |
- RTC_NOTREACHED(); |
- return -1; |
- } |
-} |
- |
-// Check all AudioFrames that are to be mixed. The highest sampling frequency |
-// found is the lowest that can be used without losing information. |
-int32_t NewAudioConferenceMixerImpl::GetLowestMixingFrequency() const { |
- const int audioSourceListFrequency = |
- GetLowestMixingFrequencyFromList(audio_source_list_); |
- const int anonymousListFrequency = |
- GetLowestMixingFrequencyFromList(additional_audio_source_list_); |
- const int highestFreq = (audioSourceListFrequency > anonymousListFrequency) |
- ? audioSourceListFrequency |
- : anonymousListFrequency; |
- // Check if the user specified a lowest mixing frequency. |
- if (_minimumMixingFreq != kLowestPossible) { |
- if (_minimumMixingFreq > highestFreq) { |
- return _minimumMixingFreq; |
- } |
- } |
- return highestFreq; |
-} |
- |
-int32_t NewAudioConferenceMixerImpl::GetLowestMixingFrequencyFromList( |
- const MixerAudioSourceList& mixList) const { |
- int32_t highestFreq = 8000; |
- for (MixerAudioSourceList::const_iterator iter = mixList.begin(); |
- iter != mixList.end(); ++iter) { |
- const int32_t neededFrequency = (*iter)->NeededFrequency(_id); |
- if (neededFrequency > highestFreq) { |
- highestFreq = neededFrequency; |
- } |
- } |
- return highestFreq; |
-} |
- |
AudioFrameList NewAudioConferenceMixerImpl::UpdateToMix( |
size_t maxAudioFrameCounter) const { |
AudioFrameList result; |