Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Side by Side Diff: webrtc/modules/audio_device/ios/audio_device_ios.mm

Issue 1554163002: iOS stability improvement for device switching (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: nit Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 case AVAudioSessionRouteChangeReasonUnknown: 575 case AVAudioSessionRouteChangeReasonUnknown:
576 LOG(LS_INFO) << " ReasonUnknown"; 576 LOG(LS_INFO) << " ReasonUnknown";
577 break; 577 break;
578 case AVAudioSessionRouteChangeReasonNewDeviceAvailable: 578 case AVAudioSessionRouteChangeReasonNewDeviceAvailable:
579 LOG(LS_INFO) << " NewDeviceAvailable"; 579 LOG(LS_INFO) << " NewDeviceAvailable";
580 break; 580 break;
581 case AVAudioSessionRouteChangeReasonOldDeviceUnavailable: 581 case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
582 LOG(LS_INFO) << " OldDeviceUnavailable"; 582 LOG(LS_INFO) << " OldDeviceUnavailable";
583 break; 583 break;
584 case AVAudioSessionRouteChangeReasonCategoryChange: 584 case AVAudioSessionRouteChangeReasonCategoryChange:
585 // It turns out that we see this notification (at least in iOS 9.2)
586 // when making a switch from a BT device to e.g. Speaker using the
587 // iOS Control Center and that we therefore must check if the sample
588 // rate has changed. And if so is the case, restart the audio unit.
585 LOG(LS_INFO) << " CategoryChange"; 589 LOG(LS_INFO) << " CategoryChange";
586 LOG(LS_INFO) << " New category: " << ios::GetAudioSessionCategory(); 590 LOG(LS_INFO) << " New category: " << ios::GetAudioSessionCategory();
587 // Don't see this as route change since it can be triggered in
588 // combination with session interruptions as well.
589 valid_route_change = false;
590 break; 591 break;
591 case AVAudioSessionRouteChangeReasonOverride: 592 case AVAudioSessionRouteChangeReasonOverride:
592 LOG(LS_INFO) << " Override"; 593 LOG(LS_INFO) << " Override";
593 break; 594 break;
594 case AVAudioSessionRouteChangeReasonWakeFromSleep: 595 case AVAudioSessionRouteChangeReasonWakeFromSleep:
595 LOG(LS_INFO) << " WakeFromSleep"; 596 LOG(LS_INFO) << " WakeFromSleep";
596 break; 597 break;
597 case AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory: 598 case AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory:
598 LOG(LS_INFO) << " NoSuitableRouteForCategory"; 599 LOG(LS_INFO) << " NoSuitableRouteForCategory";
599 break; 600 break;
600 case AVAudioSessionRouteChangeReasonRouteConfigurationChange: 601 case AVAudioSessionRouteChangeReasonRouteConfigurationChange:
601 // Ignore this type of route change since we are focusing 602 // The set of input and output ports has not changed, but their
603 // configuration has, e.g., a port’s selected data source has
604 // changed. Ignore this type of route change since we are focusing
602 // on detecting headset changes. 605 // on detecting headset changes.
603 LOG(LS_INFO) << " RouteConfigurationChange"; 606 LOG(LS_INFO) << " RouteConfigurationChange (ignored)";
604 valid_route_change = false; 607 valid_route_change = false;
605 break; 608 break;
606 } 609 }
607 610
608 if (valid_route_change) { 611 if (valid_route_change) {
609 // Log previous route configuration. 612 // Log previous route configuration.
610 AVAudioSessionRouteDescription* prev_route = 613 AVAudioSessionRouteDescription* prev_route =
611 notification.userInfo[AVAudioSessionRouteChangePreviousRouteKey]; 614 notification.userInfo[AVAudioSessionRouteChangePreviousRouteKey];
612 LOG(LS_INFO) << "Previous route:"; 615 LOG(LS_INFO) << "Previous route:";
613 LOG(LS_INFO) << ios::StdStringFromNSString( 616 LOG(LS_INFO) << ios::StdStringFromNSString(
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 application_format_.mSampleRate = playout_parameters_.sample_rate(); 930 application_format_.mSampleRate = playout_parameters_.sample_rate();
928 UInt32 size = sizeof(application_format_); 931 UInt32 size = sizeof(application_format_);
929 AudioUnitSetProperty(vpio_unit_, kAudioUnitProperty_StreamFormat, 932 AudioUnitSetProperty(vpio_unit_, kAudioUnitProperty_StreamFormat,
930 kAudioUnitScope_Output, 1, &application_format_, size); 933 kAudioUnitScope_Output, 1, &application_format_, size);
931 AudioUnitSetProperty(vpio_unit_, kAudioUnitProperty_StreamFormat, 934 AudioUnitSetProperty(vpio_unit_, kAudioUnitProperty_StreamFormat,
932 kAudioUnitScope_Input, 0, &application_format_, size); 935 kAudioUnitScope_Input, 0, &application_format_, size);
933 936
934 // Prepare the audio unit to render audio again. 937 // Prepare the audio unit to render audio again.
935 LOG_AND_RETURN_IF_ERROR(AudioUnitInitialize(vpio_unit_), 938 LOG_AND_RETURN_IF_ERROR(AudioUnitInitialize(vpio_unit_),
936 "Failed to initialize the Voice-Processing I/O unit"); 939 "Failed to initialize the Voice-Processing I/O unit");
940 LOG(LS_INFO) << "Voice-Processing I/O unit is now reinitialized";
937 941
938 // Start rendering audio using the new format. 942 // Start rendering audio using the new format.
939 LOG_AND_RETURN_IF_ERROR(AudioOutputUnitStart(vpio_unit_), 943 LOG_AND_RETURN_IF_ERROR(AudioOutputUnitStart(vpio_unit_),
940 "Failed to start the Voice-Processing I/O unit"); 944 "Failed to start the Voice-Processing I/O unit");
945 LOG(LS_INFO) << "Voice-Processing I/O unit is now restarted";
941 return true; 946 return true;
942 } 947 }
943 948
944 bool AudioDeviceIOS::InitPlayOrRecord() { 949 bool AudioDeviceIOS::InitPlayOrRecord() {
945 LOGI() << "InitPlayOrRecord"; 950 LOGI() << "InitPlayOrRecord";
946 // Activate the audio session if not already activated. 951 // Activate the audio session if not already activated.
947 if (!ActivateAudioSession()) { 952 if (!ActivateAudioSession()) {
948 return false; 953 return false;
949 } 954 }
950 955
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 const AudioTimeStamp* in_time_stamp, 1031 const AudioTimeStamp* in_time_stamp,
1027 UInt32 in_bus_number, 1032 UInt32 in_bus_number,
1028 UInt32 in_number_frames) { 1033 UInt32 in_number_frames) {
1029 OSStatus result = noErr; 1034 OSStatus result = noErr;
1030 // Simply return if recording is not enabled. 1035 // Simply return if recording is not enabled.
1031 if (!rtc::AtomicOps::AcquireLoad(&recording_)) 1036 if (!rtc::AtomicOps::AcquireLoad(&recording_))
1032 return result; 1037 return result;
1033 if (in_number_frames != record_parameters_.frames_per_buffer()) { 1038 if (in_number_frames != record_parameters_.frames_per_buffer()) {
1034 // We have seen short bursts (1-2 frames) where |in_number_frames| changes. 1039 // We have seen short bursts (1-2 frames) where |in_number_frames| changes.
1035 // Add a log to keep track of longer sequences if that should ever happen. 1040 // Add a log to keep track of longer sequences if that should ever happen.
1041 // Also return since calling AudioUnitRender in this state will only result
1042 // in kAudio_ParamError (-50) anyhow.
1036 LOG(LS_WARNING) << "in_number_frames (" << in_number_frames 1043 LOG(LS_WARNING) << "in_number_frames (" << in_number_frames
1037 << ") != " << record_parameters_.frames_per_buffer(); 1044 << ") != " << record_parameters_.frames_per_buffer();
1045 return noErr;
1038 } 1046 }
1039 // Obtain the recorded audio samples by initiating a rendering cycle. 1047 // Obtain the recorded audio samples by initiating a rendering cycle.
1040 // Since it happens on the input bus, the |io_data| parameter is a reference 1048 // Since it happens on the input bus, the |io_data| parameter is a reference
1041 // to the preallocated audio buffer list that the audio unit renders into. 1049 // to the preallocated audio buffer list that the audio unit renders into.
1042 // TODO(henrika): should error handling be improved? 1050 // TODO(henrika): should error handling be improved?
1043 AudioBufferList* io_data = &audio_record_buffer_list_; 1051 AudioBufferList* io_data = &audio_record_buffer_list_;
1044 result = AudioUnitRender(vpio_unit_, io_action_flags, in_time_stamp, 1052 result = AudioUnitRender(vpio_unit_, io_action_flags, in_time_stamp,
1045 in_bus_number, in_number_frames, io_data); 1053 in_bus_number, in_number_frames, io_data);
1046 if (result != noErr) { 1054 if (result != noErr) {
1047 LOG_F(LS_ERROR) << "AudioOutputUnitStart failed: " << result; 1055 LOG_F(LS_ERROR) << "AudioUnitRender failed: " << result;
1048 return result; 1056 return result;
1049 } 1057 }
1050 // Get a pointer to the recorded audio and send it to the WebRTC ADB. 1058 // Get a pointer to the recorded audio and send it to the WebRTC ADB.
1051 // Use the FineAudioBuffer instance to convert between native buffer size 1059 // Use the FineAudioBuffer instance to convert between native buffer size
1052 // and the 10ms buffer size used by WebRTC. 1060 // and the 10ms buffer size used by WebRTC.
1053 const UInt32 data_size_in_bytes = io_data->mBuffers[0].mDataByteSize; 1061 const UInt32 data_size_in_bytes = io_data->mBuffers[0].mDataByteSize;
1054 RTC_CHECK_EQ(data_size_in_bytes / kBytesPerSample, in_number_frames); 1062 RTC_CHECK_EQ(data_size_in_bytes / kBytesPerSample, in_number_frames);
1055 SInt8* data = static_cast<SInt8*>(io_data->mBuffers[0].mData); 1063 SInt8* data = static_cast<SInt8*>(io_data->mBuffers[0].mData);
1056 fine_audio_buffer_->DeliverRecordedData(data, data_size_in_bytes, 1064 fine_audio_buffer_->DeliverRecordedData(data, data_size_in_bytes,
1057 kFixedPlayoutDelayEstimate, 1065 kFixedPlayoutDelayEstimate,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 // Read decoded 16-bit PCM samples from WebRTC (using a size that matches 1103 // Read decoded 16-bit PCM samples from WebRTC (using a size that matches
1096 // the native I/O audio unit) to a preallocated intermediate buffer and 1104 // the native I/O audio unit) to a preallocated intermediate buffer and
1097 // copy the result to the audio buffer in the |io_data| destination. 1105 // copy the result to the audio buffer in the |io_data| destination.
1098 SInt8* source = playout_audio_buffer_.get(); 1106 SInt8* source = playout_audio_buffer_.get();
1099 fine_audio_buffer_->GetPlayoutData(source); 1107 fine_audio_buffer_->GetPlayoutData(source);
1100 memcpy(destination, source, dataSizeInBytes); 1108 memcpy(destination, source, dataSizeInBytes);
1101 return noErr; 1109 return noErr;
1102 } 1110 }
1103 1111
1104 } // namespace webrtc 1112 } // namespace webrtc
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698