audio_manager_cras.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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 <algorithm> 8 9#include "base/command_line.h" 10#include "base/environment.h" 11#include "base/logging.h" 12#include "base/nix/xdg_util.h" 13#include "base/stl_util.h" 14#include "media/audio/cras/cras_input.h" 15#include "media/audio/cras/cras_unified.h" 16#include "media/base/channel_layout.h" 17 18// cras_util.h headers pull in min/max macros... 19// TODO(dgreid): Fix headers such that these aren't imported. 20#undef min 21#undef max 22 23namespace media { 24 25static void AddDefaultDevice(AudioDeviceNames* device_names) { 26 DCHECK(device_names->empty()); 27 28 // Cras will route audio from a proper physical device automatically. 29 device_names->push_back( 30 AudioDeviceName(AudioManagerBase::kDefaultDeviceName, 31 AudioManagerBase::kDefaultDeviceId)); 32} 33 34// Maximum number of output streams that can be open simultaneously. 35static const int kMaxOutputStreams = 50; 36 37// Default sample rate for input and output streams. 38static const int kDefaultSampleRate = 48000; 39 40// Define bounds for the output buffer size. 41static const int kMinimumOutputBufferSize = 512; 42static const int kMaximumOutputBufferSize = 8192; 43 44// Default input buffer size. 45static const int kDefaultInputBufferSize = 1024; 46 47bool AudioManagerCras::HasAudioOutputDevices() { 48 return true; 49} 50 51bool AudioManagerCras::HasAudioInputDevices() { 52 return true; 53} 54 55AudioManagerCras::AudioManagerCras(AudioLogFactory* audio_log_factory) 56 : AudioManagerBase(audio_log_factory) { 57 SetMaxOutputStreamsAllowed(kMaxOutputStreams); 58} 59 60AudioManagerCras::~AudioManagerCras() { 61 Shutdown(); 62} 63 64void AudioManagerCras::ShowAudioInputSettings() { 65 NOTIMPLEMENTED(); 66} 67 68void AudioManagerCras::GetAudioInputDeviceNames( 69 AudioDeviceNames* device_names) { 70 AddDefaultDevice(device_names); 71} 72 73void AudioManagerCras::GetAudioOutputDeviceNames( 74 AudioDeviceNames* device_names) { 75 AddDefaultDevice(device_names); 76} 77 78AudioParameters AudioManagerCras::GetInputStreamParameters( 79 const std::string& device_id) { 80 int user_buffer_size = GetUserBufferSize(); 81 int buffer_size = user_buffer_size ? 82 user_buffer_size : kDefaultInputBufferSize; 83 84 // TODO(hshi): Fine-tune audio parameters based on |device_id|. The optimal 85 // parameters for the loopback stream may differ from the default. 86 return AudioParameters( 87 AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO, 88 kDefaultSampleRate, 16, buffer_size); 89} 90 91AudioOutputStream* AudioManagerCras::MakeLinearOutputStream( 92 const AudioParameters& params) { 93 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); 94 return MakeOutputStream(params); 95} 96 97AudioOutputStream* AudioManagerCras::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 // TODO(dgreid): Open the correct input device for unified IO. 103 return MakeOutputStream(params); 104} 105 106AudioInputStream* AudioManagerCras::MakeLinearInputStream( 107 const AudioParameters& params, const std::string& device_id) { 108 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); 109 return MakeInputStream(params, device_id); 110} 111 112AudioInputStream* AudioManagerCras::MakeLowLatencyInputStream( 113 const AudioParameters& params, const std::string& device_id) { 114 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); 115 return MakeInputStream(params, device_id); 116} 117 118AudioParameters AudioManagerCras::GetPreferredOutputStreamParameters( 119 const std::string& output_device_id, 120 const AudioParameters& input_params) { 121 // TODO(tommi): Support |output_device_id|. 122 DLOG_IF(ERROR, !output_device_id.empty()) << "Not implemented!"; 123 ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO; 124 int sample_rate = kDefaultSampleRate; 125 int buffer_size = kMinimumOutputBufferSize; 126 int bits_per_sample = 16; 127 int input_channels = 0; 128 if (input_params.IsValid()) { 129 sample_rate = input_params.sample_rate(); 130 bits_per_sample = input_params.bits_per_sample(); 131 channel_layout = input_params.channel_layout(); 132 input_channels = input_params.input_channels(); 133 buffer_size = 134 std::min(kMaximumOutputBufferSize, 135 std::max(buffer_size, input_params.frames_per_buffer())); 136 } 137 138 int user_buffer_size = GetUserBufferSize(); 139 if (user_buffer_size) 140 buffer_size = user_buffer_size; 141 142 return AudioParameters( 143 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels, 144 sample_rate, bits_per_sample, buffer_size, AudioParameters::NO_EFFECTS); 145} 146 147AudioOutputStream* AudioManagerCras::MakeOutputStream( 148 const AudioParameters& params) { 149 return new CrasUnifiedStream(params, this); 150} 151 152AudioInputStream* AudioManagerCras::MakeInputStream( 153 const AudioParameters& params, const std::string& device_id) { 154 return new CrasInputStream(params, this, device_id); 155} 156 157snd_pcm_format_t AudioManagerCras::BitsToFormat(int bits_per_sample) { 158 switch (bits_per_sample) { 159 case 8: 160 return SND_PCM_FORMAT_U8; 161 case 16: 162 return SND_PCM_FORMAT_S16; 163 case 24: 164 return SND_PCM_FORMAT_S24; 165 case 32: 166 return SND_PCM_FORMAT_S32; 167 default: 168 return SND_PCM_FORMAT_UNKNOWN; 169 } 170} 171 172} // namespace media 173