blob: 5a30c53b3d63364b9bbbbb5ccc1c9d97395e9e91 [file] [log] [blame]
solenberg566ef242015-11-06 15:34:49 -08001/*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "audio/audio_state.h"
solenberg566ef242015-11-06 15:34:49 -080012
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "modules/audio_device/include/audio_device.h"
14#include "rtc_base/atomicops.h"
15#include "rtc_base/checks.h"
16#include "rtc_base/logging.h"
henrika5f6bf242017-11-01 11:06:56 +010017#include "rtc_base/ptr_util.h"
18#include "rtc_base/thread.h"
solenbergfc3a2e32017-09-26 09:35:01 -070019#include "voice_engine/transmit_mixer.h"
solenberg566ef242015-11-06 15:34:49 -080020
21namespace webrtc {
22namespace internal {
23
24AudioState::AudioState(const AudioState::Config& config)
aleloidd310712016-11-17 06:28:59 -080025 : config_(config),
26 voe_base_(config.voice_engine),
27 audio_transport_proxy_(voe_base_->audio_transport(),
peahe67bedb2017-07-07 04:25:11 -070028 config_.audio_processing.get(),
aleloidd310712016-11-17 06:28:59 -080029 config_.audio_mixer) {
solenberg566ef242015-11-06 15:34:49 -080030 process_thread_checker_.DetachFromThread();
aleloi10111bc2016-11-17 06:48:48 -080031 RTC_DCHECK(config_.audio_mixer);
solenberg566ef242015-11-06 15:34:49 -080032}
33
34AudioState::~AudioState() {
35 RTC_DCHECK(thread_checker_.CalledOnValidThread());
solenberg566ef242015-11-06 15:34:49 -080036}
37
38VoiceEngine* AudioState::voice_engine() {
39 RTC_DCHECK(thread_checker_.CalledOnValidThread());
40 return config_.voice_engine;
41}
42
aleloidd310712016-11-17 06:28:59 -080043rtc::scoped_refptr<AudioMixer> AudioState::mixer() {
aleloi10111bc2016-11-17 06:48:48 -080044 RTC_DCHECK(thread_checker_.CalledOnValidThread());
aleloidd310712016-11-17 06:28:59 -080045 return config_.audio_mixer;
46}
47
solenberg566ef242015-11-06 15:34:49 -080048bool AudioState::typing_noise_detected() const {
49 RTC_DCHECK(thread_checker_.CalledOnValidThread());
solenbergfc3a2e32017-09-26 09:35:01 -070050 // TODO(solenberg): Remove const_cast once AudioState owns transmit mixer
51 // functionality.
52 voe::TransmitMixer* transmit_mixer =
53 const_cast<AudioState*>(this)->voe_base_->transmit_mixer();
54 return transmit_mixer->typing_noise_detected();
solenberg566ef242015-11-06 15:34:49 -080055}
56
henrika5f6bf242017-11-01 11:06:56 +010057void AudioState::SetPlayout(bool enabled) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010058 RTC_LOG(INFO) << "SetPlayout(" << enabled << ")";
henrika5f6bf242017-11-01 11:06:56 +010059 RTC_DCHECK(thread_checker_.CalledOnValidThread());
60 const bool currently_enabled = (null_audio_poller_ == nullptr);
61 if (enabled == currently_enabled) {
62 return;
63 }
64 VoEBase* const voe = VoEBase::GetInterface(voice_engine());
65 RTC_DCHECK(voe);
66 if (enabled) {
67 null_audio_poller_.reset();
68 }
69 // Will stop/start playout of the underlying device, if necessary, and
70 // remember the setting for when it receives subsequent calls of
71 // StartPlayout.
72 voe->SetPlayout(enabled);
73 if (!enabled) {
74 null_audio_poller_ =
75 rtc::MakeUnique<NullAudioPoller>(&audio_transport_proxy_);
76 }
henrika6d852522017-11-09 16:37:41 +010077 voe->Release();
henrika5f6bf242017-11-01 11:06:56 +010078}
79
80void AudioState::SetRecording(bool enabled) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010081 RTC_LOG(INFO) << "SetRecording(" << enabled << ")";
henrika5f6bf242017-11-01 11:06:56 +010082 RTC_DCHECK(thread_checker_.CalledOnValidThread());
83 // TODO(henrika): keep track of state as in SetPlayout().
84 VoEBase* const voe = VoEBase::GetInterface(voice_engine());
85 RTC_DCHECK(voe);
86 // Will stop/start recording of the underlying device, if necessary, and
87 // remember the setting for when it receives subsequent calls of
88 // StartPlayout.
89 voe->SetRecording(enabled);
henrika6d852522017-11-09 16:37:41 +010090 voe->Release();
henrika5f6bf242017-11-01 11:06:56 +010091}
92
solenberg566ef242015-11-06 15:34:49 -080093// Reference count; implementation copied from rtc::RefCountedObject.
Niels Möller6f72f562017-10-19 13:15:17 +020094void AudioState::AddRef() const {
95 rtc::AtomicOps::Increment(&ref_count_);
solenberg566ef242015-11-06 15:34:49 -080096}
97
98// Reference count; implementation copied from rtc::RefCountedObject.
Niels Möller6f72f562017-10-19 13:15:17 +020099rtc::RefCountReleaseStatus AudioState::Release() const {
100 if (rtc::AtomicOps::Decrement(&ref_count_) == 0) {
solenberg566ef242015-11-06 15:34:49 -0800101 delete this;
Niels Möller6f72f562017-10-19 13:15:17 +0200102 return rtc::RefCountReleaseStatus::kDroppedLastRef;
solenberg566ef242015-11-06 15:34:49 -0800103 }
Niels Möller6f72f562017-10-19 13:15:17 +0200104 return rtc::RefCountReleaseStatus::kOtherRefsRemained;
solenberg566ef242015-11-06 15:34:49 -0800105}
solenberg566ef242015-11-06 15:34:49 -0800106} // namespace internal
107
108rtc::scoped_refptr<AudioState> AudioState::Create(
109 const AudioState::Config& config) {
110 return rtc::scoped_refptr<AudioState>(new internal::AudioState(config));
111}
112} // namespace webrtc