Move more logic from AudioDestinationNode to its subclasses
[WebKit-https.git] / Source / WebCore / Modules / webaudio / DefaultAudioDestinationNode.cpp
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