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 "base/metrics/histogram_macros.h"
6 #include "base/memory/ptr_util.h"
7
8 #include "media/audio/openbsd/audio_manager_openbsd.h"
9
10 #include "media/audio/audio_device_description.h"
11 #include "media/audio/audio_output_dispatcher.h"
12 #if defined(USE_SNDIO)
13 #include "media/audio/sndio/sndio_input.h"
14 #include "media/audio/sndio/sndio_output.h"
15 #else
16 #include "media/audio/fake_audio_manager.h"
17 #endif
18 #include "media/base/limits.h"
19 #include "media/base/media_switches.h"
20
21 namespace media {
22
23 enum OpenBSDAudioIO {
24 kPulse,
25 kSndio,
26 kAudioIOMax = kSndio
27 };
28
29 #if defined(USE_SNDIO)
30 // Maximum number of output streams that can be open simultaneously.
31 static const int kMaxOutputStreams = 4;
32
33 // Default sample rate for input and output streams.
34 static const int kDefaultSampleRate = 48000;
35
AddDefaultDevice(AudioDeviceNames * device_names)36 void AddDefaultDevice(AudioDeviceNames* device_names) {
37 DCHECK(device_names->empty());
38 device_names->push_front(AudioDeviceName::CreateDefault());
39 }
40
HasAudioOutputDevices()41 bool AudioManagerOpenBSD::HasAudioOutputDevices() {
42 return true;
43 }
44
HasAudioInputDevices()45 bool AudioManagerOpenBSD::HasAudioInputDevices() {
46 return true;
47 }
48
GetAudioInputDeviceNames(AudioDeviceNames * device_names)49 void AudioManagerOpenBSD::GetAudioInputDeviceNames(
50 AudioDeviceNames* device_names) {
51 DCHECK(device_names->empty());
52 AddDefaultDevice(device_names);
53 }
54
GetAudioOutputDeviceNames(AudioDeviceNames * device_names)55 void AudioManagerOpenBSD::GetAudioOutputDeviceNames(
56 AudioDeviceNames* device_names) {
57 AddDefaultDevice(device_names);
58 }
59
60 #if defined(USE_SNDIO)
GetName()61 const char* AudioManagerOpenBSD::GetName() {
62 return "SNDIO";
63 }
64 #endif
65
GetInputStreamParameters(const std::string & device_id)66 AudioParameters AudioManagerOpenBSD::GetInputStreamParameters(
67 const std::string& device_id) {
68 static const int kDefaultInputBufferSize = 1024;
69
70 int user_buffer_size = GetUserBufferSize();
71 int buffer_size = user_buffer_size ?
72 user_buffer_size : kDefaultInputBufferSize;
73
74 return AudioParameters(
75 AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO,
76 kDefaultSampleRate, buffer_size);
77 }
78
AudioManagerOpenBSD(std::unique_ptr<AudioThread> audio_thread,AudioLogFactory * audio_log_factory)79 AudioManagerOpenBSD::AudioManagerOpenBSD(std::unique_ptr<AudioThread> audio_thread,
80 AudioLogFactory* audio_log_factory)
81 : AudioManagerBase(std::move(audio_thread),
82 audio_log_factory) {
83 DLOG(WARNING) << "AudioManagerOpenBSD";
84 SetMaxOutputStreamsAllowed(kMaxOutputStreams);
85 }
86
~AudioManagerOpenBSD()87 AudioManagerOpenBSD::~AudioManagerOpenBSD() {
88 Shutdown();
89 }
90
MakeLinearOutputStream(const AudioParameters & params,const LogCallback & log_callback)91 AudioOutputStream* AudioManagerOpenBSD::MakeLinearOutputStream(
92 const AudioParameters& params,
93 const LogCallback& log_callback) {
94 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format());
95 return MakeOutputStream(params);
96 }
97
MakeLowLatencyOutputStream(const AudioParameters & params,const std::string & device_id,const LogCallback & log_callback)98 AudioOutputStream* AudioManagerOpenBSD::MakeLowLatencyOutputStream(
99 const AudioParameters& params,
100 const std::string& device_id,
101 const LogCallback& log_callback) {
102 DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!";
103 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format());
104 return MakeOutputStream(params);
105 }
106
MakeLinearInputStream(const AudioParameters & params,const std::string & device_id,const LogCallback & log_callback)107 AudioInputStream* AudioManagerOpenBSD::MakeLinearInputStream(
108 const AudioParameters& params,
109 const std::string& device_id,
110 const LogCallback& log_callback) {
111 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format());
112 return MakeInputStream(params);
113 }
114
MakeLowLatencyInputStream(const AudioParameters & params,const std::string & device_id,const LogCallback & log_callback)115 AudioInputStream* AudioManagerOpenBSD::MakeLowLatencyInputStream(
116 const AudioParameters& params,
117 const std::string& device_id,
118 const LogCallback& log_callback) {
119 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format());
120 return MakeInputStream(params);
121 }
122
GetPreferredOutputStreamParameters(const std::string & output_device_id,const AudioParameters & input_params)123 AudioParameters AudioManagerOpenBSD::GetPreferredOutputStreamParameters(
124 const std::string& output_device_id,
125 const AudioParameters& input_params) {
126 // TODO(tommi): Support |output_device_id|.
127 DLOG_IF(ERROR, !output_device_id.empty()) << "Not implemented!";
128 static const int kDefaultOutputBufferSize = 2048;
129
130 ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
131 int sample_rate = kDefaultSampleRate;
132 int buffer_size = kDefaultOutputBufferSize;
133 if (input_params.IsValid()) {
134 sample_rate = input_params.sample_rate();
135 channel_layout = input_params.channel_layout();
136 buffer_size = std::min(buffer_size, input_params.frames_per_buffer());
137 }
138
139 int user_buffer_size = GetUserBufferSize();
140 if (user_buffer_size)
141 buffer_size = user_buffer_size;
142
143 return AudioParameters(
144 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout,
145 sample_rate, buffer_size);
146 }
147
MakeInputStream(const AudioParameters & params)148 AudioInputStream* AudioManagerOpenBSD::MakeInputStream(
149 const AudioParameters& params) {
150 DLOG(WARNING) << "MakeInputStream";
151 return new SndioAudioInputStream(this,
152 AudioDeviceDescription::kDefaultDeviceId, params);
153 }
154
MakeOutputStream(const AudioParameters & params)155 AudioOutputStream* AudioManagerOpenBSD::MakeOutputStream(
156 const AudioParameters& params) {
157 DLOG(WARNING) << "MakeOutputStream";
158 return new SndioAudioOutputStream(params, this);
159 }
160 #endif
161
CreateAudioManager(std::unique_ptr<AudioThread> audio_thread,AudioLogFactory * audio_log_factory)162 std::unique_ptr<media::AudioManager> CreateAudioManager(
163 std::unique_ptr<AudioThread> audio_thread,
164 AudioLogFactory* audio_log_factory) {
165 DLOG(WARNING) << "CreateAudioManager";
166 #if defined(USE_SNDIO)
167 UMA_HISTOGRAM_ENUMERATION("Media.OpenBSDAudioIO", kSndio, kAudioIOMax + 1);
168 return std::make_unique<AudioManagerOpenBSD>(std::move(audio_thread),
169 audio_log_factory);
170 #else
171 return std::make_unique<FakeAudioManager>(std::move(audio_thread),
172 audio_log_factory);
173 #endif
174
175 }
176
177 } // namespace media
178