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 return AudioParameters( 63 AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO, 64 kDefaultSampleRate, 16, kDefaultInputBufferSize); 65} 66 67AudioManagerOpenBSD::AudioManagerOpenBSD(AudioLogFactory* audio_log_factory) 68 : AudioManagerBase(audio_log_factory), 69 pulse_library_is_initialized_(false) { 70 SetMaxOutputStreamsAllowed(kMaxOutputStreams); 71 StubPathMap paths; 72 73 // Check if the pulse library is avialbale. 74 paths[kModulePulse].push_back(kPulseLib); 75 if (!InitializeStubs(paths)) { 76 DLOG(WARNING) << "Failed on loading the Pulse library and symbols"; 77 return; 78 } 79 80 pulse_library_is_initialized_ = true; 81} 82 83AudioManagerOpenBSD::~AudioManagerOpenBSD() { 84 Shutdown(); 85} 86 87AudioOutputStream* AudioManagerOpenBSD::MakeLinearOutputStream( 88 const AudioParameters& params) { 89 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format); 90 return MakeOutputStream(params); 91} 92 93AudioOutputStream* AudioManagerOpenBSD::MakeLowLatencyOutputStream( 94 const AudioParameters& params, 95 const std::string& device_id, 96 const std::string& input_device_id) { 97 DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!"; 98 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format); 99 return MakeOutputStream(params); 100} 101 102AudioInputStream* AudioManagerOpenBSD::MakeLinearInputStream( 103 const AudioParameters& params, const std::string& device_id) { 104 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format); 105 NOTIMPLEMENTED(); 106 return NULL; 107} 108 109AudioInputStream* AudioManagerOpenBSD::MakeLowLatencyInputStream( 110 const AudioParameters& params, const std::string& device_id) { 111 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format); 112 NOTIMPLEMENTED(); 113 return NULL; 114} 115 116AudioParameters AudioManagerOpenBSD::GetPreferredOutputStreamParameters( 117 const std::string& output_device_id, 118 const AudioParameters& input_params) { 119 // TODO(tommi): Support |output_device_id|. 120 DLOG_IF(ERROR, !output_device_id.empty()) << "Not implemented!"; 121 static const int kDefaultOutputBufferSize = 512; 122 123 ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO; 124 int sample_rate = kDefaultSampleRate; 125 int buffer_size = kDefaultOutputBufferSize; 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 = std::min(buffer_size, input_params.frames_per_buffer()); 134 } 135 136 int user_buffer_size = GetUserBufferSize(); 137 if (user_buffer_size) 138 buffer_size = user_buffer_size; 139 140 return AudioParameters( 141 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels, 142 sample_rate, bits_per_sample, buffer_size, AudioParameters::NO_EFFECTS); 143} 144 145AudioOutputStream* AudioManagerOpenBSD::MakeOutputStream( 146 const AudioParameters& params) { 147 if (pulse_library_is_initialized_) 148 return new PulseAudioOutputStream(params, this); 149 150 return NULL; 151} 152 153// TODO(xians): Merge AudioManagerOpenBSD with AudioManagerPulse; 154// static 155AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) { 156 return new AudioManagerOpenBSD(audio_log_factory); 157} 158 159} // namespace media 160