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 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 LOG(LS_INFO) << " system version: " << ios::GetSystemVersion(); | 186 LOG(LS_INFO) << " system version: " << ios::GetSystemVersion(); |
187 LOG(LS_INFO) << " device type: " << ios::GetDeviceType(); | 187 LOG(LS_INFO) << " device type: " << ios::GetDeviceType(); |
188 LOG(LS_INFO) << " device name: " << ios::GetDeviceName(); | 188 LOG(LS_INFO) << " device name: " << ios::GetDeviceName(); |
189 } | 189 } |
190 } | 190 } |
191 #endif // !defined(NDEBUG) | 191 #endif // !defined(NDEBUG) |
192 | 192 |
193 AudioDeviceIOS::AudioDeviceIOS() | 193 AudioDeviceIOS::AudioDeviceIOS() |
194 : audio_device_buffer_(nullptr), | 194 : audio_device_buffer_(nullptr), |
195 vpio_unit_(nullptr), | 195 vpio_unit_(nullptr), |
| 196 recording_(0), |
| 197 playing_(0), |
196 initialized_(false), | 198 initialized_(false), |
197 rec_is_initialized_(false), | 199 rec_is_initialized_(false), |
198 play_is_initialized_(false), | 200 play_is_initialized_(false), |
199 audio_interruption_observer_(nullptr), | 201 audio_interruption_observer_(nullptr), |
200 route_change_observer_(nullptr) { | 202 route_change_observer_(nullptr) { |
201 LOGI() << "ctor" << ios::GetCurrentThreadDescription(); | 203 LOGI() << "ctor" << ios::GetCurrentThreadDescription(); |
202 } | 204 } |
203 | 205 |
204 AudioDeviceIOS::~AudioDeviceIOS() { | 206 AudioDeviceIOS::~AudioDeviceIOS() { |
205 LOGI() << "~dtor"; | 207 LOGI() << "~dtor"; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 ShutdownPlayOrRecord(); | 249 ShutdownPlayOrRecord(); |
248 initialized_ = false; | 250 initialized_ = false; |
249 return 0; | 251 return 0; |
250 } | 252 } |
251 | 253 |
252 int32_t AudioDeviceIOS::InitPlayout() { | 254 int32_t AudioDeviceIOS::InitPlayout() { |
253 LOGI() << "InitPlayout"; | 255 LOGI() << "InitPlayout"; |
254 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 256 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
255 RTC_DCHECK(initialized_); | 257 RTC_DCHECK(initialized_); |
256 RTC_DCHECK(!play_is_initialized_); | 258 RTC_DCHECK(!play_is_initialized_); |
257 RTC_DCHECK(!Playing()); | 259 RTC_DCHECK(!playing_); |
258 if (!rec_is_initialized_) { | 260 if (!rec_is_initialized_) { |
259 if (!InitPlayOrRecord()) { | 261 if (!InitPlayOrRecord()) { |
260 LOG_F(LS_ERROR) << "InitPlayOrRecord failed!"; | 262 LOG_F(LS_ERROR) << "InitPlayOrRecord failed!"; |
261 return -1; | 263 return -1; |
262 } | 264 } |
263 } | 265 } |
264 play_is_initialized_ = true; | 266 play_is_initialized_ = true; |
265 return 0; | 267 return 0; |
266 } | 268 } |
267 | 269 |
268 int32_t AudioDeviceIOS::InitRecording() { | 270 int32_t AudioDeviceIOS::InitRecording() { |
269 LOGI() << "InitRecording"; | 271 LOGI() << "InitRecording"; |
270 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 272 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
271 RTC_DCHECK(initialized_); | 273 RTC_DCHECK(initialized_); |
272 RTC_DCHECK(!rec_is_initialized_); | 274 RTC_DCHECK(!rec_is_initialized_); |
273 RTC_DCHECK(!Recording()); | 275 RTC_DCHECK(!recording_); |
274 if (!play_is_initialized_) { | 276 if (!play_is_initialized_) { |
275 if (!InitPlayOrRecord()) { | 277 if (!InitPlayOrRecord()) { |
276 LOG_F(LS_ERROR) << "InitPlayOrRecord failed!"; | 278 LOG_F(LS_ERROR) << "InitPlayOrRecord failed!"; |
277 return -1; | 279 return -1; |
278 } | 280 } |
279 } | 281 } |
280 rec_is_initialized_ = true; | 282 rec_is_initialized_ = true; |
281 return 0; | 283 return 0; |
282 } | 284 } |
283 | 285 |
284 int32_t AudioDeviceIOS::StartPlayout() { | 286 int32_t AudioDeviceIOS::StartPlayout() { |
285 LOGI() << "StartPlayout"; | 287 LOGI() << "StartPlayout"; |
286 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 288 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
287 RTC_DCHECK(play_is_initialized_); | 289 RTC_DCHECK(play_is_initialized_); |
288 RTC_DCHECK(!Playing()); | 290 RTC_DCHECK(!playing_); |
289 fine_audio_buffer_->ResetPlayout(); | 291 fine_audio_buffer_->ResetPlayout(); |
290 if (!Recording()) { | 292 if (!recording_) { |
291 OSStatus result = AudioOutputUnitStart(vpio_unit_); | 293 OSStatus result = AudioOutputUnitStart(vpio_unit_); |
292 if (result != noErr) { | 294 if (result != noErr) { |
293 LOG_F(LS_ERROR) << "AudioOutputUnitStart failed: " << result; | 295 LOG_F(LS_ERROR) << "AudioOutputUnitStart failed: " << result; |
294 return -1; | 296 return -1; |
295 } | 297 } |
296 } | 298 } |
297 rtc::AtomicInt::ReleaseStore(&playing_, 1); | 299 rtc::AtomicOps::ReleaseStore(&playing_, 1); |
298 return 0; | 300 return 0; |
299 } | 301 } |
300 | 302 |
301 int32_t AudioDeviceIOS::StopPlayout() { | 303 int32_t AudioDeviceIOS::StopPlayout() { |
302 LOGI() << "StopPlayout"; | 304 LOGI() << "StopPlayout"; |
303 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 305 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
304 if (!play_is_initialized_ || !Playing()) { | 306 if (!play_is_initialized_ || !playing_) { |
305 return 0; | 307 return 0; |
306 } | 308 } |
307 if (!Recording()) { | 309 if (!recording_) { |
308 ShutdownPlayOrRecord(); | 310 ShutdownPlayOrRecord(); |
309 } | 311 } |
310 play_is_initialized_ = false; | 312 play_is_initialized_ = false; |
311 rtc::AtomicInt::ReleaseStore(&playing_, 0); | 313 rtc::AtomicOps::ReleaseStore(&playing_, 0); |
312 return 0; | 314 return 0; |
313 } | 315 } |
314 | 316 |
315 int32_t AudioDeviceIOS::StartRecording() { | 317 int32_t AudioDeviceIOS::StartRecording() { |
316 LOGI() << "StartRecording"; | 318 LOGI() << "StartRecording"; |
317 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 319 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
318 RTC_DCHECK(rec_is_initialized_); | 320 RTC_DCHECK(rec_is_initialized_); |
319 RTC_DCHECK(!Recording()); | 321 RTC_DCHECK(!recording_); |
320 fine_audio_buffer_->ResetRecord(); | 322 fine_audio_buffer_->ResetRecord(); |
321 if (!Playing()) { | 323 if (!playing_) { |
322 OSStatus result = AudioOutputUnitStart(vpio_unit_); | 324 OSStatus result = AudioOutputUnitStart(vpio_unit_); |
323 if (result != noErr) { | 325 if (result != noErr) { |
324 LOG_F(LS_ERROR) << "AudioOutputUnitStart failed: " << result; | 326 LOG_F(LS_ERROR) << "AudioOutputUnitStart failed: " << result; |
325 return -1; | 327 return -1; |
326 } | 328 } |
327 } | 329 } |
328 rtc::AtomicInt::ReleaseStore(&recording_, 1); | 330 rtc::AtomicOps::ReleaseStore(&recording_, 1); |
329 return 0; | 331 return 0; |
330 } | 332 } |
331 | 333 |
332 int32_t AudioDeviceIOS::StopRecording() { | 334 int32_t AudioDeviceIOS::StopRecording() { |
333 LOGI() << "StopRecording"; | 335 LOGI() << "StopRecording"; |
334 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 336 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
335 if (!rec_is_initialized_ || !Recording()) { | 337 if (!rec_is_initialized_ || !recording_) { |
336 return 0; | 338 return 0; |
337 } | 339 } |
338 if (!Playing()) { | 340 if (!playing_) { |
339 ShutdownPlayOrRecord(); | 341 ShutdownPlayOrRecord(); |
340 } | 342 } |
341 rec_is_initialized_ = false; | 343 rec_is_initialized_ = false; |
342 rtc::AtomicInt::ReleaseStore(&recording_, 0); | 344 rtc::AtomicOps::ReleaseStore(&recording_, 0); |
343 return 0; | 345 return 0; |
344 } | 346 } |
345 | 347 |
346 // Change the default receiver playout route to speaker. | 348 // Change the default receiver playout route to speaker. |
347 int32_t AudioDeviceIOS::SetLoudspeakerStatus(bool enable) { | 349 int32_t AudioDeviceIOS::SetLoudspeakerStatus(bool enable) { |
348 LOGI() << "SetLoudspeakerStatus(" << enable << ")"; | 350 LOGI() << "SetLoudspeakerStatus(" << enable << ")"; |
349 | 351 |
350 AVAudioSession* session = [AVAudioSession sharedInstance]; | 352 AVAudioSession* session = [AVAudioSession sharedInstance]; |
351 NSString* category = session.category; | 353 NSString* category = session.category; |
352 AVAudioSessionCategoryOptions options = session.categoryOptions; | 354 AVAudioSessionCategoryOptions options = session.categoryOptions; |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
842 io_action_flags, in_time_stamp, in_bus_number, in_number_frames); | 844 io_action_flags, in_time_stamp, in_bus_number, in_number_frames); |
843 } | 845 } |
844 | 846 |
845 OSStatus AudioDeviceIOS::OnRecordedDataIsAvailable( | 847 OSStatus AudioDeviceIOS::OnRecordedDataIsAvailable( |
846 AudioUnitRenderActionFlags* io_action_flags, | 848 AudioUnitRenderActionFlags* io_action_flags, |
847 const AudioTimeStamp* in_time_stamp, | 849 const AudioTimeStamp* in_time_stamp, |
848 UInt32 in_bus_number, | 850 UInt32 in_bus_number, |
849 UInt32 in_number_frames) { | 851 UInt32 in_number_frames) { |
850 OSStatus result = noErr; | 852 OSStatus result = noErr; |
851 // Simply return if recording is not enabled. | 853 // Simply return if recording is not enabled. |
852 if (!Recording()) | 854 if (!rtc::AtomicOps::AcquireLoad(&recording_)) |
853 return result; | 855 return result; |
854 if (in_number_frames != record_parameters_.frames_per_buffer()) { | 856 if (in_number_frames != record_parameters_.frames_per_buffer()) { |
855 // We have seen short bursts (1-2 frames) where |in_number_frames| changes. | 857 // We have seen short bursts (1-2 frames) where |in_number_frames| changes. |
856 // Add a log to keep track of longer sequences if that should ever happen. | 858 // Add a log to keep track of longer sequences if that should ever happen. |
857 LOG(LS_WARNING) << "in_number_frames (" << in_number_frames | 859 LOG(LS_WARNING) << "in_number_frames (" << in_number_frames |
858 << ") != " << record_parameters_.frames_per_buffer(); | 860 << ") != " << record_parameters_.frames_per_buffer(); |
859 } | 861 } |
860 // Obtain the recorded audio samples by initiating a rendering cycle. | 862 // Obtain the recorded audio samples by initiating a rendering cycle. |
861 // Since it happens on the input bus, the |io_data| parameter is a reference | 863 // Since it happens on the input bus, the |io_data| parameter is a reference |
862 // to the preallocated audio buffer list that the audio unit renders into. | 864 // to the preallocated audio buffer list that the audio unit renders into. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
901 // Verify 16-bit, noninterleaved mono PCM signal format. | 903 // Verify 16-bit, noninterleaved mono PCM signal format. |
902 RTC_DCHECK_EQ(1u, io_data->mNumberBuffers); | 904 RTC_DCHECK_EQ(1u, io_data->mNumberBuffers); |
903 RTC_DCHECK_EQ(1u, io_data->mBuffers[0].mNumberChannels); | 905 RTC_DCHECK_EQ(1u, io_data->mBuffers[0].mNumberChannels); |
904 // Get pointer to internal audio buffer to which new audio data shall be | 906 // Get pointer to internal audio buffer to which new audio data shall be |
905 // written. | 907 // written. |
906 const UInt32 dataSizeInBytes = io_data->mBuffers[0].mDataByteSize; | 908 const UInt32 dataSizeInBytes = io_data->mBuffers[0].mDataByteSize; |
907 RTC_CHECK_EQ(dataSizeInBytes / kBytesPerSample, in_number_frames); | 909 RTC_CHECK_EQ(dataSizeInBytes / kBytesPerSample, in_number_frames); |
908 SInt8* destination = static_cast<SInt8*>(io_data->mBuffers[0].mData); | 910 SInt8* destination = static_cast<SInt8*>(io_data->mBuffers[0].mData); |
909 // Produce silence and give audio unit a hint about it if playout is not | 911 // Produce silence and give audio unit a hint about it if playout is not |
910 // activated. | 912 // activated. |
911 if (!Playing()) { | 913 if (!rtc::AtomicOps::AcquireLoad(&playing_)) { |
912 *io_action_flags |= kAudioUnitRenderAction_OutputIsSilence; | 914 *io_action_flags |= kAudioUnitRenderAction_OutputIsSilence; |
913 memset(destination, 0, dataSizeInBytes); | 915 memset(destination, 0, dataSizeInBytes); |
914 return noErr; | 916 return noErr; |
915 } | 917 } |
916 // Read decoded 16-bit PCM samples from WebRTC (using a size that matches | 918 // Read decoded 16-bit PCM samples from WebRTC (using a size that matches |
917 // the native I/O audio unit) to a preallocated intermediate buffer and | 919 // the native I/O audio unit) to a preallocated intermediate buffer and |
918 // copy the result to the audio buffer in the |io_data| destination. | 920 // copy the result to the audio buffer in the |io_data| destination. |
919 SInt8* source = playout_audio_buffer_.get(); | 921 SInt8* source = playout_audio_buffer_.get(); |
920 fine_audio_buffer_->GetPlayoutData(source); | 922 fine_audio_buffer_->GetPlayoutData(source); |
921 memcpy(destination, source, dataSizeInBytes); | 923 memcpy(destination, source, dataSizeInBytes); |
922 return noErr; | 924 return noErr; |
923 } | 925 } |
924 | 926 |
925 } // namespace webrtc | 927 } // namespace webrtc |
OLD | NEW |