// stereo at most.
//
// TODO(andrew): consider not modifying |frame| here.
-void MixFrames(AudioFrame* mixed_frame, AudioFrame* frame) {
+void MixFrames(AudioFrame* mixed_frame, AudioFrame* frame, bool use_limiter) {
assert(mixed_frame->num_channels_ >= frame->num_channels_);
- // Divide by two to avoid saturation in the mixing.
- *frame >>= 1;
+ if (use_limiter) {
+ // Divide by two to avoid saturation in the mixing.
+ // 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.
assert(mixed_frame->num_channels_ == 2 &&
_participantList(),
_additionalParticipantList(),
_numMixedParticipants(0),
+ use_limiter_(true),
_timeStamp(0),
_timeScheduler(kProcessPeriodicityInMs),
_mixedAudioLevel(),
_timeStamp += _sampleSize;
+ // We only use the limiter if it supports the output sample rate and
+ // we're actually mixing multiple streams.
+ use_limiter_ = _numMixedParticipants > 1 &&
+ _outputFrequency <= kAudioProcMaxNativeSampleRateHz;
+
MixFromList(*mixedAudio, &mixList);
MixAnonomouslyFromList(*mixedAudio, &additionalFramesList);
MixAnonomouslyFromList(*mixedAudio, &rampOutList);
if(audioFrameList->empty()) return 0;
uint32_t position = 0;
- if(_numMixedParticipants == 1) {
- // No mixing required here; skip the saturation protection.
- AudioFrame* audioFrame = audioFrameList->front();
- mixedAudio.CopyFrom(*audioFrame);
- SetParticipantStatistics(&_scratchMixedParticipants[position],
- *audioFrame);
- return 0;
- }
- if (audioFrameList->size() == 1) {
+ if (_numMixedParticipants == 1) {
mixedAudio.timestamp_ = audioFrameList->front()->timestamp_;
mixedAudio.elapsed_time_ms_ = audioFrameList->front()->elapsed_time_ms_;
} else {
assert(false);
position = 0;
}
- MixFrames(&mixedAudio, (*iter));
+ MixFrames(&mixedAudio, (*iter), use_limiter_);
SetParticipantStatistics(&_scratchMixedParticipants[position],
**iter);
if(audioFrameList->empty()) return 0;
- if(_numMixedParticipants == 1) {
- // No mixing required here; skip the saturation protection.
- AudioFrame* audioFrame = audioFrameList->front();
- mixedAudio.CopyFrom(*audioFrame);
- return 0;
- }
-
for (AudioFrameList::const_iterator iter = audioFrameList->begin();
iter != audioFrameList->end();
++iter) {
- MixFrames(&mixedAudio, *iter);
+ MixFrames(&mixedAudio, *iter, use_limiter_);
}
return 0;
}
bool AudioConferenceMixerImpl::LimitMixedAudio(AudioFrame& mixedAudio) {
- if(_numMixedParticipants == 1) {
- return true;
+ if (!use_limiter_) {
+ return true;
}
// Smoothly limit the mixed frame.