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

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

Issue 637223011: Redesign the copresence audio handlers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git/+/master
Patch Set: Created 6 years, 2 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/copresence/mediums/audio/audio_player.h" 5 #include "components/copresence/mediums/audio/audio_player_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/run_loop.h" 13 #include "base/run_loop.h"
14 #include "components/copresence/public/copresence_constants.h" 14 #include "components/copresence/public/copresence_constants.h"
15 #include "content/public/browser/browser_thread.h" 15 #include "content/public/browser/browser_thread.h"
16 #include "media/audio/audio_manager.h" 16 #include "media/audio/audio_manager.h"
17 #include "media/audio/audio_parameters.h" 17 #include "media/audio/audio_parameters.h"
18 #include "media/base/audio_bus.h" 18 #include "media/base/audio_bus.h"
19 19
20 namespace { 20 namespace {
21 21
22 const int kDefaultFrameCount = 1024; 22 const int kDefaultFrameCount = 1024;
23 const double kOutputVolumePercent = 1.0f; 23 const double kOutputVolumePercent = 1.0f;
24 24
25 } // namespace 25 } // namespace
26 26
27 namespace copresence { 27 namespace copresence {
28 28
29 // Public methods. 29 // Public methods.
30 30
31 AudioPlayer::AudioPlayer() 31 AudioPlayerImpl::AudioPlayerImpl()
32 : is_playing_(false), stream_(NULL), frame_index_(0) { 32 : is_playing_(false), stream_(NULL), frame_index_(0) {
33 } 33 }
34 34
35 AudioPlayer::~AudioPlayer() { 35 AudioPlayerImpl::~AudioPlayerImpl() {
36 } 36 }
37 37
38 void AudioPlayer::Initialize() { 38 void AudioPlayerImpl::Initialize() {
39 media::AudioManager::Get()->GetTaskRunner()->PostTask( 39 media::AudioManager::Get()->GetTaskRunner()->PostTask(
40 FROM_HERE, 40 FROM_HERE,
41 base::Bind(&AudioPlayer::InitializeOnAudioThread, 41 base::Bind(&AudioPlayerImpl::InitializeOnAudioThread,
42 base::Unretained(this))); 42 base::Unretained(this)));
43 } 43 }
44 44
45 void AudioPlayer::Play( 45 void AudioPlayerImpl::Play(
46 const scoped_refptr<media::AudioBusRefCounted>& samples) { 46 const scoped_refptr<media::AudioBusRefCounted>& samples) {
47 media::AudioManager::Get()->GetTaskRunner()->PostTask( 47 media::AudioManager::Get()->GetTaskRunner()->PostTask(
48 FROM_HERE, 48 FROM_HERE,
49 base::Bind( 49 base::Bind(&AudioPlayerImpl::PlayOnAudioThread,
50 &AudioPlayer::PlayOnAudioThread, base::Unretained(this), samples)); 50 base::Unretained(this),
51 samples));
51 } 52 }
52 53
53 void AudioPlayer::Stop() { 54 void AudioPlayerImpl::Stop() {
54 media::AudioManager::Get()->GetTaskRunner()->PostTask( 55 media::AudioManager::Get()->GetTaskRunner()->PostTask(
55 FROM_HERE, 56 FROM_HERE,
56 base::Bind(&AudioPlayer::StopOnAudioThread, base::Unretained(this))); 57 base::Bind(&AudioPlayerImpl::StopOnAudioThread, base::Unretained(this)));
57 } 58 }
58 59
59 bool AudioPlayer::IsPlaying() { 60 bool AudioPlayerImpl::IsPlaying() {
60 return is_playing_; 61 return is_playing_;
61 } 62 }
62 63
63 void AudioPlayer::Finalize() { 64 void AudioPlayerImpl::Finalize() {
64 media::AudioManager::Get()->GetTaskRunner()->PostTask( 65 media::AudioManager::Get()->GetTaskRunner()->PostTask(
65 FROM_HERE, 66 FROM_HERE,
66 base::Bind(&AudioPlayer::FinalizeOnAudioThread, base::Unretained(this))); 67 base::Bind(&AudioPlayerImpl::FinalizeOnAudioThread,
68 base::Unretained(this)));
67 } 69 }
68 70
69 // Private methods. 71 // Private methods.
70 72
71 void AudioPlayer::InitializeOnAudioThread() { 73 void AudioPlayerImpl::InitializeOnAudioThread() {
72 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); 74 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
73 stream_ = output_stream_for_testing_ 75 stream_ = output_stream_for_testing_
74 ? output_stream_for_testing_.get() 76 ? output_stream_for_testing_.get()
75 : media::AudioManager::Get()->MakeAudioOutputStreamProxy( 77 : media::AudioManager::Get()->MakeAudioOutputStreamProxy(
76 media::AudioParameters( 78 media::AudioParameters(
77 media::AudioParameters::AUDIO_PCM_LOW_LATENCY, 79 media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
78 media::CHANNEL_LAYOUT_MONO, 80 media::CHANNEL_LAYOUT_MONO,
79 kDefaultSampleRate, 81 kDefaultSampleRate,
80 kDefaultBitsPerSample, 82 kDefaultBitsPerSample,
81 kDefaultFrameCount), 83 kDefaultFrameCount),
82 std::string()); 84 std::string());
83 85
84 if (!stream_ || !stream_->Open()) { 86 if (!stream_ || !stream_->Open()) {
85 LOG(ERROR) << "Failed to open an output stream."; 87 LOG(ERROR) << "Failed to open an output stream.";
86 if (stream_) { 88 if (stream_) {
87 stream_->Close(); 89 stream_->Close();
88 stream_ = NULL; 90 stream_ = NULL;
89 } 91 }
90 return; 92 return;
91 } 93 }
92 stream_->SetVolume(kOutputVolumePercent); 94 stream_->SetVolume(kOutputVolumePercent);
93 } 95 }
94 96
95 void AudioPlayer::PlayOnAudioThread( 97 void AudioPlayerImpl::PlayOnAudioThread(
96 const scoped_refptr<media::AudioBusRefCounted>& samples) { 98 const scoped_refptr<media::AudioBusRefCounted>& samples) {
97 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); 99 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
98 if (!stream_) 100 if (!stream_)
99 return; 101 return;
100 102
101 { 103 {
102 base::AutoLock al(state_lock_); 104 base::AutoLock al(state_lock_);
103 105
104 samples_ = samples; 106 samples_ = samples;
105 frame_index_ = 0; 107 frame_index_ = 0;
106 108
107 if (is_playing_) 109 if (is_playing_)
108 return; 110 return;
109 } 111 }
110 112
111 is_playing_ = true; 113 is_playing_ = true;
112 stream_->Start(this); 114 stream_->Start(this);
113 } 115 }
114 116
115 void AudioPlayer::StopOnAudioThread() { 117 void AudioPlayerImpl::StopOnAudioThread() {
116 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); 118 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
117 if (!stream_) 119 if (!stream_)
118 return; 120 return;
119 121
120 stream_->Stop(); 122 stream_->Stop();
121 is_playing_ = false; 123 is_playing_ = false;
122 } 124 }
123 125
124 void AudioPlayer::StopAndCloseOnAudioThread() { 126 void AudioPlayerImpl::StopAndCloseOnAudioThread() {
125 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); 127 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
126 if (!stream_) 128 if (!stream_)
127 return; 129 return;
128 130
129 if (is_playing_) 131 if (is_playing_)
130 stream_->Stop(); 132 stream_->Stop();
131 stream_->Close(); 133 stream_->Close();
132 stream_ = NULL; 134 stream_ = NULL;
133 135
134 is_playing_ = false; 136 is_playing_ = false;
135 } 137 }
136 138
137 void AudioPlayer::FinalizeOnAudioThread() { 139 void AudioPlayerImpl::FinalizeOnAudioThread() {
138 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); 140 DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
139 StopAndCloseOnAudioThread(); 141 StopAndCloseOnAudioThread();
140 delete this; 142 delete this;
141 } 143 }
142 144
143 int AudioPlayer::OnMoreData(media::AudioBus* dest, 145 int AudioPlayerImpl::OnMoreData(media::AudioBus* dest,
144 uint32 /* total_bytes_delay */) { 146 uint32 /* total_bytes_delay */) {
145 base::AutoLock al(state_lock_); 147 base::AutoLock al(state_lock_);
146 // Continuously play our samples till explicitly told to stop. 148 // Continuously play our samples till explicitly told to stop.
147 const int leftover_frames = samples_->frames() - frame_index_; 149 const int leftover_frames = samples_->frames() - frame_index_;
148 const int frames_to_copy = std::min(dest->frames(), leftover_frames); 150 const int frames_to_copy = std::min(dest->frames(), leftover_frames);
149 151
150 samples_->CopyPartialFramesTo(frame_index_, frames_to_copy, 0, dest); 152 samples_->CopyPartialFramesTo(frame_index_, frames_to_copy, 0, dest);
151 frame_index_ += frames_to_copy; 153 frame_index_ += frames_to_copy;
152 154
153 // If we didn't fill the destination audio bus, wrap around and fill the rest. 155 // If we didn't fill the destination audio bus, wrap around and fill the rest.
154 if (leftover_frames <= dest->frames()) { 156 if (leftover_frames <= dest->frames()) {
155 samples_->CopyPartialFramesTo( 157 samples_->CopyPartialFramesTo(
156 0, dest->frames() - frames_to_copy, frames_to_copy, dest); 158 0, dest->frames() - frames_to_copy, frames_to_copy, dest);
157 frame_index_ = dest->frames() - frames_to_copy; 159 frame_index_ = dest->frames() - frames_to_copy;
158 } 160 }
159 161
160 return dest->frames(); 162 return dest->frames();
161 } 163 }
162 164
163 void AudioPlayer::OnError(media::AudioOutputStream* /* stream */) { 165 void AudioPlayerImpl::OnError(media::AudioOutputStream* /* stream */) {
164 LOG(ERROR) << "Error during system sound reproduction."; 166 LOG(ERROR) << "Error during system sound reproduction.";
165 media::AudioManager::Get()->GetTaskRunner()->PostTask( 167 media::AudioManager::Get()->GetTaskRunner()->PostTask(
166 FROM_HERE, 168 FROM_HERE,
167 base::Bind(&AudioPlayer::StopAndCloseOnAudioThread, 169 base::Bind(&AudioPlayerImpl::StopAndCloseOnAudioThread,
168 base::Unretained(this))); 170 base::Unretained(this)));
169 } 171 }
170 172
171 void AudioPlayer::FlushAudioLoopForTesting() { 173 void AudioPlayerImpl::FlushAudioLoopForTesting() {
172 if (media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()) 174 if (media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread())
173 return; 175 return;
174 176
175 // Queue task on the audio thread, when it is executed, that means we've 177 // Queue task on the audio thread, when it is executed, that means we've
176 // successfully executed all the tasks before us. 178 // successfully executed all the tasks before us.
177 base::RunLoop rl; 179 base::RunLoop rl;
178 media::AudioManager::Get()->GetTaskRunner()->PostTaskAndReply( 180 media::AudioManager::Get()->GetTaskRunner()->PostTaskAndReply(
179 FROM_HERE, 181 FROM_HERE,
180 base::Bind(base::IgnoreResult(&AudioPlayer::FlushAudioLoopForTesting), 182 base::Bind(base::IgnoreResult(&AudioPlayerImpl::FlushAudioLoopForTesting),
181 base::Unretained(this)), 183 base::Unretained(this)),
182 rl.QuitClosure()); 184 rl.QuitClosure());
183 rl.Run(); 185 rl.Run();
184 } 186 }
185 187
186 } // namespace copresence 188 } // namespace copresence
OLDNEW
« no previous file with comments | « components/copresence/mediums/audio/audio_player_impl.h ('k') | components/copresence/mediums/audio/audio_player_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698