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

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

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