1/*
2 *  Copyright (c) 2012 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#include "audio_device_module_ios.h"
12
13#include "api/task_queue/default_task_queue_factory.h"
14#include "modules/audio_device/audio_device_config.h"
15#include "modules/audio_device/audio_device_generic.h"
16#include "rtc_base/checks.h"
17#include "rtc_base/logging.h"
18#include "rtc_base/ref_count.h"
19#include "rtc_base/ref_counted_object.h"
20#include "system_wrappers/include/metrics.h"
21
22#if defined(WEBRTC_IOS)
23#include "audio_device_ios.h"
24#endif
25
26#define CHECKinitialized_() \
27  {                         \
28    if (!initialized_) {    \
29      return -1;            \
30    };                      \
31  }
32
33#define CHECKinitialized__BOOL() \
34  {                              \
35    if (!initialized_) {         \
36      return false;              \
37    };                           \
38  }
39
40namespace webrtc {
41namespace ios_adm {
42
43AudioDeviceModuleIOS::AudioDeviceModuleIOS(bool bypass_voice_processing)
44    : bypass_voice_processing_(bypass_voice_processing),
45      task_queue_factory_(CreateDefaultTaskQueueFactory()) {
46  RTC_LOG(INFO) << "current platform is IOS";
47  RTC_LOG(INFO) << "iPhone Audio APIs will be utilized.";
48}
49
50  int32_t AudioDeviceModuleIOS::AttachAudioBuffer() {
51    RTC_DLOG(INFO) << __FUNCTION__;
52    audio_device_->AttachAudioBuffer(audio_device_buffer_.get());
53    return 0;
54  }
55
56  AudioDeviceModuleIOS::~AudioDeviceModuleIOS() {
57    RTC_DLOG(INFO) << __FUNCTION__;
58  }
59
60  int32_t AudioDeviceModuleIOS::ActiveAudioLayer(AudioLayer* audioLayer) const {
61    RTC_DLOG(INFO) << __FUNCTION__;
62    AudioLayer activeAudio;
63    if (audio_device_->ActiveAudioLayer(activeAudio) == -1) {
64      return -1;
65    }
66    *audioLayer = activeAudio;
67    return 0;
68  }
69
70  int32_t AudioDeviceModuleIOS::Init() {
71    RTC_DLOG(INFO) << __FUNCTION__;
72    if (initialized_)
73      return 0;
74
75    audio_device_buffer_.reset(new webrtc::AudioDeviceBuffer(task_queue_factory_.get()));
76    audio_device_.reset(new ios_adm::AudioDeviceIOS(bypass_voice_processing_));
77    RTC_CHECK(audio_device_);
78
79    this->AttachAudioBuffer();
80
81    AudioDeviceGeneric::InitStatus status = audio_device_->Init();
82    RTC_HISTOGRAM_ENUMERATION(
83        "WebRTC.Audio.InitializationResult", static_cast<int>(status),
84        static_cast<int>(AudioDeviceGeneric::InitStatus::NUM_STATUSES));
85    if (status != AudioDeviceGeneric::InitStatus::OK) {
86      RTC_LOG(LS_ERROR) << "Audio device initialization failed.";
87      return -1;
88    }
89    initialized_ = true;
90    return 0;
91  }
92
93  int32_t AudioDeviceModuleIOS::Terminate() {
94    RTC_DLOG(INFO) << __FUNCTION__;
95    if (!initialized_)
96      return 0;
97    if (audio_device_->Terminate() == -1) {
98      return -1;
99    }
100    initialized_ = false;
101    return 0;
102  }
103
104  bool AudioDeviceModuleIOS::Initialized() const {
105    RTC_DLOG(INFO) << __FUNCTION__ << ": " << initialized_;
106    return initialized_;
107  }
108
109  int32_t AudioDeviceModuleIOS::InitSpeaker() {
110    RTC_DLOG(INFO) << __FUNCTION__;
111    CHECKinitialized_();
112    return audio_device_->InitSpeaker();
113  }
114
115  int32_t AudioDeviceModuleIOS::InitMicrophone() {
116    RTC_DLOG(INFO) << __FUNCTION__;
117    CHECKinitialized_();
118    return audio_device_->InitMicrophone();
119  }
120
121  int32_t AudioDeviceModuleIOS::SpeakerVolumeIsAvailable(bool* available) {
122    RTC_DLOG(INFO) << __FUNCTION__;
123    CHECKinitialized_();
124    bool isAvailable = false;
125    if (audio_device_->SpeakerVolumeIsAvailable(isAvailable) == -1) {
126      return -1;
127    }
128    *available = isAvailable;
129    RTC_DLOG(INFO) << "output: " << isAvailable;
130    return 0;
131  }
132
133  int32_t AudioDeviceModuleIOS::SetSpeakerVolume(uint32_t volume) {
134    RTC_DLOG(INFO) << __FUNCTION__ << "(" << volume << ")";
135    CHECKinitialized_();
136    return audio_device_->SetSpeakerVolume(volume);
137  }
138
139  int32_t AudioDeviceModuleIOS::SpeakerVolume(uint32_t* volume) const {
140    RTC_DLOG(INFO) << __FUNCTION__;
141    CHECKinitialized_();
142    uint32_t level = 0;
143    if (audio_device_->SpeakerVolume(level) == -1) {
144      return -1;
145    }
146    *volume = level;
147    RTC_DLOG(INFO) << "output: " << *volume;
148    return 0;
149  }
150
151  bool AudioDeviceModuleIOS::SpeakerIsInitialized() const {
152    RTC_DLOG(INFO) << __FUNCTION__;
153    CHECKinitialized__BOOL();
154    bool isInitialized = audio_device_->SpeakerIsInitialized();
155    RTC_DLOG(INFO) << "output: " << isInitialized;
156    return isInitialized;
157  }
158
159  bool AudioDeviceModuleIOS::MicrophoneIsInitialized() const {
160    RTC_DLOG(INFO) << __FUNCTION__;
161    CHECKinitialized__BOOL();
162    bool isInitialized = audio_device_->MicrophoneIsInitialized();
163    RTC_DLOG(INFO) << "output: " << isInitialized;
164    return isInitialized;
165  }
166
167  int32_t AudioDeviceModuleIOS::MaxSpeakerVolume(uint32_t* maxVolume) const {
168    CHECKinitialized_();
169    uint32_t maxVol = 0;
170    if (audio_device_->MaxSpeakerVolume(maxVol) == -1) {
171      return -1;
172    }
173    *maxVolume = maxVol;
174    return 0;
175  }
176
177  int32_t AudioDeviceModuleIOS::MinSpeakerVolume(uint32_t* minVolume) const {
178    CHECKinitialized_();
179    uint32_t minVol = 0;
180    if (audio_device_->MinSpeakerVolume(minVol) == -1) {
181      return -1;
182    }
183    *minVolume = minVol;
184    return 0;
185  }
186
187  int32_t AudioDeviceModuleIOS::SpeakerMuteIsAvailable(bool* available) {
188    RTC_DLOG(INFO) << __FUNCTION__;
189    CHECKinitialized_();
190    bool isAvailable = false;
191    if (audio_device_->SpeakerMuteIsAvailable(isAvailable) == -1) {
192      return -1;
193    }
194    *available = isAvailable;
195    RTC_DLOG(INFO) << "output: " << isAvailable;
196    return 0;
197  }
198
199  int32_t AudioDeviceModuleIOS::SetSpeakerMute(bool enable) {
200    RTC_DLOG(INFO) << __FUNCTION__ << "(" << enable << ")";
201    CHECKinitialized_();
202    return audio_device_->SetSpeakerMute(enable);
203  }
204
205  int32_t AudioDeviceModuleIOS::SpeakerMute(bool* enabled) const {
206    RTC_DLOG(INFO) << __FUNCTION__;
207    CHECKinitialized_();
208    bool muted = false;
209    if (audio_device_->SpeakerMute(muted) == -1) {
210      return -1;
211    }
212    *enabled = muted;
213    RTC_DLOG(INFO) << "output: " << muted;
214    return 0;
215  }
216
217  int32_t AudioDeviceModuleIOS::MicrophoneMuteIsAvailable(bool* available) {
218    RTC_DLOG(INFO) << __FUNCTION__;
219    CHECKinitialized_();
220    bool isAvailable = false;
221    if (audio_device_->MicrophoneMuteIsAvailable(isAvailable) == -1) {
222      return -1;
223    }
224    *available = isAvailable;
225    RTC_DLOG(INFO) << "output: " << isAvailable;
226    return 0;
227  }
228
229  int32_t AudioDeviceModuleIOS::SetMicrophoneMute(bool enable) {
230    RTC_DLOG(INFO) << __FUNCTION__ << "(" << enable << ")";
231    CHECKinitialized_();
232    return (audio_device_->SetMicrophoneMute(enable));
233  }
234
235  int32_t AudioDeviceModuleIOS::MicrophoneMute(bool* enabled) const {
236    RTC_DLOG(INFO) << __FUNCTION__;
237    CHECKinitialized_();
238    bool muted = false;
239    if (audio_device_->MicrophoneMute(muted) == -1) {
240      return -1;
241    }
242    *enabled = muted;
243    RTC_DLOG(INFO) << "output: " << muted;
244    return 0;
245  }
246
247  int32_t AudioDeviceModuleIOS::MicrophoneVolumeIsAvailable(bool* available) {
248    RTC_DLOG(INFO) << __FUNCTION__;
249    CHECKinitialized_();
250    bool isAvailable = false;
251    if (audio_device_->MicrophoneVolumeIsAvailable(isAvailable) == -1) {
252      return -1;
253    }
254    *available = isAvailable;
255    RTC_DLOG(INFO) << "output: " << isAvailable;
256    return 0;
257  }
258
259  int32_t AudioDeviceModuleIOS::SetMicrophoneVolume(uint32_t volume) {
260    RTC_DLOG(INFO) << __FUNCTION__ << "(" << volume << ")";
261    CHECKinitialized_();
262    return (audio_device_->SetMicrophoneVolume(volume));
263  }
264
265  int32_t AudioDeviceModuleIOS::MicrophoneVolume(uint32_t* volume) const {
266    RTC_DLOG(INFO) << __FUNCTION__;
267    CHECKinitialized_();
268    uint32_t level = 0;
269    if (audio_device_->MicrophoneVolume(level) == -1) {
270      return -1;
271    }
272    *volume = level;
273    RTC_DLOG(INFO) << "output: " << *volume;
274    return 0;
275  }
276
277  int32_t AudioDeviceModuleIOS::StereoRecordingIsAvailable(
278      bool* available) const {
279    RTC_DLOG(INFO) << __FUNCTION__;
280    CHECKinitialized_();
281    bool isAvailable = false;
282    if (audio_device_->StereoRecordingIsAvailable(isAvailable) == -1) {
283      return -1;
284    }
285    *available = isAvailable;
286    RTC_DLOG(INFO) << "output: " << isAvailable;
287    return 0;
288  }
289
290  int32_t AudioDeviceModuleIOS::SetStereoRecording(bool enable) {
291    RTC_DLOG(INFO) << __FUNCTION__ << "(" << enable << ")";
292    CHECKinitialized_();
293    if (enable) {
294      RTC_LOG(WARNING) << "recording in stereo is not supported";
295    }
296    return -1;
297  }
298
299  int32_t AudioDeviceModuleIOS::StereoRecording(bool* enabled) const {
300    RTC_DLOG(INFO) << __FUNCTION__;
301    CHECKinitialized_();
302    bool stereo = false;
303    if (audio_device_->StereoRecording(stereo) == -1) {
304      return -1;
305    }
306    *enabled = stereo;
307    RTC_DLOG(INFO) << "output: " << stereo;
308    return 0;
309  }
310
311  int32_t AudioDeviceModuleIOS::StereoPlayoutIsAvailable(bool* available) const {
312    RTC_DLOG(INFO) << __FUNCTION__;
313    CHECKinitialized_();
314    bool isAvailable = false;
315    if (audio_device_->StereoPlayoutIsAvailable(isAvailable) == -1) {
316      return -1;
317    }
318    *available = isAvailable;
319    RTC_DLOG(INFO) << "output: " << isAvailable;
320    return 0;
321  }
322
323  int32_t AudioDeviceModuleIOS::SetStereoPlayout(bool enable) {
324    RTC_DLOG(INFO) << __FUNCTION__ << "(" << enable << ")";
325    CHECKinitialized_();
326    if (audio_device_->PlayoutIsInitialized()) {
327      RTC_LOG(LERROR)
328      << "unable to set stereo mode while playing side is initialized";
329      return -1;
330    }
331    if (audio_device_->SetStereoPlayout(enable)) {
332      RTC_LOG(WARNING) << "stereo playout is not supported";
333      return -1;
334    }
335    int8_t nChannels(1);
336    if (enable) {
337      nChannels = 2;
338    }
339    audio_device_buffer_.get()->SetPlayoutChannels(nChannels);
340    return 0;
341  }
342
343  int32_t AudioDeviceModuleIOS::StereoPlayout(bool* enabled) const {
344    RTC_DLOG(INFO) << __FUNCTION__;
345    CHECKinitialized_();
346    bool stereo = false;
347    if (audio_device_->StereoPlayout(stereo) == -1) {
348      return -1;
349    }
350    *enabled = stereo;
351    RTC_DLOG(INFO) << "output: " << stereo;
352    return 0;
353  }
354
355  int32_t AudioDeviceModuleIOS::PlayoutIsAvailable(bool* available) {
356    RTC_DLOG(INFO) << __FUNCTION__;
357    CHECKinitialized_();
358    bool isAvailable = false;
359    if (audio_device_->PlayoutIsAvailable(isAvailable) == -1) {
360      return -1;
361    }
362    *available = isAvailable;
363    RTC_DLOG(INFO) << "output: " << isAvailable;
364    return 0;
365  }
366
367  int32_t AudioDeviceModuleIOS::RecordingIsAvailable(bool* available) {
368    RTC_DLOG(INFO) << __FUNCTION__;
369    CHECKinitialized_();
370    bool isAvailable = false;
371    if (audio_device_->RecordingIsAvailable(isAvailable) == -1) {
372      return -1;
373    }
374    *available = isAvailable;
375    RTC_DLOG(INFO) << "output: " << isAvailable;
376    return 0;
377  }
378
379  int32_t AudioDeviceModuleIOS::MaxMicrophoneVolume(uint32_t* maxVolume) const {
380    CHECKinitialized_();
381    uint32_t maxVol(0);
382    if (audio_device_->MaxMicrophoneVolume(maxVol) == -1) {
383      return -1;
384    }
385    *maxVolume = maxVol;
386    return 0;
387  }
388
389  int32_t AudioDeviceModuleIOS::MinMicrophoneVolume(uint32_t* minVolume) const {
390    CHECKinitialized_();
391    uint32_t minVol(0);
392    if (audio_device_->MinMicrophoneVolume(minVol) == -1) {
393      return -1;
394    }
395    *minVolume = minVol;
396    return 0;
397  }
398
399  int16_t AudioDeviceModuleIOS::PlayoutDevices() {
400    RTC_DLOG(INFO) << __FUNCTION__;
401    CHECKinitialized_();
402    uint16_t nPlayoutDevices = audio_device_->PlayoutDevices();
403    RTC_DLOG(INFO) << "output: " << nPlayoutDevices;
404    return (int16_t)(nPlayoutDevices);
405  }
406
407  int32_t AudioDeviceModuleIOS::SetPlayoutDevice(uint16_t index) {
408    RTC_DLOG(INFO) << __FUNCTION__ << "(" << index << ")";
409    CHECKinitialized_();
410    return audio_device_->SetPlayoutDevice(index);
411  }
412
413  int32_t AudioDeviceModuleIOS::SetPlayoutDevice(WindowsDeviceType device) {
414    RTC_DLOG(INFO) << __FUNCTION__;
415    CHECKinitialized_();
416    return audio_device_->SetPlayoutDevice(device);
417  }
418
419  int32_t AudioDeviceModuleIOS::PlayoutDeviceName(
420      uint16_t index,
421      char name[kAdmMaxDeviceNameSize],
422      char guid[kAdmMaxGuidSize]) {
423    RTC_DLOG(INFO) << __FUNCTION__ << "(" << index << ", ...)";
424    CHECKinitialized_();
425    if (name == NULL) {
426      return -1;
427    }
428    if (audio_device_->PlayoutDeviceName(index, name, guid) == -1) {
429      return -1;
430    }
431    if (name != NULL) {
432      RTC_DLOG(INFO) << "output: name = " << name;
433    }
434    if (guid != NULL) {
435      RTC_DLOG(INFO) << "output: guid = " << guid;
436    }
437    return 0;
438  }
439
440  int32_t AudioDeviceModuleIOS::RecordingDeviceName(
441      uint16_t index,
442      char name[kAdmMaxDeviceNameSize],
443      char guid[kAdmMaxGuidSize]) {
444    RTC_DLOG(INFO) << __FUNCTION__ << "(" << index << ", ...)";
445    CHECKinitialized_();
446    if (name == NULL) {
447      return -1;
448    }
449    if (audio_device_->RecordingDeviceName(index, name, guid) == -1) {
450      return -1;
451    }
452    if (name != NULL) {
453      RTC_DLOG(INFO) << "output: name = " << name;
454    }
455    if (guid != NULL) {
456      RTC_DLOG(INFO) << "output: guid = " << guid;
457    }
458    return 0;
459  }
460
461  int16_t AudioDeviceModuleIOS::RecordingDevices() {
462    RTC_DLOG(INFO) << __FUNCTION__;
463    CHECKinitialized_();
464    uint16_t nRecordingDevices = audio_device_->RecordingDevices();
465    RTC_DLOG(INFO) << "output: " << nRecordingDevices;
466    return (int16_t)nRecordingDevices;
467  }
468
469  int32_t AudioDeviceModuleIOS::SetRecordingDevice(uint16_t index) {
470    RTC_DLOG(INFO) << __FUNCTION__ << "(" << index << ")";
471    CHECKinitialized_();
472    return audio_device_->SetRecordingDevice(index);
473  }
474
475  int32_t AudioDeviceModuleIOS::SetRecordingDevice(WindowsDeviceType device) {
476    RTC_DLOG(INFO) << __FUNCTION__;
477    CHECKinitialized_();
478    return audio_device_->SetRecordingDevice(device);
479  }
480
481  int32_t AudioDeviceModuleIOS::InitPlayout() {
482    RTC_DLOG(INFO) << __FUNCTION__;
483    CHECKinitialized_();
484    if (PlayoutIsInitialized()) {
485      return 0;
486    }
487    int32_t result = audio_device_->InitPlayout();
488    RTC_DLOG(INFO) << "output: " << result;
489    RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.InitPlayoutSuccess",
490                          static_cast<int>(result == 0));
491    return result;
492  }
493
494  int32_t AudioDeviceModuleIOS::InitRecording() {
495    RTC_DLOG(INFO) << __FUNCTION__;
496    CHECKinitialized_();
497    if (RecordingIsInitialized()) {
498      return 0;
499    }
500    int32_t result = audio_device_->InitRecording();
501    RTC_DLOG(INFO) << "output: " << result;
502    RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.InitRecordingSuccess",
503                          static_cast<int>(result == 0));
504    return result;
505  }
506
507  bool AudioDeviceModuleIOS::PlayoutIsInitialized() const {
508    RTC_DLOG(INFO) << __FUNCTION__;
509    CHECKinitialized__BOOL();
510    return audio_device_->PlayoutIsInitialized();
511  }
512
513  bool AudioDeviceModuleIOS::RecordingIsInitialized() const {
514    RTC_DLOG(INFO) << __FUNCTION__;
515    CHECKinitialized__BOOL();
516    return audio_device_->RecordingIsInitialized();
517  }
518
519  int32_t AudioDeviceModuleIOS::StartPlayout() {
520    RTC_DLOG(INFO) << __FUNCTION__;
521    CHECKinitialized_();
522    if (Playing()) {
523      return 0;
524    }
525    audio_device_buffer_.get()->StartPlayout();
526    int32_t result = audio_device_->StartPlayout();
527    RTC_DLOG(INFO) << "output: " << result;
528    RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StartPlayoutSuccess",
529                          static_cast<int>(result == 0));
530    return result;
531  }
532
533  int32_t AudioDeviceModuleIOS::StopPlayout() {
534    RTC_DLOG(INFO) << __FUNCTION__;
535    CHECKinitialized_();
536    int32_t result = audio_device_->StopPlayout();
537    audio_device_buffer_.get()->StopPlayout();
538    RTC_DLOG(INFO) << "output: " << result;
539    RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StopPlayoutSuccess",
540                          static_cast<int>(result == 0));
541    return result;
542  }
543
544  bool AudioDeviceModuleIOS::Playing() const {
545    RTC_DLOG(INFO) << __FUNCTION__;
546    CHECKinitialized__BOOL();
547    return audio_device_->Playing();
548  }
549
550  int32_t AudioDeviceModuleIOS::StartRecording() {
551    RTC_DLOG(INFO) << __FUNCTION__;
552    CHECKinitialized_();
553    if (Recording()) {
554      return 0;
555    }
556    audio_device_buffer_.get()->StartRecording();
557    int32_t result = audio_device_->StartRecording();
558    RTC_DLOG(INFO) << "output: " << result;
559    RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StartRecordingSuccess",
560                          static_cast<int>(result == 0));
561    return result;
562  }
563
564  int32_t AudioDeviceModuleIOS::StopRecording() {
565    RTC_DLOG(INFO) << __FUNCTION__;
566    CHECKinitialized_();
567    int32_t result = audio_device_->StopRecording();
568    audio_device_buffer_.get()->StopRecording();
569    RTC_DLOG(INFO) << "output: " << result;
570    RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StopRecordingSuccess",
571                          static_cast<int>(result == 0));
572    return result;
573  }
574
575  bool AudioDeviceModuleIOS::Recording() const {
576    RTC_DLOG(INFO) << __FUNCTION__;
577    CHECKinitialized__BOOL();
578    return audio_device_->Recording();
579  }
580
581  int32_t AudioDeviceModuleIOS::RegisterAudioCallback(
582      AudioTransport* audioCallback) {
583    RTC_DLOG(INFO) << __FUNCTION__;
584    return audio_device_buffer_.get()->RegisterAudioCallback(audioCallback);
585  }
586
587  int32_t AudioDeviceModuleIOS::PlayoutDelay(uint16_t* delayMS) const {
588    CHECKinitialized_();
589    uint16_t delay = 0;
590    if (audio_device_->PlayoutDelay(delay) == -1) {
591      RTC_LOG(LERROR) << "failed to retrieve the playout delay";
592      return -1;
593    }
594    *delayMS = delay;
595    return 0;
596  }
597
598  bool AudioDeviceModuleIOS::BuiltInAECIsAvailable() const {
599    RTC_DLOG(INFO) << __FUNCTION__;
600    CHECKinitialized__BOOL();
601    bool isAvailable = audio_device_->BuiltInAECIsAvailable();
602    RTC_DLOG(INFO) << "output: " << isAvailable;
603    return isAvailable;
604  }
605
606  int32_t AudioDeviceModuleIOS::EnableBuiltInAEC(bool enable) {
607    RTC_DLOG(INFO) << __FUNCTION__ << "(" << enable << ")";
608    CHECKinitialized_();
609    int32_t ok = audio_device_->EnableBuiltInAEC(enable);
610    RTC_DLOG(INFO) << "output: " << ok;
611    return ok;
612  }
613
614  bool AudioDeviceModuleIOS::BuiltInAGCIsAvailable() const {
615    RTC_DLOG(INFO) << __FUNCTION__;
616    CHECKinitialized__BOOL();
617    bool isAvailable = audio_device_->BuiltInAGCIsAvailable();
618    RTC_DLOG(INFO) << "output: " << isAvailable;
619    return isAvailable;
620  }
621
622  int32_t AudioDeviceModuleIOS::EnableBuiltInAGC(bool enable) {
623    RTC_DLOG(INFO) << __FUNCTION__ << "(" << enable << ")";
624    CHECKinitialized_();
625    int32_t ok = audio_device_->EnableBuiltInAGC(enable);
626    RTC_DLOG(INFO) << "output: " << ok;
627    return ok;
628  }
629
630  bool AudioDeviceModuleIOS::BuiltInNSIsAvailable() const {
631    RTC_DLOG(INFO) << __FUNCTION__;
632    CHECKinitialized__BOOL();
633    bool isAvailable = audio_device_->BuiltInNSIsAvailable();
634    RTC_DLOG(INFO) << "output: " << isAvailable;
635    return isAvailable;
636  }
637
638  int32_t AudioDeviceModuleIOS::EnableBuiltInNS(bool enable) {
639    RTC_DLOG(INFO) << __FUNCTION__ << "(" << enable << ")";
640    CHECKinitialized_();
641    int32_t ok = audio_device_->EnableBuiltInNS(enable);
642    RTC_DLOG(INFO) << "output: " << ok;
643    return ok;
644  }
645
646  int32_t AudioDeviceModuleIOS::GetPlayoutUnderrunCount() const {
647    // Don't log here, as this method can be called very often.
648    CHECKinitialized_();
649    int32_t ok = audio_device_->GetPlayoutUnderrunCount();
650    return ok;
651  }
652
653#if defined(WEBRTC_IOS)
654  int AudioDeviceModuleIOS::GetPlayoutAudioParameters(
655      AudioParameters* params) const {
656    RTC_DLOG(INFO) << __FUNCTION__;
657    int r = audio_device_->GetPlayoutAudioParameters(params);
658    RTC_DLOG(INFO) << "output: " << r;
659    return r;
660  }
661
662  int AudioDeviceModuleIOS::GetRecordAudioParameters(
663      AudioParameters* params) const {
664    RTC_DLOG(INFO) << __FUNCTION__;
665    int r = audio_device_->GetRecordAudioParameters(params);
666    RTC_DLOG(INFO) << "output: " << r;
667    return r;
668  }
669#endif  // WEBRTC_IOS
670}
671}
672