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

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: Fix Mac CQ errors. Created 4 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 (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::TimeDelta /* delay */,
119 uint32_t total_bytes_delay, 120 base::TimeTicks /* delay_timestamp */,
120 uint32_t frames_skipped) { 121 int /* prior_frames_skipped */,
122 AudioBus* dest) {
121 base::AutoLock auto_lock(time_lock_); 123 base::AutoLock auto_lock(time_lock_);
122 callbacks_++; 124 callbacks_++;
123 125
124 // The table is filled with s(t) = kint16max*sin(Theta*t), 126 // The table is filled with s(t) = kint16max*sin(Theta*t),
125 // where Theta = 2*PI*fs. 127 // where Theta = 2*PI*fs.
126 // We store the discrete time value |t| in a member to ensure that the 128 // We store the discrete time value |t| in a member to ensure that the
127 // next pass starts at a correct state. 129 // next pass starts at a correct state.
128 int max_frames = cap_ > 0 ? 130 int max_frames =
129 std::min(audio_bus->frames(), cap_ - time_state_) : audio_bus->frames(); 131 cap_ > 0 ? std::min(dest->frames(), cap_ - time_state_) : dest->frames();
130 for (int i = 0; i < max_frames; ++i) 132 for (int i = 0; i < max_frames; ++i)
131 audio_bus->channel(0)[i] = sin(2.0 * M_PI * f_ * time_state_++); 133 dest->channel(0)[i] = sin(2.0 * M_PI * f_ * time_state_++);
132 for (int i = 1; i < audio_bus->channels(); ++i) { 134 for (int i = 1; i < dest->channels(); ++i) {
133 memcpy(audio_bus->channel(i), audio_bus->channel(0), 135 memcpy(dest->channel(i), dest->channel(0),
134 max_frames * sizeof(*audio_bus->channel(i))); 136 max_frames * sizeof(*dest->channel(i)));
135 } 137 }
136 return max_frames; 138 return max_frames;
137 } 139 }
138 140
139 void SineWaveAudioSource::OnError(AudioOutputStream* stream) { 141 void SineWaveAudioSource::OnError(AudioOutputStream* stream) {
140 errors_++; 142 errors_++;
141 } 143 }
142 144
143 void SineWaveAudioSource::CapSamples(int cap) { 145 void SineWaveAudioSource::CapSamples(int cap) {
144 base::AutoLock auto_lock(time_lock_); 146 base::AutoLock auto_lock(time_lock_);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 AudioParameters::AUDIO_PCM_LOW_LATENCY, 196 AudioParameters::AUDIO_PCM_LOW_LATENCY,
195 GuessChannelLayout(wav_audio_handler_->num_channels()), 197 GuessChannelLayout(wav_audio_handler_->num_channels()),
196 wav_audio_handler_->sample_rate(), wav_audio_handler_->bits_per_sample(), 198 wav_audio_handler_->sample_rate(), wav_audio_handler_->bits_per_sample(),
197 params_.frames_per_buffer()); 199 params_.frames_per_buffer());
198 200
199 file_audio_converter_.reset( 201 file_audio_converter_.reset(
200 new AudioConverter(file_audio_slice, params_, false)); 202 new AudioConverter(file_audio_slice, params_, false));
201 file_audio_converter_->AddInput(this); 203 file_audio_converter_->AddInput(this);
202 } 204 }
203 205
204 int FileSource::OnMoreData(AudioBus* audio_bus, 206 int FileSource::OnMoreData(base::TimeDelta /* delay */,
205 uint32_t total_bytes_delay, 207 base::TimeTicks /* delay_timestamp */,
206 uint32_t frames_skipped) { 208 int /* prior_frames_skipped */,
209 AudioBus* dest) {
207 // Load the file if we haven't already. This load needs to happen on the 210 // 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. 211 // 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. 212 // This will massively delay the first OnMoreData, but we'll catch up.
210 if (!wav_audio_handler_) 213 if (!wav_audio_handler_)
211 LoadWavFile(path_to_wav_file_); 214 LoadWavFile(path_to_wav_file_);
212 if (load_failed_) 215 if (load_failed_)
213 return 0; 216 return 0;
214 217
215 DCHECK(wav_audio_handler_.get()); 218 DCHECK(wav_audio_handler_.get());
216 219
217 if (wav_audio_handler_->AtEnd(wav_file_read_pos_)) { 220 if (wav_audio_handler_->AtEnd(wav_file_read_pos_)) {
218 if (looping_) 221 if (looping_)
219 Rewind(); 222 Rewind();
220 else 223 else
221 return 0; 224 return 0;
222 } 225 }
223 226
224 // This pulls data from ProvideInput. 227 // This pulls data from ProvideInput.
225 file_audio_converter_->Convert(audio_bus); 228 file_audio_converter_->Convert(dest);
226 return audio_bus->frames(); 229 return dest->frames();
227 } 230 }
228 231
229 void FileSource::Rewind() { 232 void FileSource::Rewind() {
230 wav_file_read_pos_ = 0; 233 wav_file_read_pos_ = 0;
231 } 234 }
232 235
233 double FileSource::ProvideInput(AudioBus* audio_bus_into_converter, 236 double FileSource::ProvideInput(AudioBus* audio_bus_into_converter,
234 uint32_t frames_delayed) { 237 uint32_t frames_delayed) {
235 // Unfilled frames will be zeroed by CopyTo. 238 // Unfilled frames will be zeroed by CopyTo.
236 size_t bytes_written; 239 size_t bytes_written;
(...skipping 14 matching lines...) Expand all
251 beep_duration_in_buffers_(kBeepDurationMilliseconds * 254 beep_duration_in_buffers_(kBeepDurationMilliseconds *
252 params.sample_rate() / 255 params.sample_rate() /
253 params.frames_per_buffer() / 256 params.frames_per_buffer() /
254 1000), 257 1000),
255 beep_generated_in_buffers_(0), 258 beep_generated_in_buffers_(0),
256 beep_period_in_frames_(params.sample_rate() / kBeepFrequency) {} 259 beep_period_in_frames_(params.sample_rate() / kBeepFrequency) {}
257 260
258 BeepingSource::~BeepingSource() { 261 BeepingSource::~BeepingSource() {
259 } 262 }
260 263
261 int BeepingSource::OnMoreData(AudioBus* audio_bus, 264 int BeepingSource::OnMoreData(base::TimeDelta /* delay */,
262 uint32_t total_bytes_delay, 265 base::TimeTicks /* delay_timestamp */,
263 uint32_t frames_skipped) { 266 int /* prior_frames_skipped */,
267 AudioBus* dest) {
264 // Accumulate the time from the last beep. 268 // Accumulate the time from the last beep.
265 interval_from_last_beep_ += base::TimeTicks::Now() - last_callback_time_; 269 interval_from_last_beep_ += base::TimeTicks::Now() - last_callback_time_;
266 270
267 memset(buffer_.get(), 0, buffer_size_); 271 memset(buffer_.get(), 0, buffer_size_);
268 bool should_beep = false; 272 bool should_beep = false;
269 BeepContext* beep_context = g_beep_context.Pointer(); 273 BeepContext* beep_context = g_beep_context.Pointer();
270 if (beep_context->automatic_beep()) { 274 if (beep_context->automatic_beep()) {
271 base::TimeDelta delta = interval_from_last_beep_ - 275 base::TimeDelta delta = interval_from_last_beep_ -
272 base::TimeDelta::FromMilliseconds(kAutomaticBeepIntervalInMs); 276 base::TimeDelta::FromMilliseconds(kAutomaticBeepIntervalInMs);
273 if (delta > base::TimeDelta()) { 277 if (delta > base::TimeDelta()) {
(...skipping 23 matching lines...) Expand all
297 // Then leave low values in the buffer with |high_bytes|. 301 // Then leave low values in the buffer with |high_bytes|.
298 position += high_bytes * 2; 302 position += high_bytes * 2;
299 } 303 }
300 304
301 ++beep_generated_in_buffers_; 305 ++beep_generated_in_buffers_;
302 if (beep_generated_in_buffers_ >= beep_duration_in_buffers_) 306 if (beep_generated_in_buffers_ >= beep_duration_in_buffers_)
303 beep_generated_in_buffers_ = 0; 307 beep_generated_in_buffers_ = 0;
304 } 308 }
305 309
306 last_callback_time_ = base::TimeTicks::Now(); 310 last_callback_time_ = base::TimeTicks::Now();
307 audio_bus->FromInterleaved( 311 dest->FromInterleaved(buffer_.get(), dest->frames(),
308 buffer_.get(), audio_bus->frames(), params_.bits_per_sample() / 8); 312 params_.bits_per_sample() / 8);
309 return audio_bus->frames(); 313 return dest->frames();
310 } 314 }
311 315
312 void BeepingSource::OnError(AudioOutputStream* stream) { 316 void BeepingSource::OnError(AudioOutputStream* stream) {
313 } 317 }
314 318
315 void BeepingSource::BeepOnce() { 319 void BeepingSource::BeepOnce() {
316 g_beep_context.Pointer()->SetBeepOnce(true); 320 g_beep_context.Pointer()->SetBeepOnce(true);
317 } 321 }
318 322
319 } // namespace media 323 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698