OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 10 matching lines...) Expand all Loading... |
21 #include "webrtc/base/checks.h" | 21 #include "webrtc/base/checks.h" |
22 #include "webrtc/base/logging.h" | 22 #include "webrtc/base/logging.h" |
23 #include "webrtc/system_wrappers/interface/trace.h" | 23 #include "webrtc/system_wrappers/interface/trace.h" |
24 | 24 |
25 namespace webrtc { | 25 namespace webrtc { |
26 | 26 |
27 #define LOGI() LOG(LS_INFO) << "AudioDeviceIOS::" | 27 #define LOGI() LOG(LS_INFO) << "AudioDeviceIOS::" |
28 | 28 |
29 using ios::CheckAndLogError; | 29 using ios::CheckAndLogError; |
30 | 30 |
31 #if !defined(NDEBUG) | |
32 static void LogDeviceInfo() { | |
33 LOG(LS_INFO) << "LogDeviceInfo"; | |
34 @autoreleasepool { | |
35 LOG(LS_INFO) << " system name: " << ios::GetSystemName(); | |
36 LOG(LS_INFO) << " system version: " << ios::GetSystemVersion(); | |
37 LOG(LS_INFO) << " device type: " << ios::GetDeviceType(); | |
38 LOG(LS_INFO) << " device name: " << ios::GetDeviceName(); | |
39 } | |
40 } | |
41 #endif | |
42 | |
43 static void ActivateAudioSession(AVAudioSession* session, bool activate) { | 31 static void ActivateAudioSession(AVAudioSession* session, bool activate) { |
44 LOG(LS_INFO) << "ActivateAudioSession(" << activate << ")"; | 32 LOG(LS_INFO) << "ActivateAudioSession(" << activate << ")"; |
45 @autoreleasepool { | 33 @autoreleasepool { |
46 NSError* error = nil; | 34 NSError* error = nil; |
47 BOOL success = NO; | 35 BOOL success = NO; |
48 if (!activate) { | 36 if (!activate) { |
49 // Deactivate the audio session. | 37 // Deactivate the audio session. |
50 success = [session setActive:NO error:&error]; | 38 success = [session setActive:NO error:&error]; |
51 DCHECK(CheckAndLogError(success, error)); | 39 DCHECK(CheckAndLogError(success, error)); |
52 return; | 40 return; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 // Don't keep the audio session active. Instead, deactivate when needed. | 102 // Don't keep the audio session active. Instead, deactivate when needed. |
115 ActivateAudioSession(session, false); | 103 ActivateAudioSession(session, false); |
116 // TODO(henrika): to be extra safe, we can do more here. E.g., set | 104 // TODO(henrika): to be extra safe, we can do more here. E.g., set |
117 // preferred values for sample rate, channels etc., re-activate an audio | 105 // preferred values for sample rate, channels etc., re-activate an audio |
118 // session and verify the actual values again. Then we know for sure that | 106 // session and verify the actual values again. Then we know for sure that |
119 // the current values will in fact be correct. Or, we can skip all this | 107 // the current values will in fact be correct. Or, we can skip all this |
120 // and check setting when audio is started. Probably better. | 108 // and check setting when audio is started. Probably better. |
121 } | 109 } |
122 } | 110 } |
123 | 111 |
| 112 #if !defined(NDEBUG) |
| 113 static void LogDeviceInfo() { |
| 114 LOG(LS_INFO) << "LogDeviceInfo"; |
| 115 @autoreleasepool { |
| 116 LOG(LS_INFO) << " system name: " << ios::GetSystemName(); |
| 117 LOG(LS_INFO) << " system version: " << ios::GetSystemVersion(); |
| 118 LOG(LS_INFO) << " device type: " << ios::GetDeviceType(); |
| 119 LOG(LS_INFO) << " device name: " << ios::GetDeviceName(); |
| 120 } |
| 121 } |
| 122 #endif |
| 123 |
124 AudioDeviceIOS::AudioDeviceIOS() | 124 AudioDeviceIOS::AudioDeviceIOS() |
125 : audio_device_buffer_(nullptr), | 125 : audio_device_buffer_(nullptr), |
126 _critSect(*CriticalSectionWrapper::CreateCriticalSection()), | 126 _critSect(*CriticalSectionWrapper::CreateCriticalSection()), |
127 _auVoiceProcessing(nullptr), | 127 _auVoiceProcessing(nullptr), |
128 _audioInterruptionObserver(nullptr), | 128 _audioInterruptionObserver(nullptr), |
129 _initialized(false), | 129 _initialized(false), |
130 _isShutDown(false), | 130 _isShutDown(false), |
131 _recording(false), | 131 _recording(false), |
132 _playing(false), | 132 _playing(false), |
133 _recIsInitialized(false), | 133 _recIsInitialized(false), |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 if (InitPlayOrRecord() == -1) { | 242 if (InitPlayOrRecord() == -1) { |
243 LOG_F(LS_ERROR) << "InitPlayOrRecord failed!"; | 243 LOG_F(LS_ERROR) << "InitPlayOrRecord failed!"; |
244 return -1; | 244 return -1; |
245 } | 245 } |
246 } | 246 } |
247 _playIsInitialized = true; | 247 _playIsInitialized = true; |
248 return 0; | 248 return 0; |
249 } | 249 } |
250 | 250 |
251 int32_t AudioDeviceIOS::InitRecording() { | 251 int32_t AudioDeviceIOS::InitRecording() { |
252 LOGI() << "InitPlayout"; | 252 LOGI() << "InitRecording"; |
253 DCHECK(thread_checker_.CalledOnValidThread()); | 253 DCHECK(thread_checker_.CalledOnValidThread()); |
254 DCHECK(_initialized); | 254 DCHECK(_initialized); |
255 DCHECK(!_recIsInitialized); | 255 DCHECK(!_recIsInitialized); |
256 DCHECK(!_recording); | 256 DCHECK(!_recording); |
257 if (!_playIsInitialized) { | 257 if (!_playIsInitialized) { |
258 if (InitPlayOrRecord() == -1) { | 258 if (InitPlayOrRecord() == -1) { |
259 LOG_F(LS_ERROR) << "InitPlayOrRecord failed!"; | 259 LOG_F(LS_ERROR) << "InitPlayOrRecord failed!"; |
260 return -1; | 260 return -1; |
261 } | 261 } |
262 } | 262 } |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 AudioOutputUnitStart(_auVoiceProcessing); | 659 AudioOutputUnitStart(_auVoiceProcessing); |
660 break; | 660 break; |
661 } | 661 } |
662 } | 662 } |
663 }]; | 663 }]; |
664 // Increment refcount on observer using ARC bridge. Instance variable is a | 664 // Increment refcount on observer using ARC bridge. Instance variable is a |
665 // void* instead of an id because header is included in other pure C++ | 665 // void* instead of an id because header is included in other pure C++ |
666 // files. | 666 // files. |
667 _audioInterruptionObserver = (__bridge_retained void*)observer; | 667 _audioInterruptionObserver = (__bridge_retained void*)observer; |
668 | 668 |
669 // Deactivate the audio session. | |
670 ActivateAudioSession(session, false); | |
671 | |
672 return 0; | 669 return 0; |
673 } | 670 } |
674 | 671 |
675 int32_t AudioDeviceIOS::ShutdownPlayOrRecord() { | 672 int32_t AudioDeviceIOS::ShutdownPlayOrRecord() { |
676 LOGI() << "ShutdownPlayOrRecord"; | 673 LOGI() << "ShutdownPlayOrRecord"; |
677 | 674 |
678 if (_audioInterruptionObserver != nullptr) { | 675 if (_audioInterruptionObserver != nullptr) { |
679 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; | 676 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; |
680 // Transfer ownership of observer back to ARC, which will dealloc the | 677 // Transfer ownership of observer back to ARC, which will dealloc the |
681 // observer once it exits this scope. | 678 // observer once it exits this scope. |
682 id observer = (__bridge_transfer id)_audioInterruptionObserver; | 679 id observer = (__bridge_transfer id)_audioInterruptionObserver; |
683 [center removeObserver:observer]; | 680 [center removeObserver:observer]; |
684 _audioInterruptionObserver = nullptr; | 681 _audioInterruptionObserver = nullptr; |
685 } | 682 } |
686 | 683 |
687 // Close and delete AU. | 684 // Close and delete AU. |
688 OSStatus result = -1; | 685 OSStatus result = -1; |
689 if (nullptr != _auVoiceProcessing) { | 686 if (nullptr != _auVoiceProcessing) { |
690 result = AudioOutputUnitStop(_auVoiceProcessing); | 687 result = AudioOutputUnitStop(_auVoiceProcessing); |
691 if (0 != result) { | 688 if (0 != result) { |
692 LOG_F(LS_ERROR) << "AudioOutputUnitStop failed: " << result; | 689 LOG_F(LS_ERROR) << "AudioOutputUnitStop failed: " << result; |
693 } | 690 } |
694 result = AudioComponentInstanceDispose(_auVoiceProcessing); | 691 result = AudioComponentInstanceDispose(_auVoiceProcessing); |
695 if (0 != result) { | 692 if (0 != result) { |
696 LOG_F(LS_ERROR) << "AudioComponentInstanceDispose failed: " << result; | 693 LOG_F(LS_ERROR) << "AudioComponentInstanceDispose failed: " << result; |
697 } | 694 } |
698 _auVoiceProcessing = nullptr; | 695 _auVoiceProcessing = nullptr; |
699 } | 696 } |
700 | 697 |
| 698 // All I/O should be stopped or paused prior to deactivating the audio |
| 699 // session, hence we deactivate as last action. |
| 700 AVAudioSession* session = [AVAudioSession sharedInstance]; |
| 701 ActivateAudioSession(session, false); |
701 return 0; | 702 return 0; |
702 } | 703 } |
703 | 704 |
704 // ============================================================================ | 705 // ============================================================================ |
705 // Thread Methods | 706 // Thread Methods |
706 // ============================================================================ | 707 // ============================================================================ |
707 | 708 |
708 OSStatus AudioDeviceIOS::RecordProcess( | 709 OSStatus AudioDeviceIOS::RecordProcess( |
709 void* inRefCon, | 710 void* inRefCon, |
710 AudioUnitRenderActionFlags* ioActionFlags, | 711 AudioUnitRenderActionFlags* ioActionFlags, |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1044 // Device Buffer? | 1045 // Device Buffer? |
1045 timespec t; | 1046 timespec t; |
1046 t.tv_sec = 0; | 1047 t.tv_sec = 0; |
1047 t.tv_nsec = 5 * 1000 * 1000; | 1048 t.tv_nsec = 5 * 1000 * 1000; |
1048 nanosleep(&t, nullptr); | 1049 nanosleep(&t, nullptr); |
1049 } | 1050 } |
1050 return true; | 1051 return true; |
1051 } | 1052 } |
1052 | 1053 |
1053 } // namespace webrtc | 1054 } // namespace webrtc |
OLD | NEW |