| // Copyright 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "media/audio/ios/audio_manager_ios.h" |
| |
| #import <AudioToolbox/AudioToolbox.h> |
| #import <AVFoundation/AVFoundation.h> |
| |
| #include "base/sys_info.h" |
| #include "media/audio/fake_audio_input_stream.h" |
| #include "media/audio/mac/audio_input_mac.h" |
| #include "media/base/limits.h" |
| |
| namespace media { |
| |
| enum { kMaxInputChannels = 2 }; |
| |
| // Initializes the audio session, returning a bool indicating whether |
| // initialization was successful. Should only be called once. |
| static bool InitAudioSessionInternal() { |
| OSStatus error = AudioSessionInitialize(NULL, NULL, NULL, NULL); |
| DCHECK(error != kAudioSessionAlreadyInitialized); |
| AVAudioSession* audioSession = [AVAudioSession sharedInstance]; |
| BOOL result = [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord |
| error:nil]; |
| DCHECK(result); |
| UInt32 allowMixing = true; |
| AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, |
| sizeof(allowMixing), &allowMixing); |
| return error == kAudioSessionNoError; |
| } |
| |
| AudioManagerIOS::AudioManagerIOS() { |
| } |
| |
| AudioManagerIOS::~AudioManagerIOS() { |
| Shutdown(); |
| } |
| |
| bool AudioManagerIOS::HasAudioOutputDevices() { |
| return false; |
| } |
| |
| bool AudioManagerIOS::HasAudioInputDevices() { |
| if (!InitAudioSession()) |
| return false; |
| // Note that the |kAudioSessionProperty_AudioInputAvailable| property is a |
| // 32-bit integer, not a boolean. |
| UInt32 property_size; |
| OSStatus error = |
| AudioSessionGetPropertySize(kAudioSessionProperty_AudioInputAvailable, |
| &property_size); |
| if (error != kAudioSessionNoError) |
| return false; |
| UInt32 audio_input_is_available = false; |
| DCHECK(property_size == sizeof(audio_input_is_available)); |
| error = AudioSessionGetProperty(kAudioSessionProperty_AudioInputAvailable, |
| &property_size, |
| &audio_input_is_available); |
| return error == kAudioSessionNoError ? audio_input_is_available : false; |
| } |
| |
| AudioOutputStream* AudioManagerIOS::MakeAudioOutputStream( |
| const AudioParameters& params) { |
| NOTIMPLEMENTED(); // Only input is supported on iOS. |
| return NULL; |
| } |
| |
| AudioInputStream* AudioManagerIOS::MakeAudioInputStream( |
| const AudioParameters& params, const std::string& device_id) { |
| // Current line of iOS devices has only one audio input. |
| // Ignore the device_id (unittest uses a test value in it). |
| if (!params.IsValid() || (params.channels() > kMaxInputChannels)) |
| return NULL; |
| |
| if (params.format() == AudioParameters::AUDIO_FAKE) |
| return FakeAudioInputStream::MakeFakeStream(this, params); |
| else if (params.format() == AudioParameters::AUDIO_PCM_LINEAR) |
| return new PCMQueueInAudioInputStream(this, params); |
| return NULL; |
| } |
| |
| AudioOutputStream* AudioManagerIOS::MakeLinearOutputStream( |
| const AudioParameters& params) { |
| NOTIMPLEMENTED(); // Only input is supported on iOS. |
| return NULL; |
| } |
| |
| AudioOutputStream* AudioManagerIOS::MakeLowLatencyOutputStream( |
| const AudioParameters& params) { |
| NOTIMPLEMENTED(); // Only input is supported on iOS. |
| return NULL; |
| } |
| |
| AudioInputStream* AudioManagerIOS::MakeLinearInputStream( |
| const AudioParameters& params, const std::string& device_id) { |
| return MakeAudioInputStream(params, device_id); |
| } |
| |
| AudioInputStream* AudioManagerIOS::MakeLowLatencyInputStream( |
| const AudioParameters& params, const std::string& device_id) { |
| NOTIMPLEMENTED(); // Only linear audio input is supported on iOS. |
| return MakeAudioInputStream(params, device_id); |
| } |
| |
| // Called by the stream when it has been released by calling Close(). |
| void AudioManagerIOS::ReleaseOutputStream(AudioOutputStream* stream) { |
| NOTIMPLEMENTED(); // Only input is supported on iOS. |
| } |
| |
| // Called by the stream when it has been released by calling Close(). |
| void AudioManagerIOS::ReleaseInputStream(AudioInputStream* stream) { |
| delete stream; |
| } |
| |
| bool AudioManagerIOS::InitAudioSession() { |
| static const bool kSessionInitialized = InitAudioSessionInternal(); |
| return kSessionInitialized; |
| } |
| |
| // static |
| AudioManager* CreateAudioManager() { |
| return new AudioManagerIOS(); |
| } |
| |
| } // namespace media |