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