2bd701724c9e360d2d6be9f87cd68142afb4ad70
[WebKit-https.git] / Source / WebCore / Modules / webaudio / AudioContext.cpp
1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  * Copyright (C) 2016 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1.  Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27
28 #if ENABLE(WEB_AUDIO)
29
30 #include "AudioContext.h"
31
32 #include "AnalyserNode.h"
33 #include "AsyncAudioDecoder.h"
34 #include "AudioBuffer.h"
35 #include "AudioBufferCallback.h"
36 #include "AudioBufferSourceNode.h"
37 #include "AudioListener.h"
38 #include "AudioNodeInput.h"
39 #include "AudioNodeOutput.h"
40 #include "AudioSession.h"
41 #include "BiquadFilterNode.h"
42 #include "ChannelMergerNode.h"
43 #include "ChannelSplitterNode.h"
44 #include "ConvolverNode.h"
45 #include "DefaultAudioDestinationNode.h"
46 #include "DelayNode.h"
47 #include "Document.h"
48 #include "DynamicsCompressorNode.h"
49 #include "EventNames.h"
50 #include "ExceptionCode.h"
51 #include "FFTFrame.h"
52 #include "Frame.h"
53 #include "GainNode.h"
54 #include "GenericEventQueue.h"
55 #include "HRTFDatabaseLoader.h"
56 #include "HRTFPanner.h"
57 #include "JSDOMPromiseDeferred.h"
58 #include "Logging.h"
59 #include "NetworkingContext.h"
60 #include "OfflineAudioCompletionEvent.h"
61 #include "OfflineAudioDestinationNode.h"
62 #include "OscillatorNode.h"
63 #include "Page.h"
64 #include "PannerNode.h"
65 #include "PeriodicWave.h"
66 #include "ScriptController.h"
67 #include "ScriptProcessorNode.h"
68 #include "WaveShaperNode.h"
69 #include <inspector/ScriptCallStack.h>
70
71 #if ENABLE(MEDIA_STREAM)
72 #include "MediaStream.h"
73 #include "MediaStreamAudioDestinationNode.h"
74 #include "MediaStreamAudioSource.h"
75 #include "MediaStreamAudioSourceNode.h"
76 #endif
77
78 #if ENABLE(VIDEO)
79 #include "HTMLMediaElement.h"
80 #include "MediaElementAudioSourceNode.h"
81 #endif
82
83 #if DEBUG_AUDIONODE_REFERENCES
84 #include <stdio.h>
85 #endif
86
87 #if USE(GSTREAMER)
88 #include "GStreamerUtilities.h"
89 #endif
90
91 #if PLATFORM(IOS)
92 #include "ScriptController.h"
93 #include "Settings.h"
94 #endif
95
96 #include <runtime/ArrayBuffer.h>
97 #include <wtf/Atomics.h>
98 #include <wtf/MainThread.h>
99 #include <wtf/Ref.h>
100 #include <wtf/RefCounted.h>
101 #include <wtf/text/WTFString.h>
102
103 // FIXME: check the proper way to reference an undefined thread ID
104 const int UndefinedThreadIdentifier = 0xffffffff;
105
106 const unsigned MaxPeriodicWaveLength = 4096;
107
108 namespace WebCore {
109
110 #define RELEASE_LOG_IF_ALLOWED(fmt, ...) RELEASE_LOG_IF(document()->page() && document()->page()->isAlwaysOnLoggingAllowed(), Media, "%p - AudioContext::" fmt, this, ##__VA_ARGS__)
111     
112 bool AudioContext::isSampleRateRangeGood(float sampleRate)
113 {
114     // FIXME: It would be nice if the minimum sample-rate could be less than 44.1KHz,
115     // but that will require some fixes in HRTFPanner::fftSizeForSampleRate(), and some testing there.
116     return sampleRate >= 44100 && sampleRate <= 96000;
117 }
118
119 // Don't allow more than this number of simultaneous AudioContexts talking to hardware.
120 const unsigned MaxHardwareContexts = 4;
121 unsigned AudioContext::s_hardwareContextCount = 0;
122     
123 RefPtr<AudioContext> AudioContext::create(Document& document)
124 {
125     ASSERT(isMainThread());
126     if (s_hardwareContextCount >= MaxHardwareContexts)
127         return nullptr;
128
129     RefPtr<AudioContext> audioContext(adoptRef(new AudioContext(document)));
130     audioContext->suspendIfNeeded();
131     return audioContext;
132 }
133
134 // Constructor for rendering to the audio hardware.
135 AudioContext::AudioContext(Document& document)
136     : ActiveDOMObject(&document)
137     , m_mediaSession(PlatformMediaSession::create(*this))
138     , m_eventQueue(std::make_unique<GenericEventQueue>(*this))
139     , m_graphOwnerThread(UndefinedThreadIdentifier)
140 {
141     constructCommon();
142
143     m_destinationNode = DefaultAudioDestinationNode::create(*this);
144
145     // Initialize the destination node's muted state to match the page's current muted state.
146     pageMutedStateDidChange();
147 }
148
149 // Constructor for offline (non-realtime) rendering.
150 AudioContext::AudioContext(Document& document, unsigned numberOfChannels, size_t numberOfFrames, float sampleRate)
151     : ActiveDOMObject(&document)
152     , m_isOfflineContext(true)
153     , m_mediaSession(PlatformMediaSession::create(*this))
154     , m_eventQueue(std::make_unique<GenericEventQueue>(*this))
155     , m_graphOwnerThread(UndefinedThreadIdentifier)
156 {
157     constructCommon();
158
159     // Create a new destination for offline rendering.
160     m_renderTarget = AudioBuffer::create(numberOfChannels, numberOfFrames, sampleRate);
161     m_destinationNode = OfflineAudioDestinationNode::create(*this, m_renderTarget.get());
162 }
163
164 void AudioContext::constructCommon()
165 {
166     // According to spec AudioContext must die only after page navigate.
167     // Lets mark it as ActiveDOMObject with pending activity and unmark it in clear method.
168     setPendingActivity(this);
169
170 #if USE(GSTREAMER)
171     initializeGStreamer();
172 #endif
173
174     FFTFrame::initialize();
175     
176     m_listener = AudioListener::create();
177
178 #if PLATFORM(IOS)
179     if (document()->settings().audioPlaybackRequiresUserGesture())
180         addBehaviorRestriction(RequireUserGestureForAudioStartRestriction);
181     else
182         m_restrictions = NoRestrictions;
183 #endif
184
185 #if PLATFORM(COCOA)
186     addBehaviorRestriction(RequirePageConsentForAudioStartRestriction);
187 #endif
188 }
189
190 AudioContext::~AudioContext()
191 {
192 #if DEBUG_AUDIONODE_REFERENCES
193     WTFLogAlways("%p: AudioContext::~AudioContext()\n", this);
194 #endif
195     ASSERT(!m_isInitialized);
196     ASSERT(m_isStopScheduled);
197     ASSERT(m_nodesToDelete.isEmpty());
198     ASSERT(m_referencedNodes.isEmpty());
199     ASSERT(m_finishedNodes.isEmpty()); // FIXME (bug 105870): This assertion fails on tests sometimes.
200     ASSERT(m_automaticPullNodes.isEmpty());
201     if (m_automaticPullNodesNeedUpdating)
202         m_renderingAutomaticPullNodes.resize(m_automaticPullNodes.size());
203     ASSERT(m_renderingAutomaticPullNodes.isEmpty());
204     // FIXME: Can we assert that m_deferredFinishDerefList is empty?
205 }
206
207 void AudioContext::lazyInitialize()
208 {
209     if (m_isInitialized)
210         return;
211
212     // Don't allow the context to initialize a second time after it's already been explicitly uninitialized.
213     ASSERT(!m_isAudioThreadFinished);
214     if (m_isAudioThreadFinished)
215         return;
216
217     if (m_destinationNode) {
218         m_destinationNode->initialize();
219
220         if (!isOfflineContext()) {
221             document()->addAudioProducer(this);
222             document()->registerForVisibilityStateChangedCallbacks(this);
223
224             // This starts the audio thread. The destination node's provideInput() method will now be called repeatedly to render audio.
225             // Each time provideInput() is called, a portion of the audio stream is rendered. Let's call this time period a "render quantum".
226             // NOTE: for now default AudioContext does not need an explicit startRendering() call from JavaScript.
227             // We may want to consider requiring it for symmetry with OfflineAudioContext.
228             startRendering();
229             ++s_hardwareContextCount;
230         }
231     }
232     m_isInitialized = true;
233 }
234
235 void AudioContext::clear()
236 {
237     // We have to release our reference to the destination node before the context will ever be deleted since the destination node holds a reference to the context.
238     if (m_destinationNode)
239         m_destinationNode = nullptr;
240
241     // Audio thread is dead. Nobody will schedule node deletion action. Let's do it ourselves.
242     do {
243         deleteMarkedNodes();
244         m_nodesToDelete.appendVector(m_nodesMarkedForDeletion);
245         m_nodesMarkedForDeletion.clear();
246     } while (m_nodesToDelete.size());
247
248     // It was set in constructCommon.
249     unsetPendingActivity(this);
250 }
251
252 void AudioContext::uninitialize()
253 {
254     ASSERT(isMainThread());
255
256     if (!m_isInitialized)
257         return;
258
259     // This stops the audio thread and all audio rendering.
260     m_destinationNode->uninitialize();
261
262     // Don't allow the context to initialize a second time after it's already been explicitly uninitialized.
263     m_isAudioThreadFinished = true;
264
265     if (!isOfflineContext()) {
266         document()->removeAudioProducer(this);
267         document()->unregisterForVisibilityStateChangedCallbacks(this);
268
269         ASSERT(s_hardwareContextCount);
270         --s_hardwareContextCount;
271
272         // Offline contexts move to 'Closed' state when dispatching the completion event.
273         setState(State::Closed);
274     }
275
276     // Get rid of the sources which may still be playing.
277     derefUnfinishedSourceNodes();
278
279     m_isInitialized = false;
280 }
281
282 bool AudioContext::isInitialized() const
283 {
284     return m_isInitialized;
285 }
286
287 void AudioContext::addReaction(State state, DOMPromiseDeferred<void>&& promise)
288 {
289     size_t stateIndex = static_cast<size_t>(state);
290     if (stateIndex >= m_stateReactions.size())
291         m_stateReactions.resize(stateIndex + 1);
292
293     m_stateReactions[stateIndex].append(WTFMove(promise));
294 }
295
296 void AudioContext::setState(State state)
297 {
298     if (m_state == state)
299         return;
300
301     m_state = state;
302     m_eventQueue->enqueueEvent(Event::create(eventNames().statechangeEvent, true, false));
303
304     size_t stateIndex = static_cast<size_t>(state);
305     if (stateIndex >= m_stateReactions.size())
306         return;
307
308     Vector<DOMPromiseDeferred<void>> reactions;
309     m_stateReactions[stateIndex].swap(reactions);
310
311     for (auto& promise : reactions)
312         promise.resolve();
313 }
314
315 void AudioContext::stop()
316 {
317     ASSERT(isMainThread());
318
319     // Usually ScriptExecutionContext calls stop twice.
320     if (m_isStopScheduled)
321         return;
322     m_isStopScheduled = true;
323
324     document()->updateIsPlayingMedia();
325
326     m_eventQueue->close();
327
328     // Don't call uninitialize() immediately here because the ScriptExecutionContext is in the middle
329     // of dealing with all of its ActiveDOMObjects at this point. uninitialize() can de-reference other
330     // ActiveDOMObjects so let's schedule uninitialize() to be called later.
331     // FIXME: see if there's a more direct way to handle this issue.
332     // FIXME: This sounds very wrong. The whole idea of stop() is that it stops everything, and if we
333     // schedule some observable work for later, the work likely happens at an inappropriate time.
334     callOnMainThread([this] {
335         uninitialize();
336         clear();
337     });
338 }
339
340 bool AudioContext::canSuspendForDocumentSuspension() const
341 {
342     // FIXME: We should be able to suspend while rendering as well with some more code.
343     return m_state == State::Suspended || m_state == State::Closed;
344 }
345
346 const char* AudioContext::activeDOMObjectName() const
347 {
348     return "AudioContext";
349 }
350
351 Document* AudioContext::document() const
352 {
353     ASSERT(m_scriptExecutionContext);
354     return downcast<Document>(m_scriptExecutionContext);
355 }
356
357 const Document* AudioContext::hostingDocument() const
358 {
359     return downcast<Document>(m_scriptExecutionContext);
360 }
361
362 String AudioContext::sourceApplicationIdentifier() const
363 {
364     Document* document = this->document();
365     if (Frame* frame = document ? document->frame() : nullptr) {
366         if (NetworkingContext* networkingContext = frame->loader().networkingContext())
367             return networkingContext->sourceApplicationIdentifier();
368     }
369     return emptyString();
370 }
371
372 bool AudioContext::processingUserGestureForMedia() const
373 {
374     return document() ? document()->processingUserGestureForMedia() : false;
375 }
376
377 bool AudioContext::isSuspended() const
378 {
379     return !document() || document()->activeDOMObjectsAreSuspended() || document()->activeDOMObjectsAreStopped();
380 }
381
382 void AudioContext::visibilityStateChanged()
383 {
384     // Do not suspend if audio is audible.
385     if (mediaState() == MediaProducer::IsPlayingAudio)
386         return;
387
388     if (document()->hidden()) {
389         if (state() == State::Running) {
390             RELEASE_LOG_IF_ALLOWED("visibilityStateChanged() Suspending playback after going to the background");
391             m_mediaSession->beginInterruption(PlatformMediaSession::EnteringBackground);
392         }
393     } else {
394         if (state() == State::Interrupted) {
395             RELEASE_LOG_IF_ALLOWED("visibilityStateChanged() Resuming playback after entering foreground");
396             m_mediaSession->endInterruption(PlatformMediaSession::MayResumePlaying);
397         }
398     }
399 }
400
401 ExceptionOr<Ref<AudioBuffer>> AudioContext::createBuffer(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate)
402 {
403     auto audioBuffer = AudioBuffer::create(numberOfChannels, numberOfFrames, sampleRate);
404     if (!audioBuffer)
405         return Exception { NOT_SUPPORTED_ERR };
406     return audioBuffer.releaseNonNull();
407 }
408
409 ExceptionOr<Ref<AudioBuffer>> AudioContext::createBuffer(ArrayBuffer& arrayBuffer, bool mixToMono)
410 {
411     auto audioBuffer = AudioBuffer::createFromAudioFileData(arrayBuffer.data(), arrayBuffer.byteLength(), mixToMono, sampleRate());
412     if (!audioBuffer)
413         return Exception { SYNTAX_ERR };
414     return audioBuffer.releaseNonNull();
415 }
416
417 void AudioContext::decodeAudioData(Ref<ArrayBuffer>&& audioData, RefPtr<AudioBufferCallback>&& successCallback, RefPtr<AudioBufferCallback>&& errorCallback)
418 {
419     m_audioDecoder.decodeAsync(WTFMove(audioData), sampleRate(), WTFMove(successCallback), WTFMove(errorCallback));
420 }
421
422 Ref<AudioBufferSourceNode> AudioContext::createBufferSource()
423 {
424     ASSERT(isMainThread());
425     lazyInitialize();
426     Ref<AudioBufferSourceNode> node = AudioBufferSourceNode::create(*this, m_destinationNode->sampleRate());
427
428     // Because this is an AudioScheduledSourceNode, the context keeps a reference until it has finished playing.
429     // When this happens, AudioScheduledSourceNode::finish() calls AudioContext::notifyNodeFinishedProcessing().
430     refNode(node);
431
432     return node;
433 }
434
435 #if ENABLE(VIDEO)
436
437 ExceptionOr<Ref<MediaElementAudioSourceNode>> AudioContext::createMediaElementSource(HTMLMediaElement& mediaElement)
438 {
439     ASSERT(isMainThread());
440     lazyInitialize();
441     
442     if (mediaElement.audioSourceNode())
443         return Exception { INVALID_STATE_ERR };
444
445     auto node = MediaElementAudioSourceNode::create(*this, mediaElement);
446
447     mediaElement.setAudioSourceNode(node.ptr());
448
449     refNode(node.get()); // context keeps reference until node is disconnected
450     return WTFMove(node);
451 }
452
453 #endif
454
455 #if ENABLE(MEDIA_STREAM)
456
457 ExceptionOr<Ref<MediaStreamAudioSourceNode>> AudioContext::createMediaStreamSource(MediaStream& mediaStream)
458 {
459     ASSERT(isMainThread());
460
461     auto audioTracks = mediaStream.getAudioTracks();
462     if (audioTracks.isEmpty())
463         return Exception { INVALID_STATE_ERR };
464
465     MediaStreamTrack* providerTrack = nullptr;
466     for (auto& track : audioTracks) {
467         if (track->audioSourceProvider()) {
468             providerTrack = track.get();
469             break;
470         }
471     }
472     if (!providerTrack)
473         return Exception { INVALID_STATE_ERR };
474
475     lazyInitialize();
476
477     auto node = MediaStreamAudioSourceNode::create(*this, mediaStream, *providerTrack);
478     node->setFormat(2, sampleRate());
479
480     refNode(node); // context keeps reference until node is disconnected
481     return WTFMove(node);
482 }
483
484 Ref<MediaStreamAudioDestinationNode> AudioContext::createMediaStreamDestination()
485 {
486     // FIXME: Add support for an optional argument which specifies the number of channels.
487     // FIXME: The default should probably be stereo instead of mono.
488     return MediaStreamAudioDestinationNode::create(*this, 1);
489 }
490
491 #endif
492
493 ExceptionOr<Ref<ScriptProcessorNode>> AudioContext::createScriptProcessor(size_t bufferSize, size_t numberOfInputChannels, size_t numberOfOutputChannels)
494 {
495     ASSERT(isMainThread());
496     lazyInitialize();
497
498     // W3C Editor's Draft 06 June 2017
499     //  https://webaudio.github.io/web-audio-api/#widl-BaseAudioContext-createScriptProcessor-ScriptProcessorNode-unsigned-long-bufferSize-unsigned-long-numberOfInputChannels-unsigned-long-numberOfOutputChannels
500
501     // The bufferSize parameter determines the buffer size in units of sample-frames. If it's not passed in,
502     // or if the value is 0, then the implementation will choose the best buffer size for the given environment,
503     // which will be constant power of 2 throughout the lifetime of the node. ... If the value of this parameter
504     // is not one of the allowed power-of-2 values listed above, an IndexSizeError must be thrown.
505     switch (bufferSize) {
506     case 0:
507 #if USE(AUDIO_SESSION)
508         // Pick a value between 256 (2^8) and 16384 (2^14), based on the buffer size of the current AudioSession:
509         bufferSize = 1 << std::max<size_t>(8, std::min<size_t>(14, std::log2(AudioSession::sharedSession().bufferSize())));
510 #else
511         bufferSize = 2048;
512 #endif
513         break;
514     case 256:
515     case 512:
516     case 1024:
517     case 2048:
518     case 4096:
519     case 8192:
520     case 16384:
521         break;
522     default:
523         return Exception { INDEX_SIZE_ERR };
524     }
525
526     // An IndexSizeError exception must be thrown if bufferSize or numberOfInputChannels or numberOfOutputChannels
527     // are outside the valid range. It is invalid for both numberOfInputChannels and numberOfOutputChannels to be zero.
528     // In this case an IndexSizeError must be thrown.
529
530     if (!numberOfInputChannels && !numberOfOutputChannels)
531         return Exception { NOT_SUPPORTED_ERR };
532
533     // This parameter [numberOfInputChannels] determines the number of channels for this node's input. Values of
534     // up to 32 must be supported. A NotSupportedError must be thrown if the number of channels is not supported.
535
536     if (numberOfInputChannels > maxNumberOfChannels())
537         return Exception { NOT_SUPPORTED_ERR };
538
539     // This parameter [numberOfOutputChannels] determines the number of channels for this node's output. Values of
540     // up to 32 must be supported. A NotSupportedError must be thrown if the number of channels is not supported.
541
542     if (numberOfOutputChannels > maxNumberOfChannels())
543         return Exception { NOT_SUPPORTED_ERR };
544
545     auto node = ScriptProcessorNode::create(*this, m_destinationNode->sampleRate(), bufferSize, numberOfInputChannels, numberOfOutputChannels);
546
547     refNode(node); // context keeps reference until we stop making javascript rendering callbacks
548     return WTFMove(node);
549 }
550
551 Ref<BiquadFilterNode> AudioContext::createBiquadFilter()
552 {
553     ASSERT(isMainThread());
554     lazyInitialize();
555     return BiquadFilterNode::create(*this, m_destinationNode->sampleRate());
556 }
557
558 Ref<WaveShaperNode> AudioContext::createWaveShaper()
559 {
560     ASSERT(isMainThread());
561     lazyInitialize();
562     return WaveShaperNode::create(*this);
563 }
564
565 Ref<PannerNode> AudioContext::createPanner()
566 {
567     ASSERT(isMainThread());
568     lazyInitialize();
569     return PannerNode::create(*this, m_destinationNode->sampleRate());
570 }
571
572 Ref<ConvolverNode> AudioContext::createConvolver()
573 {
574     ASSERT(isMainThread());
575     lazyInitialize();
576     return ConvolverNode::create(*this, m_destinationNode->sampleRate());
577 }
578
579 Ref<DynamicsCompressorNode> AudioContext::createDynamicsCompressor()
580 {
581     ASSERT(isMainThread());
582     lazyInitialize();
583     return DynamicsCompressorNode::create(*this, m_destinationNode->sampleRate());
584 }
585
586 Ref<AnalyserNode> AudioContext::createAnalyser()
587 {
588     ASSERT(isMainThread());
589     lazyInitialize();
590     return AnalyserNode::create(*this, m_destinationNode->sampleRate());
591 }
592
593 Ref<GainNode> AudioContext::createGain()
594 {
595     ASSERT(isMainThread());
596     lazyInitialize();
597     return GainNode::create(*this, m_destinationNode->sampleRate());
598 }
599
600 ExceptionOr<Ref<DelayNode>> AudioContext::createDelay(double maxDelayTime)
601 {
602     ASSERT(isMainThread());
603     lazyInitialize();
604     return DelayNode::create(*this, m_destinationNode->sampleRate(), maxDelayTime);
605 }
606
607 ExceptionOr<Ref<ChannelSplitterNode>> AudioContext::createChannelSplitter(size_t numberOfOutputs)
608 {
609     ASSERT(isMainThread());
610     lazyInitialize();
611     auto node = ChannelSplitterNode::create(*this, m_destinationNode->sampleRate(), numberOfOutputs);
612     if (!node)
613         return Exception { INDEX_SIZE_ERR };
614     return node.releaseNonNull();
615 }
616
617 ExceptionOr<Ref<ChannelMergerNode>> AudioContext::createChannelMerger(size_t numberOfInputs)
618 {
619     ASSERT(isMainThread());
620     lazyInitialize();
621     auto node = ChannelMergerNode::create(*this, m_destinationNode->sampleRate(), numberOfInputs);
622     if (!node)
623         return Exception { INDEX_SIZE_ERR };
624     return node.releaseNonNull();
625 }
626
627 Ref<OscillatorNode> AudioContext::createOscillator()
628 {
629     ASSERT(isMainThread());
630     lazyInitialize();
631
632     Ref<OscillatorNode> node = OscillatorNode::create(*this, m_destinationNode->sampleRate());
633
634     // Because this is an AudioScheduledSourceNode, the context keeps a reference until it has finished playing.
635     // When this happens, AudioScheduledSourceNode::finish() calls AudioContext::notifyNodeFinishedProcessing().
636     refNode(node);
637
638     return node;
639 }
640
641 ExceptionOr<Ref<PeriodicWave>> AudioContext::createPeriodicWave(Float32Array& real, Float32Array& imaginary)
642 {
643     ASSERT(isMainThread());
644     if (real.length() != imaginary.length() || (real.length() > MaxPeriodicWaveLength) || !real.length())
645         return Exception { INDEX_SIZE_ERR };
646     lazyInitialize();
647     return PeriodicWave::create(sampleRate(), real, imaginary);
648 }
649
650 void AudioContext::notifyNodeFinishedProcessing(AudioNode* node)
651 {
652     ASSERT(isAudioThread());
653     m_finishedNodes.append(node);
654 }
655
656 void AudioContext::derefFinishedSourceNodes()
657 {
658     ASSERT(isGraphOwner());
659     ASSERT(isAudioThread() || isAudioThreadFinished());
660     for (auto& node : m_finishedNodes)
661         derefNode(*node);
662
663     m_finishedNodes.clear();
664 }
665
666 void AudioContext::refNode(AudioNode& node)
667 {
668     ASSERT(isMainThread());
669     AutoLocker locker(*this);
670     
671     node.ref(AudioNode::RefTypeConnection);
672     m_referencedNodes.append(&node);
673 }
674
675 void AudioContext::derefNode(AudioNode& node)
676 {
677     ASSERT(isGraphOwner());
678     
679     node.deref(AudioNode::RefTypeConnection);
680
681     ASSERT(m_referencedNodes.contains(&node));
682     m_referencedNodes.removeFirst(&node);
683 }
684
685 void AudioContext::derefUnfinishedSourceNodes()
686 {
687     ASSERT(isMainThread() && isAudioThreadFinished());
688     for (auto& node : m_referencedNodes)
689         node->deref(AudioNode::RefTypeConnection);
690
691     m_referencedNodes.clear();
692 }
693
694 void AudioContext::lock(bool& mustReleaseLock)
695 {
696     // Don't allow regular lock in real-time audio thread.
697     ASSERT(isMainThread());
698
699     ThreadIdentifier thisThread = currentThread();
700
701     if (thisThread == m_graphOwnerThread) {
702         // We already have the lock.
703         mustReleaseLock = false;
704     } else {
705         // Acquire the lock.
706         m_contextGraphMutex.lock();
707         m_graphOwnerThread = thisThread;
708         mustReleaseLock = true;
709     }
710 }
711
712 bool AudioContext::tryLock(bool& mustReleaseLock)
713 {
714     ThreadIdentifier thisThread = currentThread();
715     bool isAudioThread = thisThread == audioThread();
716
717     // Try to catch cases of using try lock on main thread - it should use regular lock.
718     ASSERT(isAudioThread || isAudioThreadFinished());
719     
720     if (!isAudioThread) {
721         // In release build treat tryLock() as lock() (since above ASSERT(isAudioThread) never fires) - this is the best we can do.
722         lock(mustReleaseLock);
723         return true;
724     }
725     
726     bool hasLock;
727     
728     if (thisThread == m_graphOwnerThread) {
729         // Thread already has the lock.
730         hasLock = true;
731         mustReleaseLock = false;
732     } else {
733         // Don't already have the lock - try to acquire it.
734         hasLock = m_contextGraphMutex.tryLock();
735         
736         if (hasLock)
737             m_graphOwnerThread = thisThread;
738
739         mustReleaseLock = hasLock;
740     }
741     
742     return hasLock;
743 }
744
745 void AudioContext::unlock()
746 {
747     ASSERT(currentThread() == m_graphOwnerThread);
748
749     m_graphOwnerThread = UndefinedThreadIdentifier;
750     m_contextGraphMutex.unlock();
751 }
752
753 bool AudioContext::isAudioThread() const
754 {
755     return currentThread() == m_audioThread;
756 }
757
758 bool AudioContext::isGraphOwner() const
759 {
760     return currentThread() == m_graphOwnerThread;
761 }
762
763 void AudioContext::addDeferredFinishDeref(AudioNode* node)
764 {
765     ASSERT(isAudioThread());
766     m_deferredFinishDerefList.append(node);
767 }
768
769 void AudioContext::handlePreRenderTasks()
770 {
771     ASSERT(isAudioThread());
772
773     // At the beginning of every render quantum, try to update the internal rendering graph state (from main thread changes).
774     // It's OK if the tryLock() fails, we'll just take slightly longer to pick up the changes.
775     bool mustReleaseLock;
776     if (tryLock(mustReleaseLock)) {
777         // Fixup the state of any dirty AudioSummingJunctions and AudioNodeOutputs.
778         handleDirtyAudioSummingJunctions();
779         handleDirtyAudioNodeOutputs();
780
781         updateAutomaticPullNodes();
782
783         if (mustReleaseLock)
784             unlock();
785     }
786 }
787
788 void AudioContext::handlePostRenderTasks()
789 {
790     ASSERT(isAudioThread());
791
792     // Must use a tryLock() here too. Don't worry, the lock will very rarely be contended and this method is called frequently.
793     // The worst that can happen is that there will be some nodes which will take slightly longer than usual to be deleted or removed
794     // from the render graph (in which case they'll render silence).
795     bool mustReleaseLock;
796     if (tryLock(mustReleaseLock)) {
797         // Take care of finishing any derefs where the tryLock() failed previously.
798         handleDeferredFinishDerefs();
799
800         // Dynamically clean up nodes which are no longer needed.
801         derefFinishedSourceNodes();
802
803         // Don't delete in the real-time thread. Let the main thread do it.
804         // Ref-counted objects held by certain AudioNodes may not be thread-safe.
805         scheduleNodeDeletion();
806
807         // Fixup the state of any dirty AudioSummingJunctions and AudioNodeOutputs.
808         handleDirtyAudioSummingJunctions();
809         handleDirtyAudioNodeOutputs();
810
811         updateAutomaticPullNodes();
812
813         if (mustReleaseLock)
814             unlock();
815     }
816 }
817
818 void AudioContext::handleDeferredFinishDerefs()
819 {
820     ASSERT(isAudioThread() && isGraphOwner());
821     for (auto& node : m_deferredFinishDerefList)
822         node->finishDeref(AudioNode::RefTypeConnection);
823     
824     m_deferredFinishDerefList.clear();
825 }
826
827 void AudioContext::markForDeletion(AudioNode* node)
828 {
829     ASSERT(isGraphOwner());
830
831     if (isAudioThreadFinished())
832         m_nodesToDelete.append(node);
833     else
834         m_nodesMarkedForDeletion.append(node);
835
836     // This is probably the best time for us to remove the node from automatic pull list,
837     // since all connections are gone and we hold the graph lock. Then when handlePostRenderTasks()
838     // gets a chance to schedule the deletion work, updateAutomaticPullNodes() also gets a chance to
839     // modify m_renderingAutomaticPullNodes.
840     removeAutomaticPullNode(node);
841 }
842
843 void AudioContext::scheduleNodeDeletion()
844 {
845     bool isGood = m_isInitialized && isGraphOwner();
846     ASSERT(isGood);
847     if (!isGood)
848         return;
849
850     // Make sure to call deleteMarkedNodes() on main thread.    
851     if (m_nodesMarkedForDeletion.size() && !m_isDeletionScheduled) {
852         m_nodesToDelete.appendVector(m_nodesMarkedForDeletion);
853         m_nodesMarkedForDeletion.clear();
854
855         m_isDeletionScheduled = true;
856
857         callOnMainThread([protectedThis = makeRef(*this)]() mutable {
858             protectedThis->deleteMarkedNodes();
859         });
860     }
861 }
862
863 void AudioContext::deleteMarkedNodes()
864 {
865     ASSERT(isMainThread());
866
867     // Protect this object from being deleted before we release the mutex locked by AutoLocker.
868     Ref<AudioContext> protectedThis(*this);
869     {
870         AutoLocker locker(*this);
871
872         while (m_nodesToDelete.size()) {
873             AudioNode* node = m_nodesToDelete.takeLast();
874
875             // Before deleting the node, clear out any AudioNodeInputs from m_dirtySummingJunctions.
876             unsigned numberOfInputs = node->numberOfInputs();
877             for (unsigned i = 0; i < numberOfInputs; ++i)
878                 m_dirtySummingJunctions.remove(node->input(i));
879
880             // Before deleting the node, clear out any AudioNodeOutputs from m_dirtyAudioNodeOutputs.
881             unsigned numberOfOutputs = node->numberOfOutputs();
882             for (unsigned i = 0; i < numberOfOutputs; ++i)
883                 m_dirtyAudioNodeOutputs.remove(node->output(i));
884
885             // Finally, delete it.
886             delete node;
887         }
888         m_isDeletionScheduled = false;
889     }
890 }
891
892 void AudioContext::markSummingJunctionDirty(AudioSummingJunction* summingJunction)
893 {
894     ASSERT(isGraphOwner());    
895     m_dirtySummingJunctions.add(summingJunction);
896 }
897
898 void AudioContext::removeMarkedSummingJunction(AudioSummingJunction* summingJunction)
899 {
900     ASSERT(isMainThread());
901     AutoLocker locker(*this);
902     m_dirtySummingJunctions.remove(summingJunction);
903 }
904
905 void AudioContext::markAudioNodeOutputDirty(AudioNodeOutput* output)
906 {
907     ASSERT(isGraphOwner());    
908     m_dirtyAudioNodeOutputs.add(output);
909 }
910
911 void AudioContext::handleDirtyAudioSummingJunctions()
912 {
913     ASSERT(isGraphOwner());    
914
915     for (auto& junction : m_dirtySummingJunctions)
916         junction->updateRenderingState();
917
918     m_dirtySummingJunctions.clear();
919 }
920
921 void AudioContext::handleDirtyAudioNodeOutputs()
922 {
923     ASSERT(isGraphOwner());    
924
925     for (auto& output : m_dirtyAudioNodeOutputs)
926         output->updateRenderingState();
927
928     m_dirtyAudioNodeOutputs.clear();
929 }
930
931 void AudioContext::addAutomaticPullNode(AudioNode* node)
932 {
933     ASSERT(isGraphOwner());
934
935     if (m_automaticPullNodes.add(node).isNewEntry)
936         m_automaticPullNodesNeedUpdating = true;
937 }
938
939 void AudioContext::removeAutomaticPullNode(AudioNode* node)
940 {
941     ASSERT(isGraphOwner());
942
943     if (m_automaticPullNodes.remove(node))
944         m_automaticPullNodesNeedUpdating = true;
945 }
946
947 void AudioContext::updateAutomaticPullNodes()
948 {
949     ASSERT(isGraphOwner());
950
951     if (m_automaticPullNodesNeedUpdating) {
952         // Copy from m_automaticPullNodes to m_renderingAutomaticPullNodes.
953         m_renderingAutomaticPullNodes.resize(m_automaticPullNodes.size());
954
955         unsigned i = 0;
956         for (auto& output : m_automaticPullNodes)
957             m_renderingAutomaticPullNodes[i++] = output;
958
959         m_automaticPullNodesNeedUpdating = false;
960     }
961 }
962
963 void AudioContext::processAutomaticPullNodes(size_t framesToProcess)
964 {
965     ASSERT(isAudioThread());
966
967     for (auto& node : m_renderingAutomaticPullNodes)
968         node->processIfNecessary(framesToProcess);
969 }
970
971 ScriptExecutionContext* AudioContext::scriptExecutionContext() const
972 {
973     return m_isStopScheduled ? 0 : ActiveDOMObject::scriptExecutionContext();
974 }
975
976 void AudioContext::nodeWillBeginPlayback()
977 {
978     // Called by scheduled AudioNodes when clients schedule their start times.
979     // Prior to the introduction of suspend(), resume(), and stop(), starting
980     // a scheduled AudioNode would remove the user-gesture restriction, if present,
981     // and would thus unmute the context. Now that AudioContext stays in the
982     // "suspended" state if a user-gesture restriction is present, starting a
983     // schedule AudioNode should set the state to "running", but only if the
984     // user-gesture restriction is set.
985     if (userGestureRequiredForAudioStart())
986         startRendering();
987 }
988
989 bool AudioContext::willBeginPlayback()
990 {
991     if (userGestureRequiredForAudioStart()) {
992         if (!processingUserGestureForMedia())
993             return false;
994         removeBehaviorRestriction(AudioContext::RequireUserGestureForAudioStartRestriction);
995     }
996
997     if (pageConsentRequiredForAudioStart()) {
998         Page* page = document()->page();
999         if (page && !page->canStartMedia()) {
1000             document()->addMediaCanStartListener(this);
1001             return false;
1002         }
1003         removeBehaviorRestriction(AudioContext::RequirePageConsentForAudioStartRestriction);
1004     }
1005
1006     return m_mediaSession->clientWillBeginPlayback();
1007 }
1008
1009 bool AudioContext::willPausePlayback()
1010 {
1011     if (userGestureRequiredForAudioStart()) {
1012         if (!processingUserGestureForMedia())
1013             return false;
1014         removeBehaviorRestriction(AudioContext::RequireUserGestureForAudioStartRestriction);
1015     }
1016
1017     if (pageConsentRequiredForAudioStart()) {
1018         Page* page = document()->page();
1019         if (page && !page->canStartMedia()) {
1020             document()->addMediaCanStartListener(this);
1021             return false;
1022         }
1023         removeBehaviorRestriction(AudioContext::RequirePageConsentForAudioStartRestriction);
1024     }
1025     
1026     return m_mediaSession->clientWillPausePlayback();
1027 }
1028
1029 void AudioContext::startRendering()
1030 {
1031     if (!willBeginPlayback())
1032         return;
1033
1034     destination()->startRendering();
1035     setState(State::Running);
1036 }
1037
1038 void AudioContext::mediaCanStart(Document& document)
1039 {
1040     ASSERT_UNUSED(document, &document == this->document());
1041     removeBehaviorRestriction(AudioContext::RequirePageConsentForAudioStartRestriction);
1042     mayResumePlayback(true);
1043 }
1044
1045 MediaProducer::MediaStateFlags AudioContext::mediaState() const
1046 {
1047     if (!m_isStopScheduled && m_destinationNode && m_destinationNode->isPlayingAudio())
1048         return MediaProducer::IsPlayingAudio;
1049
1050     return MediaProducer::IsNotPlaying;
1051 }
1052
1053 void AudioContext::pageMutedStateDidChange()
1054 {
1055     if (m_destinationNode && document()->page())
1056         m_destinationNode->setMuted(document()->page()->isAudioMuted());
1057 }
1058
1059 void AudioContext::isPlayingAudioDidChange()
1060 {
1061     // Make sure to call Document::updateIsPlayingMedia() on the main thread, since
1062     // we could be on the audio I/O thread here and the call into WebCore could block.
1063     callOnMainThread([protectedThis = makeRef(*this)] {
1064         if (protectedThis->document())
1065             protectedThis->document()->updateIsPlayingMedia();
1066     });
1067 }
1068
1069 void AudioContext::fireCompletionEvent()
1070 {
1071     ASSERT(isMainThread());
1072     if (!isMainThread())
1073         return;
1074         
1075     AudioBuffer* renderedBuffer = m_renderTarget.get();
1076     setState(State::Closed);
1077
1078     ASSERT(renderedBuffer);
1079     if (!renderedBuffer)
1080         return;
1081
1082     // Avoid firing the event if the document has already gone away.
1083     if (scriptExecutionContext()) {
1084         // Call the offline rendering completion event listener.
1085         m_eventQueue->enqueueEvent(OfflineAudioCompletionEvent::create(renderedBuffer));
1086     }
1087 }
1088
1089 void AudioContext::incrementActiveSourceCount()
1090 {
1091     ++m_activeSourceCount;
1092 }
1093
1094 void AudioContext::decrementActiveSourceCount()
1095 {
1096     --m_activeSourceCount;
1097 }
1098
1099 void AudioContext::suspend(DOMPromiseDeferred<void>&& promise)
1100 {
1101     if (isOfflineContext()) {
1102         promise.reject(INVALID_STATE_ERR);
1103         return;
1104     }
1105
1106     if (m_state == State::Suspended) {
1107         promise.resolve();
1108         return;
1109     }
1110
1111     if (m_state == State::Closed || m_state == State::Interrupted || !m_destinationNode) {
1112         promise.reject();
1113         return;
1114     }
1115
1116     addReaction(State::Suspended, WTFMove(promise));
1117
1118     if (!willPausePlayback())
1119         return;
1120
1121     lazyInitialize();
1122
1123     m_destinationNode->suspend([this, protectedThis = makeRef(*this)] {
1124         setState(State::Suspended);
1125     });
1126 }
1127
1128 void AudioContext::resume(DOMPromiseDeferred<void>&& promise)
1129 {
1130     if (isOfflineContext()) {
1131         promise.reject(INVALID_STATE_ERR);
1132         return;
1133     }
1134
1135     if (m_state == State::Running) {
1136         promise.resolve();
1137         return;
1138     }
1139
1140     if (m_state == State::Closed || !m_destinationNode) {
1141         promise.reject();
1142         return;
1143     }
1144
1145     addReaction(State::Running, WTFMove(promise));
1146
1147     if (!willBeginPlayback())
1148         return;
1149
1150     lazyInitialize();
1151
1152     m_destinationNode->resume([this, protectedThis = makeRef(*this)] {
1153         setState(State::Running);
1154     });
1155 }
1156
1157 void AudioContext::close(DOMPromiseDeferred<void>&& promise)
1158 {
1159     if (isOfflineContext()) {
1160         promise.reject(INVALID_STATE_ERR);
1161         return;
1162     }
1163
1164     if (m_state == State::Closed || !m_destinationNode) {
1165         promise.resolve();
1166         return;
1167     }
1168
1169     addReaction(State::Closed, WTFMove(promise));
1170
1171     lazyInitialize();
1172
1173     m_destinationNode->close([this, protectedThis = makeRef(*this)] {
1174         setState(State::Closed);
1175         uninitialize();
1176     });
1177 }
1178
1179
1180 void AudioContext::suspendPlayback()
1181 {
1182     if (!m_destinationNode || m_state == State::Closed)
1183         return;
1184
1185     if (m_state == State::Suspended) {
1186         if (m_mediaSession->state() == PlatformMediaSession::Interrupted)
1187             setState(State::Interrupted);
1188         return;
1189     }
1190
1191     lazyInitialize();
1192
1193     m_destinationNode->suspend([this, protectedThis = makeRef(*this)] {
1194         bool interrupted = m_mediaSession->state() == PlatformMediaSession::Interrupted;
1195         setState(interrupted ? State::Interrupted : State::Suspended);
1196     });
1197 }
1198
1199 void AudioContext::mayResumePlayback(bool shouldResume)
1200 {
1201     if (!m_destinationNode || m_state == State::Closed || m_state == State::Running)
1202         return;
1203
1204     if (!shouldResume) {
1205         setState(State::Suspended);
1206         return;
1207     }
1208
1209     if (!willBeginPlayback())
1210         return;
1211
1212     lazyInitialize();
1213
1214     m_destinationNode->resume([this, protectedThis = makeRef(*this)] {
1215         setState(State::Running);
1216     });
1217 }
1218
1219
1220 } // namespace WebCore
1221
1222 #endif // ENABLE(WEB_AUDIO)