Ver código fonte

LibWeb: Add Implement GainNode interface

As with all other current audio nodes we still need to wire up the
inputs and outputs so it can be properly used in an audio context - but
this is enough to implement the public IDL interface.
Shannon Booth 1 ano atrás
pai
commit
1fa7235fec

+ 1 - 0
Userland/Libraries/LibWeb/CMakeLists.txt

@@ -673,6 +673,7 @@ set(SOURCES
     WebAudio/AudioScheduledSourceNode.cpp
     WebAudio/BaseAudioContext.cpp
     WebAudio/DynamicsCompressorNode.cpp
+    WebAudio/GainNode.cpp
     WebAudio/OfflineAudioContext.cpp
     WebAudio/OscillatorNode.cpp
     WebAudio/PeriodicWave.cpp

+ 1 - 0
Userland/Libraries/LibWeb/Forward.h

@@ -700,6 +700,7 @@ class AudioParam;
 class AudioScheduledSourceNode;
 class BaseAudioContext;
 class DynamicsCompressorNode;
+class GainNode;
 class OfflineAudioContext;
 class OscillatorNode;
 class PeriodicWave;

+ 48 - 0
Userland/Libraries/LibWeb/WebAudio/GainNode.cpp

@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2024, Shannon Booth <shannon@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibWeb/Bindings/Intrinsics.h>
+#include <LibWeb/WebAudio/AudioParam.h>
+#include <LibWeb/WebAudio/BaseAudioContext.h>
+#include <LibWeb/WebAudio/GainNode.h>
+
+namespace Web::WebAudio {
+
+JS_DEFINE_ALLOCATOR(GainNode);
+
+GainNode::~GainNode() = default;
+
+JS::NonnullGCPtr<GainNode> GainNode::create(JS::Realm& realm, JS::NonnullGCPtr<BaseAudioContext> context, GainOptions const& options)
+{
+    return construct_impl(realm, context, options);
+}
+
+// https://webaudio.github.io/web-audio-api/#dom-gainnode-gainnode
+JS::NonnullGCPtr<GainNode> GainNode::construct_impl(JS::Realm& realm, JS::NonnullGCPtr<BaseAudioContext> context, GainOptions const& options)
+{
+    // FIXME: Invoke "Initialize the AudioNode" steps.
+    return realm.vm().heap().allocate<GainNode>(realm, realm, context, options);
+}
+
+GainNode::GainNode(JS::Realm& realm, JS::NonnullGCPtr<BaseAudioContext> context, GainOptions const& options)
+    : AudioNode(realm, context)
+    , m_gain(AudioParam::create(realm, options.gain, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
+{
+}
+
+void GainNode::initialize(JS::Realm& realm)
+{
+    Base::initialize(realm);
+    WEB_SET_PROTOTYPE_FOR_INTERFACE(GainNode);
+}
+
+void GainNode::visit_edges(Cell::Visitor& visitor)
+{
+    Base::visit_edges(visitor);
+    visitor.visit(m_gain);
+}
+
+}

+ 43 - 0
Userland/Libraries/LibWeb/WebAudio/GainNode.h

@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2024, Shannon Booth <shannon@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <LibWeb/Bindings/GainNodePrototype.h>
+#include <LibWeb/WebAudio/AudioScheduledSourceNode.h>
+
+namespace Web::WebAudio {
+
+// https://webaudio.github.io/web-audio-api/#GainOptions
+struct GainOptions : AudioNodeOptions {
+    float gain { 1.0 };
+};
+
+// https://webaudio.github.io/web-audio-api/#GainNode
+class GainNode : public AudioNode {
+    WEB_PLATFORM_OBJECT(GainNode, AudioNode);
+    JS_DECLARE_ALLOCATOR(GainNode);
+
+public:
+    virtual ~GainNode() override;
+
+    static JS::NonnullGCPtr<GainNode> create(JS::Realm&, JS::NonnullGCPtr<BaseAudioContext>, GainOptions const& = {});
+    static JS::NonnullGCPtr<GainNode> construct_impl(JS::Realm&, JS::NonnullGCPtr<BaseAudioContext>, GainOptions const& = {});
+
+    JS::NonnullGCPtr<AudioParam const> gain() const { return m_gain; }
+
+protected:
+    GainNode(JS::Realm&, JS::NonnullGCPtr<BaseAudioContext>, GainOptions const& = {});
+
+    virtual void initialize(JS::Realm&) override;
+    virtual void visit_edges(Cell::Visitor&) override;
+
+private:
+    // https://webaudio.github.io/web-audio-api/#dom-gainnode-gain
+    JS::NonnullGCPtr<AudioParam> m_gain;
+};
+
+}

+ 15 - 0
Userland/Libraries/LibWeb/WebAudio/GainNode.idl

@@ -0,0 +1,15 @@
+#import <WebAudio/AudioNode.idl>
+#import <WebAudio/AudioParam.idl>
+#import <WebAudio/BaseAudioContext.idl>
+
+// https://webaudio.github.io/web-audio-api/#GainOptions
+dictionary GainOptions : AudioNodeOptions {
+    float gain = 1.0;
+};
+
+// https://webaudio.github.io/web-audio-api/#GainNode
+[Exposed=Window]
+interface GainNode : AudioNode {
+    constructor(BaseAudioContext context, optional GainOptions options = {});
+    readonly attribute AudioParam gain;
+};

+ 1 - 0
Userland/Libraries/LibWeb/idl_files.cmake

@@ -306,6 +306,7 @@ libweb_js_bindings(WebAudio/AudioParam)
 libweb_js_bindings(WebAudio/AudioScheduledSourceNode)
 libweb_js_bindings(WebAudio/BaseAudioContext)
 libweb_js_bindings(WebAudio/DynamicsCompressorNode)
+libweb_js_bindings(WebAudio/GainNode)
 libweb_js_bindings(WebAudio/OfflineAudioContext)
 libweb_js_bindings(WebAudio/OscillatorNode)
 libweb_js_bindings(WebAudio/PeriodicWave)