Chromium Code Reviews

Side by Side Diff: media/audio/cras/audio_manager_cras.cc

Issue 1275783003: Add a virtual beamforming audio device on ChromeOS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: aluebs comments. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
« no previous file with comments | « media/audio/cras/audio_manager_cras.h ('k') | media/audio/openbsd/audio_manager_openbsd.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/audio/cras/audio_manager_cras.h" 5 #include "media/audio/cras/audio_manager_cras.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/environment.h" 10 #include "base/environment.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/nix/xdg_util.h" 12 #include "base/nix/xdg_util.h"
13 #include "base/stl_util.h" 13 #include "base/stl_util.h"
14 #include "chromeos/audio/audio_device.h" 14 #include "chromeos/audio/audio_device.h"
15 #include "chromeos/audio/cras_audio_handler.h" 15 #include "chromeos/audio/cras_audio_handler.h"
16 #include "media/audio/cras/cras_input.h" 16 #include "media/audio/cras/cras_input.h"
17 #include "media/audio/cras/cras_unified.h" 17 #include "media/audio/cras/cras_unified.h"
18 #include "media/base/channel_layout.h" 18 #include "media/base/channel_layout.h"
19 19
20 // cras_util.h headers pull in min/max macros... 20 // cras_util.h headers pull in min/max macros...
21 // TODO(dgreid): Fix headers such that these aren't imported. 21 // TODO(dgreid): Fix headers such that these aren't imported.
22 #undef min 22 #undef min
23 #undef max 23 #undef max
24 24
25 namespace media { 25 namespace media {
26 namespace {
26 27
27 static void AddDefaultDevice(AudioDeviceNames* device_names) { 28 // Maximum number of output streams that can be open simultaneously.
28 DCHECK(device_names->empty()); 29 const int kMaxOutputStreams = 50;
29 30
31 // Default sample rate for input and output streams.
32 const int kDefaultSampleRate = 48000;
33
34 // Define bounds for the output buffer size.
35 const int kMinimumOutputBufferSize = 512;
36 const int kMaximumOutputBufferSize = 8192;
37
38 // Default input buffer size.
39 const int kDefaultInputBufferSize = 1024;
40
41 void AddDefaultDevice(AudioDeviceNames* device_names) {
30 // Cras will route audio from a proper physical device automatically. 42 // Cras will route audio from a proper physical device automatically.
31 device_names->push_back( 43 device_names->push_back(
32 AudioDeviceName(AudioManagerBase::kDefaultDeviceName, 44 AudioDeviceName(AudioManagerBase::kDefaultDeviceName,
33 AudioManagerBase::kDefaultDeviceId)); 45 AudioManagerBase::kDefaultDeviceId));
34 } 46 }
35 47
36 // Maximum number of output streams that can be open simultaneously. 48 // Returns the AudioDeviceName of the virtual device with beamforming on.
37 static const int kMaxOutputStreams = 50; 49 AudioDeviceName BeamformingOnDeviceName() {
50 // TODO(ajm): Replace these strings with properly localized ones.
51 // (crbug.com/497001)
52 static const char kBeamformingOnNameSuffix[] = " (pick up just one person)";
53 static const char kBeamformingOnIdSuffix[] = "-beamforming";
38 54
39 // Default sample rate for input and output streams. 55 return AudioDeviceName(
40 static const int kDefaultSampleRate = 48000; 56 std::string(AudioManagerBase::kDefaultDeviceName) +
57 kBeamformingOnNameSuffix,
58 std::string(AudioManagerBase::kDefaultDeviceId) + kBeamformingOnIdSuffix);
59 }
41 60
42 // Define bounds for the output buffer size. 61 // Returns the AudioDeviceName of the virtual device with beamforming off.
43 static const int kMinimumOutputBufferSize = 512; 62 AudioDeviceName BeamformingOffDeviceName() {
44 static const int kMaximumOutputBufferSize = 8192; 63 static const char kBeamformingOffNameSuffix[] = " (pick up everything)";
64 return AudioDeviceName(std::string(AudioManagerBase::kDefaultDeviceName) +
65 kBeamformingOffNameSuffix,
66 AudioManagerBase::kDefaultDeviceId);
67 }
45 68
46 // Default input buffer size. 69 // Returns a mic positions string if the machine has a beamforming capable
47 static const int kDefaultInputBufferSize = 1024; 70 // internal mic and otherwise an empty string.
71 std::string MicPositions() {
72 // Get the list of devices from CRAS. An internal mic with a non-empty
73 // positions field indicates the machine has a beamforming capable mic array.
74 chromeos::AudioDeviceList devices;
75 chromeos::CrasAudioHandler::Get()->GetAudioDevices(&devices);
76 for (const auto& device : devices) {
77 if (device.type == chromeos::AUDIO_TYPE_INTERNAL_MIC) {
78 // There should be only one internal mic device.
79 return device.mic_positions;
80 }
81 }
82 return "";
83 }
84
85 } // namespace
48 86
49 bool AudioManagerCras::HasAudioOutputDevices() { 87 bool AudioManagerCras::HasAudioOutputDevices() {
50 return true; 88 return true;
51 } 89 }
52 90
53 bool AudioManagerCras::HasAudioInputDevices() { 91 bool AudioManagerCras::HasAudioInputDevices() {
54 chromeos::AudioDeviceList devices; 92 chromeos::AudioDeviceList devices;
55 chromeos::CrasAudioHandler::Get()->GetAudioDevices(&devices); 93 chromeos::CrasAudioHandler::Get()->GetAudioDevices(&devices);
56 for (size_t i = 0; i < devices.size(); ++i) { 94 for (size_t i = 0; i < devices.size(); ++i) {
57 if (devices[i].is_input && devices[i].is_for_simple_usage()) 95 if (devices[i].is_input && devices[i].is_for_simple_usage())
58 return true; 96 return true;
59 } 97 }
60 return false; 98 return false;
61 } 99 }
62 100
63 AudioManagerCras::AudioManagerCras(AudioLogFactory* audio_log_factory) 101 AudioManagerCras::AudioManagerCras(AudioLogFactory* audio_log_factory)
64 : AudioManagerBase(audio_log_factory), 102 : AudioManagerBase(audio_log_factory),
65 has_keyboard_mic_(false) { 103 has_keyboard_mic_(false),
104 beamforming_on_device_name_(BeamformingOnDeviceName()),
105 beamforming_off_device_name_(BeamformingOffDeviceName()) {
66 SetMaxOutputStreamsAllowed(kMaxOutputStreams); 106 SetMaxOutputStreamsAllowed(kMaxOutputStreams);
67 } 107 }
68 108
69 AudioManagerCras::~AudioManagerCras() { 109 AudioManagerCras::~AudioManagerCras() {
70 Shutdown(); 110 Shutdown();
71 } 111 }
72 112
73 void AudioManagerCras::ShowAudioInputSettings() { 113 void AudioManagerCras::ShowAudioInputSettings() {
74 NOTIMPLEMENTED(); 114 NOTIMPLEMENTED();
75 } 115 }
76 116
77 void AudioManagerCras::GetAudioInputDeviceNames( 117 void AudioManagerCras::GetAudioInputDeviceNames(
78 AudioDeviceNames* device_names) { 118 AudioDeviceNames* device_names) {
79 AddDefaultDevice(device_names); 119 DCHECK(device_names->empty());
120
121 mic_positions_ = ParsePointsFromString(MicPositions());
122 // At least two mic positions indicates we have a beamforming capable mic
123 // array. Add the virtual beamforming device to the list. When this device is
124 // queried through GetInputStreamParameters, provide the cached mic positions.
125 if (mic_positions_.size() > 1) {
126 device_names->push_back(beamforming_on_device_name_);
127 device_names->push_back(beamforming_off_device_name_);
128 } else {
129 AddDefaultDevice(device_names);
130 }
80 } 131 }
81 132
82 void AudioManagerCras::GetAudioOutputDeviceNames( 133 void AudioManagerCras::GetAudioOutputDeviceNames(
83 AudioDeviceNames* device_names) { 134 AudioDeviceNames* device_names) {
135 DCHECK(device_names->empty());
136
84 AddDefaultDevice(device_names); 137 AddDefaultDevice(device_names);
85 } 138 }
86 139
87 AudioParameters AudioManagerCras::GetInputStreamParameters( 140 AudioParameters AudioManagerCras::GetInputStreamParameters(
88 const std::string& device_id) { 141 const std::string& device_id) {
89 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); 142 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
90 143
91 int user_buffer_size = GetUserBufferSize(); 144 int user_buffer_size = GetUserBufferSize();
92 int buffer_size = user_buffer_size ? 145 int buffer_size = user_buffer_size ?
93 user_buffer_size : kDefaultInputBufferSize; 146 user_buffer_size : kDefaultInputBufferSize;
94 AudioParameters::PlatformEffectsMask effects =
95 has_keyboard_mic_ ? AudioParameters::KEYBOARD_MIC
96 : AudioParameters::NO_EFFECTS;
97 147
98 // TODO(hshi): Fine-tune audio parameters based on |device_id|. The optimal 148 // TODO(hshi): Fine-tune audio parameters based on |device_id|. The optimal
99 // parameters for the loopback stream may differ from the default. 149 // parameters for the loopback stream may differ from the default.
100 AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY, 150 AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY,
101 CHANNEL_LAYOUT_STEREO, kDefaultSampleRate, 16, 151 CHANNEL_LAYOUT_STEREO, kDefaultSampleRate, 16,
102 buffer_size); 152 buffer_size);
103 params.set_effects(effects); 153 if (has_keyboard_mic_)
154 params.set_effects(AudioParameters::KEYBOARD_MIC);
155 if (device_id == beamforming_on_device_name_.unique_id)
156 params.set_mic_positions(mic_positions_);
104 return params; 157 return params;
105 } 158 }
106 159
107 void AudioManagerCras::SetHasKeyboardMic() { 160 void AudioManagerCras::SetHasKeyboardMic() {
108 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); 161 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
109 has_keyboard_mic_ = true; 162 has_keyboard_mic_ = true;
110 } 163 }
111 164
112 AudioOutputStream* AudioManagerCras::MakeLinearOutputStream( 165 AudioOutputStream* AudioManagerCras::MakeLinearOutputStream(
113 const AudioParameters& params) { 166 const AudioParameters& params) {
(...skipping 67 matching lines...)
181 case 24: 234 case 24:
182 return SND_PCM_FORMAT_S24; 235 return SND_PCM_FORMAT_S24;
183 case 32: 236 case 32:
184 return SND_PCM_FORMAT_S32; 237 return SND_PCM_FORMAT_S32;
185 default: 238 default:
186 return SND_PCM_FORMAT_UNKNOWN; 239 return SND_PCM_FORMAT_UNKNOWN;
187 } 240 }
188 } 241 }
189 242
190 } // namespace media 243 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/cras/audio_manager_cras.h ('k') | media/audio/openbsd/audio_manager_openbsd.h » ('j') | no next file with comments »

Powered by Google App Engine