summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorblundell@chromium.org <blundell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-07 17:38:54 +0000
committerblundell@chromium.org <blundell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-07 17:38:54 +0000
commitf197e838dea659748724adaffda7a4c9db0c3bc6 (patch)
treea64f37745baecdd3d123bcef00b1eb355d68e69f /media
parent392738bbb1f7d1e25429fbf53e70054f71d9101a (diff)
downloadchromium_src-f197e838dea659748724adaffda7a4c9db0c3bc6.zip
chromium_src-f197e838dea659748724adaffda7a4c9db0c3bc6.tar.gz
chromium_src-f197e838dea659748724adaffda7a4c9db0c3bc6.tar.bz2
Create iOS Audio Manager implementation.
The iOS audio manager supports audio input only (for voice search). This CL also makes slight changes to audio_input_mac to make it usable on iOS. BUG=None Review URL: https://chromiumcodereview.appspot.com/10907110 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@155416 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/audio/ios/audio_manager_ios.h55
-rw-r--r--media/audio/ios/audio_manager_ios.mm119
-rw-r--r--media/audio/ios/audio_manager_ios_unittest.cc33
-rw-r--r--media/audio/mac/audio_input_mac.cc15
-rw-r--r--media/audio/mac/audio_input_mac.h6
-rw-r--r--media/media.gyp17
6 files changed, 236 insertions, 9 deletions
diff --git a/media/audio/ios/audio_manager_ios.h b/media/audio/ios/audio_manager_ios.h
new file mode 100644
index 0000000..55cbe6e
--- /dev/null
+++ b/media/audio/ios/audio_manager_ios.h
@@ -0,0 +1,55 @@
+// 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.
+
+#ifndef MEDIA_AUDIO_IOS_AUDIO_MANAGER_IOS_H_
+#define MEDIA_AUDIO_IOS_AUDIO_MANAGER_IOS_H_
+
+#include "base/basictypes.h"
+#include "media/audio/audio_manager_base.h"
+
+namespace media {
+
+class PCMQueueInAudioInputStream;
+class PCMQueueOutAudioOutputStream;
+
+// iOS implementation of the AudioManager singleton. Supports only audio input.
+class MEDIA_EXPORT AudioManagerIOS : public AudioManagerBase {
+ public:
+ AudioManagerIOS();
+
+ // Implementation of AudioManager.
+ virtual bool HasAudioOutputDevices() OVERRIDE;
+ virtual bool HasAudioInputDevices() OVERRIDE;
+ virtual AudioOutputStream* MakeAudioOutputStream(
+ const AudioParameters& params) OVERRIDE;
+ virtual AudioInputStream* MakeAudioInputStream(
+ const AudioParameters& params, const std::string& device_id) OVERRIDE;
+
+ // Implementation of AudioManagerBase.
+ virtual AudioOutputStream* MakeLinearOutputStream(
+ const AudioParameters& params) OVERRIDE;
+ virtual AudioOutputStream* MakeLowLatencyOutputStream(
+ const AudioParameters& params) OVERRIDE;
+ virtual AudioInputStream* MakeLinearInputStream(
+ const AudioParameters& params, const std::string& device_id) OVERRIDE;
+ virtual AudioInputStream* MakeLowLatencyInputStream(
+ const AudioParameters& params, const std::string& device_id) OVERRIDE;
+ virtual void ReleaseOutputStream(AudioOutputStream* stream) OVERRIDE;
+ virtual void ReleaseInputStream(AudioInputStream* stream) OVERRIDE;
+
+ protected:
+ virtual ~AudioManagerIOS();
+
+ private:
+ // Initializes the audio session if necessary. Safe to call multiple times.
+ // Returns a bool indicating whether the audio session has been successfully
+ // initialized (either in the current call or in a previous call).
+ bool InitAudioSession();
+
+ DISALLOW_COPY_AND_ASSIGN(AudioManagerIOS);
+};
+
+} // namespace media
+
+#endif // MEDIA_AUDIO_IOS_AUDIO_MANAGER_IOS_H_
diff --git a/media/audio/ios/audio_manager_ios.mm b/media/audio/ios/audio_manager_ios.mm
new file mode 100644
index 0000000..fe93aee
--- /dev/null
+++ b/media/audio/ios/audio_manager_ios.mm
@@ -0,0 +1,119 @@
+// 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>
+
+#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);
+ 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_MOCK)
+ 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
diff --git a/media/audio/ios/audio_manager_ios_unittest.cc b/media/audio/ios/audio_manager_ios_unittest.cc
new file mode 100644
index 0000000..e8013cc
--- /dev/null
+++ b/media/audio/ios/audio_manager_ios_unittest.cc
@@ -0,0 +1,33 @@
+// 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 "base/basictypes.h"
+#include "media/audio/audio_io.h"
+#include "media/audio/audio_manager.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using namespace media;
+
+// Test that input is supported and output is not.
+TEST(IOSAudioTest, AudioSupport) {
+ AudioManager* audio_manager = AudioManager::Create();
+ ASSERT_TRUE(NULL != audio_manager);
+ ASSERT_FALSE(audio_manager->HasAudioOutputDevices());
+ ASSERT_TRUE(audio_manager->HasAudioInputDevices());
+}
+
+// Test that input stream can be opened and closed.
+TEST(IOSAudioTest, InputStreamOpenAndClose) {
+ AudioManager* audio_manager = AudioManager::Create();
+ ASSERT_TRUE(NULL != audio_manager);
+ if (!audio_manager->HasAudioInputDevices())
+ return;
+ AudioInputStream* ias = audio_manager->MakeAudioInputStream(
+ AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_STEREO,
+ 8000, 16, 1024),
+ std::string("test_device"));
+ ASSERT_TRUE(NULL != ias);
+ EXPECT_TRUE(ias->Open());
+ ias->Close();
+}
diff --git a/media/audio/mac/audio_input_mac.cc b/media/audio/mac/audio_input_mac.cc
index c70b80b..fd2d9be 100644
--- a/media/audio/mac/audio_input_mac.cc
+++ b/media/audio/mac/audio_input_mac.cc
@@ -4,17 +4,20 @@
#include "media/audio/mac/audio_input_mac.h"
-#include <CoreServices/CoreServices.h>
-
#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/mac/mac_logging.h"
+#include "media/audio/audio_manager_base.h"
#include "media/audio/audio_util.h"
-#include "media/audio/mac/audio_manager_mac.h"
+
+#if !defined(OS_IOS)
+#include <CoreServices/CoreServices.h>
+#endif
namespace media {
PCMQueueInAudioInputStream::PCMQueueInAudioInputStream(
- AudioManagerMac* manager, const AudioParameters& params)
+ AudioManagerBase* manager, const AudioParameters& params)
: manager_(manager),
callback_(NULL),
audio_queue_(NULL),
@@ -134,8 +137,8 @@ bool PCMQueueInAudioInputStream::GetAutomaticGainControl() {
void PCMQueueInAudioInputStream::HandleError(OSStatus err) {
if (callback_)
callback_->OnError(this, static_cast<int>(err));
- NOTREACHED() << "error " << GetMacOSStatusErrorString(err)
- << " (" << err << ")";
+ // This point should never be reached.
+ OSSTATUS_DCHECK(0, err);
}
bool PCMQueueInAudioInputStream::SetupBuffers() {
diff --git a/media/audio/mac/audio_input_mac.h b/media/audio/mac/audio_input_mac.h
index d290bcb..5f52d53 100644
--- a/media/audio/mac/audio_input_mac.h
+++ b/media/audio/mac/audio_input_mac.h
@@ -14,14 +14,14 @@
namespace media {
-class AudioManagerMac;
+class AudioManagerBase;
// Implementation of AudioInputStream for Mac OS X using the audio queue service
// present in OS 10.5 and later. Design reflects PCMQueueOutAudioOutputStream.
class PCMQueueInAudioInputStream : public AudioInputStream {
public:
// Parameters as per AudioManager::MakeAudioInputStream.
- PCMQueueInAudioInputStream(AudioManagerMac* manager,
+ PCMQueueInAudioInputStream(AudioManagerBase* manager,
const AudioParameters& params);
virtual ~PCMQueueInAudioInputStream();
@@ -65,7 +65,7 @@ class PCMQueueInAudioInputStream : public AudioInputStream {
static const int kNumberBuffers = 3;
// Manager that owns this stream, used for closing down.
- AudioManagerMac* manager_;
+ AudioManagerBase* manager_;
// We use the callback mostly to periodically supply the recorded audio data.
AudioInputCallback* callback_;
// Structure that holds the stream format details such as bitrate.
diff --git a/media/media.gyp b/media/media.gyp
index c039481..3cfcc2e 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -89,6 +89,8 @@
'audio/fake_audio_input_stream.h',
'audio/fake_audio_output_stream.cc',
'audio/fake_audio_output_stream.h',
+ 'audio/ios/audio_manager_ios.h',
+ 'audio/ios/audio_manager_ios.mm',
'audio/linux/alsa_input.cc',
'audio/linux/alsa_input.h',
'audio/linux/alsa_output.cc',
@@ -379,6 +381,8 @@
['include', '^audio/audio_parameters\\.'],
['include', '^audio/fake_audio_input_stream\\.'],
['include', '^audio/fake_audio_output_stream\\.'],
+ ['include', '^audio/ios/audio_manager_ios\\.'],
+ ['include', '^base/audio_bus\\.'],
['include', '^base/channel_layout\\.'],
['include', '^base/media\\.h$'],
['include', '^base/media_stub\\.cc$'],
@@ -539,6 +543,15 @@
],
}],
],
+ 'target_conditions': [
+ ['OS == "ios"', {
+ 'sources/': [
+ # Pull in specific Mac files for iOS (which have been filtered out
+ # by file name rules).
+ ['include', '^audio/mac/audio_input_mac\\.'],
+ ],
+ }],
+ ],
},
{
'target_name': 'media_unittests',
@@ -566,6 +579,7 @@
'audio/audio_parameters_unittest.cc',
'audio/audio_util_unittest.cc',
'audio/cross_process_notification_unittest.cc',
+ 'audio/ios/audio_manager_ios_unittest.cc',
'audio/linux/alsa_output_unittest.cc',
'audio/mac/audio_low_latency_input_mac_unittest.cc',
'audio/mac/audio_output_mac_unittest.cc',
@@ -646,7 +660,10 @@
['OS == "ios"', {
'sources/': [
['exclude', '.*'],
+ ['include', '^audio/audio_input_controller_unittest\\.cc$'],
+ ['include', '^audio/audio_input_unittest\\.cc$'],
['include', '^audio/audio_parameters_unittest\\.cc$'],
+ ['include', '^audio/ios/audio_manager_ios_unittest\\.cc$'],
['include', '^base/mock_reader\\.h$'],
['include', '^base/run_all_unittests\\.cc$'],
],