Home | History | Annotate | Download | only in openbsd
      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