1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "host/frontend/webrtc/libcommon/audio_device.h"
18
19 #include <string.h>
20
21 #include <android-base/logging.h>
22
23 #include <chrono>
24 #include <thread>
25
26 namespace cuttlefish {
27 namespace webrtc_streaming {
28
CfAudioDeviceModule()29 CfAudioDeviceModule::CfAudioDeviceModule() {}
30
GetMoreAudioData(void * data,int bytes_per_sample,int samples_per_channel,int num_channels,int sample_rate,bool & muted)31 int CfAudioDeviceModule::GetMoreAudioData(void* data, int bytes_per_sample,
32 int samples_per_channel,
33 int num_channels, int sample_rate,
34 bool& muted) {
35 muted = !playing_ || !audio_callback_;
36 if (muted) {
37 return 0;
38 }
39
40 size_t read_samples;
41 int64_t elapsed_time;
42 int64_t ntp_time_ms;
43 auto res = audio_callback_->NeedMorePlayData(
44 samples_per_channel, bytes_per_sample, num_channels, sample_rate, data,
45 read_samples, &elapsed_time, &ntp_time_ms);
46 if (res != 0) {
47 return res;
48 }
49 return read_samples / num_channels;
50 }
51
52 // Retrieve the currently utilized audio layer
ActiveAudioLayer(AudioLayer * audioLayer) const53 int32_t CfAudioDeviceModule::ActiveAudioLayer(AudioLayer* audioLayer) const {
54 return -1;
55 }
56
57 // Full-duplex transportation of PCM audio
RegisterAudioCallback(webrtc::AudioTransport * audio_callback)58 int32_t CfAudioDeviceModule::RegisterAudioCallback(
59 webrtc::AudioTransport* audio_callback) {
60 audio_callback_ = audio_callback;
61 return 0;
62 }
63
64 // Main initialization and termination
Init()65 int32_t CfAudioDeviceModule::Init() { return 0; }
Terminate()66 int32_t CfAudioDeviceModule::Terminate() { return 0; }
Initialized() const67 bool CfAudioDeviceModule::Initialized() const { return true; }
68
69 // Device enumeration
PlayoutDevices()70 int16_t CfAudioDeviceModule::PlayoutDevices() { return 1; }
RecordingDevices()71 int16_t CfAudioDeviceModule::RecordingDevices() { return 1; }
PlayoutDeviceName(uint16_t index,char name[webrtc::kAdmMaxDeviceNameSize],char guid[webrtc::kAdmMaxGuidSize])72 int32_t CfAudioDeviceModule::PlayoutDeviceName(
73 uint16_t index, char name[webrtc::kAdmMaxDeviceNameSize],
74 char guid[webrtc::kAdmMaxGuidSize]) {
75 if (index != 0) {
76 return -1;
77 }
78 constexpr auto device_name = "Cuttlefish Webrtc Audio";
79 constexpr auto device_guid = "Cuttlefish Webrtc Audio Device Id";
80 strncpy(name, device_name, webrtc::kAdmMaxDeviceNameSize);
81 name[webrtc::kAdmMaxDeviceNameSize - 1] = '\0';
82 strncpy(guid, device_guid, webrtc::kAdmMaxGuidSize);
83 guid[webrtc::kAdmMaxGuidSize - 1] = '\0';
84 return 0;
85 }
RecordingDeviceName(uint16_t index,char name[webrtc::kAdmMaxDeviceNameSize],char guid[webrtc::kAdmMaxGuidSize])86 int32_t CfAudioDeviceModule::RecordingDeviceName(
87 uint16_t index, char name[webrtc::kAdmMaxDeviceNameSize],
88 char guid[webrtc::kAdmMaxGuidSize]) {
89 if (index != 0) {
90 return -1;
91 }
92 constexpr auto device_name = "Cuttlefish Webrtc Audio";
93 constexpr auto device_guid = "Cuttlefish Webrtc Audio Device Id";
94 strncpy(name, device_name, webrtc::kAdmMaxDeviceNameSize);
95 name[webrtc::kAdmMaxDeviceNameSize - 1] = '\0';
96 strncpy(guid, device_guid, webrtc::kAdmMaxGuidSize);
97 guid[webrtc::kAdmMaxGuidSize - 1] = '\0';
98 return 0;
99 }
100
101 // Device selection
SetPlayoutDevice(uint16_t index)102 int32_t CfAudioDeviceModule::SetPlayoutDevice(uint16_t index) { return 0; }
SetPlayoutDevice(WindowsDeviceType device)103 int32_t CfAudioDeviceModule::SetPlayoutDevice(WindowsDeviceType device) {
104 return -1;
105 }
SetRecordingDevice(uint16_t index)106 int32_t CfAudioDeviceModule::SetRecordingDevice(uint16_t index) { return 0; }
SetRecordingDevice(WindowsDeviceType device)107 int32_t CfAudioDeviceModule::SetRecordingDevice(WindowsDeviceType device) {
108 return -1;
109 }
110
111 // Audio transport initialization
PlayoutIsAvailable(bool * available)112 int32_t CfAudioDeviceModule::PlayoutIsAvailable(bool* available) {
113 *available = true;
114 return 0;
115 }
InitPlayout()116 int32_t CfAudioDeviceModule::InitPlayout() { return 0; }
PlayoutIsInitialized() const117 bool CfAudioDeviceModule::PlayoutIsInitialized() const { return true; }
RecordingIsAvailable(bool * available)118 int32_t CfAudioDeviceModule::RecordingIsAvailable(bool* available) {
119 *available = 0;
120 return 0;
121 }
InitRecording()122 int32_t CfAudioDeviceModule::InitRecording() { return 0; }
RecordingIsInitialized() const123 bool CfAudioDeviceModule::RecordingIsInitialized() const { return true; }
124
125 // Audio transport control
StartPlayout()126 int32_t CfAudioDeviceModule::StartPlayout() {
127 playing_ = true;
128 return 0;
129 }
StopPlayout()130 int32_t CfAudioDeviceModule::StopPlayout() {
131 playing_ = false;
132 return 0;
133 }
Playing() const134 bool CfAudioDeviceModule::Playing() const { return playing_; }
StartRecording()135 int32_t CfAudioDeviceModule::StartRecording() {
136 recording_ = true;
137 return 0;
138 }
StopRecording()139 int32_t CfAudioDeviceModule::StopRecording() {
140 recording_ = false;
141 return 0;
142 }
Recording() const143 bool CfAudioDeviceModule::Recording() const { return recording_; }
144
145 // Audio mixer initialization
InitSpeaker()146 int32_t CfAudioDeviceModule::InitSpeaker() { return -1; }
SpeakerIsInitialized() const147 bool CfAudioDeviceModule::SpeakerIsInitialized() const { return false; }
InitMicrophone()148 int32_t CfAudioDeviceModule::InitMicrophone() { return 0; }
MicrophoneIsInitialized() const149 bool CfAudioDeviceModule::MicrophoneIsInitialized() const { return true; }
150
151 // Speaker volume controls
SpeakerVolumeIsAvailable(bool * available)152 int32_t CfAudioDeviceModule::SpeakerVolumeIsAvailable(bool* available) {
153 *available = false;
154 return 0;
155 }
SetSpeakerVolume(uint32_t volume)156 int32_t CfAudioDeviceModule::SetSpeakerVolume(uint32_t volume) { return -1; }
SpeakerVolume(uint32_t * volume) const157 int32_t CfAudioDeviceModule::SpeakerVolume(uint32_t* volume) const {
158 return -1;
159 }
MaxSpeakerVolume(uint32_t * maxVolume) const160 int32_t CfAudioDeviceModule::MaxSpeakerVolume(uint32_t* maxVolume) const {
161 return -1;
162 }
MinSpeakerVolume(uint32_t * minVolume) const163 int32_t CfAudioDeviceModule::MinSpeakerVolume(uint32_t* minVolume) const {
164 return -1;
165 }
166
167 // Microphone volume controls
MicrophoneVolumeIsAvailable(bool * available)168 int32_t CfAudioDeviceModule::MicrophoneVolumeIsAvailable(bool* available) {
169 *available = false;
170 return 0;
171 }
SetMicrophoneVolume(uint32_t volume)172 int32_t CfAudioDeviceModule::SetMicrophoneVolume(uint32_t volume) { return -1; }
MicrophoneVolume(uint32_t * volume) const173 int32_t CfAudioDeviceModule::MicrophoneVolume(uint32_t* volume) const {
174 return -1;
175 }
MaxMicrophoneVolume(uint32_t * maxVolume) const176 int32_t CfAudioDeviceModule::MaxMicrophoneVolume(uint32_t* maxVolume) const {
177 return -1;
178 }
MinMicrophoneVolume(uint32_t * minVolume) const179 int32_t CfAudioDeviceModule::MinMicrophoneVolume(uint32_t* minVolume) const {
180 return -1;
181 }
182
183 // Speaker mute control
SpeakerMuteIsAvailable(bool * available)184 int32_t CfAudioDeviceModule::SpeakerMuteIsAvailable(bool* available) {
185 *available = false;
186 return 0;
187 }
SetSpeakerMute(bool enable)188 int32_t CfAudioDeviceModule::SetSpeakerMute(bool enable) { return -1; }
SpeakerMute(bool * enabled) const189 int32_t CfAudioDeviceModule::SpeakerMute(bool* enabled) const { return -1; }
190
191 // Microphone mute control
MicrophoneMuteIsAvailable(bool * available)192 int32_t CfAudioDeviceModule::MicrophoneMuteIsAvailable(bool* available) {
193 *available = false;
194 return 0;
195 }
SetMicrophoneMute(bool enable)196 int32_t CfAudioDeviceModule::SetMicrophoneMute(bool enable) { return -1; }
MicrophoneMute(bool * enabled) const197 int32_t CfAudioDeviceModule::MicrophoneMute(bool* enabled) const { return -1; }
198
199 // Stereo support
StereoPlayoutIsAvailable(bool * available) const200 int32_t CfAudioDeviceModule::StereoPlayoutIsAvailable(bool* available) const {
201 *available = true;
202 return 0;
203 }
SetStereoPlayout(bool enable)204 int32_t CfAudioDeviceModule::SetStereoPlayout(bool enable) {
205 stereo_playout_enabled_ = enable;
206 return 0;
207 }
StereoPlayout(bool * enabled) const208 int32_t CfAudioDeviceModule::StereoPlayout(bool* enabled) const {
209 *enabled = stereo_playout_enabled_;
210 return 0;
211 }
StereoRecordingIsAvailable(bool * available) const212 int32_t CfAudioDeviceModule::StereoRecordingIsAvailable(bool* available) const {
213 *available = true;
214 return 0;
215 }
SetStereoRecording(bool enable)216 int32_t CfAudioDeviceModule::SetStereoRecording(bool enable) {
217 stereo_recording_enabled_ = enable;
218 return 0;
219 }
StereoRecording(bool * enabled) const220 int32_t CfAudioDeviceModule::StereoRecording(bool* enabled) const {
221 *enabled = stereo_recording_enabled_;
222 return 0;
223 }
224
225 // Playout delay
PlayoutDelay(uint16_t * delayMS) const226 int32_t CfAudioDeviceModule::PlayoutDelay(uint16_t* delayMS) const {
227 // There is currently no way to estimate the real delay for thiese streams.
228 // Given that 10ms buffers are used almost everywhere in the pipeline we know
229 // the delay is at least 10ms, so that's the best guess here.
230 *delayMS = 10;
231 return 0;
232 }
233
234 // Only supported on Android.
BuiltInAECIsAvailable() const235 bool CfAudioDeviceModule::BuiltInAECIsAvailable() const { return false; }
BuiltInAGCIsAvailable() const236 bool CfAudioDeviceModule::BuiltInAGCIsAvailable() const { return false; }
BuiltInNSIsAvailable() const237 bool CfAudioDeviceModule::BuiltInNSIsAvailable() const { return false; }
238
239 // Enables the built-in audio effects. Only supported on Android.
EnableBuiltInAEC(bool enable)240 int32_t CfAudioDeviceModule::EnableBuiltInAEC(bool enable) { return -1; }
EnableBuiltInAGC(bool enable)241 int32_t CfAudioDeviceModule::EnableBuiltInAGC(bool enable) { return -1; }
EnableBuiltInNS(bool enable)242 int32_t CfAudioDeviceModule::EnableBuiltInNS(bool enable) { return -1; }
243
GetPlayoutUnderrunCount() const244 int32_t CfAudioDeviceModule::GetPlayoutUnderrunCount() const { return -1; }
245
246 } // namespace webrtc_streaming
247 } // namespace cuttlefish
248