OLD | NEW |
| (Empty) |
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/filters/reference_audio_renderer.h" | |
6 | |
7 #include <math.h> | |
8 | |
9 #include "base/bind.h" | |
10 #include "base/synchronization/waitable_event.h" | |
11 | |
12 namespace media { | |
13 | |
14 ReferenceAudioRenderer::ReferenceAudioRenderer(AudioManager* audio_manager) | |
15 : AudioRendererBase(), | |
16 audio_manager_(audio_manager), | |
17 bytes_per_second_(0), | |
18 has_buffered_data_(true), | |
19 buffer_capacity_(0) { | |
20 } | |
21 | |
22 ReferenceAudioRenderer::~ReferenceAudioRenderer() { | |
23 // Close down the audio device. | |
24 if (controller_) { | |
25 base::WaitableEvent closed_event(true, false); | |
26 controller_->Close(base::Bind(&base::WaitableEvent::Signal, | |
27 base::Unretained(&closed_event))); | |
28 closed_event.Wait(); | |
29 } | |
30 } | |
31 | |
32 void ReferenceAudioRenderer::SetPlaybackRate(float rate) { | |
33 // TODO(fbarchard): limit rate to reasonable values | |
34 AudioRendererBase::SetPlaybackRate(rate); | |
35 | |
36 if (controller_ && rate > 0.0f) | |
37 controller_->Play(); | |
38 } | |
39 | |
40 void ReferenceAudioRenderer::SetVolume(float volume) { | |
41 if (controller_) | |
42 controller_->SetVolume(volume); | |
43 } | |
44 | |
45 void ReferenceAudioRenderer::OnCreated(AudioOutputController* controller) { | |
46 NOTIMPLEMENTED(); | |
47 } | |
48 | |
49 void ReferenceAudioRenderer::OnPlaying(AudioOutputController* controller) { | |
50 NOTIMPLEMENTED(); | |
51 } | |
52 | |
53 void ReferenceAudioRenderer::OnPaused(AudioOutputController* controller) { | |
54 NOTIMPLEMENTED(); | |
55 } | |
56 | |
57 void ReferenceAudioRenderer::OnError(AudioOutputController* controller, | |
58 int error_code) { | |
59 NOTIMPLEMENTED(); | |
60 } | |
61 | |
62 void ReferenceAudioRenderer::OnMoreData(AudioOutputController* controller, | |
63 AudioBuffersState buffers_state) { | |
64 // TODO(fbarchard): Waveout_output_win.h should handle zero length buffers | |
65 // without clicking. | |
66 uint32 pending_bytes = static_cast<uint32>(ceil(buffers_state.total_bytes() * | |
67 GetPlaybackRate())); | |
68 base::TimeDelta delay = base::TimeDelta::FromMicroseconds( | |
69 base::Time::kMicrosecondsPerSecond * pending_bytes / | |
70 bytes_per_second_); | |
71 has_buffered_data_ = buffers_state.pending_bytes != 0; | |
72 uint32 read = FillBuffer(buffer_.get(), buffer_capacity_, delay); | |
73 controller->EnqueueData(buffer_.get(), read); | |
74 } | |
75 | |
76 void ReferenceAudioRenderer::OnRenderEndOfStream() { | |
77 // We cannot signal end of stream as long as we have buffered data. | |
78 // In such case eventually host would playback all the data, and OnMoreData() | |
79 // would be called with buffers_state.pending_bytes == 0. At that moment | |
80 // we'll call SignalEndOfStream(); | |
81 if (!has_buffered_data_) | |
82 SignalEndOfStream(); | |
83 } | |
84 | |
85 bool ReferenceAudioRenderer::OnInitialize(int bits_per_channel, | |
86 ChannelLayout channel_layout, | |
87 int sample_rate) { | |
88 int samples_per_packet = sample_rate / 10; | |
89 int hardware_buffer_size = samples_per_packet * | |
90 ChannelLayoutToChannelCount(channel_layout) * bits_per_channel / 8; | |
91 | |
92 // Allocate audio buffer based on hardware buffer size. | |
93 buffer_capacity_ = 3 * hardware_buffer_size; | |
94 buffer_.reset(new uint8[buffer_capacity_]); | |
95 | |
96 AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, channel_layout, | |
97 sample_rate, bits_per_channel, samples_per_packet); | |
98 bytes_per_second_ = params.GetBytesPerSecond(); | |
99 | |
100 controller_ = AudioOutputController::Create(audio_manager_, this, params, | |
101 buffer_capacity_); | |
102 return controller_ != NULL; | |
103 } | |
104 | |
105 void ReferenceAudioRenderer::OnStop() { | |
106 if (controller_) | |
107 controller_->Pause(); | |
108 } | |
109 | |
110 } // namespace media | |
OLD | NEW |