1 /* 2 * Copyright (C) 2012, 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 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 * DAMAGE. 24 */ 25 26 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_OFFLINE_AUDIO_CONTEXT_H_ 27 #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_OFFLINE_AUDIO_CONTEXT_H_ 28 29 #include "third_party/blink/renderer/modules/modules_export.h" 30 #include "third_party/blink/renderer/modules/webaudio/base_audio_context.h" 31 #include "third_party/blink/renderer/platform/wtf/hash_map.h" 32 33 namespace blink { 34 35 class ExceptionState; 36 class OfflineAudioContextOptions; 37 class OfflineAudioDestinationHandler; 38 39 class MODULES_EXPORT OfflineAudioContext final : public BaseAudioContext { 40 DEFINE_WRAPPERTYPEINFO(); 41 42 public: 43 static OfflineAudioContext* Create(ExecutionContext*, 44 unsigned number_of_channels, 45 unsigned number_of_frames, 46 float sample_rate, 47 ExceptionState&); 48 49 static OfflineAudioContext* Create(ExecutionContext*, 50 const OfflineAudioContextOptions*, 51 ExceptionState&); 52 53 OfflineAudioContext(Document*, 54 unsigned number_of_channels, 55 uint32_t number_of_frames, 56 float sample_rate, 57 ExceptionState&); 58 ~OfflineAudioContext() override; 59 60 void Trace(Visitor*) override; 61 length()62 uint32_t length() const { return total_render_frames_; } 63 64 ScriptPromise startOfflineRendering(ScriptState*, ExceptionState&); 65 66 ScriptPromise suspendContext(ScriptState*, double); 67 ScriptPromise resumeContext(ScriptState*); 68 69 void RejectPendingResolvers() override; 70 HasRealtimeConstraint()71 bool HasRealtimeConstraint() final { return false; } 72 73 bool IsPullingAudioGraph() const final; 74 75 DEFINE_ATTRIBUTE_EVENT_LISTENER(complete, kComplete) 76 77 // Fire completion event when the rendering is finished. 78 void FireCompletionEvent(); 79 80 bool HandlePreRenderTasks(const AudioIOPosition* output_position, 81 const AudioCallbackMetric* metric) final; 82 void HandlePostRenderTasks() final; 83 84 // Resolve a suspend scheduled at the specified frame. With this specified 85 // frame as a unique key, the associated promise resolver can be retrieved 86 // from the map (m_scheduledSuspends) and resolved. 87 void ResolveSuspendOnMainThread(size_t); 88 89 // OfflineAudioContext is not affected by Autoplay, so this MUST do nothing. NotifySourceNodeStart()90 void NotifySourceNodeStart() final {} 91 92 // The HashMap with 'zero' key is needed because |currentSampleFrame| can be 93 // zero. 94 using SuspendMap = HeapHashMap<size_t, 95 Member<ScriptPromiseResolver>, 96 DefaultHash<size_t>::Hash, 97 WTF::UnsignedWithZeroKeyHashTraits<size_t>>; 98 99 using OfflineGraphAutoLocker = DeferredTaskHandler::OfflineGraphAutoLocker; 100 101 // Document notification 102 bool HasPendingActivity() const final; 103 104 private: 105 // Fetch directly the destination handler. 106 OfflineAudioDestinationHandler& DestinationHandler(); 107 108 // Check if the rendering needs to be suspended. 109 bool ShouldSuspend(); 110 111 // This map is to store the timing of scheduled suspends (frame) and the 112 // associated promise resolver. This storage can only be modified by the 113 // main thread and accessed by the audio thread with the graph lock. 114 // 115 // The map consists of key-value pairs of: 116 // { size_t quantizedFrame: ScriptPromiseResolver resolver } 117 // 118 // Note that |quantizedFrame| is a unique key, since you can have only one 119 // suspend scheduled for a certain frame. Accessing to this must be 120 // protected by the offline context lock. 121 SuspendMap scheduled_suspends_; 122 123 Member<ScriptPromiseResolver> complete_resolver_; 124 125 // This flag is necessary to indicate the rendering has actually started or 126 // running. Note that initial state of context is 'Suspended', which is the 127 // same state when the context is suspended, so we cannot utilize it for this 128 // purpose. 129 bool is_rendering_started_; 130 131 // Total render sample length. 132 uint32_t total_render_frames_; 133 }; 134 135 } // namespace blink 136 137 #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_OFFLINE_AUDIO_CONTEXT_H_ 138