summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/webrtc/audio/audio_state.cc
blob: 5a30c53b3d63364b9bbbbb5ccc1c9d97395e9e91 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
 *  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/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);
}

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) {
  RTC_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_);
  }
  voe->Release();
}

void AudioState::SetRecording(bool enabled) {
  RTC_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);
  voe->Release();
}

// 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