OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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) |
OLD | NEW |