Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(368)

Side by Side Diff: components/copresence/mediums/audio/audio_player.cc

Issue 419073002: Add the copresence DirectiveHandler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "components/copresence/mediums/audio/audio_player.h"
6
7 #include <algorithm>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/logging.h"
13 #include "base/run_loop.h"
14 #include "components/copresence/public/copresence_constants.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "media/audio/audio_manager.h"
17 #include "media/audio/audio_parameters.h"
18 #include "media/base/audio_bus.h"
19
20 namespace {
21
22 const int kDefaultFrameCount = 1024;
23 const double kOutputVolumePercent = 1.0f;
24
25 } // namespace
26
27 namespace copresence {
28
29 // Public methods.
30
31 AudioPlayer::AudioPlayer()
32 : stream_(NULL), is_playing_(false), frame_index_(0) {
33 }
34
35 AudioPlayer::~AudioPlayer() {
36 }
37
38 void AudioPlayer::Initialize() {
39 media::AudioManager::Get()->GetTaskRunner()->PostTask(
40 FROM_HERE,
41 base::Bind(&AudioPlayer::InitializeOnAudioThread,
42 base::Unretained(this)));
43 }
44
45 void AudioPlayer::Play(
46 const scoped_refptr<media::AudioBusRefCounted>& samples) {
47 media::AudioManager::Get()->GetTaskRunner()->PostTask(
48 FROM_HERE,
49 base::Bind(
50 &AudioPlayer::PlayOnAudioThread, base::Unretained(this), samples));
51 }
52
53 void AudioPlayer::Stop() {
54 media::AudioManager::Get()->GetTaskRunner()->PostTask(
55 FROM_HERE,
56 base::Bind(&AudioPlayer::StopOnAudioThread, base::Unretained(this)));
57 }
58
59 void AudioPlayer::Finalize() {
60 media::AudioManager::Get()->GetTaskRunner()->PostTask(
61 FROM_HERE,
62 base::Bind(&AudioPlayer::FinalizeOnAudioThread, base::Unretained(this)));
63 }
64
65 // Private methods.
66
67 void AudioPlayer::InitializeOnAudioThread() {
68 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
69 stream_ = output_stream_for_testing_
70 ? output_stream_for_testing_.get()
71 : media::AudioManager::Get()->MakeAudioOutputStreamProxy(
72 media::AudioParameters(
73 media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
74 media::CHANNEL_LAYOUT_MONO,
75 kDefaultSampleRate,
76 kDefaultBitsPerSample,
77 kDefaultFrameCount),
78 std::string());
79
80 if (!stream_ || !stream_->Open()) {
81 LOG(ERROR) << "Failed to open an output stream.";
82 if (stream_) {
83 stream_->Close();
84 stream_ = NULL;
85 }
86 return;
87 }
88 stream_->SetVolume(kOutputVolumePercent);
89 }
90
91 void AudioPlayer::PlayOnAudioThread(
92 const scoped_refptr<media::AudioBusRefCounted>& samples) {
93 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
94 if (!stream_)
95 return;
96
97 {
98 base::AutoLock al(state_lock_);
99
100 samples_ = samples;
101 frame_index_ = 0;
102
103 if (is_playing_)
104 return;
105 }
106
107 DVLOG(2) << "Playing Audio.";
108 is_playing_ = true;
Daniel Erat 2014/08/05 16:38:52 you have an unprotected write to is_playing_ here
rkc 2014/08/05 18:00:35 This lock is in place to prevent simultaneous read
109 stream_->Start(this);
110 }
111
112 void AudioPlayer::StopOnAudioThread() {
113 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
114 if (!stream_)
115 return;
116
117 stream_->Stop();
118 is_playing_ = false;
119 }
120
121 void AudioPlayer::StopAndCloseOnAudioThread() {
122 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
123 if (!stream_)
124 return;
125
126 if (is_playing_)
127 stream_->Stop();
128 stream_->Close();
129 stream_ = NULL;
130
131 is_playing_ = false;
132 }
133
134 void AudioPlayer::FinalizeOnAudioThread() {
135 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
136 StopAndCloseOnAudioThread();
137 delete this;
138 }
139
140 int AudioPlayer::OnMoreData(media::AudioBus* dest,
141 media::AudioBuffersState /* state */) {
142 base::AutoLock al(state_lock_);
143 DCHECK(is_playing_);
144
145 // Continuously play our samples till explicitly told to stop.
146 const int leftover_frames = samples_->frames() - frame_index_;
147 const int frames_to_copy = std::min(dest->frames(), leftover_frames);
148
149 samples_->CopyPartialFramesTo(frame_index_, frames_to_copy, 0, dest);
150 frame_index_ += frames_to_copy;
151
152 // If we didn't fill the destination audio bus, wrap around and fill the rest.
153 if (leftover_frames <= dest->frames()) {
154 samples_->CopyPartialFramesTo(
155 0, dest->frames() - frames_to_copy, frames_to_copy, dest);
156 frame_index_ = dest->frames() - frames_to_copy;
157 }
158
159 return dest->frames();
160 }
161
162 void AudioPlayer::OnError(media::AudioOutputStream* /* stream */) {
163 LOG(ERROR) << "Error during system sound reproduction.";
164 media::AudioManager::Get()->GetTaskRunner()->PostTask(
165 FROM_HERE,
166 base::Bind(&AudioPlayer::StopAndCloseOnAudioThread,
167 base::Unretained(this)));
168 }
169
170 void AudioPlayer::FlushAudioLoopForTesting() {
171 if (media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread())
172 return;
173
174 // Queue task on the audio thread, when it is executed, that means we've
175 // successfully executed all the tasks before us.
176 base::RunLoop rl;
177 media::AudioManager::Get()->GetTaskRunner()->PostTaskAndReply(
178 FROM_HERE,
179 base::Bind(base::IgnoreResult(&AudioPlayer::FlushAudioLoopForTesting),
180 base::Unretained(this)),
181 rl.QuitClosure());
182 rl.Run();
183 }
184
185 } // namespace copresence
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698