audio_manager_openbsd.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "media/audio/openbsd/audio_manager_openbsd.h"
6
7#include <fcntl.h>
8
9#include "base/command_line.h"
10#include "base/file_path.h"
11#include "base/stl_util.h"
12#include "media/audio/audio_output_dispatcher.h"
13#include "media/audio/audio_parameters.h"
14#include "media/audio/pulse/pulse_output.h"
15#include "media/audio/pulse/pulse_stubs.h"
16#include "media/base/channel_layout.h"
17#include "media/base/limits.h"
18#include "media/base/media_switches.h"
19
20using media_audio_pulse::kModulePulse;
21using media_audio_pulse::InitializeStubs;
22using media_audio_pulse::StubPathMap;
23
24namespace media {
25
26// Maximum number of output streams that can be open simultaneously.
27static const int kMaxOutputStreams = 50;
28
29// Default sample rate for input and output streams.
30static const int kDefaultSampleRate = 48000;
31
32static const base::FilePath::CharType kPulseLib[] =
33    FILE_PATH_LITERAL("libpulse.so.0");
34
35// Implementation of AudioManager.
36static bool HasAudioHardware() {
37  int fd;
38  const char *file;
39
40  if ((file = getenv("AUDIOCTLDEVICE")) == 0 || *file == '\0')
41    file = "/dev/audioctl";
42
43  if ((fd = open(file, O_RDONLY)) < 0)
44    return false;
45
46  close(fd);
47  return true;
48}
49
50bool AudioManagerOpenBSD::HasAudioOutputDevices() {
51  return HasAudioHardware();
52}
53
54bool AudioManagerOpenBSD::HasAudioInputDevices() {
55  return HasAudioHardware();
56}
57
58AudioParameters AudioManagerOpenBSD::GetInputStreamParameters(
59    const std::string& device_id) {
60  static const int kDefaultInputBufferSize = 1024;
61
62  int user_buffer_size = GetUserBufferSize();
63  int buffer_size = user_buffer_size ?
64      user_buffer_size : kDefaultInputBufferSize;
65
66  return AudioParameters(
67      AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO,
68      kDefaultSampleRate, 16, buffer_size);
69}
70
71AudioManagerOpenBSD::AudioManagerOpenBSD(AudioLogFactory* audio_log_factory)
72    : AudioManagerBase(audio_log_factory),
73      pulse_library_is_initialized_(false) {
74  SetMaxOutputStreamsAllowed(kMaxOutputStreams);
75  StubPathMap paths;
76
77  // Check if the pulse library is avialbale.
78  paths[kModulePulse].push_back(kPulseLib);
79  if (!InitializeStubs(paths)) {
80    DLOG(WARNING) << "Failed on loading the Pulse library and symbols";
81    return;
82  }
83
84  pulse_library_is_initialized_ = true;
85}
86
87AudioManagerOpenBSD::~AudioManagerOpenBSD() {
88  Shutdown();
89}
90
91AudioOutputStream* AudioManagerOpenBSD::MakeLinearOutputStream(
92    const AudioParameters& params) {
93  DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format);
94  return MakeOutputStream(params);
95}
96
97AudioOutputStream* AudioManagerOpenBSD::MakeLowLatencyOutputStream(
98    const AudioParameters& params,
99    const std::string& device_id) {
100  DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!";
101  DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format);
102  return MakeOutputStream(params);
103}
104
105AudioInputStream* AudioManagerOpenBSD::MakeLinearInputStream(
106    const AudioParameters& params, const std::string& device_id) {
107  DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format);
108  NOTIMPLEMENTED();
109  return NULL;
110}
111
112AudioInputStream* AudioManagerOpenBSD::MakeLowLatencyInputStream(
113    const AudioParameters& params, const std::string& device_id) {
114  DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format);
115  NOTIMPLEMENTED();
116  return NULL;
117}
118
119AudioParameters AudioManagerOpenBSD::GetPreferredOutputStreamParameters(
120    const std::string& output_device_id,
121    const AudioParameters& input_params) {
122  // TODO(tommi): Support |output_device_id|.
123  DLOG_IF(ERROR, !output_device_id.empty()) << "Not implemented!";
124  static const int kDefaultOutputBufferSize = 512;
125
126  ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
127  int sample_rate = kDefaultSampleRate;
128  int buffer_size = kDefaultOutputBufferSize;
129  int bits_per_sample = 16;
130  if (input_params.IsValid()) {
131    sample_rate = input_params.sample_rate();
132    bits_per_sample = input_params.bits_per_sample();
133    channel_layout = input_params.channel_layout();
134    buffer_size = std::min(buffer_size, input_params.frames_per_buffer());
135  }
136
137  int user_buffer_size = GetUserBufferSize();
138  if (user_buffer_size)
139    buffer_size = user_buffer_size;
140
141  return AudioParameters(
142      AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout,
143      sample_rate, bits_per_sample, buffer_size, AudioParameters::NO_EFFECTS);
144}
145
146AudioOutputStream* AudioManagerOpenBSD::MakeOutputStream(
147    const AudioParameters& params) {
148  if (pulse_library_is_initialized_)
149    return new PulseAudioOutputStream(params, this);
150
151  return NULL;
152}
153
154// TODO(xians): Merge AudioManagerOpenBSD with AudioManagerPulse;
155// static
156AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) {
157  return new AudioManagerOpenBSD(audio_log_factory);
158}
159
160}  // namespace media
161