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

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: gn fix 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),
33 output_stream_for_testing_(NULL),
34 is_playing_(false),
35 frame_index_(0) {
36 }
37
38 AudioPlayer::~AudioPlayer() {
39 }
40
41 void AudioPlayer::Initialize() {
42 media::AudioManager::Get()->GetTaskRunner()->PostTask(
43 FROM_HERE,
44 base::Bind(&AudioPlayer::InitializeOnAudioThread,
45 base::Unretained(this)));
46 }
47
48 void AudioPlayer::Play(
49 const scoped_refptr<media::AudioBusRefCounted>& samples) {
50 media::AudioManager::Get()->GetTaskRunner()->PostTask(
51 FROM_HERE,
52 base::Bind(
53 &AudioPlayer::PlayOnAudioThread, base::Unretained(this), samples));
54 }
55
56 void AudioPlayer::Stop() {
57 media::AudioManager::Get()->GetTaskRunner()->PostTask(
58 FROM_HERE,
59 base::Bind(&AudioPlayer::StopOnAudioThread, base::Unretained(this)));
60 }
61
62 void AudioPlayer::Finalize() {
63 media::AudioManager::Get()->GetTaskRunner()->PostTask(
64 FROM_HERE,
65 base::Bind(&AudioPlayer::FinalizeOnAudioThread, base::Unretained(this)));
66 }
67
68 // Private methods.
69
70 void AudioPlayer::InitializeOnAudioThread() {
71 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
72 stream_ = output_stream_for_testing_
73 ? output_stream_for_testing_
74 : media::AudioManager::Get()->MakeAudioOutputStreamProxy(
75 media::AudioParameters(
76 media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
77 media::CHANNEL_LAYOUT_MONO,
78 kDefaultSampleRate,
79 kDefaultBitsPerSample,
80 kDefaultFrameCount),
81 std::string());
82
83 if (!stream_ || !stream_->Open()) {
84 LOG(ERROR) << "Failed to open an output stream.";
85 if (stream_) {
86 stream_->Close();
87 stream_ = NULL;
88 }
89 return;
90 }
91 stream_->SetVolume(kOutputVolumePercent);
92 }
93
94 void AudioPlayer::PlayOnAudioThread(
95 const scoped_refptr<media::AudioBusRefCounted>& samples) {
96 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
97 if (!stream_)
98 return;
99
100 {
101 base::AutoLock al(state_lock_);
102
103 samples_ = samples;
104 frame_index_ = 0;
105
106 if (is_playing_)
107 return;
108 }
109
110 DVLOG(2) << "Playing Audio.";
111 is_playing_ = true;
112 stream_->Start(this);
113 }
114
115 void AudioPlayer::StopOnAudioThread() {
116 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
117 if (!stream_)
118 return;
119
120 stream_->Stop();
121 is_playing_ = false;
122 }
123
124 void AudioPlayer::StopAndCloseOnAudioThread() {
125 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
126 if (!stream_)
127 return;
128
129 if (is_playing_)
130 stream_->Stop();
131 stream_->Close();
132 stream_ = NULL;
133
134 is_playing_ = false;
135 }
136
137 void AudioPlayer::FinalizeOnAudioThread() {
138 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
139 StopAndCloseOnAudioThread();
140 if (output_stream_for_testing_)
141 delete output_stream_for_testing_;
142 delete this;
143 }
144
145 int AudioPlayer::OnMoreData(media::AudioBus* dest,
146 media::AudioBuffersState /* state */) {
147 base::AutoLock al(state_lock_);
148 DCHECK(is_playing_);
149
150 // Continuously play our samples till explicitly told to stop.
151 const int leftover_frames = samples_->frames() - frame_index_;
152 const int frames_to_copy = std::min(dest->frames(), leftover_frames);
153
154 samples_->CopyPartialFramesTo(frame_index_, frames_to_copy, 0, dest);
155 frame_index_ += frames_to_copy;
156
157 // If we didn't fill the destination audio bus, wrap around and fill the rest.
158 if (leftover_frames <= dest->frames()) {
159 samples_->CopyPartialFramesTo(
160 0, dest->frames() - frames_to_copy, frames_to_copy, dest);
161 frame_index_ = dest->frames() - frames_to_copy;
162 }
163
164 return dest->frames();
165 }
166
167 void AudioPlayer::OnError(media::AudioOutputStream* /* stream */) {
168 LOG(ERROR) << "Error during system sound reproduction.";
169 media::AudioManager::Get()->GetTaskRunner()->PostTask(
170 FROM_HERE,
171 base::Bind(&AudioPlayer::StopAndCloseOnAudioThread,
172 base::Unretained(this)));
173 }
174
175 void AudioPlayer::FlushAudioLoopForTesting() {
176 if (media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread())
177 return;
178
179 // Queue task on the audio thread, when it is executed, that means we've
180 // successfully executed all the tasks before us.
181 base::RunLoop rl;
182 media::AudioManager::Get()->GetTaskRunner()->PostTaskAndReply(
183 FROM_HERE,
184 base::Bind(base::IgnoreResult(&AudioPlayer::FlushAudioLoopForTesting),
185 base::Unretained(this)),
186 rl.QuitClosure());
187 rl.Run();
188 }
189
190 } // namespace copresence
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698