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/audio_util.h" 15 #include "media/audio/pulse/pulse_output.h" 16 #include "media/audio/pulse/pulse_stubs.h" 17 #include "media/base/channel_layout.h" 18 #include "media/base/limits.h" 19 #include "media/base/media_switches.h" 20 21 using media_audio_pulse::kModulePulse; 22 using media_audio_pulse::InitializeStubs; 23 using media_audio_pulse::StubPathMap; 24 25 namespace media { 26 27 // Maximum number of output streams that can be open simultaneously. 28 static const int kMaxOutputStreams = 50; 29 30 // Default sample rate for input and output streams. 31 static const int kDefaultSampleRate = 48000; 32 33 static const base::FilePath::CharType kPulseLib[] = 34 FILE_PATH_LITERAL("libpulse.so.0"); 35 36 // Implementation of AudioManager. 37 static bool HasAudioHardware() { 38 int fd; 39 const char *file; 40 41 if ((file = getenv("AUDIOCTLDEVICE")) == 0 || *file == '\0') 42 file = "/dev/audioctl"; 43 44 if ((fd = open(file, O_RDONLY)) < 0) 45 return false; 46 47 close(fd); 48 return true; 49 } 50 51 bool AudioManagerOpenBSD::HasAudioOutputDevices() { 52 return HasAudioHardware(); 53 } 54 55 bool AudioManagerOpenBSD::HasAudioInputDevices() { 56 return HasAudioHardware(); 57 } 58 59 AudioParameters AudioManagerOpenBSD::GetInputStreamParameters( 60 const std::string& device_id) { 61 static const int kDefaultInputBufferSize = 1024; 62 63 return AudioParameters( 64 AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO, 65 kDefaultSampleRate, 16, kDefaultInputBufferSize); 66 } 67 68 AudioManagerOpenBSD::AudioManagerOpenBSD() 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 83 AudioManagerOpenBSD::~AudioManagerOpenBSD() { 84 Shutdown(); 85 } 86 87 AudioOutputStream* AudioManagerOpenBSD::MakeLinearOutputStream( 88 const AudioParameters& params) { 89 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format); 90 return MakeOutputStream(params); 91 } 92 93 AudioOutputStream* AudioManagerOpenBSD::MakeLowLatencyOutputStream( 94 const AudioParameters& params, 95 const std::string& input_device_id) { 96 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format); 97 return MakeOutputStream(params); 98 } 99 100 AudioInputStream* AudioManagerOpenBSD::MakeLinearInputStream( 101 const AudioParameters& params, const std::string& device_id) { 102 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format); 103 NOTIMPLEMENTED(); 104 return NULL; 105 } 106 107 AudioInputStream* AudioManagerOpenBSD::MakeLowLatencyInputStream( 108 const AudioParameters& params, const std::string& device_id) { 109 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format); 110 NOTIMPLEMENTED(); 111 return NULL; 112 } 113 114 AudioParameters AudioManagerOpenBSD::GetPreferredOutputStreamParameters( 115 const AudioParameters& input_params) { 116 static const int kDefaultOutputBufferSize = 512; 117 118 ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO; 119 int sample_rate = kDefaultSampleRate; 120 int buffer_size = kDefaultOutputBufferSize; 121 int bits_per_sample = 16; 122 int input_channels = 0; 123 if (input_params.IsValid()) { 124 sample_rate = input_params.sample_rate(); 125 bits_per_sample = input_params.bits_per_sample(); 126 channel_layout = input_params.channel_layout(); 127 input_channels = input_params.input_channels(); 128 buffer_size = std::min(buffer_size, input_params.frames_per_buffer()); 129 } 130 131 int user_buffer_size = GetUserBufferSize(); 132 if (user_buffer_size) 133 buffer_size = user_buffer_size; 134 135 return AudioParameters( 136 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels, 137 sample_rate, bits_per_sample, buffer_size); 138 } 139 140 AudioOutputStream* AudioManagerOpenBSD::MakeOutputStream( 141 const AudioParameters& params) { 142 if (pulse_library_is_initialized_) 143 return new PulseAudioOutputStream(params, this); 144 145 return NULL; 146 } 147 148 // TODO(xians): Merge AudioManagerOpenBSD with AudioManagerPulse; 149 // static 150 AudioManager* CreateAudioManager() { 151 return new AudioManagerOpenBSD(); 152 } 153 154 } // namespace media 155