diff options
author | ajm <ajm@chromium.org> | 2015-09-14 11:41:13 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-09-14 18:42:13 +0000 |
commit | 42979149ac67727de85b1e5fc5cf874cf709eb36 (patch) | |
tree | 23c9f13e413db3258ac667fbcbe9e32250ac6a7d /media | |
parent | 4528b0df09b22145b71e3d04836319aab5a47920 (diff) | |
download | chromium_src-42979149ac67727de85b1e5fc5cf874cf709eb36.zip chromium_src-42979149ac67727de85b1e5fc5cf874cf709eb36.tar.gz chromium_src-42979149ac67727de85b1e5fc5cf874cf709eb36.tar.bz2 |
Add a virtual beamforming audio device on ChromeOS.
AudioManagerCras checks with CrasAudioHandler for an internal mic
device with a valid positions field. If present, it adds a virtual
beamforming device.
When this device is selected by a web app, the mic positions are plumbed
up to MediaStreamAudioProcessor via AudioParameters. MSAP will enable
beamforming when it sees valid mic positions.
See the design doc for background:
go/virtual-beamforming-device
BUG=497001
TEST=Selecting the beamforming device on a swanky indeed enables
beamforming for the internal mic and continues to work fine for an
external USB mic. Selecting the non-beamforming device disables
beamforming for the internal mic.
Review URL: https://codereview.chromium.org/1275783003
Cr-Commit-Position: refs/heads/master@{#348668}
Diffstat (limited to 'media')
-rw-r--r-- | media/BUILD.gn | 3 | ||||
-rw-r--r-- | media/audio/BUILD.gn | 7 | ||||
-rw-r--r-- | media/audio/audio_parameters.cc | 14 | ||||
-rw-r--r-- | media/audio/audio_parameters.h | 25 | ||||
-rw-r--r-- | media/audio/audio_parameters_unittest.cc | 5 | ||||
-rw-r--r-- | media/audio/cras/audio_manager_cras.cc | 87 | ||||
-rw-r--r-- | media/audio/cras/audio_manager_cras.h | 7 | ||||
-rw-r--r-- | media/audio/openbsd/audio_manager_openbsd.cc | 160 | ||||
-rw-r--r-- | media/audio/openbsd/audio_manager_openbsd.h | 55 | ||||
-rw-r--r-- | media/audio/point.cc | 61 | ||||
-rw-r--r-- | media/audio/point.h | 31 | ||||
-rw-r--r-- | media/audio/point_unittest.cc | 41 | ||||
-rw-r--r-- | media/audio/pulse/audio_manager_pulse.cc | 6 | ||||
-rw-r--r-- | media/base/audio_buffer_unittest.cc | 9 | ||||
-rw-r--r-- | media/media.gyp | 11 | ||||
-rw-r--r-- | media/shared_memory_support.gypi | 2 |
16 files changed, 261 insertions, 263 deletions
diff --git a/media/BUILD.gn b/media/BUILD.gn index 51fb153..78c5310 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -793,6 +793,8 @@ component("shared_memory_support") { sources = [ "audio/audio_parameters.cc", "audio/audio_parameters.h", + "audio/point.cc", + "audio/point.h", "base/audio_bus.cc", "base/audio_bus.h", "base/channel_layout.cc", @@ -808,6 +810,7 @@ component("shared_memory_support") { ] deps = [ "//base", + "//ui/gfx/geometry", ] } diff --git a/media/audio/BUILD.gn b/media/audio/BUILD.gn index 24ef1efe..369d7d0 100644 --- a/media/audio/BUILD.gn +++ b/media/audio/BUILD.gn @@ -185,13 +185,6 @@ source_set("audio") { deps += [ "//media/base/android:media_jni_headers" ] } - if (is_openbsd) { - sources += [ - "openbsd/audio_manager_openbsd.cc", - "openbsd/audio_manager_openbsd.h", - ] - } - if (is_linux) { sources += [ "linux/audio_manager_linux.cc" ] } diff --git a/media/audio/audio_parameters.cc b/media/audio/audio_parameters.cc index a78eb84..14c3214 100644 --- a/media/audio/audio_parameters.cc +++ b/media/audio/audio_parameters.cc @@ -21,6 +21,11 @@ AudioParameters::AudioParameters(Format format, frames_per_buffer); } +AudioParameters::~AudioParameters() {} + +AudioParameters::AudioParameters(const AudioParameters&) = default; +AudioParameters& AudioParameters::operator=(const AudioParameters&) = default; + void AudioParameters::Reset(Format format, ChannelLayout channel_layout, int sample_rate, @@ -33,6 +38,7 @@ void AudioParameters::Reset(Format format, bits_per_sample_ = bits_per_sample; frames_per_buffer_ = frames_per_buffer; effects_ = NO_EFFECTS; + mic_positions_.clear(); } bool AudioParameters::IsValid() const { @@ -54,7 +60,8 @@ std::string AudioParameters::AsHumanReadableString() const { << " channels: " << channels() << " sample_rate: " << sample_rate() << " bits_per_sample: " << bits_per_sample() << " frames_per_buffer: " << frames_per_buffer() - << " effects: " << effects(); + << " effects: " << effects() + << " mic_positions: " << PointsToString(mic_positions_); return s.str(); } @@ -77,13 +84,12 @@ base::TimeDelta AudioParameters::GetBufferDuration() const { } bool AudioParameters::Equals(const AudioParameters& other) const { - return format_ == other.format() && - sample_rate_ == other.sample_rate() && + return format_ == other.format() && sample_rate_ == other.sample_rate() && channel_layout_ == other.channel_layout() && channels_ == other.channels() && bits_per_sample_ == other.bits_per_sample() && frames_per_buffer_ == other.frames_per_buffer() && - effects_ == other.effects(); + effects_ == other.effects() && mic_positions_ == other.mic_positions_; } } // namespace media diff --git a/media/audio/audio_parameters.h b/media/audio/audio_parameters.h index 57fb960..61ca812 100644 --- a/media/audio/audio_parameters.h +++ b/media/audio/audio_parameters.h @@ -11,6 +11,7 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/time/time.h" +#include "media/audio/point.h" #include "media/base/audio_bus.h" #include "media/base/channel_layout.h" #include "media/base/media_export.h" @@ -86,6 +87,8 @@ class MEDIA_EXPORT AudioParameters { int bits_per_sample, int frames_per_buffer); + ~AudioParameters(); + // Re-initializes all members. void Reset(Format format, ChannelLayout channel_layout, @@ -148,8 +151,13 @@ class MEDIA_EXPORT AudioParameters { void set_effects(int effects) { effects_ = effects; } int effects() const { return effects_; } - AudioParameters(const AudioParameters&) = default; - AudioParameters& operator=(const AudioParameters&) = default; + void set_mic_positions(const std::vector<Point>& mic_positions) { + mic_positions_ = mic_positions; + } + const std::vector<Point>& mic_positions() const { return mic_positions_; } + + AudioParameters(const AudioParameters&); + AudioParameters& operator=(const AudioParameters&); private: Format format_; // Format of the stream. @@ -160,6 +168,19 @@ class MEDIA_EXPORT AudioParameters { int bits_per_sample_; // Number of bits per sample. int frames_per_buffer_; // Number of frames in a buffer. int effects_; // Bitmask using PlatformEffectsMask. + + // Microphone positions using Cartesian coordinates: + // x: the horizontal dimension, with positive to the right from the camera's + // perspective. + // y: the depth dimension, with positive forward from the camera's + // perspective. + // z: the vertical dimension, with positive upwards. + // + // Usually, the center of the microphone array will be treated as the origin + // (often the position of the camera). + // + // An empty vector indicates unknown positions. + std::vector<Point> mic_positions_; }; // Comparison is useful when AudioParameters is used with std structures. diff --git a/media/audio/audio_parameters_unittest.cc b/media/audio/audio_parameters_unittest.cc index 2cf541d..c39e8d4 100644 --- a/media/audio/audio_parameters_unittest.cc +++ b/media/audio/audio_parameters_unittest.cc @@ -16,6 +16,9 @@ TEST(AudioParameters, Constructor_Default) { ChannelLayout expected_channel_layout = CHANNEL_LAYOUT_NONE; int expected_rate = 0; int expected_samples = 0; + AudioParameters::PlatformEffectsMask expected_effects = + AudioParameters::NO_EFFECTS; + std::vector<Point> expected_mic_positions; AudioParameters params; @@ -25,6 +28,8 @@ TEST(AudioParameters, Constructor_Default) { EXPECT_EQ(expected_channel_layout, params.channel_layout()); EXPECT_EQ(expected_rate, params.sample_rate()); EXPECT_EQ(expected_samples, params.frames_per_buffer()); + EXPECT_EQ(expected_effects, params.effects()); + EXPECT_EQ(expected_mic_positions, params.mic_positions()); } TEST(AudioParameters, Constructor_ParameterValues) { diff --git a/media/audio/cras/audio_manager_cras.cc b/media/audio/cras/audio_manager_cras.cc index 31a1780..2b47de4 100644 --- a/media/audio/cras/audio_manager_cras.cc +++ b/media/audio/cras/audio_manager_cras.cc @@ -23,28 +23,66 @@ #undef max namespace media { +namespace { -static void AddDefaultDevice(AudioDeviceNames* device_names) { - DCHECK(device_names->empty()); +// Maximum number of output streams that can be open simultaneously. +const int kMaxOutputStreams = 50; + +// Default sample rate for input and output streams. +const int kDefaultSampleRate = 48000; +// Define bounds for the output buffer size. +const int kMinimumOutputBufferSize = 512; +const int kMaximumOutputBufferSize = 8192; + +// Default input buffer size. +const int kDefaultInputBufferSize = 1024; + +void AddDefaultDevice(AudioDeviceNames* device_names) { // Cras will route audio from a proper physical device automatically. device_names->push_back( AudioDeviceName(AudioManagerBase::kDefaultDeviceName, AudioManagerBase::kDefaultDeviceId)); } -// Maximum number of output streams that can be open simultaneously. -static const int kMaxOutputStreams = 50; +// Returns the AudioDeviceName of the virtual device with beamforming on. +AudioDeviceName BeamformingOnDeviceName() { + // TODO(ajm): Replace these strings with properly localized ones. + // (crbug.com/497001) + static const char kBeamformingOnNameSuffix[] = " (pick up just one person)"; + static const char kBeamformingOnIdSuffix[] = "-beamforming"; -// Default sample rate for input and output streams. -static const int kDefaultSampleRate = 48000; + return AudioDeviceName( + std::string(AudioManagerBase::kDefaultDeviceName) + + kBeamformingOnNameSuffix, + std::string(AudioManagerBase::kDefaultDeviceId) + kBeamformingOnIdSuffix); +} -// Define bounds for the output buffer size. -static const int kMinimumOutputBufferSize = 512; -static const int kMaximumOutputBufferSize = 8192; +// Returns the AudioDeviceName of the virtual device with beamforming off. +AudioDeviceName BeamformingOffDeviceName() { + static const char kBeamformingOffNameSuffix[] = " (pick up everything)"; + return AudioDeviceName(std::string(AudioManagerBase::kDefaultDeviceName) + + kBeamformingOffNameSuffix, + AudioManagerBase::kDefaultDeviceId); +} -// Default input buffer size. -static const int kDefaultInputBufferSize = 1024; +// Returns a mic positions string if the machine has a beamforming capable +// internal mic and otherwise an empty string. +std::string MicPositions() { + // Get the list of devices from CRAS. An internal mic with a non-empty + // positions field indicates the machine has a beamforming capable mic array. + chromeos::AudioDeviceList devices; + chromeos::CrasAudioHandler::Get()->GetAudioDevices(&devices); + for (const auto& device : devices) { + if (device.type == chromeos::AUDIO_TYPE_INTERNAL_MIC) { + // There should be only one internal mic device. + return device.mic_positions; + } + } + return ""; +} + +} // namespace bool AudioManagerCras::HasAudioOutputDevices() { return true; @@ -62,7 +100,9 @@ bool AudioManagerCras::HasAudioInputDevices() { AudioManagerCras::AudioManagerCras(AudioLogFactory* audio_log_factory) : AudioManagerBase(audio_log_factory), - has_keyboard_mic_(false) { + has_keyboard_mic_(false), + beamforming_on_device_name_(BeamformingOnDeviceName()), + beamforming_off_device_name_(BeamformingOffDeviceName()) { SetMaxOutputStreamsAllowed(kMaxOutputStreams); } @@ -76,11 +116,24 @@ void AudioManagerCras::ShowAudioInputSettings() { void AudioManagerCras::GetAudioInputDeviceNames( AudioDeviceNames* device_names) { - AddDefaultDevice(device_names); + DCHECK(device_names->empty()); + + mic_positions_ = ParsePointsFromString(MicPositions()); + // At least two mic positions indicates we have a beamforming capable mic + // array. Add the virtual beamforming device to the list. When this device is + // queried through GetInputStreamParameters, provide the cached mic positions. + if (mic_positions_.size() > 1) { + device_names->push_back(beamforming_on_device_name_); + device_names->push_back(beamforming_off_device_name_); + } else { + AddDefaultDevice(device_names); + } } void AudioManagerCras::GetAudioOutputDeviceNames( AudioDeviceNames* device_names) { + DCHECK(device_names->empty()); + AddDefaultDevice(device_names); } @@ -91,16 +144,16 @@ AudioParameters AudioManagerCras::GetInputStreamParameters( int user_buffer_size = GetUserBufferSize(); int buffer_size = user_buffer_size ? user_buffer_size : kDefaultInputBufferSize; - AudioParameters::PlatformEffectsMask effects = - has_keyboard_mic_ ? AudioParameters::KEYBOARD_MIC - : AudioParameters::NO_EFFECTS; // TODO(hshi): Fine-tune audio parameters based on |device_id|. The optimal // parameters for the loopback stream may differ from the default. AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO, kDefaultSampleRate, 16, buffer_size); - params.set_effects(effects); + if (has_keyboard_mic_) + params.set_effects(AudioParameters::KEYBOARD_MIC); + if (device_id == beamforming_on_device_name_.unique_id) + params.set_mic_positions(mic_positions_); return params; } diff --git a/media/audio/cras/audio_manager_cras.h b/media/audio/cras/audio_manager_cras.h index 4c8f992..d55756d 100644 --- a/media/audio/cras/audio_manager_cras.h +++ b/media/audio/cras/audio_manager_cras.h @@ -61,6 +61,13 @@ class MEDIA_EXPORT AudioManagerCras : public AudioManagerBase { bool has_keyboard_mic_; + // Holds the name and ID of the virtual beamforming devices. + const AudioDeviceName beamforming_on_device_name_; + const AudioDeviceName beamforming_off_device_name_; + + // Stores the mic positions field from the device. + std::vector<Point> mic_positions_; + DISALLOW_COPY_AND_ASSIGN(AudioManagerCras); }; diff --git a/media/audio/openbsd/audio_manager_openbsd.cc b/media/audio/openbsd/audio_manager_openbsd.cc deleted file mode 100644 index 618fb0c..0000000 --- a/media/audio/openbsd/audio_manager_openbsd.cc +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright (c) 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/openbsd/audio_manager_openbsd.h" - -#include <fcntl.h> - -#include "base/command_line.h" -#include "base/file_path.h" -#include "base/stl_util.h" -#include "media/audio/audio_output_dispatcher.h" -#include "media/audio/audio_parameters.h" -#include "media/audio/pulse/pulse_output.h" -#include "media/audio/pulse/pulse_stubs.h" -#include "media/base/channel_layout.h" -#include "media/base/limits.h" -#include "media/base/media_switches.h" - -using media_audio_pulse::kModulePulse; -using media_audio_pulse::InitializeStubs; -using media_audio_pulse::StubPathMap; - -namespace media { - -// Maximum number of output streams that can be open simultaneously. -static const int kMaxOutputStreams = 50; - -// Default sample rate for input and output streams. -static const int kDefaultSampleRate = 48000; - -static const base::FilePath::CharType kPulseLib[] = - FILE_PATH_LITERAL("libpulse.so.0"); - -// Implementation of AudioManager. -static bool HasAudioHardware() { - int fd; - const char *file; - - if ((file = getenv("AUDIOCTLDEVICE")) == 0 || *file == '\0') - file = "/dev/audioctl"; - - if ((fd = open(file, O_RDONLY)) < 0) - return false; - - close(fd); - return true; -} - -bool AudioManagerOpenBSD::HasAudioOutputDevices() { - return HasAudioHardware(); -} - -bool AudioManagerOpenBSD::HasAudioInputDevices() { - return HasAudioHardware(); -} - -AudioParameters AudioManagerOpenBSD::GetInputStreamParameters( - const std::string& device_id) { - static const int kDefaultInputBufferSize = 1024; - - int user_buffer_size = GetUserBufferSize(); - int buffer_size = user_buffer_size ? - user_buffer_size : kDefaultInputBufferSize; - - return AudioParameters( - AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO, - kDefaultSampleRate, 16, buffer_size); -} - -AudioManagerOpenBSD::AudioManagerOpenBSD(AudioLogFactory* audio_log_factory) - : AudioManagerBase(audio_log_factory), - pulse_library_is_initialized_(false) { - SetMaxOutputStreamsAllowed(kMaxOutputStreams); - StubPathMap paths; - - // Check if the pulse library is avialbale. - paths[kModulePulse].push_back(kPulseLib); - if (!InitializeStubs(paths)) { - DLOG(WARNING) << "Failed on loading the Pulse library and symbols"; - return; - } - - pulse_library_is_initialized_ = true; -} - -AudioManagerOpenBSD::~AudioManagerOpenBSD() { - Shutdown(); -} - -AudioOutputStream* AudioManagerOpenBSD::MakeLinearOutputStream( - const AudioParameters& params) { - DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format); - return MakeOutputStream(params); -} - -AudioOutputStream* AudioManagerOpenBSD::MakeLowLatencyOutputStream( - const AudioParameters& params, - const std::string& device_id) { - DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!"; - DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format); - return MakeOutputStream(params); -} - -AudioInputStream* AudioManagerOpenBSD::MakeLinearInputStream( - const AudioParameters& params, const std::string& device_id) { - DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format); - NOTIMPLEMENTED(); - return NULL; -} - -AudioInputStream* AudioManagerOpenBSD::MakeLowLatencyInputStream( - const AudioParameters& params, const std::string& device_id) { - DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format); - NOTIMPLEMENTED(); - return NULL; -} - -AudioParameters AudioManagerOpenBSD::GetPreferredOutputStreamParameters( - const std::string& output_device_id, - const AudioParameters& input_params) { - // TODO(tommi): Support |output_device_id|. - DLOG_IF(ERROR, !output_device_id.empty()) << "Not implemented!"; - static const int kDefaultOutputBufferSize = 512; - - ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO; - int sample_rate = kDefaultSampleRate; - int buffer_size = kDefaultOutputBufferSize; - int bits_per_sample = 16; - if (input_params.IsValid()) { - sample_rate = input_params.sample_rate(); - bits_per_sample = input_params.bits_per_sample(); - channel_layout = input_params.channel_layout(); - buffer_size = std::min(buffer_size, input_params.frames_per_buffer()); - } - - int user_buffer_size = GetUserBufferSize(); - if (user_buffer_size) - buffer_size = user_buffer_size; - - return AudioParameters( - AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, - sample_rate, bits_per_sample, buffer_size, AudioParameters::NO_EFFECTS); -} - -AudioOutputStream* AudioManagerOpenBSD::MakeOutputStream( - const AudioParameters& params) { - if (pulse_library_is_initialized_) - return new PulseAudioOutputStream(params, this); - - return NULL; -} - -// TODO(xians): Merge AudioManagerOpenBSD with AudioManagerPulse; -// static -AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) { - return new AudioManagerOpenBSD(audio_log_factory); -} - -} // namespace media diff --git a/media/audio/openbsd/audio_manager_openbsd.h b/media/audio/openbsd/audio_manager_openbsd.h deleted file mode 100644 index 3326952..0000000 --- a/media/audio/openbsd/audio_manager_openbsd.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 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_OPENBSD_AUDIO_MANAGER_OPENBSD_H_ -#define MEDIA_AUDIO_OPENBSD_AUDIO_MANAGER_OPENBSD_H_ - -#include <set> - -#include "base/compiler_specific.h" -#include "media/audio/audio_manager_base.h" - -namespace media { - -class MEDIA_EXPORT AudioManagerOpenBSD : public AudioManagerBase { - public: - AudioManagerOpenBSD(AudioLogFactory* audio_log_factory); - - // Implementation of AudioManager. - bool HasAudioOutputDevices() override; - bool HasAudioInputDevices() override; - AudioParameters GetInputStreamParameters( - const std::string& device_id) override; - - // Implementation of AudioManagerBase. - AudioOutputStream* MakeLinearOutputStream( - const AudioParameters& params) override; - AudioOutputStream* MakeLowLatencyOutputStream( - const AudioParameters& params, - const std::string& device_id) override; - AudioInputStream* MakeLinearInputStream( - const AudioParameters& params, const std::string& device_id) override; - AudioInputStream* MakeLowLatencyInputStream( - const AudioParameters& params, const std::string& device_id) override; - - protected: - ~AudioManagerOpenBSD() override; - - AudioParameters GetPreferredOutputStreamParameters( - const std::string& output_device_id, - const AudioParameters& input_params) override; - - private: - // Called by MakeLinearOutputStream and MakeLowLatencyOutputStream. - AudioOutputStream* MakeOutputStream(const AudioParameters& params); - - // Flag to indicate whether the pulse library has been initialized or not. - bool pulse_library_is_initialized_; - - DISALLOW_COPY_AND_ASSIGN(AudioManagerOpenBSD); -}; - -} // namespace media - -#endif // MEDIA_AUDIO_OPENBSD_AUDIO_MANAGER_OPENBSD_H_ diff --git a/media/audio/point.cc b/media/audio/point.cc new file mode 100644 index 0000000..3246089 --- /dev/null +++ b/media/audio/point.cc @@ -0,0 +1,61 @@ +// Copyright 2015 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/point.h" + +#include "base/logging.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" + +namespace media { + +std::string PointsToString(const std::vector<Point>& points) { + std::string points_string; + if (!points.empty()) { + for (size_t i = 0; i < points.size() - 1; ++i) { + points_string.append(points[i].ToString()); + points_string.append(", "); + } + points_string.append(points.back().ToString()); + } + return points_string; +} + +std::vector<Point> ParsePointsFromString(const std::string& points_string) { + std::vector<Point> points; + if (points_string.empty()) + return points; + + const auto& tokens = + base::SplitString(points_string, base::kWhitespaceASCII, + base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + if (tokens.size() < 3 || tokens.size() % 3 != 0) { + LOG(ERROR) << "Malformed points string: " << points_string; + return points; + } + + std::vector<float> float_tokens; + float_tokens.reserve(tokens.size()); + for (const auto& token : tokens) { + double float_token; + if (!base::StringToDouble(token, &float_token)) { + LOG(ERROR) << "Unable to convert token=" << token + << " to double from points string: " << points_string; + return points; + } + float_tokens.push_back(float_token); + } + + points.reserve(float_tokens.size() / 3); + for (size_t i = 0; i < float_tokens.size(); i += 3) { + points.push_back( + Point(float_tokens[i + 0], float_tokens[i + 1], float_tokens[i + 2])); + } + + return points; +} + +} // namespace media diff --git a/media/audio/point.h b/media/audio/point.h new file mode 100644 index 0000000..d215a59 --- /dev/null +++ b/media/audio/point.h @@ -0,0 +1,31 @@ +// Copyright 2015 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_POINT_H_ +#define MEDIA_AUDIO_POINT_H_ + +#include <string> +#include <vector> + +#include "media/base/media_export.h" +#include "ui/gfx/geometry/point3_f.h" + +namespace media { + +using Point = gfx::Point3F; + +// Returns a vector of points parsed from a whitespace-separated string +// formatted as: "x1 y1 z1 ... zn yn zn" for n points. +// +// Returns an empty vector if |points_string| is empty or isn't parseable. +MEDIA_EXPORT std::vector<Point> ParsePointsFromString( + const std::string& points_string); + +// Returns |points| as a human-readable string. (Not necessarily in the format +// required by ParsePointsFromString). +MEDIA_EXPORT std::string PointsToString(const std::vector<Point>& points); + +} // namespace media + +#endif // MEDIA_AUDIO_POINT_H_ diff --git a/media/audio/point_unittest.cc b/media/audio/point_unittest.cc new file mode 100644 index 0000000..98aec64 --- /dev/null +++ b/media/audio/point_unittest.cc @@ -0,0 +1,41 @@ +// Copyright (c) 2015 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 <cmath> + +#include "media/audio/point.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace media { +namespace { + +TEST(PointTest, PointsToString) { + std::vector<Point> points(1, Point(1, 0, 0.01f)); + points.push_back(Point(0, 2, 0.02f)); + EXPECT_EQ("1.000000,0.000000,0.010000, 0.000000,2.000000,0.020000", + PointsToString(points)); + + EXPECT_EQ("", PointsToString(std::vector<Point>())); +} + +TEST(PointTest, ParsePointString) { + const std::vector<Point> expected_empty; + EXPECT_EQ(expected_empty, ParsePointsFromString("")); + EXPECT_EQ(expected_empty, ParsePointsFromString("0 0 a")); + EXPECT_EQ(expected_empty, ParsePointsFromString("1 2")); + EXPECT_EQ(expected_empty, ParsePointsFromString("1 2 3 4")); + + { + std::vector<Point> expected(1, Point(-0.02f, 0, 0)); + expected.push_back(Point(0.02f, 0, 0)); + EXPECT_EQ(expected, ParsePointsFromString("-0.02 0 0 0.02 0 0")); + } + { + std::vector<Point> expected(1, Point(1, 2, 3)); + EXPECT_EQ(expected, ParsePointsFromString("1 2 3")); + } +} + +} // namespace +} // namespace media diff --git a/media/audio/pulse/audio_manager_pulse.cc b/media/audio/pulse/audio_manager_pulse.cc index 3044f3c..f3d8832 100644 --- a/media/audio/pulse/audio_manager_pulse.cc +++ b/media/audio/pulse/audio_manager_pulse.cc @@ -135,9 +135,9 @@ AudioParameters AudioManagerPulse::GetInputStreamParameters( user_buffer_size : kDefaultInputBufferSize; // TODO(xians): add support for querying native channel layout for pulse. - return AudioParameters( - AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO, - GetNativeSampleRate(), 16, buffer_size); + return AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, + CHANNEL_LAYOUT_STEREO, GetNativeSampleRate(), 16, + buffer_size); } AudioOutputStream* AudioManagerPulse::MakeLinearOutputStream( diff --git a/media/base/audio_buffer_unittest.cc b/media/base/audio_buffer_unittest.cc index 43c763e..b48220d 100644 --- a/media/base/audio_buffer_unittest.cc +++ b/media/base/audio_buffer_unittest.cc @@ -202,13 +202,8 @@ TEST(AudioBufferTest, FrameSize) { kTimestamp); EXPECT_EQ(16, buffer->frame_count()); // 2 channels of 8-bit data - buffer = AudioBuffer::CopyFrom(kSampleFormatF32, - CHANNEL_LAYOUT_4_0, - 4, - kSampleRate, - 2, - data, - kTimestamp); + buffer = AudioBuffer::CopyFrom(kSampleFormatF32, CHANNEL_LAYOUT_4_0, 4, + kSampleRate, 2, data, kTimestamp); EXPECT_EQ(2, buffer->frame_count()); // now 4 channels of 32-bit data } diff --git a/media/media.gyp b/media/media.gyp index 102117e..21b9ece 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -161,8 +161,6 @@ 'audio/mac/audio_manager_mac.h', 'audio/null_audio_sink.cc', 'audio/null_audio_sink.h', - 'audio/openbsd/audio_manager_openbsd.cc', - 'audio/openbsd/audio_manager_openbsd.h', 'audio/pulse/audio_manager_pulse.cc', 'audio/pulse/audio_manager_pulse.h', 'audio/pulse/pulse_input.cc', @@ -780,12 +778,7 @@ ['exclude', '_alsa\\.(h|cc)$'], ], }], - ['OS!="openbsd"', { - 'sources!': [ - 'audio/openbsd/audio_manager_openbsd.cc', - 'audio/openbsd/audio_manager_openbsd.h', - ], - }, { # else: openbsd==1 + ['OS=="openbsd"', { 'sources!': [ 'capture/video/linux/v4l2_capture_delegate_multi_plane.cc', 'capture/video/linux/v4l2_capture_delegate_multi_plane.h', @@ -1502,6 +1495,7 @@ 'audio/audio_parameters_unittest.cc', 'audio/audio_power_monitor_unittest.cc', 'audio/fake_audio_worker_unittest.cc', + 'audio/point_unittest.cc', 'audio/simple_sources_unittest.cc', 'audio/virtual_audio_input_stream_unittest.cc', 'audio/virtual_audio_output_stream_unittest.cc', @@ -1651,6 +1645,7 @@ 'type': '<(component)', 'dependencies': [ '../base/base.gyp:base', + '../ui/gfx/gfx.gyp:gfx_geometry', ], 'defines': [ 'MEDIA_IMPLEMENTATION', diff --git a/media/shared_memory_support.gypi b/media/shared_memory_support.gypi index 65403f7..721f6aa 100644 --- a/media/shared_memory_support.gypi +++ b/media/shared_memory_support.gypi @@ -10,6 +10,8 @@ 'shared_memory_support_sources': [ 'audio/audio_parameters.cc', 'audio/audio_parameters.h', + 'audio/point.cc', + 'audio/point.h', 'base/audio_bus.cc', 'base/audio_bus.h', 'base/channel_layout.cc', |