xref: /aosp_15_r20/external/webrtc/modules/audio_device/android/audio_device_template.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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