1 /* 2 * Copyright (c) 2013 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 11 #ifndef MODULES_AUDIO_DEVICE_ANDROID_AUDIO_DEVICE_TEMPLATE_H_ 12 #define MODULES_AUDIO_DEVICE_ANDROID_AUDIO_DEVICE_TEMPLATE_H_ 13 14 #include "api/sequence_checker.h" 15 #include "modules/audio_device/android/audio_manager.h" 16 #include "modules/audio_device/audio_device_generic.h" 17 #include "rtc_base/checks.h" 18 #include "rtc_base/logging.h" 19 20 namespace webrtc { 21 22 // InputType/OutputType can be any class that implements the capturing/rendering 23 // part of the AudioDeviceGeneric API. 24 // Construction and destruction must be done on one and the same thread. Each 25 // internal implementation of InputType and OutputType will RTC_DCHECK if that 26 // is not the case. All implemented methods must also be called on the same 27 // thread. See comments in each InputType/OutputType class for more info. 28 // It is possible to call the two static methods (SetAndroidAudioDeviceObjects 29 // and ClearAndroidAudioDeviceObjects) from a different thread but both will 30 // RTC_CHECK that the calling thread is attached to a Java VM. 31 32 template <class InputType, class OutputType> 33 class AudioDeviceTemplate : public AudioDeviceGeneric { 34 public: AudioDeviceTemplate(AudioDeviceModule::AudioLayer audio_layer,AudioManager * audio_manager)35 AudioDeviceTemplate(AudioDeviceModule::AudioLayer audio_layer, 36 AudioManager* audio_manager) 37 : audio_layer_(audio_layer), 38 audio_manager_(audio_manager), 39 output_(audio_manager_), 40 input_(audio_manager_), 41 initialized_(false) { 42 RTC_DLOG(LS_INFO) << __FUNCTION__; 43 RTC_CHECK(audio_manager); 44 audio_manager_->SetActiveAudioLayer(audio_layer); 45 } 46 ~AudioDeviceTemplate()47 virtual ~AudioDeviceTemplate() { RTC_LOG(LS_INFO) << __FUNCTION__; } 48 ActiveAudioLayer(AudioDeviceModule::AudioLayer & audioLayer)49 int32_t ActiveAudioLayer( 50 AudioDeviceModule::AudioLayer& audioLayer) const override { 51 RTC_DLOG(LS_INFO) << __FUNCTION__; 52 audioLayer = audio_layer_; 53 return 0; 54 } 55 Init()56 InitStatus Init() override { 57 RTC_DLOG(LS_INFO) << __FUNCTION__; 58 RTC_DCHECK(thread_checker_.IsCurrent()); 59 RTC_DCHECK(!initialized_); 60 if (!audio_manager_->Init()) { 61 return InitStatus::OTHER_ERROR; 62 } 63 if (output_.Init() != 0) { 64 audio_manager_->Close(); 65 return InitStatus::PLAYOUT_ERROR; 66 } 67 if (input_.Init() != 0) { 68 output_.Terminate(); 69 audio_manager_->Close(); 70 return InitStatus::RECORDING_ERROR; 71 } 72 initialized_ = true; 73 return InitStatus::OK; 74 } 75 Terminate()76 int32_t Terminate() override { 77 RTC_DLOG(LS_INFO) << __FUNCTION__; 78 RTC_DCHECK(thread_checker_.IsCurrent()); 79 int32_t err = input_.Terminate(); 80 err |= output_.Terminate(); 81 err |= !audio_manager_->Close(); 82 initialized_ = false; 83 RTC_DCHECK_EQ(err, 0); 84 return err; 85 } 86 Initialized()87 bool Initialized() const override { 88 RTC_DLOG(LS_INFO) << __FUNCTION__; 89 RTC_DCHECK(thread_checker_.IsCurrent()); 90 return initialized_; 91 } 92 PlayoutDevices()93 int16_t PlayoutDevices() override { 94 RTC_DLOG(LS_INFO) << __FUNCTION__; 95 return 1; 96 } 97 RecordingDevices()98 int16_t RecordingDevices() override { 99 RTC_DLOG(LS_INFO) << __FUNCTION__; 100 return 1; 101 } 102 PlayoutDeviceName(uint16_t index,char name[kAdmMaxDeviceNameSize],char guid[kAdmMaxGuidSize])103 int32_t PlayoutDeviceName(uint16_t index, 104 char name[kAdmMaxDeviceNameSize], 105 char guid[kAdmMaxGuidSize]) override { 106 RTC_CHECK_NOTREACHED(); 107 } 108 RecordingDeviceName(uint16_t index,char name[kAdmMaxDeviceNameSize],char guid[kAdmMaxGuidSize])109 int32_t RecordingDeviceName(uint16_t index, 110 char name[kAdmMaxDeviceNameSize], 111 char guid[kAdmMaxGuidSize]) override { 112 RTC_CHECK_NOTREACHED(); 113 } 114 SetPlayoutDevice(uint16_t index)115 int32_t SetPlayoutDevice(uint16_t index) override { 116 // OK to use but it has no effect currently since device selection is 117 // done using Andoid APIs instead. 118 RTC_DLOG(LS_INFO) << __FUNCTION__; 119 return 0; 120 } 121 SetPlayoutDevice(AudioDeviceModule::WindowsDeviceType device)122 int32_t SetPlayoutDevice( 123 AudioDeviceModule::WindowsDeviceType device) override { 124 RTC_CHECK_NOTREACHED(); 125 } 126 SetRecordingDevice(uint16_t index)127 int32_t SetRecordingDevice(uint16_t index) override { 128 // OK to use but it has no effect currently since device selection is 129 // done using Andoid APIs instead. 130 RTC_DLOG(LS_INFO) << __FUNCTION__; 131 return 0; 132 } 133 SetRecordingDevice(AudioDeviceModule::WindowsDeviceType device)134 int32_t SetRecordingDevice( 135 AudioDeviceModule::WindowsDeviceType device) override { 136 RTC_CHECK_NOTREACHED(); 137 } 138 PlayoutIsAvailable(bool & available)139 int32_t PlayoutIsAvailable(bool& available) override { 140 RTC_DLOG(LS_INFO) << __FUNCTION__; 141 available = true; 142 return 0; 143 } 144 InitPlayout()145 int32_t InitPlayout() override { 146 RTC_DLOG(LS_INFO) << __FUNCTION__; 147 return output_.InitPlayout(); 148 } 149 PlayoutIsInitialized()150 bool PlayoutIsInitialized() const override { 151 RTC_DLOG(LS_INFO) << __FUNCTION__; 152 return output_.PlayoutIsInitialized(); 153 } 154 RecordingIsAvailable(bool & available)155 int32_t RecordingIsAvailable(bool& available) override { 156 RTC_DLOG(LS_INFO) << __FUNCTION__; 157 available = true; 158 return 0; 159 } 160 InitRecording()161 int32_t InitRecording() override { 162 RTC_DLOG(LS_INFO) << __FUNCTION__; 163 return input_.InitRecording(); 164 } 165 RecordingIsInitialized()166 bool RecordingIsInitialized() const override { 167 RTC_DLOG(LS_INFO) << __FUNCTION__; 168 return input_.RecordingIsInitialized(); 169 } 170 StartPlayout()171 int32_t StartPlayout() override { 172 RTC_DLOG(LS_INFO) << __FUNCTION__; 173 if (!audio_manager_->IsCommunicationModeEnabled()) { 174 RTC_LOG(LS_WARNING) 175 << "The application should use MODE_IN_COMMUNICATION audio mode!"; 176 } 177 return output_.StartPlayout(); 178 } 179 StopPlayout()180 int32_t StopPlayout() override { 181 // Avoid using audio manger (JNI/Java cost) if playout was inactive. 182 if (!Playing()) 183 return 0; 184 RTC_DLOG(LS_INFO) << __FUNCTION__; 185 int32_t err = output_.StopPlayout(); 186 return err; 187 } 188 Playing()189 bool Playing() const override { 190 RTC_LOG(LS_INFO) << __FUNCTION__; 191 return output_.Playing(); 192 } 193 StartRecording()194 int32_t StartRecording() override { 195 RTC_DLOG(LS_INFO) << __FUNCTION__; 196 if (!audio_manager_->IsCommunicationModeEnabled()) { 197 RTC_LOG(LS_WARNING) 198 << "The application should use MODE_IN_COMMUNICATION audio mode!"; 199 } 200 return input_.StartRecording(); 201 } 202 StopRecording()203 int32_t StopRecording() override { 204 // Avoid using audio manger (JNI/Java cost) if recording was inactive. 205 RTC_DLOG(LS_INFO) << __FUNCTION__; 206 if (!Recording()) 207 return 0; 208 int32_t err = input_.StopRecording(); 209 return err; 210 } 211 Recording()212 bool Recording() const override { return input_.Recording(); } 213 InitSpeaker()214 int32_t InitSpeaker() override { 215 RTC_DLOG(LS_INFO) << __FUNCTION__; 216 return 0; 217 } 218 SpeakerIsInitialized()219 bool SpeakerIsInitialized() const override { 220 RTC_DLOG(LS_INFO) << __FUNCTION__; 221 return true; 222 } 223 InitMicrophone()224 int32_t InitMicrophone() override { 225 RTC_DLOG(LS_INFO) << __FUNCTION__; 226 return 0; 227 } 228 MicrophoneIsInitialized()229 bool MicrophoneIsInitialized() const override { 230 RTC_DLOG(LS_INFO) << __FUNCTION__; 231 return true; 232 } 233 SpeakerVolumeIsAvailable(bool & available)234 int32_t SpeakerVolumeIsAvailable(bool& available) override { 235 RTC_DLOG(LS_INFO) << __FUNCTION__; 236 return output_.SpeakerVolumeIsAvailable(available); 237 } 238 SetSpeakerVolume(uint32_t volume)239 int32_t SetSpeakerVolume(uint32_t volume) override { 240 RTC_DLOG(LS_INFO) << __FUNCTION__; 241 return output_.SetSpeakerVolume(volume); 242 } 243 SpeakerVolume(uint32_t & volume)244 int32_t SpeakerVolume(uint32_t& volume) const override { 245 RTC_DLOG(LS_INFO) << __FUNCTION__; 246 return output_.SpeakerVolume(volume); 247 } 248 MaxSpeakerVolume(uint32_t & maxVolume)249 int32_t MaxSpeakerVolume(uint32_t& maxVolume) const override { 250 RTC_DLOG(LS_INFO) << __FUNCTION__; 251 return output_.MaxSpeakerVolume(maxVolume); 252 } 253 MinSpeakerVolume(uint32_t & minVolume)254 int32_t MinSpeakerVolume(uint32_t& minVolume) const override { 255 RTC_DLOG(LS_INFO) << __FUNCTION__; 256 return output_.MinSpeakerVolume(minVolume); 257 } 258 MicrophoneVolumeIsAvailable(bool & available)259 int32_t MicrophoneVolumeIsAvailable(bool& available) override { 260 available = false; 261 return -1; 262 } 263 SetMicrophoneVolume(uint32_t volume)264 int32_t SetMicrophoneVolume(uint32_t volume) override { 265 RTC_CHECK_NOTREACHED(); 266 } 267 MicrophoneVolume(uint32_t & volume)268 int32_t MicrophoneVolume(uint32_t& volume) const override { 269 RTC_CHECK_NOTREACHED(); 270 return -1; 271 } 272 MaxMicrophoneVolume(uint32_t & maxVolume)273 int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const override { 274 RTC_CHECK_NOTREACHED(); 275 } 276 MinMicrophoneVolume(uint32_t & minVolume)277 int32_t MinMicrophoneVolume(uint32_t& minVolume) const override { 278 RTC_CHECK_NOTREACHED(); 279 } 280 SpeakerMuteIsAvailable(bool & available)281 int32_t SpeakerMuteIsAvailable(bool& available) override { 282 RTC_CHECK_NOTREACHED(); 283 } 284 SetSpeakerMute(bool enable)285 int32_t SetSpeakerMute(bool enable) override { RTC_CHECK_NOTREACHED(); } 286 SpeakerMute(bool & enabled)287 int32_t SpeakerMute(bool& enabled) const override { RTC_CHECK_NOTREACHED(); } 288 MicrophoneMuteIsAvailable(bool & available)289 int32_t MicrophoneMuteIsAvailable(bool& available) override { 290 RTC_CHECK_NOTREACHED(); 291 } 292 SetMicrophoneMute(bool enable)293 int32_t SetMicrophoneMute(bool enable) override { RTC_CHECK_NOTREACHED(); } 294 MicrophoneMute(bool & enabled)295 int32_t MicrophoneMute(bool& enabled) const override { 296 RTC_CHECK_NOTREACHED(); 297 } 298 299 // Returns true if the audio manager has been configured to support stereo 300 // and false otherwised. Default is mono. StereoPlayoutIsAvailable(bool & available)301 int32_t StereoPlayoutIsAvailable(bool& available) override { 302 RTC_DLOG(LS_INFO) << __FUNCTION__; 303 available = audio_manager_->IsStereoPlayoutSupported(); 304 return 0; 305 } 306 SetStereoPlayout(bool enable)307 int32_t SetStereoPlayout(bool enable) override { 308 RTC_DLOG(LS_INFO) << __FUNCTION__; 309 bool available = audio_manager_->IsStereoPlayoutSupported(); 310 // Android does not support changes between mono and stero on the fly. 311 // Instead, the native audio layer is configured via the audio manager 312 // to either support mono or stereo. It is allowed to call this method 313 // if that same state is not modified. 314 return (enable == available) ? 0 : -1; 315 } 316 StereoPlayout(bool & enabled)317 int32_t StereoPlayout(bool& enabled) const override { 318 enabled = audio_manager_->IsStereoPlayoutSupported(); 319 return 0; 320 } 321 StereoRecordingIsAvailable(bool & available)322 int32_t StereoRecordingIsAvailable(bool& available) override { 323 RTC_DLOG(LS_INFO) << __FUNCTION__; 324 available = audio_manager_->IsStereoRecordSupported(); 325 return 0; 326 } 327 SetStereoRecording(bool enable)328 int32_t SetStereoRecording(bool enable) override { 329 RTC_DLOG(LS_INFO) << __FUNCTION__; 330 bool available = audio_manager_->IsStereoRecordSupported(); 331 // Android does not support changes between mono and stero on the fly. 332 // Instead, the native audio layer is configured via the audio manager 333 // to either support mono or stereo. It is allowed to call this method 334 // if that same state is not modified. 335 return (enable == available) ? 0 : -1; 336 } 337 StereoRecording(bool & enabled)338 int32_t StereoRecording(bool& enabled) const override { 339 RTC_DLOG(LS_INFO) << __FUNCTION__; 340 enabled = audio_manager_->IsStereoRecordSupported(); 341 return 0; 342 } 343 PlayoutDelay(uint16_t & delay_ms)344 int32_t PlayoutDelay(uint16_t& delay_ms) const override { 345 // Best guess we can do is to use half of the estimated total delay. 346 delay_ms = audio_manager_->GetDelayEstimateInMilliseconds() / 2; 347 RTC_DCHECK_GT(delay_ms, 0); 348 return 0; 349 } 350 AttachAudioBuffer(AudioDeviceBuffer * audioBuffer)351 void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) override { 352 RTC_DLOG(LS_INFO) << __FUNCTION__; 353 output_.AttachAudioBuffer(audioBuffer); 354 input_.AttachAudioBuffer(audioBuffer); 355 } 356 357 // Returns true if the device both supports built in AEC and the device 358 // is not blacklisted. 359 // Currently, if OpenSL ES is used in both directions, this method will still 360 // report the correct value and it has the correct effect. As an example: 361 // a device supports built in AEC and this method returns true. Libjingle 362 // will then disable the WebRTC based AEC and that will work for all devices 363 // (mainly Nexus) even when OpenSL ES is used for input since our current 364 // implementation will enable built-in AEC by default also for OpenSL ES. 365 // The only "bad" thing that happens today is that when Libjingle calls 366 // OpenSLESRecorder::EnableBuiltInAEC() it will not have any real effect and 367 // a "Not Implemented" log will be filed. This non-perfect state will remain 368 // until I have added full support for audio effects based on OpenSL ES APIs. BuiltInAECIsAvailable()369 bool BuiltInAECIsAvailable() const override { 370 RTC_DLOG(LS_INFO) << __FUNCTION__; 371 return audio_manager_->IsAcousticEchoCancelerSupported(); 372 } 373 374 // TODO(henrika): add implementation for OpenSL ES based audio as well. EnableBuiltInAEC(bool enable)375 int32_t EnableBuiltInAEC(bool enable) override { 376 RTC_DLOG(LS_INFO) << __FUNCTION__ << "(" << enable << ")"; 377 RTC_CHECK(BuiltInAECIsAvailable()) << "HW AEC is not available"; 378 return input_.EnableBuiltInAEC(enable); 379 } 380 381 // Returns true if the device both supports built in AGC and the device 382 // is not blacklisted. 383 // TODO(henrika): add implementation for OpenSL ES based audio as well. 384 // In addition, see comments for BuiltInAECIsAvailable(). BuiltInAGCIsAvailable()385 bool BuiltInAGCIsAvailable() const override { 386 RTC_DLOG(LS_INFO) << __FUNCTION__; 387 return audio_manager_->IsAutomaticGainControlSupported(); 388 } 389 390 // TODO(henrika): add implementation for OpenSL ES based audio as well. EnableBuiltInAGC(bool enable)391 int32_t EnableBuiltInAGC(bool enable) override { 392 RTC_DLOG(LS_INFO) << __FUNCTION__ << "(" << enable << ")"; 393 RTC_CHECK(BuiltInAGCIsAvailable()) << "HW AGC is not available"; 394 return input_.EnableBuiltInAGC(enable); 395 } 396 397 // Returns true if the device both supports built in NS and the device 398 // is not blacklisted. 399 // TODO(henrika): add implementation for OpenSL ES based audio as well. 400 // In addition, see comments for BuiltInAECIsAvailable(). BuiltInNSIsAvailable()401 bool BuiltInNSIsAvailable() const override { 402 RTC_DLOG(LS_INFO) << __FUNCTION__; 403 return audio_manager_->IsNoiseSuppressorSupported(); 404 } 405 406 // TODO(henrika): add implementation for OpenSL ES based audio as well. EnableBuiltInNS(bool enable)407 int32_t EnableBuiltInNS(bool enable) override { 408 RTC_DLOG(LS_INFO) << __FUNCTION__ << "(" << enable << ")"; 409 RTC_CHECK(BuiltInNSIsAvailable()) << "HW NS is not available"; 410 return input_.EnableBuiltInNS(enable); 411 } 412 413 private: 414 SequenceChecker thread_checker_; 415 416 // Local copy of the audio layer set during construction of the 417 // AudioDeviceModuleImpl instance. Read only value. 418 const AudioDeviceModule::AudioLayer audio_layer_; 419 420 // Non-owning raw pointer to AudioManager instance given to use at 421 // construction. The real object is owned by AudioDeviceModuleImpl and the 422 // life time is the same as that of the AudioDeviceModuleImpl, hence there 423 // is no risk of reading a NULL pointer at any time in this class. 424 AudioManager* const audio_manager_; 425 426 OutputType output_; 427 428 InputType input_; 429 430 bool initialized_; 431 }; 432 433 } // namespace webrtc 434 435 #endif // MODULES_AUDIO_DEVICE_ANDROID_AUDIO_DEVICE_TEMPLATE_H_ 436