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

Side by Side Diff: Source/modules/webaudio/OscillatorNode.cpp

Issue 1256053006: Protect AudioScheduledSoureNode::m_startTime and m_endTime. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Use tryLock instead of atomic access Created 5 years, 3 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
« no previous file with comments | « Source/modules/webaudio/OscillatorNode.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012, Google Inc. All rights reserved. 2 * Copyright (C) 2012, Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 outputBus->zero(); 219 outputBus->zero();
220 return; 220 return;
221 } 221 }
222 222
223 ASSERT(framesToProcess <= m_phaseIncrements.size()); 223 ASSERT(framesToProcess <= m_phaseIncrements.size());
224 if (framesToProcess > m_phaseIncrements.size()) 224 if (framesToProcess > m_phaseIncrements.size())
225 return; 225 return;
226 226
227 // The audio thread can't block on this lock, so we call tryLock() instead. 227 // The audio thread can't block on this lock, so we call tryLock() instead.
228 MutexTryLocker tryLocker(m_processLock); 228 MutexTryLocker tryLocker(m_processLock);
229 if (!tryLocker.locked()) { 229 if (tryLocker.locked()) {
230 // Too bad - the tryLock() failed. We must be in the middle of changing wave-tables. 230
tkent 2015/09/11 00:02:00 Is this change necessary? The scope of tryLocker
231 // We must access m_periodicWave only inside the lock.
232 if (!m_periodicWave.get()) {
233 outputBus->zero();
234 return;
235 }
236
237 size_t quantumFrameOffset;
238 size_t nonSilentFramesToProcess;
239
240 updateSchedulingInfo(framesToProcess, outputBus, quantumFrameOffset, non SilentFramesToProcess);
241
242 if (!nonSilentFramesToProcess) {
243 outputBus->zero();
244 return;
245 }
246
247 unsigned periodicWaveSize = m_periodicWave->periodicWaveSize();
248 double invPeriodicWaveSize = 1.0 / periodicWaveSize;
249
250 float* destP = outputBus->channel(0)->mutableData();
251
252 ASSERT(quantumFrameOffset <= framesToProcess);
253
254 // We keep virtualReadIndex double-precision since we're accumulating va lues.
255 double virtualReadIndex = m_virtualReadIndex;
256
257 float rateScale = m_periodicWave->rateScale();
258 float invRateScale = 1 / rateScale;
259 bool hasSampleAccurateValues = calculateSampleAccuratePhaseIncrements(fr amesToProcess);
260
261 float frequency = 0;
262 float* higherWaveData = 0;
263 float* lowerWaveData = 0;
264 float tableInterpolationFactor = 0;
265
266 if (!hasSampleAccurateValues) {
267 frequency = m_frequency->smoothedValue();
268 float detune = m_detune->smoothedValue();
269 float detuneScale = powf(2, detune / 1200);
270 frequency *= detuneScale;
271 m_periodicWave->waveDataForFundamentalFrequency(frequency, lowerWave Data, higherWaveData, tableInterpolationFactor);
272 }
273
274 float incr = frequency * rateScale;
275 float* phaseIncrements = m_phaseIncrements.data();
276
277 unsigned readIndexMask = periodicWaveSize - 1;
278
279 // Start rendering at the correct offset.
280 destP += quantumFrameOffset;
281 int n = nonSilentFramesToProcess;
282
283 while (n--) {
284 unsigned readIndex = static_cast<unsigned>(virtualReadIndex);
285 unsigned readIndex2 = readIndex + 1;
286
287 // Contain within valid range.
288 readIndex = readIndex & readIndexMask;
289 readIndex2 = readIndex2 & readIndexMask;
290
291 if (hasSampleAccurateValues) {
292 incr = *phaseIncrements++;
293
294 frequency = invRateScale * incr;
295 m_periodicWave->waveDataForFundamentalFrequency(frequency, lower WaveData, higherWaveData, tableInterpolationFactor);
296 }
297
298 float sample1Lower = lowerWaveData[readIndex];
299 float sample2Lower = lowerWaveData[readIndex2];
300 float sample1Higher = higherWaveData[readIndex];
301 float sample2Higher = higherWaveData[readIndex2];
302
303 // Linearly interpolate within each table (lower and higher).
304 float interpolationFactor = static_cast<float>(virtualReadIndex) - r eadIndex;
305 float sampleHigher = (1 - interpolationFactor) * sample1Higher + int erpolationFactor * sample2Higher;
306 float sampleLower = (1 - interpolationFactor) * sample1Lower + inter polationFactor * sample2Lower;
307
308 // Then interpolate between the two tables.
309 float sample = (1 - tableInterpolationFactor) * sampleHigher + table InterpolationFactor * sampleLower;
310
311 *destP++ = sample;
312
313 // Increment virtual read index and wrap virtualReadIndex into the r ange 0 -> periodicWaveSize.
314 virtualReadIndex += incr;
315 virtualReadIndex -= floor(virtualReadIndex * invPeriodicWaveSize) * periodicWaveSize;
316 }
317
318 m_virtualReadIndex = virtualReadIndex;
319
320 outputBus->clearSilentFlag();
321 } else {
322 // Too bad - the tryLock() failed. We must be in the middle of changing wave-tables or
323 // updating scheduling.
231 outputBus->zero(); 324 outputBus->zero();
232 return; 325 return;
233 } 326 }
234
235 // We must access m_periodicWave only inside the lock.
236 if (!m_periodicWave.get()) {
237 outputBus->zero();
238 return;
239 }
240
241 size_t quantumFrameOffset;
242 size_t nonSilentFramesToProcess;
243
244 updateSchedulingInfo(framesToProcess, outputBus, quantumFrameOffset, nonSile ntFramesToProcess);
245
246 if (!nonSilentFramesToProcess) {
247 outputBus->zero();
248 return;
249 }
250
251 unsigned periodicWaveSize = m_periodicWave->periodicWaveSize();
252 double invPeriodicWaveSize = 1.0 / periodicWaveSize;
253
254 float* destP = outputBus->channel(0)->mutableData();
255
256 ASSERT(quantumFrameOffset <= framesToProcess);
257
258 // We keep virtualReadIndex double-precision since we're accumulating values .
259 double virtualReadIndex = m_virtualReadIndex;
260
261 float rateScale = m_periodicWave->rateScale();
262 float invRateScale = 1 / rateScale;
263 bool hasSampleAccurateValues = calculateSampleAccuratePhaseIncrements(frames ToProcess);
264
265 float frequency = 0;
266 float* higherWaveData = 0;
267 float* lowerWaveData = 0;
268 float tableInterpolationFactor = 0;
269
270 if (!hasSampleAccurateValues) {
271 frequency = m_frequency->smoothedValue();
272 float detune = m_detune->smoothedValue();
273 float detuneScale = powf(2, detune / 1200);
274 frequency *= detuneScale;
275 m_periodicWave->waveDataForFundamentalFrequency(frequency, lowerWaveData , higherWaveData, tableInterpolationFactor);
276 }
277
278 float incr = frequency * rateScale;
279 float* phaseIncrements = m_phaseIncrements.data();
280
281 unsigned readIndexMask = periodicWaveSize - 1;
282
283 // Start rendering at the correct offset.
284 destP += quantumFrameOffset;
285 int n = nonSilentFramesToProcess;
286
287 while (n--) {
288 unsigned readIndex = static_cast<unsigned>(virtualReadIndex);
289 unsigned readIndex2 = readIndex + 1;
290
291 // Contain within valid range.
292 readIndex = readIndex & readIndexMask;
293 readIndex2 = readIndex2 & readIndexMask;
294
295 if (hasSampleAccurateValues) {
296 incr = *phaseIncrements++;
297
298 frequency = invRateScale * incr;
299 m_periodicWave->waveDataForFundamentalFrequency(frequency, lowerWave Data, higherWaveData, tableInterpolationFactor);
300 }
301
302 float sample1Lower = lowerWaveData[readIndex];
303 float sample2Lower = lowerWaveData[readIndex2];
304 float sample1Higher = higherWaveData[readIndex];
305 float sample2Higher = higherWaveData[readIndex2];
306
307 // Linearly interpolate within each table (lower and higher).
308 float interpolationFactor = static_cast<float>(virtualReadIndex) - readI ndex;
309 float sampleHigher = (1 - interpolationFactor) * sample1Higher + interpo lationFactor * sample2Higher;
310 float sampleLower = (1 - interpolationFactor) * sample1Lower + interpola tionFactor * sample2Lower;
311
312 // Then interpolate between the two tables.
313 float sample = (1 - tableInterpolationFactor) * sampleHigher + tableInte rpolationFactor * sampleLower;
314
315 *destP++ = sample;
316
317 // Increment virtual read index and wrap virtualReadIndex into the range 0 -> periodicWaveSize.
318 virtualReadIndex += incr;
319 virtualReadIndex -= floor(virtualReadIndex * invPeriodicWaveSize) * peri odicWaveSize;
320 }
321
322 m_virtualReadIndex = virtualReadIndex;
323
324 outputBus->clearSilentFlag();
325 } 327 }
326 328
327 void OscillatorHandler::setPeriodicWave(PeriodicWave* periodicWave) 329 void OscillatorHandler::setPeriodicWave(PeriodicWave* periodicWave)
328 { 330 {
329 ASSERT(isMainThread()); 331 ASSERT(isMainThread());
330 332
331 // This synchronizes with process(). 333 // This synchronizes with process().
332 MutexLocker processLocker(m_processLock); 334 MutexLocker processLocker(m_processLock);
333 m_periodicWave = periodicWave; 335 m_periodicWave = periodicWave;
334 m_type = CUSTOM; 336 m_type = CUSTOM;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 } 391 }
390 392
391 void OscillatorNode::setPeriodicWave(PeriodicWave* wave) 393 void OscillatorNode::setPeriodicWave(PeriodicWave* wave)
392 { 394 {
393 oscillatorHandler().setPeriodicWave(wave); 395 oscillatorHandler().setPeriodicWave(wave);
394 } 396 }
395 397
396 } // namespace blink 398 } // namespace blink
397 399
398 #endif // ENABLE(WEB_AUDIO) 400 #endif // ENABLE(WEB_AUDIO)
OLDNEW
« no previous file with comments | « Source/modules/webaudio/OscillatorNode.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698