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 20 using media_audio_pulse::kModulePulse; 21 using media_audio_pulse::InitializeStubs; 22 using media_audio_pulse::StubPathMap; 23 24 namespace media { 25 26 // Maximum number of output streams that can be open simultaneously. 27 static const int kMaxOutputStreams = 50; 28 29 // Default sample rate for input and output streams. 30 static const int kDefaultSampleRate = 48000; 31 32 static const base::FilePath::CharType kPulseLib[] = 33 FILE_PATH_LITERAL("libpulse.so.0"); 34 35 // Implementation of AudioManager. 36 static 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 50 bool AudioManagerOpenBSD::HasAudioOutputDevices() { 51 return HasAudioHardware(); 52 } 53 54 bool AudioManagerOpenBSD::HasAudioInputDevices() { 55 return HasAudioHardware(); 56 } 57 58 AudioParameters 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 71 AudioManagerOpenBSD::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 87 AudioManagerOpenBSD::~AudioManagerOpenBSD() { 88 Shutdown(); 89 } 90 91 AudioOutputStream* AudioManagerOpenBSD::MakeLinearOutputStream( 92 const AudioParameters& params) { 93 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format); 94 return MakeOutputStream(params); 95 } 96 97 AudioOutputStream* 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 105 AudioInputStream* 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 112 AudioInputStream* 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 119 AudioParameters 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 146 AudioOutputStream* 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 156 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) { 157 return new AudioManagerOpenBSD(audio_log_factory); 158 } 159 160 } // namespace media 161