Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / modules / webaudio / AudioBufferSourceNode.cpp
1 /*
2  * Copyright (C) 2010, Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26
27 #if ENABLE(WEB_AUDIO)
28
29 #include "modules/webaudio/AudioBufferSourceNode.h"
30
31 #include "bindings/core/v8/ExceptionState.h"
32 #include "core/dom/ExceptionCode.h"
33 #include "platform/audio/AudioUtilities.h"
34 #include "modules/webaudio/AudioContext.h"
35 #include "modules/webaudio/AudioNodeOutput.h"
36 #include "platform/FloatConversion.h"
37 #include "wtf/MainThread.h"
38 #include "wtf/MathExtras.h"
39 #include <algorithm>
40
41 namespace blink {
42
43 const double DefaultGrainDuration = 0.020; // 20ms
44
45 // Arbitrary upper limit on playback rate.
46 // Higher than expected rates can be useful when playing back oversampled buffers
47 // to minimize linear interpolation aliasing.
48 const double MaxRate = 1024;
49
50 PassRefPtrWillBeRawPtr<AudioBufferSourceNode> AudioBufferSourceNode::create(AudioContext* context, float sampleRate)
51 {
52     return adoptRefWillBeNoop(new AudioBufferSourceNode(context, sampleRate));
53 }
54
55 AudioBufferSourceNode::AudioBufferSourceNode(AudioContext* context, float sampleRate)
56     : AudioScheduledSourceNode(context, sampleRate)
57     , m_buffer(nullptr)
58     , m_isLooping(false)
59     , m_loopStart(0)
60     , m_loopEnd(0)
61     , m_virtualReadIndex(0)
62     , m_isGrain(false)
63     , m_grainOffset(0.0)
64     , m_grainDuration(DefaultGrainDuration)
65 {
66     ScriptWrappable::init(this);
67     setNodeType(NodeTypeAudioBufferSource);
68
69     m_playbackRate = AudioParam::create(context, 1.0);
70
71     // Default to mono. A call to setBuffer() will set the number of output
72     // channels to that of the buffer.
73     addOutput(AudioNodeOutput::create(this, 1));
74
75     initialize();
76 }
77
78 AudioBufferSourceNode::~AudioBufferSourceNode()
79 {
80     ASSERT(!isInitialized());
81 }
82
83 void AudioBufferSourceNode::dispose()
84 {
85     clearPannerNode();
86     uninitialize();
87     AudioScheduledSourceNode::dispose();
88 }
89
90 void AudioBufferSourceNode::process(size_t framesToProcess)
91 {
92     AudioBus* outputBus = output(0)->bus();
93
94     if (!isInitialized()) {
95         outputBus->zero();
96         return;
97     }
98
99     // The audio thread can't block on this lock, so we call tryLock() instead.
100     MutexTryLocker tryLocker(m_processLock);
101     if (tryLocker.locked()) {
102         if (!buffer()) {
103             outputBus->zero();
104             return;
105         }
106
107         // After calling setBuffer() with a buffer having a different number of channels, there can in rare cases be a slight delay
108         // before the output bus is updated to the new number of channels because of use of tryLocks() in the context's updating system.
109         // In this case, if the the buffer has just been changed and we're not quite ready yet, then just output silence.
110         if (numberOfChannels() != buffer()->numberOfChannels()) {
111             outputBus->zero();
112             return;
113         }
114
115         size_t quantumFrameOffset;
116         size_t bufferFramesToProcess;
117
118         updateSchedulingInfo(framesToProcess,
119                              outputBus,
120                              quantumFrameOffset,
121                              bufferFramesToProcess);
122
123         if (!bufferFramesToProcess) {
124             outputBus->zero();
125             return;
126         }
127
128         for (unsigned i = 0; i < outputBus->numberOfChannels(); ++i)
129             m_destinationChannels[i] = outputBus->channel(i)->mutableData();
130
131         // Render by reading directly from the buffer.
132         if (!renderFromBuffer(outputBus, quantumFrameOffset, bufferFramesToProcess)) {
133             outputBus->zero();
134             return;
135         }
136
137         outputBus->clearSilentFlag();
138     } else {
139         // Too bad - the tryLock() failed.  We must be in the middle of changing buffers and were already outputting silence anyway.
140         outputBus->zero();
141     }
142 }
143
144 // Returns true if we're finished.
145 bool AudioBufferSourceNode::renderSilenceAndFinishIfNotLooping(AudioBus*, unsigned index, size_t framesToProcess)
146 {
147     if (!loop()) {
148         // If we're not looping, then stop playing when we get to the end.
149
150         if (framesToProcess > 0) {
151             // We're not looping and we've reached the end of the sample data, but we still need to provide more output,
152             // so generate silence for the remaining.
153             for (unsigned i = 0; i < numberOfChannels(); ++i)
154                 memset(m_destinationChannels[i] + index, 0, sizeof(float) * framesToProcess);
155         }
156
157         finish();
158         return true;
159     }
160     return false;
161 }
162
163 bool AudioBufferSourceNode::renderFromBuffer(AudioBus* bus, unsigned destinationFrameOffset, size_t numberOfFrames)
164 {
165     ASSERT(context()->isAudioThread());
166
167     // Basic sanity checking
168     ASSERT(bus);
169     ASSERT(buffer());
170     if (!bus || !buffer())
171         return false;
172
173     unsigned numberOfChannels = this->numberOfChannels();
174     unsigned busNumberOfChannels = bus->numberOfChannels();
175
176     bool channelCountGood = numberOfChannels && numberOfChannels == busNumberOfChannels;
177     ASSERT(channelCountGood);
178     if (!channelCountGood)
179         return false;
180
181     // Sanity check destinationFrameOffset, numberOfFrames.
182     size_t destinationLength = bus->length();
183
184     bool isLengthGood = destinationLength <= 4096 && numberOfFrames <= 4096;
185     ASSERT(isLengthGood);
186     if (!isLengthGood)
187         return false;
188
189     bool isOffsetGood = destinationFrameOffset <= destinationLength && destinationFrameOffset + numberOfFrames <= destinationLength;
190     ASSERT(isOffsetGood);
191     if (!isOffsetGood)
192         return false;
193
194     // Potentially zero out initial frames leading up to the offset.
195     if (destinationFrameOffset) {
196         for (unsigned i = 0; i < numberOfChannels; ++i)
197             memset(m_destinationChannels[i], 0, sizeof(float) * destinationFrameOffset);
198     }
199
200     // Offset the pointers to the correct offset frame.
201     unsigned writeIndex = destinationFrameOffset;
202
203     size_t bufferLength = buffer()->length();
204     double bufferSampleRate = buffer()->sampleRate();
205
206     // Avoid converting from time to sample-frames twice by computing
207     // the grain end time first before computing the sample frame.
208     unsigned endFrame = m_isGrain ? AudioUtilities::timeToSampleFrame(m_grainOffset + m_grainDuration, bufferSampleRate) : bufferLength;
209
210     // This is a HACK to allow for HRTF tail-time - avoids glitch at end.
211     // FIXME: implement tailTime for each AudioNode for a more general solution to this problem.
212     // https://bugs.webkit.org/show_bug.cgi?id=77224
213     if (m_isGrain)
214         endFrame += 512;
215
216     // Do some sanity checking.
217     if (endFrame > bufferLength)
218         endFrame = bufferLength;
219     if (m_virtualReadIndex >= endFrame)
220         m_virtualReadIndex = 0; // reset to start
221
222     // If the .loop attribute is true, then values of m_loopStart == 0 && m_loopEnd == 0 implies
223     // that we should use the entire buffer as the loop, otherwise use the loop values in m_loopStart and m_loopEnd.
224     double virtualEndFrame = endFrame;
225     double virtualDeltaFrames = endFrame;
226
227     if (loop() && (m_loopStart || m_loopEnd) && m_loopStart >= 0 && m_loopEnd > 0 && m_loopStart < m_loopEnd) {
228         // Convert from seconds to sample-frames.
229         double loopStartFrame = m_loopStart * buffer()->sampleRate();
230         double loopEndFrame = m_loopEnd * buffer()->sampleRate();
231
232         virtualEndFrame = std::min(loopEndFrame, virtualEndFrame);
233         virtualDeltaFrames = virtualEndFrame - loopStartFrame;
234     }
235
236
237     double pitchRate = totalPitchRate();
238
239     // Sanity check that our playback rate isn't larger than the loop size.
240     if (pitchRate >= virtualDeltaFrames)
241         return false;
242
243     // Get local copy.
244     double virtualReadIndex = m_virtualReadIndex;
245
246     // Render loop - reading from the source buffer to the destination using linear interpolation.
247     int framesToProcess = numberOfFrames;
248
249     const float** sourceChannels = m_sourceChannels.get();
250     float** destinationChannels = m_destinationChannels.get();
251
252     // Optimize for the very common case of playing back with pitchRate == 1.
253     // We can avoid the linear interpolation.
254     if (pitchRate == 1 && virtualReadIndex == floor(virtualReadIndex)
255         && virtualDeltaFrames == floor(virtualDeltaFrames)
256         && virtualEndFrame == floor(virtualEndFrame)) {
257         unsigned readIndex = static_cast<unsigned>(virtualReadIndex);
258         unsigned deltaFrames = static_cast<unsigned>(virtualDeltaFrames);
259         endFrame = static_cast<unsigned>(virtualEndFrame);
260         while (framesToProcess > 0) {
261             int framesToEnd = endFrame - readIndex;
262             int framesThisTime = std::min(framesToProcess, framesToEnd);
263             framesThisTime = std::max(0, framesThisTime);
264
265             for (unsigned i = 0; i < numberOfChannels; ++i)
266                 memcpy(destinationChannels[i] + writeIndex, sourceChannels[i] + readIndex, sizeof(float) * framesThisTime);
267
268             writeIndex += framesThisTime;
269             readIndex += framesThisTime;
270             framesToProcess -= framesThisTime;
271
272             // Wrap-around.
273             if (readIndex >= endFrame) {
274                 readIndex -= deltaFrames;
275                 if (renderSilenceAndFinishIfNotLooping(bus, writeIndex, framesToProcess))
276                     break;
277             }
278         }
279         virtualReadIndex = readIndex;
280     } else {
281         while (framesToProcess--) {
282             unsigned readIndex = static_cast<unsigned>(virtualReadIndex);
283             double interpolationFactor = virtualReadIndex - readIndex;
284
285             // For linear interpolation we need the next sample-frame too.
286             unsigned readIndex2 = readIndex + 1;
287             if (readIndex2 >= bufferLength) {
288                 if (loop()) {
289                     // Make sure to wrap around at the end of the buffer.
290                     readIndex2 = static_cast<unsigned>(virtualReadIndex + 1 - virtualDeltaFrames);
291                 } else
292                     readIndex2 = readIndex;
293             }
294
295             // Final sanity check on buffer access.
296             // FIXME: as an optimization, try to get rid of this inner-loop check and put assertions and guards before the loop.
297             if (readIndex >= bufferLength || readIndex2 >= bufferLength)
298                 break;
299
300             // Linear interpolation.
301             for (unsigned i = 0; i < numberOfChannels; ++i) {
302                 float* destination = destinationChannels[i];
303                 const float* source = sourceChannels[i];
304
305                 double sample1 = source[readIndex];
306                 double sample2 = source[readIndex2];
307                 double sample = (1.0 - interpolationFactor) * sample1 + interpolationFactor * sample2;
308
309                 destination[writeIndex] = narrowPrecisionToFloat(sample);
310             }
311             writeIndex++;
312
313             virtualReadIndex += pitchRate;
314
315             // Wrap-around, retaining sub-sample position since virtualReadIndex is floating-point.
316             if (virtualReadIndex >= virtualEndFrame) {
317                 virtualReadIndex -= virtualDeltaFrames;
318                 if (renderSilenceAndFinishIfNotLooping(bus, writeIndex, framesToProcess))
319                     break;
320             }
321         }
322     }
323
324     bus->clearSilentFlag();
325
326     m_virtualReadIndex = virtualReadIndex;
327
328     return true;
329 }
330
331
332 void AudioBufferSourceNode::setBuffer(AudioBuffer* buffer, ExceptionState& exceptionState)
333 {
334     ASSERT(isMainThread());
335
336     // The context must be locked since changing the buffer can re-configure the number of channels that are output.
337     AudioContext::AutoLocker contextLocker(context());
338
339     // This synchronizes with process().
340     MutexLocker processLocker(m_processLock);
341
342     if (buffer) {
343         // Do any necesssary re-configuration to the buffer's number of channels.
344         unsigned numberOfChannels = buffer->numberOfChannels();
345
346         if (numberOfChannels > AudioContext::maxNumberOfChannels()) {
347             exceptionState.throwTypeError("number of input channels (" + String::number(numberOfChannels)
348                 + ") exceeds maximum ("
349                 + String::number(AudioContext::maxNumberOfChannels()) + ").");
350             return;
351         }
352
353         output(0)->setNumberOfChannels(numberOfChannels);
354
355         m_sourceChannels = adoptArrayPtr(new const float* [numberOfChannels]);
356         m_destinationChannels = adoptArrayPtr(new float* [numberOfChannels]);
357
358         for (unsigned i = 0; i < numberOfChannels; ++i)
359             m_sourceChannels[i] = buffer->getChannelData(i)->data();
360     }
361
362     m_virtualReadIndex = 0;
363     m_buffer = buffer;
364 }
365
366 unsigned AudioBufferSourceNode::numberOfChannels()
367 {
368     return output(0)->numberOfChannels();
369 }
370
371 void AudioBufferSourceNode::start(double when, ExceptionState& exceptionState)
372 {
373     AudioScheduledSourceNode::start(when, exceptionState);
374 }
375
376 void AudioBufferSourceNode::start(double when, double grainOffset, ExceptionState& exceptionState)
377 {
378     start(when, grainOffset, buffer() ? buffer()->duration() : 0, exceptionState);
379 }
380
381 void AudioBufferSourceNode::start(double when, double grainOffset, double grainDuration, ExceptionState& exceptionState)
382 {
383     ASSERT(isMainThread());
384
385     if (m_playbackState != UNSCHEDULED_STATE) {
386         exceptionState.throwDOMException(
387             InvalidStateError,
388             "cannot call start more than once.");
389         return;
390     }
391
392     if (!buffer())
393         return;
394
395     // Do sanity checking of grain parameters versus buffer size.
396     double bufferDuration = buffer()->duration();
397
398     grainOffset = std::max(0.0, grainOffset);
399     grainOffset = std::min(bufferDuration, grainOffset);
400     m_grainOffset = grainOffset;
401
402     double maxDuration = bufferDuration - grainOffset;
403
404     grainDuration = std::max(0.0, grainDuration);
405     grainDuration = std::min(maxDuration, grainDuration);
406     m_grainDuration = grainDuration;
407
408     m_isGrain = true;
409     m_startTime = when;
410
411     // We call timeToSampleFrame here since at playbackRate == 1 we don't want to go through linear interpolation
412     // at a sub-sample position since it will degrade the quality.
413     // When aligned to the sample-frame the playback will be identical to the PCM data stored in the buffer.
414     // Since playbackRate == 1 is very common, it's worth considering quality.
415     m_virtualReadIndex = AudioUtilities::timeToSampleFrame(m_grainOffset, buffer()->sampleRate());
416
417     m_playbackState = SCHEDULED_STATE;
418 }
419
420 double AudioBufferSourceNode::totalPitchRate()
421 {
422     double dopplerRate = 1.0;
423     if (m_pannerNode)
424         dopplerRate = m_pannerNode->dopplerRate();
425
426     // Incorporate buffer's sample-rate versus AudioContext's sample-rate.
427     // Normally it's not an issue because buffers are loaded at the AudioContext's sample-rate, but we can handle it in any case.
428     double sampleRateFactor = 1.0;
429     if (buffer())
430         sampleRateFactor = buffer()->sampleRate() / sampleRate();
431
432     double basePitchRate = playbackRate()->value();
433
434     double totalRate = dopplerRate * sampleRateFactor * basePitchRate;
435
436     // Sanity check the total rate.  It's very important that the resampler not get any bad rate values.
437     totalRate = std::max(0.0, totalRate);
438     if (!totalRate)
439         totalRate = 1; // zero rate is considered illegal
440     totalRate = std::min(MaxRate, totalRate);
441
442     bool isTotalRateValid = !std::isnan(totalRate) && !std::isinf(totalRate);
443     ASSERT(isTotalRateValid);
444     if (!isTotalRateValid)
445         totalRate = 1.0;
446
447     return totalRate;
448 }
449
450 bool AudioBufferSourceNode::propagatesSilence() const
451 {
452     return !isPlayingOrScheduled() || hasFinished() || !m_buffer;
453 }
454
455 void AudioBufferSourceNode::setPannerNode(PannerNode* pannerNode)
456 {
457     if (m_pannerNode != pannerNode && !hasFinished()) {
458         RefPtrWillBeRawPtr<PannerNode> oldPannerNode(m_pannerNode.release());
459         m_pannerNode = pannerNode;
460         if (pannerNode)
461             pannerNode->makeConnection();
462         if (oldPannerNode)
463             oldPannerNode->breakConnection();
464     }
465 }
466
467 void AudioBufferSourceNode::clearPannerNode()
468 {
469     if (m_pannerNode) {
470         m_pannerNode->breakConnection();
471         m_pannerNode.clear();
472     }
473 }
474
475 void AudioBufferSourceNode::finish()
476 {
477     clearPannerNode();
478     ASSERT(!m_pannerNode);
479     AudioScheduledSourceNode::finish();
480 }
481
482 void AudioBufferSourceNode::trace(Visitor* visitor)
483 {
484     visitor->trace(m_buffer);
485     visitor->trace(m_playbackRate);
486     visitor->trace(m_pannerNode);
487     AudioScheduledSourceNode::trace(visitor);
488 }
489
490 } // namespace blink
491
492 #endif // ENABLE(WEB_AUDIO)