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

Side by Side Diff: media/audio/simple_sources.cc

Issue 2101303004: Pass delay and timestamp to AudioSourceCallback::OnMoreData. (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: Pass target playout time to AudioSourceCallback::OnMoreData. Created 4 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 // MSVC++ requires this to be set before any other includes to get M_PI. 4 // MSVC++ requires this to be set before any other includes to get M_PI.
5 #define _USE_MATH_DEFINES 5 #define _USE_MATH_DEFINES
6 6
7 #include "media/audio/simple_sources.h" 7 #include "media/audio/simple_sources.h"
8 8
9 #include <stddef.h> 9 #include <stddef.h>
10 10
11 #include <algorithm> 11 #include <algorithm>
12 #include <cmath> 12 #include <cmath>
13 13
14 #include "base/files/file.h" 14 #include "base/files/file.h"
15 #include "base/lazy_instance.h" 15 #include "base/lazy_instance.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/time/time.h"
17 #include "media/audio/sounds/wav_audio_handler.h" 18 #include "media/audio/sounds/wav_audio_handler.h"
18 #include "media/base/audio_bus.h" 19 #include "media/base/audio_bus.h"
19 20
20 namespace media { 21 namespace media {
21 namespace { 22 namespace {
22 // Opens |wav_filename|, reads it and loads it as a wav file. This function will 23 // Opens |wav_filename|, reads it and loads it as a wav file. This function will
23 // return a null pointer if we can't read the file or if it's malformed. The 24 // return a null pointer if we can't read the file or if it's malformed. The
24 // caller takes ownership of the returned data. The size of the data is stored 25 // caller takes ownership of the returned data. The size of the data is stored
25 // in |read_length|. 26 // in |read_length|.
26 std::unique_ptr<char[]> ReadWavFile(const base::FilePath& wav_filename, 27 std::unique_ptr<char[]> ReadWavFile(const base::FilePath& wav_filename,
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 cap_(0), 109 cap_(0),
109 callbacks_(0), 110 callbacks_(0),
110 errors_(0) { 111 errors_(0) {
111 } 112 }
112 113
113 SineWaveAudioSource::~SineWaveAudioSource() { 114 SineWaveAudioSource::~SineWaveAudioSource() {
114 } 115 }
115 116
116 // The implementation could be more efficient if a lookup table is constructed 117 // The implementation could be more efficient if a lookup table is constructed
117 // but it is efficient enough for our simple needs. 118 // but it is efficient enough for our simple needs.
118 int SineWaveAudioSource::OnMoreData(AudioBus* audio_bus, 119 int SineWaveAudioSource::OnMoreData(base::TimeTicks /* target_playout_time */,
119 uint32_t total_bytes_delay, 120 int /* prior_frames_skipped */,
120 uint32_t frames_skipped) { 121 AudioBus* dest) {
121 base::AutoLock auto_lock(time_lock_); 122 base::AutoLock auto_lock(time_lock_);
122 callbacks_++; 123 callbacks_++;
123 124
124 // The table is filled with s(t) = kint16max*sin(Theta*t), 125 // The table is filled with s(t) = kint16max*sin(Theta*t),
125 // where Theta = 2*PI*fs. 126 // where Theta = 2*PI*fs.
126 // We store the discrete time value |t| in a member to ensure that the 127 // We store the discrete time value |t| in a member to ensure that the
127 // next pass starts at a correct state. 128 // next pass starts at a correct state.
128 int max_frames = cap_ > 0 ? 129 int max_frames =
129 std::min(audio_bus->frames(), cap_ - time_state_) : audio_bus->frames(); 130 cap_ > 0 ? std::min(dest->frames(), cap_ - time_state_) : dest->frames();
130 for (int i = 0; i < max_frames; ++i) 131 for (int i = 0; i < max_frames; ++i)
131 audio_bus->channel(0)[i] = sin(2.0 * M_PI * f_ * time_state_++); 132 dest->channel(0)[i] = sin(2.0 * M_PI * f_ * time_state_++);
132 for (int i = 1; i < audio_bus->channels(); ++i) { 133 for (int i = 1; i < dest->channels(); ++i) {
133 memcpy(audio_bus->channel(i), audio_bus->channel(0), 134 memcpy(dest->channel(i), dest->channel(0),
134 max_frames * sizeof(*audio_bus->channel(i))); 135 max_frames * sizeof(*dest->channel(i)));
135 } 136 }
136 return max_frames; 137 return max_frames;
137 } 138 }
138 139
139 void SineWaveAudioSource::OnError(AudioOutputStream* stream) { 140 void SineWaveAudioSource::OnError(AudioOutputStream* stream) {
140 errors_++; 141 errors_++;
141 } 142 }
142 143
143 void SineWaveAudioSource::CapSamples(int cap) { 144 void SineWaveAudioSource::CapSamples(int cap) {
144 base::AutoLock auto_lock(time_lock_); 145 base::AutoLock auto_lock(time_lock_);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 AudioParameters::AUDIO_PCM_LOW_LATENCY, 195 AudioParameters::AUDIO_PCM_LOW_LATENCY,
195 GuessChannelLayout(wav_audio_handler_->num_channels()), 196 GuessChannelLayout(wav_audio_handler_->num_channels()),
196 wav_audio_handler_->sample_rate(), wav_audio_handler_->bits_per_sample(), 197 wav_audio_handler_->sample_rate(), wav_audio_handler_->bits_per_sample(),
197 params_.frames_per_buffer()); 198 params_.frames_per_buffer());
198 199
199 file_audio_converter_.reset( 200 file_audio_converter_.reset(
200 new AudioConverter(file_audio_slice, params_, false)); 201 new AudioConverter(file_audio_slice, params_, false));
201 file_audio_converter_->AddInput(this); 202 file_audio_converter_->AddInput(this);
202 } 203 }
203 204
204 int FileSource::OnMoreData(AudioBus* audio_bus, 205 int FileSource::OnMoreData(base::TimeTicks /* target_playout_time */,
205 uint32_t total_bytes_delay, 206 int /* prior_frames_skipped */,
206 uint32_t frames_skipped) { 207 AudioBus* dest) {
207 // Load the file if we haven't already. This load needs to happen on the 208 // Load the file if we haven't already. This load needs to happen on the
208 // audio thread, otherwise we'll run on the UI thread on Mac for instance. 209 // audio thread, otherwise we'll run on the UI thread on Mac for instance.
209 // This will massively delay the first OnMoreData, but we'll catch up. 210 // This will massively delay the first OnMoreData, but we'll catch up.
210 if (!wav_audio_handler_) 211 if (!wav_audio_handler_)
211 LoadWavFile(path_to_wav_file_); 212 LoadWavFile(path_to_wav_file_);
212 if (load_failed_) 213 if (load_failed_)
213 return 0; 214 return 0;
214 215
215 DCHECK(wav_audio_handler_.get()); 216 DCHECK(wav_audio_handler_.get());
216 217
217 if (wav_audio_handler_->AtEnd(wav_file_read_pos_)) { 218 if (wav_audio_handler_->AtEnd(wav_file_read_pos_)) {
218 if (looping_) 219 if (looping_)
219 Rewind(); 220 Rewind();
220 else 221 else
221 return 0; 222 return 0;
222 } 223 }
223 224
224 // This pulls data from ProvideInput. 225 // This pulls data from ProvideInput.
225 file_audio_converter_->Convert(audio_bus); 226 file_audio_converter_->Convert(dest);
226 return audio_bus->frames(); 227 return dest->frames();
227 } 228 }
228 229
229 void FileSource::Rewind() { 230 void FileSource::Rewind() {
230 wav_file_read_pos_ = 0; 231 wav_file_read_pos_ = 0;
231 } 232 }
232 233
233 double FileSource::ProvideInput(AudioBus* audio_bus_into_converter, 234 double FileSource::ProvideInput(AudioBus* audio_bus_into_converter,
234 uint32_t frames_delayed) { 235 uint32_t frames_delayed) {
235 // Unfilled frames will be zeroed by CopyTo. 236 // Unfilled frames will be zeroed by CopyTo.
236 size_t bytes_written; 237 size_t bytes_written;
(...skipping 14 matching lines...) Expand all
251 beep_duration_in_buffers_(kBeepDurationMilliseconds * 252 beep_duration_in_buffers_(kBeepDurationMilliseconds *
252 params.sample_rate() / 253 params.sample_rate() /
253 params.frames_per_buffer() / 254 params.frames_per_buffer() /
254 1000), 255 1000),
255 beep_generated_in_buffers_(0), 256 beep_generated_in_buffers_(0),
256 beep_period_in_frames_(params.sample_rate() / kBeepFrequency) {} 257 beep_period_in_frames_(params.sample_rate() / kBeepFrequency) {}
257 258
258 BeepingSource::~BeepingSource() { 259 BeepingSource::~BeepingSource() {
259 } 260 }
260 261
261 int BeepingSource::OnMoreData(AudioBus* audio_bus, 262 int BeepingSource::OnMoreData(base::TimeTicks /* target_playout_time */,
262 uint32_t total_bytes_delay, 263 int /* prior_frames_skipped */,
263 uint32_t frames_skipped) { 264 AudioBus* dest) {
264 // Accumulate the time from the last beep. 265 // Accumulate the time from the last beep.
265 interval_from_last_beep_ += base::TimeTicks::Now() - last_callback_time_; 266 interval_from_last_beep_ += base::TimeTicks::Now() - last_callback_time_;
266 267
267 memset(buffer_.get(), 0, buffer_size_); 268 memset(buffer_.get(), 0, buffer_size_);
268 bool should_beep = false; 269 bool should_beep = false;
269 BeepContext* beep_context = g_beep_context.Pointer(); 270 BeepContext* beep_context = g_beep_context.Pointer();
270 if (beep_context->automatic_beep()) { 271 if (beep_context->automatic_beep()) {
271 base::TimeDelta delta = interval_from_last_beep_ - 272 base::TimeDelta delta = interval_from_last_beep_ -
272 base::TimeDelta::FromMilliseconds(kAutomaticBeepIntervalInMs); 273 base::TimeDelta::FromMilliseconds(kAutomaticBeepIntervalInMs);
273 if (delta > base::TimeDelta()) { 274 if (delta > base::TimeDelta()) {
(...skipping 23 matching lines...) Expand all
297 // Then leave low values in the buffer with |high_bytes|. 298 // Then leave low values in the buffer with |high_bytes|.
298 position += high_bytes * 2; 299 position += high_bytes * 2;
299 } 300 }
300 301
301 ++beep_generated_in_buffers_; 302 ++beep_generated_in_buffers_;
302 if (beep_generated_in_buffers_ >= beep_duration_in_buffers_) 303 if (beep_generated_in_buffers_ >= beep_duration_in_buffers_)
303 beep_generated_in_buffers_ = 0; 304 beep_generated_in_buffers_ = 0;
304 } 305 }
305 306
306 last_callback_time_ = base::TimeTicks::Now(); 307 last_callback_time_ = base::TimeTicks::Now();
307 audio_bus->FromInterleaved( 308 dest->FromInterleaved(buffer_.get(), dest->frames(),
308 buffer_.get(), audio_bus->frames(), params_.bits_per_sample() / 8); 309 params_.bits_per_sample() / 8);
309 return audio_bus->frames(); 310 return dest->frames();
310 } 311 }
311 312
312 void BeepingSource::OnError(AudioOutputStream* stream) { 313 void BeepingSource::OnError(AudioOutputStream* stream) {
313 } 314 }
314 315
315 void BeepingSource::BeepOnce() { 316 void BeepingSource::BeepOnce() {
316 g_beep_context.Pointer()->SetBeepOnce(true); 317 g_beep_context.Pointer()->SetBeepOnce(true);
317 } 318 }
318 319
319 } // namespace media 320 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698