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.
5 #include "media/audio/pulse/pulse_input.h"
7 #include "base/logging.h"
8 #include "media/audio/pulse/audio_manager_pulse.h"
9 #include "media/audio/pulse/pulse_util.h"
13 using pulse::AutoPulseLock
;
14 using pulse::WaitForOperationCompletion
;
16 // Number of blocks of buffers used in the |fifo_|.
17 const int kNumberOfBlocksBufferInFifo
= 2;
19 PulseAudioInputStream::PulseAudioInputStream(AudioManagerPulse
* audio_manager
,
20 const std::string
& device_name
,
21 const AudioParameters
& params
,
22 pa_threaded_mainloop
* mainloop
,
24 : audio_manager_(audio_manager
),
26 device_name_(device_name
),
30 stream_started_(false),
32 fifo_(params
.channels(),
33 params
.frames_per_buffer(),
34 kNumberOfBlocksBufferInFifo
),
35 pa_mainloop_(mainloop
),
40 CHECK(params_
.IsValid());
43 PulseAudioInputStream::~PulseAudioInputStream() {
44 // All internal structures should already have been freed in Close(),
45 // which calls AudioManagerPulse::Release which deletes this object.
49 bool PulseAudioInputStream::Open() {
50 DCHECK(thread_checker_
.CalledOnValidThread());
51 AutoPulseLock
auto_lock(pa_mainloop_
);
52 if (!pulse::CreateInputStream(pa_mainloop_
, pa_context_
, &handle_
, params_
,
53 device_name_
, &StreamNotifyCallback
, this)) {
62 void PulseAudioInputStream::Start(AudioInputCallback
* callback
) {
63 DCHECK(thread_checker_
.CalledOnValidThread());
67 // AGC needs to be started out of the lock.
70 AutoPulseLock
auto_lock(pa_mainloop_
);
75 // Start the streaming.
77 pa_stream_set_read_callback(handle_
, &ReadCallback
, this);
78 pa_stream_readable_size(handle_
);
79 stream_started_
= true;
81 pa_operation
* operation
=
82 pa_stream_cork(handle_
, 0, &pulse::StreamSuccessCallback
, pa_mainloop_
);
83 WaitForOperationCompletion(pa_mainloop_
, operation
);
86 void PulseAudioInputStream::Stop() {
87 DCHECK(thread_checker_
.CalledOnValidThread());
88 AutoPulseLock
auto_lock(pa_mainloop_
);
94 // Set the flag to false to stop filling new data to soundcard.
95 stream_started_
= false;
97 // Clean up the old buffer.
98 pa_stream_drop(handle_
);
101 pa_operation
* operation
= pa_stream_flush(handle_
,
102 &pulse::StreamSuccessCallback
,
104 WaitForOperationCompletion(pa_mainloop_
, operation
);
107 pa_stream_set_read_callback(handle_
, NULL
, NULL
);
108 operation
= pa_stream_cork(handle_
, 1, &pulse::StreamSuccessCallback
,
110 WaitForOperationCompletion(pa_mainloop_
, operation
);
114 void PulseAudioInputStream::Close() {
115 DCHECK(thread_checker_
.CalledOnValidThread());
117 AutoPulseLock
auto_lock(pa_mainloop_
);
119 // Disable all the callbacks before disconnecting.
120 pa_stream_set_state_callback(handle_
, NULL
, NULL
);
121 pa_operation
* operation
= pa_stream_flush(
122 handle_
, &pulse::StreamSuccessCallback
, pa_mainloop_
);
123 WaitForOperationCompletion(pa_mainloop_
, operation
);
125 if (pa_stream_get_state(handle_
) != PA_STREAM_UNCONNECTED
)
126 pa_stream_disconnect(handle_
);
128 // Release PulseAudio structures.
129 pa_stream_unref(handle_
);
134 // Signal to the manager that we're closed and can be removed.
135 // This should be the last call in the function as it deletes "this".
136 audio_manager_
->ReleaseInputStream(this);
139 double PulseAudioInputStream::GetMaxVolume() {
140 return static_cast<double>(PA_VOLUME_NORM
);
143 void PulseAudioInputStream::SetVolume(double volume
) {
144 AutoPulseLock
auto_lock(pa_mainloop_
);
148 size_t index
= pa_stream_get_device_index(handle_
);
149 pa_operation
* operation
= NULL
;
151 // Get the number of channels for the source only when the |channels_| is 0.
152 // We are assuming the stream source is not changed on the fly here.
153 operation
= pa_context_get_source_info_by_index(
154 pa_context_
, index
, &VolumeCallback
, this);
155 WaitForOperationCompletion(pa_mainloop_
, operation
);
157 DLOG(WARNING
) << "Failed to get the number of channels for the source";
162 pa_cvolume pa_volume
;
163 pa_cvolume_set(&pa_volume
, channels_
, volume
);
164 operation
= pa_context_set_source_volume_by_index(
165 pa_context_
, index
, &pa_volume
, NULL
, NULL
);
167 // Don't need to wait for this task to complete.
168 pa_operation_unref(operation
);
171 double PulseAudioInputStream::GetVolume() {
172 if (pa_threaded_mainloop_in_thread(pa_mainloop_
)) {
173 // When being called by the pulse thread, GetVolume() is asynchronous and
174 // called under AutoPulseLock.
178 size_t index
= pa_stream_get_device_index(handle_
);
179 pa_operation
* operation
= pa_context_get_source_info_by_index(
180 pa_context_
, index
, &VolumeCallback
, this);
181 // Do not wait for the operation since we can't block the pulse thread.
182 pa_operation_unref(operation
);
184 // Return zero and the callback will asynchronously update the |volume_|.
187 GetSourceInformation(&VolumeCallback
);
192 bool PulseAudioInputStream::IsMuted() {
193 DCHECK(thread_checker_
.CalledOnValidThread());
194 GetSourceInformation(&MuteCallback
);
198 // static, used by pa_stream_set_read_callback.
199 void PulseAudioInputStream::ReadCallback(pa_stream
* handle
,
202 PulseAudioInputStream
* stream
=
203 reinterpret_cast<PulseAudioInputStream
*>(user_data
);
208 // static, used by pa_context_get_source_info_by_index.
209 void PulseAudioInputStream::VolumeCallback(pa_context
* context
,
210 const pa_source_info
* info
,
211 int error
, void* user_data
) {
212 PulseAudioInputStream
* stream
=
213 reinterpret_cast<PulseAudioInputStream
*>(user_data
);
216 pa_threaded_mainloop_signal(stream
->pa_mainloop_
, 0);
220 if (stream
->channels_
!= info
->channel_map
.channels
)
221 stream
->channels_
= info
->channel_map
.channels
;
223 pa_volume_t volume
= PA_VOLUME_MUTED
; // Minimum possible value.
224 // Use the max volume of any channel as the volume.
225 for (int i
= 0; i
< stream
->channels_
; ++i
) {
226 if (volume
< info
->volume
.values
[i
])
227 volume
= info
->volume
.values
[i
];
230 // It is safe to access |volume_| here since VolumeCallback() is running
232 stream
->volume_
= static_cast<double>(volume
);
235 // static, used by pa_context_get_source_info_by_index.
236 void PulseAudioInputStream::MuteCallback(pa_context
* context
,
237 const pa_source_info
* info
,
240 // Runs on PulseAudio callback thread. It might be possible to make this
241 // method more thread safe by passing a struct (or pair) of a local copy of
242 // |pa_mainloop_| and |muted_| instead.
243 PulseAudioInputStream
* stream
=
244 reinterpret_cast<PulseAudioInputStream
*>(user_data
);
246 // Avoid infinite wait loop in case of error.
248 pa_threaded_mainloop_signal(stream
->pa_mainloop_
, 0);
252 stream
->muted_
= info
->mute
!= 0;
255 // static, used by pa_stream_set_state_callback.
256 void PulseAudioInputStream::StreamNotifyCallback(pa_stream
* s
,
258 PulseAudioInputStream
* stream
=
259 reinterpret_cast<PulseAudioInputStream
*>(user_data
);
261 if (s
&& stream
->callback_
&&
262 pa_stream_get_state(s
) == PA_STREAM_FAILED
) {
263 stream
->callback_
->OnError(stream
);
266 pa_threaded_mainloop_signal(stream
->pa_mainloop_
, 0);
269 void PulseAudioInputStream::ReadData() {
270 uint32 hardware_delay
= pulse::GetHardwareLatencyInBytes(
271 handle_
, params_
.sample_rate(), params_
.GetBytesPerFrame());
273 // Update the AGC volume level once every second. Note that,
274 // |volume| is also updated each time SetVolume() is called
275 // through IPC by the render-side AGC.
276 // We disregard the |normalized_volume| from GetAgcVolume()
277 // and use the value calculated by |volume_|.
278 double normalized_volume
= 0.0;
279 GetAgcVolume(&normalized_volume
);
280 normalized_volume
= volume_
/ GetMaxVolume();
284 const void* data
= NULL
;
285 pa_stream_peek(handle_
, &data
, &length
);
286 if (!data
|| length
== 0)
289 const int number_of_frames
= length
/ params_
.GetBytesPerFrame();
290 if (number_of_frames
> fifo_
.GetUnfilledFrames()) {
291 // Dynamically increase capacity to the FIFO to handle larger buffer got
293 const int increase_blocks_of_buffer
= static_cast<int>(
294 (number_of_frames
- fifo_
.GetUnfilledFrames()) /
295 params_
.frames_per_buffer()) + 1;
296 fifo_
.IncreaseCapacity(increase_blocks_of_buffer
);
299 fifo_
.Push(data
, number_of_frames
, params_
.bits_per_sample() / 8);
301 // Checks if we still have data.
302 pa_stream_drop(handle_
);
303 } while (pa_stream_readable_size(handle_
) > 0);
305 while (fifo_
.available_blocks()) {
306 const AudioBus
* audio_bus
= fifo_
.Consume();
308 // Compensate the audio delay caused by the FIFO.
309 hardware_delay
+= fifo_
.GetAvailableFrames() * params_
.GetBytesPerFrame();
310 callback_
->OnData(this, audio_bus
, hardware_delay
, normalized_volume
);
312 // Sleep 5ms to wait until render consumes the data in order to avoid
313 // back to back OnData() method.
314 if (fifo_
.available_blocks())
315 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(5));
318 pa_threaded_mainloop_signal(pa_mainloop_
, 0);
321 bool PulseAudioInputStream::GetSourceInformation(pa_source_info_cb_t callback
) {
322 AutoPulseLock
auto_lock(pa_mainloop_
);
326 size_t index
= pa_stream_get_device_index(handle_
);
327 pa_operation
* operation
=
328 pa_context_get_source_info_by_index(pa_context_
, index
, callback
, this);
329 WaitForOperationCompletion(pa_mainloop_
, operation
);