diff options
author | xians@chromium.org <xians@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-22 14:28:21 +0000 |
---|---|---|
committer | xians@chromium.org <xians@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-22 14:28:21 +0000 |
commit | b97f3c2e2c5ba4cdce59124efd6d3a34b53565f4 (patch) | |
tree | d62780b2284121c8089589ab71f28d67bfcd418f /media | |
parent | 0220b90986bc17a31222133204c7ff6a9d63b266 (diff) | |
download | chromium_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.cc | 14 | ||||
-rw-r--r-- | media/audio/audio_input_controller.h | 5 | ||||
-rw-r--r-- | media/audio/audio_input_device_unittest.cc | 7 | ||||
-rw-r--r-- | media/audio/audio_input_unittest.cc | 23 | ||||
-rw-r--r-- | media/audio/audio_manager.h | 2 | ||||
-rw-r--r-- | media/audio/audio_manager_base.cc | 1 | ||||
-rw-r--r-- | media/audio/audio_manager_base.h | 2 | ||||
-rw-r--r-- | media/audio/audio_output_proxy_unittest.cc | 4 | ||||
-rw-r--r-- | media/audio/linux/alsa_output_unittest.cc | 4 | ||||
-rw-r--r-- | media/audio/linux/audio_manager_linux.cc | 20 | ||||
-rw-r--r-- | media/audio/linux/audio_manager_linux.h | 4 | ||||
-rw-r--r-- | media/audio/mac/audio_low_latency_input_mac.cc | 34 | ||||
-rw-r--r-- | media/audio/mac/audio_low_latency_input_mac.h | 3 | ||||
-rw-r--r-- | media/audio/mac/audio_low_latency_input_mac_unittest.cc | 8 | ||||
-rw-r--r-- | media/audio/mac/audio_manager_mac.cc | 65 | ||||
-rw-r--r-- | media/audio/mac/audio_manager_mac.h | 2 | ||||
-rw-r--r-- | media/audio/win/audio_low_latency_input_win_unittest.cc | 5 | ||||
-rw-r--r-- | media/audio/win/audio_manager_win.cc | 17 | ||||
-rw-r--r-- | media/audio/win/audio_manager_win.h | 2 |
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; |