1 // Copyright 2014 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/audio_output_stream_sink.h"
8 #include "base/bind_helpers.h"
9 #include "base/location.h"
10 #include "media/audio/audio_manager.h"
14 AudioOutputStreamSink::AudioOutputStreamSink()
15 : render_callback_(NULL
),
16 audio_task_runner_(AudioManager::Get()->GetTaskRunner()),
18 active_render_callback_(NULL
) {
21 AudioOutputStreamSink::~AudioOutputStreamSink() {
24 void AudioOutputStreamSink::Initialize(const AudioParameters
& params
,
25 RenderCallback
* callback
) {
27 DCHECK(!render_callback_
);
29 render_callback_
= callback
;
32 void AudioOutputStreamSink::Start() {
33 audio_task_runner_
->PostTask(
34 FROM_HERE
, base::Bind(&AudioOutputStreamSink::DoStart
, this));
37 void AudioOutputStreamSink::Stop() {
39 audio_task_runner_
->PostTask(
40 FROM_HERE
, base::Bind(&AudioOutputStreamSink::DoStop
, this));
43 void AudioOutputStreamSink::Pause() {
45 audio_task_runner_
->PostTask(
46 FROM_HERE
, base::Bind(&AudioOutputStreamSink::DoPause
, this));
49 void AudioOutputStreamSink::Play() {
50 base::AutoLock
al(callback_lock_
);
51 active_render_callback_
= render_callback_
;
52 audio_task_runner_
->PostTask(
53 FROM_HERE
, base::Bind(&AudioOutputStreamSink::DoPlay
, this));
56 bool AudioOutputStreamSink::SetVolume(double volume
) {
57 audio_task_runner_
->PostTask(
58 FROM_HERE
, base::Bind(&AudioOutputStreamSink::DoSetVolume
, this, volume
));
62 int AudioOutputStreamSink::OnMoreData(AudioBus
* dest
,
63 uint32 total_bytes_delay
) {
64 // Note: Runs on the audio thread created by the OS.
65 base::AutoLock
al(callback_lock_
);
66 if (!active_render_callback_
)
69 return active_render_callback_
->Render(
70 dest
, total_bytes_delay
* 1000.0 / params_
.GetBytesPerSecond());
73 void AudioOutputStreamSink::OnError(AudioOutputStream
* stream
) {
74 // Note: Runs on the audio thread created by the OS.
75 base::AutoLock
al(callback_lock_
);
76 if (active_render_callback_
)
77 active_render_callback_
->OnRenderError();
80 void AudioOutputStreamSink::DoStart() {
81 DCHECK(audio_task_runner_
->BelongsToCurrentThread());
83 // Create an AudioOutputStreamProxy which will handle any and all resampling
84 // necessary to generate a low latency output stream.
86 AudioManager::Get()->MakeAudioOutputStreamProxy(params_
, std::string());
87 if (!stream_
|| !stream_
->Open()) {
88 render_callback_
->OnRenderError();
95 void AudioOutputStreamSink::DoStop() {
96 DCHECK(audio_task_runner_
->BelongsToCurrentThread());
106 void AudioOutputStreamSink::DoPause() {
107 DCHECK(audio_task_runner_
->BelongsToCurrentThread());
111 void AudioOutputStreamSink::DoPlay() {
112 DCHECK(audio_task_runner_
->BelongsToCurrentThread());
113 stream_
->Start(this);
116 void AudioOutputStreamSink::DoSetVolume(double volume
) {
117 DCHECK(audio_task_runner_
->BelongsToCurrentThread());
118 stream_
->SetVolume(volume
);
121 void AudioOutputStreamSink::ClearCallback() {
122 base::AutoLock
al(callback_lock_
);
123 active_render_callback_
= NULL
;