summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorxians@chromium.org <xians@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-22 14:28:21 +0000
committerxians@chromium.org <xians@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-22 14:28:21 +0000
commitb97f3c2e2c5ba4cdce59124efd6d3a34b53565f4 (patch)
treed62780b2284121c8089589ab71f28d67bfcd418f /media
parent0220b90986bc17a31222133204c7ff6a9d63b266 (diff)
downloadchromium_src-b97f3c2e2c5ba4cdce59124efd6d3a34b53565f4.zip
chromium_src-b97f3c2e2c5ba4cdce59124efd6d3a34b53565f4.tar.gz
chromium_src-b97f3c2e2c5ba4cdce59124efd6d3a34b53565f4.tar.bz2
Enable the device selection for linux and mac by passing a device unique id from renderer down to the browser.
With this patch, users should be able to create a audio stream with a non-default device, and feature is only available for low-latency audio. TEST=media_unittests, webrtc test app BUG=None Review URL: http://codereview.chromium.org/8491044 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111153 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/audio/audio_input_controller.cc14
-rw-r--r--media/audio/audio_input_controller.h5
-rw-r--r--media/audio/audio_input_device_unittest.cc7
-rw-r--r--media/audio/audio_input_unittest.cc23
-rw-r--r--media/audio/audio_manager.h2
-rw-r--r--media/audio/audio_manager_base.cc1
-rw-r--r--media/audio/audio_manager_base.h2
-rw-r--r--media/audio/audio_output_proxy_unittest.cc4
-rw-r--r--media/audio/linux/alsa_output_unittest.cc4
-rw-r--r--media/audio/linux/audio_manager_linux.cc20
-rw-r--r--media/audio/linux/audio_manager_linux.h4
-rw-r--r--media/audio/mac/audio_low_latency_input_mac.cc34
-rw-r--r--media/audio/mac/audio_low_latency_input_mac.h3
-rw-r--r--media/audio/mac/audio_low_latency_input_mac_unittest.cc8
-rw-r--r--media/audio/mac/audio_manager_mac.cc65
-rw-r--r--media/audio/mac/audio_manager_mac.h2
-rw-r--r--media/audio/win/audio_low_latency_input_win_unittest.cc5
-rw-r--r--media/audio/win/audio_manager_win.cc17
-rw-r--r--media/audio/win/audio_manager_win.h2
19 files changed, 144 insertions, 78 deletions
diff --git a/media/audio/audio_input_controller.cc b/media/audio/audio_input_controller.cc
index 1e264e6..197378c 100644
--- a/media/audio/audio_input_controller.cc
+++ b/media/audio/audio_input_controller.cc
@@ -50,9 +50,12 @@ scoped_refptr<AudioInputController> AudioInputController::Create(
event_handler, NULL));
// Start the thread and post a task to create the audio input stream.
+ // Pass an empty string to indicate using default device.
+ std::string device_id = AudioManagerBase::kDefaultDeviceId;
controller->thread_.Start();
controller->thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
- &AudioInputController::DoCreate, controller.get(), params));
+ &AudioInputController::DoCreate, controller.get(),
+ params, device_id));
return controller;
}
@@ -60,6 +63,7 @@ scoped_refptr<AudioInputController> AudioInputController::Create(
scoped_refptr<AudioInputController> AudioInputController::CreateLowLatency(
EventHandler* event_handler,
const AudioParameters& params,
+ const std::string& device_id,
SyncWriter* sync_writer) {
DCHECK(sync_writer);
@@ -76,7 +80,7 @@ scoped_refptr<AudioInputController> AudioInputController::CreateLowLatency(
// Start the thread and post a task to create the audio input stream.
controller->thread_.Start();
controller->thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
- &AudioInputController::DoCreate, controller.get(), params));
+ &AudioInputController::DoCreate, controller.get(), params, device_id));
return controller;
}
@@ -108,8 +112,10 @@ void AudioInputController::Close() {
thread_.Stop();
}
-void AudioInputController::DoCreate(const AudioParameters& params) {
- stream_ = AudioManager::GetAudioManager()->MakeAudioInputStream(params);
+void AudioInputController::DoCreate(const AudioParameters& params,
+ const std::string& device_id) {
+ stream_ = AudioManager::GetAudioManager()->MakeAudioInputStream(params,
+ device_id);
if (!stream_) {
// TODO(satish): Define error types.
diff --git a/media/audio/audio_input_controller.h b/media/audio/audio_input_controller.h
index 909f3dd..387041a 100644
--- a/media/audio/audio_input_controller.h
+++ b/media/audio/audio_input_controller.h
@@ -11,7 +11,7 @@
#include "base/threading/thread.h"
#include "base/timer.h"
#include "media/audio/audio_io.h"
-#include "media/audio/audio_manager.h"
+#include "media/audio/audio_manager_base.h"
// An AudioInputController controls an AudioInputStream and records data
// from this input stream. It has an important function that it executes
@@ -93,6 +93,7 @@ class MEDIA_EXPORT AudioInputController
static scoped_refptr<AudioInputController> CreateLowLatency(
EventHandler* event_handler,
const AudioParameters& params,
+ const std::string& device_id,
// External synchronous reader for audio controller.
SyncWriter* sync_writer);
@@ -135,7 +136,7 @@ class MEDIA_EXPORT AudioInputController
AudioInputController(EventHandler* handler, SyncWriter* sync_writer);
// The following methods are executed on the audio controller thread.
- void DoCreate(const AudioParameters& params);
+ void DoCreate(const AudioParameters& params, const std::string& device_id);
void DoRecord();
void DoClose();
void DoReportError(int code);
diff --git a/media/audio/audio_input_device_unittest.cc b/media/audio/audio_input_device_unittest.cc
index 7812d3f..e709936 100644
--- a/media/audio/audio_input_device_unittest.cc
+++ b/media/audio/audio_input_device_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "media/audio/audio_manager.h"
+#include "media/audio/audio_manager_base.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace media {
@@ -16,8 +16,9 @@ TEST(AudioInputDeviceTest, EnumerateDevices) {
if (!device_names.empty()) {
AudioDeviceNames::const_iterator it = device_names.begin();
// The first device in the list is the prepended default device.
- EXPECT_EQ("Default", it->device_name);
- EXPECT_EQ("0", it->unique_id);
+ EXPECT_EQ(std::string(AudioManagerBase::kDefaultDeviceName),
+ it->device_name);
+ EXPECT_EQ(std::string(AudioManagerBase::kDefaultDeviceId), it->unique_id);
++it;
// Other devices should have non-empty name and id.
diff --git a/media/audio/audio_input_unittest.cc b/media/audio/audio_input_unittest.cc
index 914aa4c3..02b0625 100644
--- a/media/audio/audio_input_unittest.cc
+++ b/media/audio/audio_input_unittest.cc
@@ -8,7 +8,7 @@
#include "base/message_loop.h"
#include "base/threading/platform_thread.h"
#include "media/audio/audio_io.h"
-#include "media/audio/audio_manager.h"
+#include "media/audio/audio_manager_base.h"
#include "testing/gtest/include/gtest/gtest.h"
static const int kSamplingRate = 8000;
@@ -103,7 +103,8 @@ static AudioInputStream* CreateTestAudioInputStream() {
AudioManager* audio_man = AudioManager::GetAudioManager();
AudioInputStream* ais = audio_man->MakeAudioInputStream(
AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_STEREO,
- kSamplingRate, 16, kSamplesPerPacket));
+ kSamplingRate, 16, kSamplesPerPacket),
+ AudioManagerBase::kDefaultDeviceId);
EXPECT_TRUE(NULL != ais);
return ais;
}
@@ -116,27 +117,29 @@ TEST(AudioInputTest, SanityOnMakeParams) {
AudioParameters::Format fmt = AudioParameters::AUDIO_PCM_LINEAR;
EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
AudioParameters(fmt, CHANNEL_LAYOUT_7POINT1, 8000, 16,
- kSamplesPerPacket)));
+ kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId));
EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 1024 * 1024, 16,
- kSamplesPerPacket)));
+ kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId));
EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, 80,
- kSamplesPerPacket)));
+ kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId));
EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, 80,
- 1000 * kSamplesPerPacket)));
+ 1000 * kSamplesPerPacket),
+ AudioManagerBase::kDefaultDeviceId));
EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
AudioParameters(fmt, CHANNEL_LAYOUT_UNSUPPORTED, 8000, 16,
- kSamplesPerPacket)));
+ kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId));
EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, -8000, 16,
- kSamplesPerPacket)));
+ kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId));
EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, -16,
- kSamplesPerPacket)));
+ kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId));
EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
- AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, 16, -1024)));
+ AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, 16, -1024),
+ AudioManagerBase::kDefaultDeviceId));
}
// Test create and close of an AudioInputStream without recording audio.
diff --git a/media/audio/audio_manager.h b/media/audio/audio_manager.h
index 628eee9..eb94831 100644
--- a/media/audio/audio_manager.h
+++ b/media/audio/audio_manager.h
@@ -93,7 +93,7 @@ class MEDIA_EXPORT AudioManager {
// Do not free the returned AudioInputStream. It is owned by AudioManager.
// When you are done with it, call |Stop()| and |Close()| to release it.
virtual AudioInputStream* MakeAudioInputStream(
- const AudioParameters& params) = 0;
+ const AudioParameters& params, const std::string& device_id) = 0;
// Muting continues playback but effectively the volume is set to zero.
// Un-muting returns the volume to the previous level.
diff --git a/media/audio/audio_manager_base.cc b/media/audio/audio_manager_base.cc
index 5053e87..0c872ce 100644
--- a/media/audio/audio_manager_base.cc
+++ b/media/audio/audio_manager_base.cc
@@ -9,6 +9,7 @@
static const int kStreamCloseDelayMs = 5000;
const char AudioManagerBase::kDefaultDeviceName[] = "Default";
+const char AudioManagerBase::kDefaultDeviceId[] = "default";
AudioManagerBase::AudioManagerBase()
: audio_thread_("AudioThread"),
diff --git a/media/audio/audio_manager_base.h b/media/audio/audio_manager_base.h
index f24a299..025c35f 100644
--- a/media/audio/audio_manager_base.h
+++ b/media/audio/audio_manager_base.h
@@ -18,6 +18,8 @@ class MEDIA_EXPORT AudioManagerBase : public AudioManager {
public:
// Name of the generic "default" device.
static const char kDefaultDeviceName[];
+ // Unique Id of the generic "default" device.
+ static const char kDefaultDeviceId[];
AudioManagerBase();
diff --git a/media/audio/audio_output_proxy_unittest.cc b/media/audio/audio_output_proxy_unittest.cc
index 50a5020..c5d2e9e 100644
--- a/media/audio/audio_output_proxy_unittest.cc
+++ b/media/audio/audio_output_proxy_unittest.cc
@@ -44,8 +44,8 @@ class MockAudioManager : public AudioManager {
const AudioParameters& params));
MOCK_METHOD1(MakeAudioOutputStreamProxy, AudioOutputStream*(
const AudioParameters& params));
- MOCK_METHOD1(MakeAudioInputStream, AudioInputStream*(
- const AudioParameters& params));
+ MOCK_METHOD2(MakeAudioInputStream, AudioInputStream*(
+ const AudioParameters& params, const std::string& device_id));
MOCK_METHOD0(MuteAll, void());
MOCK_METHOD0(UnMuteAll, void());
MOCK_METHOD0(CanShowAudioInputSettings, bool());
diff --git a/media/audio/linux/alsa_output_unittest.cc b/media/audio/linux/alsa_output_unittest.cc
index e151f26..3191472 100644
--- a/media/audio/linux/alsa_output_unittest.cc
+++ b/media/audio/linux/alsa_output_unittest.cc
@@ -80,8 +80,8 @@ class MockAudioManagerLinux : public AudioManagerLinux {
MOCK_METHOD0(HasAudioInputDevices, bool());
MOCK_METHOD1(MakeAudioOutputStream, AudioOutputStream*(
const AudioParameters& params));
- MOCK_METHOD1(MakeAudioInputStream, AudioInputStream*(
- const AudioParameters& params));
+ MOCK_METHOD2(MakeAudioInputStream, AudioInputStream*(
+ const AudioParameters& params, const std::string& device_id));
MOCK_METHOD0(MuteAll, void());
MOCK_METHOD0(UnMuteAll, void());
diff --git a/media/audio/linux/audio_manager_linux.cc b/media/audio/linux/audio_manager_linux.cc
index bf684d5..656c0bc 100644
--- a/media/audio/linux/audio_manager_linux.cc
+++ b/media/audio/linux/audio_manager_linux.cc
@@ -36,7 +36,6 @@ static const char* kInvalidAudioInputDevices[] = {
"null",
"pulse",
"dmix",
- "surround",
};
// Implementation of AudioManager.
@@ -87,8 +86,9 @@ AudioOutputStream* AudioManagerLinux::MakeAudioOutputStream(
}
AudioInputStream* AudioManagerLinux::MakeAudioInputStream(
- const AudioParameters& params) {
- if (!params.IsValid() || params.channels > kMaxInputChannels)
+ const AudioParameters& params, const std::string& device_id) {
+ if (!params.IsValid() || params.channels > kMaxInputChannels ||
+ device_id.empty())
return NULL;
if (params.format == AudioParameters::AUDIO_MOCK) {
@@ -100,8 +100,8 @@ AudioInputStream* AudioManagerLinux::MakeAudioInputStream(
if (!initialized())
return NULL;
- // TODO(xians): Pass the device name From AudioInputController instead.
- std::string device_name = AlsaPcmOutputStream::kAutoSelectDevice;
+ std::string device_name = (device_id == AudioManagerBase::kDefaultDeviceId) ?
+ AlsaPcmInputStream::kAutoSelectDevice : device_id;
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAlsaInputDevice)) {
device_name = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kAlsaInputDevice);
@@ -183,7 +183,8 @@ void AudioManagerLinux::GetAudioInputDeviceNames(
// counting here since the default device has been abstracted out before.
// We use index 0 to make up the unique_id to identify the default device.
device_names->push_front(media::AudioDeviceName(
- AudioManagerBase::kDefaultDeviceName, "0"));
+ AudioManagerBase::kDefaultDeviceName,
+ AudioManagerBase::kDefaultDeviceId));
}
}
@@ -256,13 +257,16 @@ void AudioManagerLinux::GetAlsaDevicesInfo(
}
bool AudioManagerLinux::IsAlsaDeviceAvailable(const char* device_name) {
+ static const char kNotWantedSurroundDevices[] = "surround";
+
if (!device_name)
return false;
// Check if the device is in the list of invalid devices.
for (size_t i = 0; i < arraysize(kInvalidAudioInputDevices); ++i) {
- if (!strncmp(kInvalidAudioInputDevices[i], device_name,
- strlen(kInvalidAudioInputDevices[i])))
+ if ((strcmp(kInvalidAudioInputDevices[i], device_name) == 0) ||
+ (strncmp(kNotWantedSurroundDevices, device_name,
+ arraysize(kNotWantedSurroundDevices) - 1) == 0))
return false;
}
diff --git a/media/audio/linux/audio_manager_linux.h b/media/audio/linux/audio_manager_linux.h
index ed08a1a2..5185013 100644
--- a/media/audio/linux/audio_manager_linux.h
+++ b/media/audio/linux/audio_manager_linux.h
@@ -26,8 +26,8 @@ class MEDIA_EXPORT AudioManagerLinux : public AudioManagerBase {
virtual bool HasAudioInputDevices() OVERRIDE;
virtual AudioOutputStream* MakeAudioOutputStream(
const AudioParameters& params) OVERRIDE;
- virtual AudioInputStream* MakeAudioInputStream(const AudioParameters& params)
- OVERRIDE;
+ virtual AudioInputStream* MakeAudioInputStream(
+ const AudioParameters& params, const std::string& device_id) OVERRIDE;
virtual bool CanShowAudioInputSettings() OVERRIDE;
virtual void ShowAudioInputSettings() OVERRIDE;
virtual void GetAudioInputDeviceNames(media::AudioDeviceNames* device_names)
diff --git a/media/audio/mac/audio_low_latency_input_mac.cc b/media/audio/mac/audio_low_latency_input_mac.cc
index 34dbf745..00236fa 100644
--- a/media/audio/mac/audio_low_latency_input_mac.cc
+++ b/media/audio/mac/audio_low_latency_input_mac.cc
@@ -29,11 +29,12 @@ static std::ostream& operator<<(std::ostream& os,
// for more details and background regarding this implementation.
AUAudioInputStream::AUAudioInputStream(
- AudioManagerMac* manager, const AudioParameters& params)
+ AudioManagerMac* manager, const AudioParameters& params,
+ AudioDeviceID audio_device_id)
: manager_(manager),
sink_(NULL),
audio_unit_(0),
- input_device_id_(kAudioObjectUnknown),
+ input_device_id_(audio_device_id),
started_(false),
hardware_latency_frames_(0) {
DCHECK(manager_);
@@ -81,6 +82,10 @@ bool AUAudioInputStream::Open() {
if (audio_unit_)
return false;
+ // Verify that we have a valid device.
+ if (input_device_id_ == kAudioObjectUnknown)
+ return false;
+
// Start by obtaining an AudioOuputUnit using an AUHAL component description.
Component comp;
@@ -137,29 +142,6 @@ bool AUAudioInputStream::Open() {
return false;
}
- // Set the current device of the AudioOuputUnit to default input device.
-
- // First, obtain the current input device selected by the user.
- AudioObjectPropertyAddress default_intput_device_address = {
- kAudioHardwarePropertyDefaultInputDevice,
- kAudioObjectPropertyScopeGlobal,
- kAudioObjectPropertyElementMaster
- };
- AudioDeviceID input_device = kAudioObjectUnknown;
- UInt32 size = sizeof(input_device);
- result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
- &default_intput_device_address,
- 0,
- 0,
- &size,
- &input_device);
- if (result) {
- HandleError(result);
- return false;
- }
-
- input_device_id_ = input_device;
-
// Next, set the audio device to be the Audio Unit's current device.
// Note that, devices can only be set to the AUHAL after enabling IO.
result = AudioUnitSetProperty(audio_unit_,
@@ -167,7 +149,7 @@ bool AUAudioInputStream::Open() {
kAudioUnitScope_Global,
0,
&input_device_id_,
- sizeof(input_device));
+ sizeof(input_device_id_));
if (result) {
HandleError(result);
return false;
diff --git a/media/audio/mac/audio_low_latency_input_mac.h b/media/audio/mac/audio_low_latency_input_mac.h
index f3b2891..1b79172 100644
--- a/media/audio/mac/audio_low_latency_input_mac.h
+++ b/media/audio/mac/audio_low_latency_input_mac.h
@@ -50,7 +50,8 @@ class AUAudioInputStream : public AudioInputStream {
// The ctor takes all the usual parameters, plus |manager| which is the
// the audio manager who is creating this object.
AUAudioInputStream(AudioManagerMac* manager,
- const AudioParameters& params);
+ const AudioParameters& params,
+ AudioDeviceID audio_device_id);
// The dtor is typically called by the AudioManager only and it is usually
// triggered by calling AudioInputStream::Close().
virtual ~AUAudioInputStream();
diff --git a/media/audio/mac/audio_low_latency_input_mac_unittest.cc b/media/audio/mac/audio_low_latency_input_mac_unittest.cc
index 3d94ad6..e18f1c8 100644
--- a/media/audio/mac/audio_low_latency_input_mac_unittest.cc
+++ b/media/audio/mac/audio_low_latency_input_mac_unittest.cc
@@ -7,7 +7,7 @@
#include "base/test/test_timeouts.h"
#include "base/threading/platform_thread.h"
#include "media/audio/audio_io.h"
-#include "media/audio/audio_manager.h"
+#include "media/audio/audio_manager_base.h"
#include "media/audio/mac/audio_low_latency_input_mac.h"
#include "media/base/seekable_buffer.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -104,7 +104,8 @@ static AudioInputStream* CreateDefaultAudioInputStream() {
int samples_per_packet = fs / 100;
AudioInputStream* ais = audio_man->MakeAudioInputStream(
AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
- CHANNEL_LAYOUT_STEREO, fs, 16, samples_per_packet));
+ CHANNEL_LAYOUT_STEREO, fs, 16, samples_per_packet),
+ AudioManagerBase::kDefaultDeviceId);
EXPECT_TRUE(ais);
return ais;
}
@@ -117,7 +118,8 @@ static AudioInputStream* CreateAudioInputStream(ChannelLayout channel_layout) {
int samples_per_packet = fs / 100;
AudioInputStream* ais = audio_man->MakeAudioInputStream(
AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
- channel_layout, fs, 16, samples_per_packet));
+ channel_layout, fs, 16, samples_per_packet),
+ AudioManagerBase::kDefaultDeviceId);
EXPECT_TRUE(ais);
return ais;
}
diff --git a/media/audio/mac/audio_manager_mac.cc b/media/audio/mac/audio_manager_mac.cc
index 152375b..f2380cb 100644
--- a/media/audio/mac/audio_manager_mac.cc
+++ b/media/audio/mac/audio_manager_mac.cc
@@ -5,6 +5,7 @@
#include <CoreAudio/AudioHardware.h>
#include "base/mac/mac_util.h"
+#include "base/mac/scoped_cftyperef.h"
#include "base/sys_string_conversions.h"
#include "media/audio/fake_audio_input_stream.h"
#include "media/audio/fake_audio_output_stream.h"
@@ -182,6 +183,57 @@ static void GetAudioDeviceInfo(bool is_input,
}
}
+static AudioDeviceID GetAudioDeviceIdByUId(bool is_input,
+ const std::string& device_id) {
+ AudioObjectPropertyAddress property_address = {
+ kAudioHardwarePropertyDevices,
+ kAudioObjectPropertyScopeGlobal,
+ kAudioObjectPropertyElementMaster
+ };
+ AudioDeviceID audio_device_id = kAudioObjectUnknown;
+ UInt32 device_size = sizeof(audio_device_id);
+ OSStatus result = -1;
+
+ if (device_id == AudioManagerBase::kDefaultDeviceId) {
+ // Default Device.
+ property_address.mSelector = is_input ?
+ kAudioHardwarePropertyDefaultInputDevice :
+ kAudioHardwarePropertyDefaultOutputDevice;
+
+ result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
+ &property_address,
+ 0,
+ 0,
+ &device_size,
+ &audio_device_id);
+ } else {
+ // Non-default device.
+ base::mac::ScopedCFTypeRef<CFStringRef>
+ uid(base::SysUTF8ToCFStringRef(device_id));
+ AudioValueTranslation value;
+ value.mInputData = &uid;
+ value.mInputDataSize = sizeof(CFStringRef);
+ value.mOutputData = &audio_device_id;
+ value.mOutputDataSize = device_size;
+ UInt32 translation_size = sizeof(AudioValueTranslation);
+
+ property_address.mSelector = kAudioHardwarePropertyDeviceForUID;
+ result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
+ &property_address,
+ 0,
+ 0,
+ &translation_size,
+ &value);
+ }
+
+ if (result) {
+ DLOG(WARNING) << "Unable to query device " << device_id
+ << " for AudioDeviceID ";
+ }
+
+ return audio_device_id;
+}
+
AudioManagerMac::AudioManagerMac()
: num_output_streams_(0) {
}
@@ -211,7 +263,7 @@ void AudioManagerMac::GetAudioInputDeviceNames(
// counting here since the default device has been abstracted out before.
media::AudioDeviceName name;
name.device_name = AudioManagerBase::kDefaultDeviceName;
- name.unique_id = "0";
+ name.unique_id = AudioManagerBase::kDefaultDeviceId;
device_names->push_front(name);
}
}
@@ -242,8 +294,9 @@ AudioOutputStream* AudioManagerMac::MakeAudioOutputStream(
}
AudioInputStream* AudioManagerMac::MakeAudioInputStream(
- const AudioParameters& params) {
- if (!params.IsValid() || (params.channels > kMaxInputChannels))
+ const AudioParameters& params, const std::string& device_id) {
+ if (!params.IsValid() || (params.channels > kMaxInputChannels) ||
+ device_id.empty())
return NULL;
if (params.format == AudioParameters::AUDIO_MOCK) {
@@ -251,7 +304,11 @@ AudioInputStream* AudioManagerMac::MakeAudioInputStream(
} else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) {
return new PCMQueueInAudioInputStream(this, params);
} else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) {
- return new AUAudioInputStream(this, params);
+ // Gets the AudioDeviceID that refers to the AudioDevice with the device
+ // unique id. This AudioDeviceID is used to set the device for Audio Unit.
+ AudioDeviceID audio_device_id = GetAudioDeviceIdByUId(true, device_id);
+ if (audio_device_id != kAudioObjectUnknown)
+ return new AUAudioInputStream(this, params, audio_device_id);
}
return NULL;
}
diff --git a/media/audio/mac/audio_manager_mac.h b/media/audio/mac/audio_manager_mac.h
index 59d2fd8..c1e1659 100644
--- a/media/audio/mac/audio_manager_mac.h
+++ b/media/audio/mac/audio_manager_mac.h
@@ -24,7 +24,7 @@ class AudioManagerMac : public AudioManagerBase {
virtual AudioOutputStream* MakeAudioOutputStream(
const AudioParameters& params) OVERRIDE;
virtual AudioInputStream* MakeAudioInputStream(
- const AudioParameters& params) OVERRIDE;
+ const AudioParameters& params, const std::string& device_id) OVERRIDE;
virtual void MuteAll() OVERRIDE;
virtual void UnMuteAll() OVERRIDE;
diff --git a/media/audio/win/audio_low_latency_input_win_unittest.cc b/media/audio/win/audio_low_latency_input_win_unittest.cc
index 4741c05..6e0c8c0 100644
--- a/media/audio/win/audio_low_latency_input_win_unittest.cc
+++ b/media/audio/win/audio_low_latency_input_win_unittest.cc
@@ -11,7 +11,7 @@
#include "base/test/test_timeouts.h"
#include "base/win/scoped_com_initializer.h"
#include "media/audio/audio_io.h"
-#include "media/audio/audio_manager.h"
+#include "media/audio/audio_manager_base.h"
#include "media/audio/win/audio_low_latency_input_win.h"
#include "media/base/seekable_buffer.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -142,7 +142,8 @@ class AudioInputStreamWrapper {
AudioInputStream* CreateInputStream() {
AudioInputStream* ais = audio_man_->MakeAudioInputStream(
AudioParameters(format_, channel_layout_, sample_rate_,
- bits_per_sample_, samples_per_packet_));
+ bits_per_sample_, samples_per_packet_),
+ AudioManagerBase::kDefaultDeviceId);
EXPECT_TRUE(ais);
return ais;
}
diff --git a/media/audio/win/audio_manager_win.cc b/media/audio/win/audio_manager_win.cc
index 4e41394..c999f61 100644
--- a/media/audio/win/audio_manager_win.cc
+++ b/media/audio/win/audio_manager_win.cc
@@ -148,8 +148,9 @@ AudioOutputStream* AudioManagerWin::MakeAudioOutputStream(
// Factory for the implementations of AudioInputStream.
AudioInputStream* AudioManagerWin::MakeAudioInputStream(
- const AudioParameters& params) {
- if (!params.IsValid() || (params.channels > kWinMaxInputChannels))
+ const AudioParameters& params, const std::string& device_id) {
+ if (!params.IsValid() || (params.channels > kWinMaxInputChannels) ||
+ device_id.empty())
return NULL;
if (params.format == AudioParameters::AUDIO_MOCK) {
@@ -161,12 +162,16 @@ AudioInputStream* AudioManagerWin::MakeAudioInputStream(
if (base::win::GetVersion() <= base::win::VERSION_XP) {
// Fall back to Windows Wave implementation on Windows XP or lower.
DLOG(INFO) << "Using WaveIn since WASAPI requires at least Vista.";
- return new PCMWaveInAudioInputStream(this, params, kNumInputBuffers,
- WAVE_MAPPER);
+ // TODO(xians): Handle the non-default device.
+ if (device_id == AudioManagerBase::kDefaultDeviceId)
+ return new PCMWaveInAudioInputStream(this, params, kNumInputBuffers,
+ WAVE_MAPPER);
} else {
// TODO(henrika): improve possibility to specify audio endpoint.
// Use the default device (same as for Wave) for now to be compatible.
- return new WASAPIAudioInputStream(this, params, eConsole);
+ // TODO(xians): Handle the non-default device.
+ if (device_id == AudioManagerBase::kDefaultDeviceId)
+ return new WASAPIAudioInputStream(this, params, eConsole);
}
}
return NULL;
@@ -282,7 +287,7 @@ void AudioManagerWin::GetAudioInputDeviceNames(
// default devices.
media::AudioDeviceName name;
name.device_name = AudioManagerBase::kDefaultDeviceName;
- name.unique_id = "0";
+ name.unique_id = AudioManagerBase::kDefaultDeviceId;
device_names->push_back(name);
}
}
diff --git a/media/audio/win/audio_manager_win.h b/media/audio/win/audio_manager_win.h
index f1ad7b4..f1d73d8 100644
--- a/media/audio/win/audio_manager_win.h
+++ b/media/audio/win/audio_manager_win.h
@@ -25,7 +25,7 @@ class AudioManagerWin : public AudioManagerBase {
virtual AudioOutputStream* MakeAudioOutputStream(
const AudioParameters& params) OVERRIDE;
virtual AudioInputStream* MakeAudioInputStream(
- const AudioParameters& params) OVERRIDE;
+ const AudioParameters& params, const std::string& device_id) OVERRIDE;
virtual void MuteAll() OVERRIDE;
virtual void UnMuteAll() OVERRIDE;
virtual string16 GetAudioInputDeviceModel() OVERRIDE;