audio_manager_cras.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
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 44bool AudioManagerCras::HasAudioOutputDevices() { 45 return true; 46} 47 48bool AudioManagerCras::HasAudioInputDevices() { 49 return true; 50} 51 52AudioManagerCras::AudioManagerCras(AudioLogFactory* audio_log_factory) 53 : AudioManagerBase(audio_log_factory) { 54 SetMaxOutputStreamsAllowed(kMaxOutputStreams); 55} 56 57AudioManagerCras::~AudioManagerCras() { 58 Shutdown(); 59} 60 61void AudioManagerCras::ShowAudioInputSettings() { 62 NOTIMPLEMENTED(); 63} 64 65void AudioManagerCras::GetAudioInputDeviceNames( 66 AudioDeviceNames* device_names) { 67 AddDefaultDevice(device_names); 68} 69 70void AudioManagerCras::GetAudioOutputDeviceNames( 71 AudioDeviceNames* device_names) { 72 AddDefaultDevice(device_names); 73} 74 75AudioParameters AudioManagerCras::GetInputStreamParameters( 76 const std::string& device_id) { 77 static const int kDefaultInputBufferSize = 1024; 78 // TODO(hshi): Fine-tune audio parameters based on |device_id|. The optimal 79 // parameters for the loopback stream may differ from the default. 80 return AudioParameters( 81 AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO, 82 kDefaultSampleRate, 16, kDefaultInputBufferSize); 83} 84 85AudioOutputStream* AudioManagerCras::MakeLinearOutputStream( 86 const AudioParameters& params) { 87 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); 88 return MakeOutputStream(params); 89} 90 91AudioOutputStream* AudioManagerCras::MakeLowLatencyOutputStream( 92 const AudioParameters& params, 93 const std::string& device_id) { 94 DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!"; 95 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); 96 // TODO(dgreid): Open the correct input device for unified IO. 97 return MakeOutputStream(params); 98} 99 100AudioInputStream* AudioManagerCras::MakeLinearInputStream( 101 const AudioParameters& params, const std::string& device_id) { 102 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); 103 return MakeInputStream(params, device_id); 104} 105 106AudioInputStream* AudioManagerCras::MakeLowLatencyInputStream( 107 const AudioParameters& params, const std::string& device_id) { 108 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); 109 return MakeInputStream(params, device_id); 110} 111 112AudioParameters AudioManagerCras::GetPreferredOutputStreamParameters( 113 const std::string& output_device_id, 114 const AudioParameters& input_params) { 115 // TODO(tommi): Support |output_device_id|. 116 DLOG_IF(ERROR, !output_device_id.empty()) << "Not implemented!"; 117 ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO; 118 int sample_rate = kDefaultSampleRate; 119 int buffer_size = kMinimumOutputBufferSize; 120 int bits_per_sample = 16; 121 int input_channels = 0; 122 if (input_params.IsValid()) { 123 sample_rate = input_params.sample_rate(); 124 bits_per_sample = input_params.bits_per_sample(); 125 channel_layout = input_params.channel_layout(); 126 input_channels = input_params.input_channels(); 127 buffer_size = 128 std::min(kMaximumOutputBufferSize, 129 std::max(buffer_size, input_params.frames_per_buffer())); 130 } 131 132 int user_buffer_size = GetUserBufferSize(); 133 if (user_buffer_size) 134 buffer_size = user_buffer_size; 135 136 return AudioParameters( 137 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels, 138 sample_rate, bits_per_sample, buffer_size, AudioParameters::NO_EFFECTS); 139} 140 141AudioOutputStream* AudioManagerCras::MakeOutputStream( 142 const AudioParameters& params) { 143 return new CrasUnifiedStream(params, this); 144} 145 146AudioInputStream* AudioManagerCras::MakeInputStream( 147 const AudioParameters& params, const std::string& device_id) { 148 return new CrasInputStream(params, this, device_id); 149} 150 151snd_pcm_format_t AudioManagerCras::BitsToFormat(int bits_per_sample) { 152 switch (bits_per_sample) { 153 case 8: 154 return SND_PCM_FORMAT_U8; 155 case 16: 156 return SND_PCM_FORMAT_S16; 157 case 24: 158 return SND_PCM_FORMAT_S24; 159 case 32: 160 return SND_PCM_FORMAT_S32; 161 default: 162 return SND_PCM_FORMAT_UNKNOWN; 163 } 164} 165 166} // namespace media 167