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 void AudioOutputStreamSink::SwitchOutputDevice(
63 const std::string
& device_id
,
64 const GURL
& security_origin
,
65 const SwitchOutputDeviceCB
& callback
) {
66 callback
.Run(SWITCH_OUTPUT_DEVICE_RESULT_ERROR_NOT_SUPPORTED
);
69 int AudioOutputStreamSink::OnMoreData(AudioBus
* dest
,
70 uint32 total_bytes_delay
) {
71 // Note: Runs on the audio thread created by the OS.
72 base::AutoLock
al(callback_lock_
);
73 if (!active_render_callback_
)
76 return active_render_callback_
->Render(
77 dest
, total_bytes_delay
* 1000.0 / params_
.GetBytesPerSecond());
80 void AudioOutputStreamSink::OnError(AudioOutputStream
* stream
) {
81 // Note: Runs on the audio thread created by the OS.
82 base::AutoLock
al(callback_lock_
);
83 if (active_render_callback_
)
84 active_render_callback_
->OnRenderError();
87 void AudioOutputStreamSink::DoStart() {
88 DCHECK(audio_task_runner_
->BelongsToCurrentThread());
90 // Create an AudioOutputStreamProxy which will handle any and all resampling
91 // necessary to generate a low latency output stream.
93 AudioManager::Get()->MakeAudioOutputStreamProxy(params_
, std::string());
94 if (!stream_
|| !stream_
->Open()) {
95 render_callback_
->OnRenderError();
102 void AudioOutputStreamSink::DoStop() {
103 DCHECK(audio_task_runner_
->BelongsToCurrentThread());
113 void AudioOutputStreamSink::DoPause() {
114 DCHECK(audio_task_runner_
->BelongsToCurrentThread());
118 void AudioOutputStreamSink::DoPlay() {
119 DCHECK(audio_task_runner_
->BelongsToCurrentThread());
120 stream_
->Start(this);
123 void AudioOutputStreamSink::DoSetVolume(double volume
) {
124 DCHECK(audio_task_runner_
->BelongsToCurrentThread());
125 stream_
->SetVolume(volume
);
128 void AudioOutputStreamSink::ClearCallback() {
129 base::AutoLock
al(callback_lock_
);
130 active_render_callback_
= NULL
;