Move more logic from AudioDestinationNode to its subclasses
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 May 2021 16:53:37 +0000 (16:53 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 May 2021 16:53:37 +0000 (16:53 +0000)
https://bugs.webkit.org/show_bug.cgi?id=225849

Reviewed by Sam Weinig.

Move more logic from AudioDestinationNode to its subclasses. In particular, AudioDestinationNode
contains a lot of things that are specific to real-time audio rendering and those should go to
DefaultAudioDestinationNode.

This allows us to move isPlayingAudioDidChange() from BaseAudioContext to AudioContext also.

* Modules/webaudio/AudioContext.cpp:
(WebCore::AudioContext::isPlayingAudioDidChange):
* Modules/webaudio/AudioContext.h:
* Modules/webaudio/AudioDestinationNode.cpp:
(WebCore::AudioDestinationNode::renderQuantum):
* Modules/webaudio/AudioDestinationNode.h:
* Modules/webaudio/BaseAudioContext.cpp:
* Modules/webaudio/BaseAudioContext.h:
* Modules/webaudio/DefaultAudioDestinationNode.cpp:
(WebCore::DefaultAudioDestinationNode::createDestination):
(WebCore::DefaultAudioDestinationNode::framesPerBuffer const):
(WebCore::DefaultAudioDestinationNode::render):
(WebCore::DefaultAudioDestinationNode::setIsSilent):
(WebCore::DefaultAudioDestinationNode::isPlayingDidChange):
(WebCore::DefaultAudioDestinationNode::updateIsEffectivelyPlayingAudio):
* Modules/webaudio/DefaultAudioDestinationNode.h:
* Modules/webaudio/OfflineAudioDestinationNode.cpp:
(WebCore::OfflineAudioDestinationNode::OfflineAudioDestinationNode):
(WebCore::OfflineAudioDestinationNode::startRendering):
(WebCore::OfflineAudioDestinationNode::renderOnAudioThread):
* Modules/webaudio/OfflineAudioDestinationNode.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277586 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/Modules/webaudio/AudioContext.cpp
Source/WebCore/Modules/webaudio/AudioContext.h
Source/WebCore/Modules/webaudio/AudioDestinationNode.cpp
Source/WebCore/Modules/webaudio/AudioDestinationNode.h
Source/WebCore/Modules/webaudio/BaseAudioContext.cpp
Source/WebCore/Modules/webaudio/BaseAudioContext.h
Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.cpp
Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.h
Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.cpp
Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.h

index 01c431d26ab8d757604e97455856492593f2759a..a00d68cd364d1f753c36603670cf2e62cb5fcb97 100644 (file)
@@ -1,3 +1,38 @@
+2021-05-17  Chris Dumez  <cdumez@apple.com>
+
+        Move more logic from AudioDestinationNode to its subclasses
+        https://bugs.webkit.org/show_bug.cgi?id=225849
+
+        Reviewed by Sam Weinig.
+
+        Move more logic from AudioDestinationNode to its subclasses. In particular, AudioDestinationNode
+        contains a lot of things that are specific to real-time audio rendering and those should go to
+        DefaultAudioDestinationNode.
+
+        This allows us to move isPlayingAudioDidChange() from BaseAudioContext to AudioContext also.
+
+        * Modules/webaudio/AudioContext.cpp:
+        (WebCore::AudioContext::isPlayingAudioDidChange):
+        * Modules/webaudio/AudioContext.h:
+        * Modules/webaudio/AudioDestinationNode.cpp:
+        (WebCore::AudioDestinationNode::renderQuantum):
+        * Modules/webaudio/AudioDestinationNode.h:
+        * Modules/webaudio/BaseAudioContext.cpp:
+        * Modules/webaudio/BaseAudioContext.h:
+        * Modules/webaudio/DefaultAudioDestinationNode.cpp:
+        (WebCore::DefaultAudioDestinationNode::createDestination):
+        (WebCore::DefaultAudioDestinationNode::framesPerBuffer const):
+        (WebCore::DefaultAudioDestinationNode::render):
+        (WebCore::DefaultAudioDestinationNode::setIsSilent):
+        (WebCore::DefaultAudioDestinationNode::isPlayingDidChange):
+        (WebCore::DefaultAudioDestinationNode::updateIsEffectivelyPlayingAudio):
+        * Modules/webaudio/DefaultAudioDestinationNode.h:
+        * Modules/webaudio/OfflineAudioDestinationNode.cpp:
+        (WebCore::OfflineAudioDestinationNode::OfflineAudioDestinationNode):
+        (WebCore::OfflineAudioDestinationNode::startRendering):
+        (WebCore::OfflineAudioDestinationNode::renderOnAudioThread):
+        * Modules/webaudio/OfflineAudioDestinationNode.h:
+
 2021-05-17  Peng Liu  <peng.liu6@apple.com>
 
         [GPUP] WebContent process should not pull audio session category from the GPU Process
index 7776a51f0da9ad2e9c950caefd32838d41205426..f0480675fee57fd75ce1e18d7690f27f03e8590e 100644 (file)
@@ -504,6 +504,20 @@ void AudioContext::mediaCanStart(Document& document)
     mayResumePlayback(true);
 }
 
+void AudioContext::isPlayingAudioDidChange()
+{
+    // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+    // explicitly allow the following allocation(s).
+    DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
+
+    // Make sure to call Document::updateIsPlayingMedia() on the main thread, since
+    // we could be on the audio I/O thread here and the call into WebCore could block.
+    callOnMainThread([protectedThis = makeRef(*this)] {
+        if (auto* document = protectedThis->document())
+            document->updateIsPlayingMedia();
+    });
+}
+
 #if !RELEASE_LOG_DISABLED
 const Logger& AudioContext::logger() const
 {
index a6ef67c1b36a3975e06389afe77d1c55a6ce7c8b..eeece4508ddc7a2bfba10bc20da88203bbc22934 100644 (file)
@@ -83,6 +83,8 @@ public:
 
     void startRendering();
 
+    void isPlayingAudioDidChange();
+
     // Restrictions to change default behaviors.
     enum BehaviorRestrictionFlags {
         NoRestrictions = 0,
index 4513f7d86586cb76cd2f3e43b2cfd61339824411..51e9e310efa5242994fa89745b2b72f260a9ed3b 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2010, Google Inc. All rights reserved.
+ * Copyright (C) 2020-2021, Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,7 +29,9 @@
 
 #include "AudioDestinationNode.h"
 
+#include "AudioBus.h"
 #include "AudioContext.h"
+#include "AudioIOCallback.h"
 #include "AudioNodeInput.h"
 #include "AudioNodeOutput.h"
 #include "AudioUtilities.h"
@@ -55,7 +58,7 @@ AudioDestinationNode::~AudioDestinationNode()
     uninitialize();
 }
 
-void AudioDestinationNode::render(AudioBus*, AudioBus* destinationBus, size_t numberOfFrames, const AudioIOPosition& outputPosition)
+void AudioDestinationNode::renderQuantum(AudioBus* destinationBus, size_t numberOfFrames, const AudioIOPosition& outputPosition)
 {
     // We don't want denormals slowing down any of the audio processing
     // since they can very seriously hurt performance.
@@ -71,14 +74,12 @@ void AudioDestinationNode::render(AudioBus*, AudioBus* destinationBus, size_t nu
     
     if (!context().isInitialized()) {
         destinationBus->zero();
-        setIsSilent(true);
         return;
     }
 
     ASSERT(numberOfFrames);
     if (!numberOfFrames) {
         destinationBus->zero();
-        setIsSilent(true);
         return;
     }
 
@@ -113,37 +114,6 @@ void AudioDestinationNode::render(AudioBus*, AudioBus* destinationBus, size_t nu
 
     if (workletGlobalScope)
         workletGlobalScope->handlePostRenderTasks(m_currentSampleFrame);
-
-    setIsSilent(destinationBus->isSilent());
-
-    // The reason we are handling mute after the call to setIsSilent() is because the muted state does
-    // not affect the audio destination node's effective playing state.
-    if (m_muted)
-        destinationBus->zero();
-}
-
-void AudioDestinationNode::isPlayingDidChange()
-{
-    updateIsEffectivelyPlayingAudio();
-}
-
-void AudioDestinationNode::setIsSilent(bool isSilent)
-{
-    if (m_isSilent == isSilent)
-        return;
-
-    m_isSilent = isSilent;
-    updateIsEffectivelyPlayingAudio();
-}
-
-void AudioDestinationNode::updateIsEffectivelyPlayingAudio()
-{
-    bool isEffectivelyPlayingAudio = isPlaying() && !m_isSilent;
-    if (m_isEffectivelyPlayingAudio == isEffectivelyPlayingAudio)
-        return;
-
-    m_isEffectivelyPlayingAudio = isEffectivelyPlayingAudio;
-    context().isPlayingAudioDidChange();
 }
 
 void AudioDestinationNode::ref()
index 26f56354aba9eefbd84b843c29cca64846b79075..9f34b5900d85e9dcd1956a03849e910d35c49658 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2010, Google Inc. All rights reserved.
+ * Copyright (C) 2020-2021, Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #pragma once
 
-#include "AudioBus.h"
-#include "AudioIOCallback.h"
 #include "AudioNode.h"
-#include "ExceptionOr.h"
 #include <wtf/CompletionHandler.h>
 
 namespace WebCore {
 
-class AudioDestinationNode : public AudioNode, public AudioIOCallback {
+class AudioBus;
+struct AudioIOPosition;
+
+class AudioDestinationNode : public AudioNode {
     WTF_MAKE_ISO_ALLOCATED(AudioDestinationNode);
 public:
-    AudioDestinationNode(BaseAudioContext&, float sampleRate);
-    virtual ~AudioDestinationNode();
+    ~AudioDestinationNode();
     
     // AudioNode   
-    void process(size_t) override { }; // we're pulled by hardware so this is never called
-    
-    // The audio hardware calls render() to get the next render quantum of audio into destinationBus.
-    // It will optionally give us local/live audio input in sourceBus (if it's not 0).
-    void render(AudioBus* sourceBus, AudioBus* destinationBus, size_t numberOfFrames, const AudioIOPosition& outputPosition) override;
+    void process(size_t) final { } // we're pulled by hardware so this is never called
 
     float sampleRate() const final { return m_sampleRate; }
 
@@ -56,34 +52,24 @@ public:
     virtual void enableInput(const String& inputDeviceId) = 0;
 
     virtual void startRendering(CompletionHandler<void(Optional<Exception>&&)>&&) = 0;
-    virtual void resume(CompletionHandler<void(Optional<Exception>&&)>&& completionHandler) { completionHandler(WTF::nullopt); }
-    virtual void suspend(CompletionHandler<void(Optional<Exception>&&)>&& completionHandler) { completionHandler(WTF::nullopt); }
-    virtual void close(CompletionHandler<void()>&& completionHandler) { completionHandler(); }
     virtual void restartRendering() { }
 
-    virtual bool isPlaying() { return false; }
-    void isPlayingDidChange() override;
-    bool isPlayingAudio() const { return m_isEffectivelyPlayingAudio; }
-    void setMuted(bool muted) { m_muted = muted; }
-
     // AudioDestinationNodes are owned by the BaseAudioContext so we forward the refcounting to its BaseAudioContext.
     void ref() final;
     void deref() final;
 
 protected:
-    double tailTime() const override { return 0; }
-    double latencyTime() const override { return 0; }
+    AudioDestinationNode(BaseAudioContext&, float sampleRate);
+
+    double tailTime() const final { return 0; }
+    double latencyTime() const final { return 0; }
 
-    void setIsSilent(bool);
-    void updateIsEffectivelyPlayingAudio();
+    void renderQuantum(AudioBus* destinationBus, size_t numberOfFrames, const AudioIOPosition& outputPosition);
 
+private:
     // Counts the number of sample-frames processed by the destination.
     std::atomic<size_t> m_currentSampleFrame { 0 };
-
     float m_sampleRate;
-    bool m_isSilent { true };
-    bool m_isEffectivelyPlayingAudio { false };
-    bool m_muted { false };
 };
 
 } // namespace WebCore
index 0625f21e3b84027943d4fa15edb4fb24bd445f6a..46be6e5280757d24312db4cbbbb5e30e8f2d0c95 100644 (file)
@@ -853,21 +853,6 @@ ScriptExecutionContext* BaseAudioContext::scriptExecutionContext() const
     return ActiveDOMObject::scriptExecutionContext();
 }
 
-// FIXME: This should probably move to AudioContext.
-void BaseAudioContext::isPlayingAudioDidChange()
-{
-    // Heap allocations are forbidden on the audio thread for performance reasons so we need to
-    // explicitly allow the following allocation(s).
-    DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
-
-    // Make sure to call Document::updateIsPlayingMedia() on the main thread, since
-    // we could be on the audio I/O thread here and the call into WebCore could block.
-    callOnMainThread([protectedThis = makeRef(*this)] {
-        if (protectedThis->document())
-            protectedThis->document()->updateIsPlayingMedia();
-    });
-}
-
 void BaseAudioContext::incrementActiveSourceCount()
 {
     ++m_activeSourceCount;
index 56306fa35c751e08bee185f7c98fa0b2ffb1cd7e..d9fe2b5a61bd01b75fe596c972dc6db4fa5c08f4 100644 (file)
@@ -29,6 +29,7 @@
 #include "ActiveDOMObject.h"
 #include "AudioContextState.h"
 #include "AudioDestinationNode.h"
+#include "AudioIOCallback.h"
 #include "EventTarget.h"
 #include "JSDOMPromiseDeferred.h"
 #include "OscillatorType.h"
@@ -214,8 +215,6 @@ public:
     // EventTarget
     ScriptExecutionContext* scriptExecutionContext() const final;
 
-    void isPlayingAudioDidChange();
-
     virtual void sourceNodeWillBeginPlayback(AudioNode&);
     // When a source node has no more processing to do (has finished playing), then it tells the context to dereference it.
     void sourceNodeDidFinishPlayback(AudioNode&);
index 09fd0c08aeaf5142d8a101eec17c33b087d82634..728bb9286a355d007d9cb018135cf6c1934b1a78 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2011, Google Inc. All rights reserved.
+ * Copyright (C) 2020-2021, Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -105,9 +106,9 @@ void DefaultAudioDestinationNode::clearDestination()
 
 void DefaultAudioDestinationNode::createDestination()
 {
-    ALWAYS_LOG(LOGIDENTIFIER, "contextSampleRate = ", m_sampleRate, ", hardwareSampleRate = ", AudioDestination::hardwareSampleRate());
+    ALWAYS_LOG(LOGIDENTIFIER, "contextSampleRate = ", sampleRate(), ", hardwareSampleRate = ", AudioDestination::hardwareSampleRate());
     ASSERT(!m_destination);
-    m_destination = platformStrategies()->mediaStrategy().createAudioDestination(*this, m_inputDeviceId, m_numberOfInputChannels, channelCount(), m_sampleRate);
+    m_destination = platformStrategies()->mediaStrategy().createAudioDestination(*this, m_inputDeviceId, m_numberOfInputChannels, channelCount(), sampleRate());
 }
 
 void DefaultAudioDestinationNode::recreateDestination()
@@ -236,14 +237,45 @@ ExceptionOr<void> DefaultAudioDestinationNode::setChannelCount(unsigned channelC
     return { };
 }
 
-bool DefaultAudioDestinationNode::isPlaying()
+unsigned DefaultAudioDestinationNode::framesPerBuffer() const
 {
-    return m_destination && m_destination->isPlaying();
+    return m_destination ? m_destination->framesPerBuffer() : 0;
 }
 
-unsigned DefaultAudioDestinationNode::framesPerBuffer() const
+void DefaultAudioDestinationNode::render(AudioBus*, AudioBus* destinationBus, size_t numberOfFrames, const AudioIOPosition& outputPosition)
 {
-    return m_destination ? m_destination->framesPerBuffer() : 0.;
+    renderQuantum(destinationBus, numberOfFrames, outputPosition);
+
+    setIsSilent(destinationBus->isSilent());
+
+    // The reason we are handling mute after the call to setIsSilent() is because the muted state does
+    // not affect the audio destination node's effective playing state.
+    if (m_muted)
+        destinationBus->zero();
+}
+
+void DefaultAudioDestinationNode::setIsSilent(bool isSilent)
+{
+    if (m_isSilent == isSilent)
+        return;
+
+    m_isSilent = isSilent;
+    updateIsEffectivelyPlayingAudio();
+}
+
+void DefaultAudioDestinationNode::isPlayingDidChange()
+{
+    updateIsEffectivelyPlayingAudio();
+}
+
+void DefaultAudioDestinationNode::updateIsEffectivelyPlayingAudio()
+{
+    bool isEffectivelyPlayingAudio = m_destination && m_destination->isPlaying() && !m_isSilent;
+    if (m_isEffectivelyPlayingAudio == isEffectivelyPlayingAudio)
+        return;
+
+    m_isEffectivelyPlayingAudio = isEffectivelyPlayingAudio;
+    context().isPlayingAudioDidChange();
 }
 
 } // namespace WebCore
index 94cbaf9ade80039ec6c9828315272b0792921285..e5e47858a01602ba682241241821d7c852cefa5f 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2011, Google Inc. All rights reserved.
+ * Copyright (C) 2020-2021, Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #pragma once
 
 #include "AudioDestinationNode.h"
+#include "AudioIOCallback.h"
 
 namespace WebCore {
 
 class AudioContext;
 class AudioDestination;
     
-class DefaultAudioDestinationNode final : public AudioDestinationNode {
+class DefaultAudioDestinationNode final : public AudioDestinationNode, public AudioIOCallback {
     WTF_MAKE_ISO_ALLOCATED(DefaultAudioDestinationNode);
 public:
-    explicit DefaultAudioDestinationNode(AudioContext&, Optional<float> = WTF::nullopt);
+    explicit DefaultAudioDestinationNode(AudioContext&, Optional<float> sampleRate = WTF::nullopt);
+    ~DefaultAudioDestinationNode();
 
     AudioContext& context();
     const AudioContext& context() const;
-    
-    virtual ~DefaultAudioDestinationNode();
 
     unsigned framesPerBuffer() const;
     
     void startRendering(CompletionHandler<void(Optional<Exception>&&)>&&) final;
-    void resume(CompletionHandler<void(Optional<Exception>&&)>&&) final;
-    void suspend(CompletionHandler<void(Optional<Exception>&&)>&&) final;
-    void close(CompletionHandler<void()>&&) final;
+    void resume(CompletionHandler<void(Optional<Exception>&&)>&&);
+    void suspend(CompletionHandler<void(Optional<Exception>&&)>&&);
+    void close(CompletionHandler<void()>&&);
+
+    void setMuted(bool muted) { m_muted = muted; }
+    bool isPlayingAudio() const { return m_isEffectivelyPlayingAudio; }
 
 private:
     void createDestination();
     void clearDestination();
     void recreateDestination();
 
+    // AudioIOCallback
+    // The audio hardware calls render() to get the next render quantum of audio into destinationBus.
+    // It will optionally give us local/live audio input in sourceBus (if it's not 0).
+    void render(AudioBus* sourceBus, AudioBus* destinationBus, size_t numberOfFrames, const AudioIOPosition& outputPosition) final;
+    void isPlayingDidChange() final;
+
+    void setIsSilent(bool);
+    void updateIsEffectivelyPlayingAudio();
+
     Function<void(Function<void()>&&)> dispatchToRenderThreadFunction();
 
     void initialize() final;
@@ -64,12 +77,14 @@ private:
     void enableInput(const String& inputDeviceId) final;
     void restartRendering() final;
     unsigned maxChannelCount() const final;
-    bool isPlaying() final;
 
     RefPtr<AudioDestination> m_destination;
-    bool m_wasDestinationStarted { false };
     String m_inputDeviceId;
     unsigned m_numberOfInputChannels { 0 };
+    bool m_wasDestinationStarted { false };
+    bool m_isEffectivelyPlayingAudio { false };
+    bool m_isSilent { true };
+    bool m_muted { false };
 };
 
 } // namespace WebCore
index 5ef86afcd81de4fa8185b43200f11440f0ccd34f..aefe2a8436d365e186813267e38ac86174bbfef5 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2011, Google Inc. All rights reserved.
+ * Copyright (C) 2020-2021, Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,6 +29,7 @@
 
 #include "OfflineAudioDestinationNode.h"
 
+#include "AudioBuffer.h"
 #include "AudioBus.h"
 #include "AudioContext.h"
 #include "AudioUtilities.h"
@@ -49,9 +51,9 @@ OfflineAudioDestinationNode::OfflineAudioDestinationNode(OfflineAudioContext& co
     : AudioDestinationNode(context, sampleRate)
     , m_numberOfChannels(numberOfChannels)
     , m_renderTarget(WTFMove(renderTarget))
+    , m_renderBus(AudioBus::create(numberOfChannels, AudioUtilities::renderQuantumSize))
     , m_framesToProcess(m_renderTarget ? m_renderTarget->length() : 0)
 {
-    m_renderBus = AudioBus::create(numberOfChannels, AudioUtilities::renderQuantumSize);
     initializeDefaultNodeOptions(numberOfChannels, ChannelCountMode::Explicit, ChannelInterpretation::Speakers);
 }
 
@@ -70,11 +72,6 @@ const OfflineAudioContext& OfflineAudioDestinationNode::context() const
     return downcast<OfflineAudioContext>(AudioDestinationNode::context());
 }
 
-unsigned OfflineAudioDestinationNode::maxChannelCount() const
-{
-    return m_numberOfChannels;
-}
-
 void OfflineAudioDestinationNode::initialize()
 {
     if (isInitialized())
@@ -121,18 +118,18 @@ void OfflineAudioDestinationNode::startRendering(CompletionHandler<void(Optional
     auto protectedThis = makeRef(*this);
 
     auto offThreadRendering = [this, protectedThis = WTFMove(protectedThis)]() mutable {
-        auto result = offlineRender();
-        callOnMainThread([this, result, currentSampleFrame = m_currentSampleFrame.load(), protectedThis = WTFMove(protectedThis)]() mutable {
+        auto result = renderOnAudioThread();
+        callOnMainThread([this, result, currentSampleFrame = this->currentSampleFrame(), protectedThis = WTFMove(protectedThis)]() mutable {
             context().postTask([this, protectedThis = WTFMove(protectedThis), result, currentSampleFrame]() mutable {
                 m_startedRendering = false;
                 switch (result) {
-                case OfflineRenderResult::Failure:
+                case RenderResult::Failure:
                     context().finishedRendering(false);
                     break;
-                case OfflineRenderResult::Complete:
+                case RenderResult::Complete:
                     context().finishedRendering(true);
                     break;
-                case OfflineRenderResult::Suspended:
+                case RenderResult::Suspended:
                     context().didSuspendRendering(currentSampleFrame);
                     break;
                 }
@@ -152,25 +149,25 @@ void OfflineAudioDestinationNode::startRendering(CompletionHandler<void(Optional
     completionHandler(WTF::nullopt);
 }
 
-auto OfflineAudioDestinationNode::offlineRender() -> OfflineRenderResult
+auto OfflineAudioDestinationNode::renderOnAudioThread() -> RenderResult
 {
     ASSERT(!isMainThread());
     ASSERT(m_renderBus.get());
 
     if (!m_renderBus.get())
-        return OfflineRenderResult::Failure;
+        return RenderResult::Failure;
 
     RELEASE_ASSERT(context().isInitialized());
 
     bool channelsMatch = m_renderBus->numberOfChannels() == m_renderTarget->numberOfChannels();
     ASSERT(channelsMatch);
     if (!channelsMatch)
-        return OfflineRenderResult::Failure;
+        return RenderResult::Failure;
 
     bool isRenderBusAllocated = m_renderBus->length() >= AudioUtilities::renderQuantumSize;
     ASSERT(isRenderBusAllocated);
     if (!isRenderBusAllocated)
-        return OfflineRenderResult::Failure;
+        return RenderResult::Failure;
 
     // Break up the render target into smaller "render quantize" sized pieces.
     // Render until we're finished.
@@ -178,10 +175,10 @@ auto OfflineAudioDestinationNode::offlineRender() -> OfflineRenderResult
 
     while (m_framesToProcess > 0) {
         if (context().shouldSuspend())
-            return OfflineRenderResult::Suspended;
+            return RenderResult::Suspended;
 
         // Render one render quantum.
-        render(0, m_renderBus.get(), AudioUtilities::renderQuantumSize, { });
+        renderQuantum(m_renderBus.get(), AudioUtilities::renderQuantumSize, { });
         
         size_t framesAvailableToCopy = std::min(m_framesToProcess, AudioUtilities::renderQuantumSize);
         
@@ -195,7 +192,7 @@ auto OfflineAudioDestinationNode::offlineRender() -> OfflineRenderResult
         m_framesToProcess -= framesAvailableToCopy;
     }
 
-    return OfflineRenderResult::Complete;
+    return RenderResult::Complete;
 }
 
 } // namespace WebCore
index bbcabaa0aa5c09cc758fcbf226b92b773863e6e1..c95468d9e7e5fe56e3f72956fb6767f560342854 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2011, Google Inc. All rights reserved.
+ * Copyright (C) 2020-2021, Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #pragma once
 
-#include "AudioBuffer.h"
 #include "AudioDestinationNode.h"
 #include <wtf/RefPtr.h>
 #include <wtf/Threading.h>
 
 namespace WebCore {
 
+class AudioBuffer;
 class AudioBus;
-class AudioContext;
 class OfflineAudioContext;
     
 class OfflineAudioDestinationNode final : public AudioDestinationNode {
     WTF_MAKE_ISO_ALLOCATED(OfflineAudioDestinationNode);
 public:
     OfflineAudioDestinationNode(OfflineAudioContext&, unsigned numberOfChannels, float sampleRate, RefPtr<AudioBuffer>&& renderTarget);
-
-    virtual ~OfflineAudioDestinationNode();
+    ~OfflineAudioDestinationNode();
 
     OfflineAudioContext& context();
     const OfflineAudioContext& context() const;
@@ -48,21 +47,21 @@ public:
     AudioBuffer* renderTarget() const { return m_renderTarget.get(); }
     
     // AudioNode   
-    void initialize() override;
-    void uninitialize() override;
+    void initialize() final;
+    void uninitialize() final;
 
     // AudioDestinationNode
-    void enableInput(const String&) override { }
+    void enableInput(const String&) final { }
     void startRendering(CompletionHandler<void(Optional<Exception>&&)>&&) final;
 
 private:
-    enum class OfflineRenderResult { Failure, Suspended, Complete };
-    OfflineRenderResult offlineRender();
+    enum class RenderResult { Failure, Suspended, Complete };
+    RenderResult renderOnAudioThread();
     void notifyOfflineRenderingSuspended();
 
     bool requiresTailProcessing() const final { return false; }
 
-    unsigned maxChannelCount() const final;
+    unsigned maxChannelCount() const final { return m_numberOfChannels; }
 
     unsigned m_numberOfChannels;