(this CL is based on the work by Taylor and Steve in https://webrtc-review.googlesource.com/c/src/+/10201) This SetAudioPlayout method lets applications disable audio playout while still processing incoming audio data and generating statistics on the received audio. This may be useful if the application wants to set up media flows as soon as possible, but isn't ready to play audio yet. Currently, native applications don't have any API point to control this, unless they completely implement their own AudioDeviceModule. The SetAudioRecording works in a similar fashion but for the recorded audio. One difference is that calling SetAudioRecording(false) does not keep any audio processing alive. TBR=solenberg Bug: webrtc:7313 Change-Id: I0aa075f6bfef9818f1080f85a8ff7842fb0750aa Reviewed-on: https://webrtc-review.googlesource.com/16180 Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Commit-Queue: Henrik Andreassson <henrika@webrtc.org> Cr-Commit-Position: refs/heads/master@{#20499}
119 lines
3.9 KiB
C++
119 lines
3.9 KiB
C++
/*
|
|
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "audio/audio_state.h"
|
|
|
|
#include "modules/audio_device/include/audio_device.h"
|
|
#include "rtc_base/atomicops.h"
|
|
#include "rtc_base/bind.h"
|
|
#include "rtc_base/checks.h"
|
|
#include "rtc_base/logging.h"
|
|
#include "rtc_base/ptr_util.h"
|
|
#include "rtc_base/thread.h"
|
|
#include "voice_engine/transmit_mixer.h"
|
|
|
|
namespace webrtc {
|
|
namespace internal {
|
|
|
|
AudioState::AudioState(const AudioState::Config& config)
|
|
: config_(config),
|
|
voe_base_(config.voice_engine),
|
|
audio_transport_proxy_(voe_base_->audio_transport(),
|
|
config_.audio_processing.get(),
|
|
config_.audio_mixer) {
|
|
process_thread_checker_.DetachFromThread();
|
|
RTC_DCHECK(config_.audio_mixer);
|
|
|
|
auto* const device = voe_base_->audio_device_module();
|
|
RTC_DCHECK(device);
|
|
|
|
// This is needed for the Chrome implementation of RegisterAudioCallback.
|
|
device->RegisterAudioCallback(nullptr);
|
|
device->RegisterAudioCallback(&audio_transport_proxy_);
|
|
}
|
|
|
|
AudioState::~AudioState() {
|
|
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
|
}
|
|
|
|
VoiceEngine* AudioState::voice_engine() {
|
|
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
|
return config_.voice_engine;
|
|
}
|
|
|
|
rtc::scoped_refptr<AudioMixer> AudioState::mixer() {
|
|
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
|
return config_.audio_mixer;
|
|
}
|
|
|
|
bool AudioState::typing_noise_detected() const {
|
|
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
|
// TODO(solenberg): Remove const_cast once AudioState owns transmit mixer
|
|
// functionality.
|
|
voe::TransmitMixer* transmit_mixer =
|
|
const_cast<AudioState*>(this)->voe_base_->transmit_mixer();
|
|
return transmit_mixer->typing_noise_detected();
|
|
}
|
|
|
|
void AudioState::SetPlayout(bool enabled) {
|
|
LOG(INFO) << "SetPlayout(" << enabled << ")";
|
|
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
|
const bool currently_enabled = (null_audio_poller_ == nullptr);
|
|
if (enabled == currently_enabled) {
|
|
return;
|
|
}
|
|
VoEBase* const voe = VoEBase::GetInterface(voice_engine());
|
|
RTC_DCHECK(voe);
|
|
if (enabled) {
|
|
null_audio_poller_.reset();
|
|
}
|
|
// Will stop/start playout of the underlying device, if necessary, and
|
|
// remember the setting for when it receives subsequent calls of
|
|
// StartPlayout.
|
|
voe->SetPlayout(enabled);
|
|
if (!enabled) {
|
|
null_audio_poller_ =
|
|
rtc::MakeUnique<NullAudioPoller>(&audio_transport_proxy_);
|
|
}
|
|
}
|
|
|
|
void AudioState::SetRecording(bool enabled) {
|
|
LOG(INFO) << "SetRecording(" << enabled << ")";
|
|
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
|
// TODO(henrika): keep track of state as in SetPlayout().
|
|
VoEBase* const voe = VoEBase::GetInterface(voice_engine());
|
|
RTC_DCHECK(voe);
|
|
// Will stop/start recording of the underlying device, if necessary, and
|
|
// remember the setting for when it receives subsequent calls of
|
|
// StartPlayout.
|
|
voe->SetRecording(enabled);
|
|
}
|
|
|
|
// Reference count; implementation copied from rtc::RefCountedObject.
|
|
void AudioState::AddRef() const {
|
|
rtc::AtomicOps::Increment(&ref_count_);
|
|
}
|
|
|
|
// Reference count; implementation copied from rtc::RefCountedObject.
|
|
rtc::RefCountReleaseStatus AudioState::Release() const {
|
|
if (rtc::AtomicOps::Decrement(&ref_count_) == 0) {
|
|
delete this;
|
|
return rtc::RefCountReleaseStatus::kDroppedLastRef;
|
|
}
|
|
return rtc::RefCountReleaseStatus::kOtherRefsRemained;
|
|
}
|
|
} // namespace internal
|
|
|
|
rtc::scoped_refptr<AudioState> AudioState::Create(
|
|
const AudioState::Config& config) {
|
|
return rtc::scoped_refptr<AudioState>(new internal::AudioState(config));
|
|
}
|
|
} // namespace webrtc
|