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
3// found in the LICENSE file.
4
5#include "media/audio/cras/audio_manager_cras.h"
6
7#include "base/command_line.h"
8#include "base/environment.h"
9#include "base/logging.h"
10#include "base/nix/xdg_util.h"
11#include "base/stl_util.h"
12#include "media/audio/audio_util.h"
13#include "media/audio/cras/cras_input.h"
14#include "media/audio/cras/cras_unified.h"
15#include "media/base/channel_layout.h"
16
17namespace media {
18
19// Maximum number of output streams that can be open simultaneously.
20static const int kMaxOutputStreams = 50;
21
22// Default sample rate for input and output streams.
23static const int kDefaultSampleRate = 48000;
24
25const char AudioManagerCras::kLoopbackDeviceId[] = "loopback";
26
27bool AudioManagerCras::HasAudioOutputDevices() {
28  return true;
29}
30
31bool AudioManagerCras::HasAudioInputDevices() {
32  return true;
33}
34
35AudioManagerCras::AudioManagerCras() {
36  SetMaxOutputStreamsAllowed(kMaxOutputStreams);
37}
38
39AudioManagerCras::~AudioManagerCras() {
40  Shutdown();
41}
42
43void AudioManagerCras::ShowAudioInputSettings() {
44  NOTIMPLEMENTED();
45}
46
47void AudioManagerCras::GetAudioInputDeviceNames(
48    media::AudioDeviceNames* device_names) {
49  DCHECK(device_names->empty());
50  GetCrasAudioInputDevices(device_names);
51  return;
52}
53
54AudioParameters AudioManagerCras::GetInputStreamParameters(
55    const std::string& device_id) {
56  static const int kDefaultInputBufferSize = 1024;
57  // TODO(hshi): Fine-tune audio parameters based on |device_id|. The optimal
58  // parameters for the loopback stream may differ from the default.
59  return AudioParameters(
60      AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO,
61      kDefaultSampleRate, 16, kDefaultInputBufferSize);
62}
63
64void AudioManagerCras::GetCrasAudioInputDevices(
65    media::AudioDeviceNames* device_names) {
66  // Cras will route audio from a proper physical device automatically.
67  device_names->push_back(
68      AudioDeviceName(AudioManagerBase::kDefaultDeviceName,
69                      AudioManagerBase::kDefaultDeviceId));
70}
71
72AudioOutputStream* AudioManagerCras::MakeLinearOutputStream(
73    const AudioParameters& params) {
74  DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format());
75  return MakeOutputStream(params);
76}
77
78AudioOutputStream* AudioManagerCras::MakeLowLatencyOutputStream(
79    const AudioParameters& params, const std::string& input_device_id) {
80  DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format());
81  // TODO(dgreid): Open the correct input device for unified IO.
82  return MakeOutputStream(params);
83}
84
85AudioInputStream* AudioManagerCras::MakeLinearInputStream(
86    const AudioParameters& params, const std::string& device_id) {
87  DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format());
88  return MakeInputStream(params, device_id);
89}
90
91AudioInputStream* AudioManagerCras::MakeLowLatencyInputStream(
92    const AudioParameters& params, const std::string& device_id) {
93  DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format());
94  return MakeInputStream(params, device_id);
95}
96
97AudioParameters AudioManagerCras::GetPreferredOutputStreamParameters(
98    const AudioParameters& input_params) {
99  static const int kDefaultOutputBufferSize = 512;
100
101  ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
102  int sample_rate = kDefaultSampleRate;
103  int buffer_size = kDefaultOutputBufferSize;
104  int bits_per_sample = 16;
105  int input_channels = 0;
106  if (input_params.IsValid()) {
107    sample_rate = input_params.sample_rate();
108    bits_per_sample = input_params.bits_per_sample();
109    channel_layout = input_params.channel_layout();
110    input_channels = input_params.input_channels();
111    buffer_size = input_params.frames_per_buffer();
112  }
113
114  int user_buffer_size = GetUserBufferSize();
115  if (user_buffer_size)
116    buffer_size = user_buffer_size;
117
118  return AudioParameters(
119      AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels,
120      sample_rate, bits_per_sample, buffer_size);
121}
122
123AudioOutputStream* AudioManagerCras::MakeOutputStream(
124    const AudioParameters& params) {
125  return new CrasUnifiedStream(params, this);
126}
127
128AudioInputStream* AudioManagerCras::MakeInputStream(
129    const AudioParameters& params, const std::string& device_id) {
130  return new CrasInputStream(params, this, device_id);
131}
132
133}  // namespace media
134