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