Bläddra i källkod

WebAudio: Stub `AudioBufferSourceNode`

bbb651 1 år sedan
förälder
incheckning
6672fb4b47

+ 2 - 1
Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp

@@ -34,6 +34,7 @@ static bool is_platform_object(Type const& type)
         "AnimationEffect"sv,
         "AnimationTimeline"sv,
         "Attr"sv,
+        "AudioBuffer"sv,
         "AudioNode"sv,
         "AudioParam"sv,
         "AudioScheduledSourceNode"sv,
@@ -2523,7 +2524,7 @@ JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object>> @constructor_class@::constru
     auto prototype = TRY(new_target.get(vm.names.prototype));
 
     // 3.3. If Type(prototype) is not Object, then:
-    if (!prototype.is_object()) {    
+    if (!prototype.is_object()) {
         // 1. Let targetRealm be ? GetFunctionRealm(newTarget).
         auto* target_realm = TRY(JS::get_function_realm(vm, new_target));
 

+ 2 - 0
Meta/gn/secondary/Userland/Libraries/LibWeb/WebAudio/BUILD.gn

@@ -6,6 +6,8 @@ source_set("WebAudio") {
   sources = [
     "AudioBuffer.cpp",
     "AudioBuffer.h",
+    "AudioBufferSourceNode.cpp",
+    "AudioBufferSourceNode.h",
     "AudioContext.cpp",
     "AudioContext.h",
     "AudioNode.cpp",

+ 1 - 0
Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni

@@ -319,6 +319,7 @@ standard_idl_files = [
   "//Userland/Libraries/LibWeb/WebAssembly/Module.idl",
   "//Userland/Libraries/LibWeb/WebAssembly/Table.idl",
   "//Userland/Libraries/LibWeb/WebAudio/AudioBuffer.idl",
+  "//Userland/Libraries/LibWeb/WebAudio/AudioBufferSourceNode.idl",
   "//Userland/Libraries/LibWeb/WebAudio/AudioContext.idl",
   "//Userland/Libraries/LibWeb/WebAudio/AudioNode.idl",
   "//Userland/Libraries/LibWeb/WebAudio/AudioParam.idl",

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

@@ -682,6 +682,7 @@ set(SOURCES
     WebAssembly/Table.cpp
     WebAssembly/WebAssembly.cpp
     WebAudio/AudioBuffer.cpp
+    WebAudio/AudioBufferSourceNode.cpp
     WebAudio/AudioContext.cpp
     WebAudio/AudioNode.cpp
     WebAudio/AudioParam.cpp

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

@@ -711,6 +711,7 @@ class Table;
 
 namespace Web::WebAudio {
 class AudioBuffer;
+class AudioBufferSourceNode;
 class AudioContext;
 class AudioNode;
 class AudioParam;

+ 49 - 0
Userland/Libraries/LibWeb/WebAudio/AudioBufferSourceNode.cpp

@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2024, Bar Yemini <bar.ye651@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibWeb/Bindings/AudioScheduledSourceNodePrototype.h>
+#include <LibWeb/Bindings/Intrinsics.h>
+#include <LibWeb/WebAudio/AudioBufferSourceNode.h>
+#include <LibWeb/WebAudio/AudioScheduledSourceNode.h>
+
+namespace Web::WebAudio {
+
+JS_DEFINE_ALLOCATOR(AudioBufferSourceNode);
+
+AudioBufferSourceNode::AudioBufferSourceNode(JS::Realm& realm, JS::NonnullGCPtr<BaseAudioContext> context, AudioBufferSourceOptions const&)
+    : AudioScheduledSourceNode(realm, context)
+{
+}
+
+AudioBufferSourceNode::~AudioBufferSourceNode() = default;
+
+WebIDL::ExceptionOr<JS::NonnullGCPtr<AudioBufferSourceNode>> AudioBufferSourceNode::create(JS::Realm& realm, JS::NonnullGCPtr<BaseAudioContext> context, AudioBufferSourceOptions const& options)
+{
+    return construct_impl(realm, context, options);
+}
+
+// https://webaudio.github.io/web-audio-api/#dom-audiobuffersourcenode-audiobuffersourcenode
+WebIDL::ExceptionOr<JS::NonnullGCPtr<AudioBufferSourceNode>> AudioBufferSourceNode::construct_impl(JS::Realm& realm, JS::NonnullGCPtr<BaseAudioContext> context, AudioBufferSourceOptions const& options)
+{
+    // When the constructor is called with a BaseAudioContext c and an option object option, the user agent
+    // MUST initialize the AudioNode this, with context and options as arguments.
+
+    auto node = realm.vm().heap().allocate<AudioBufferSourceNode>(realm, realm, context, options);
+    return node;
+}
+
+void AudioBufferSourceNode::initialize(JS::Realm& realm)
+{
+    Base::initialize(realm);
+    WEB_SET_PROTOTYPE_FOR_INTERFACE(AudioBufferSourceNode);
+}
+
+void AudioBufferSourceNode::visit_edges(Cell::Visitor& visitor)
+{
+    Base::visit_edges(visitor);
+}
+
+}

+ 42 - 0
Userland/Libraries/LibWeb/WebAudio/AudioBufferSourceNode.h

@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2024, Bar Yemini <bar.ye651@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <LibWeb/Bindings/AudioBufferSourceNodePrototype.h>
+#include <LibWeb/WebAudio/AudioScheduledSourceNode.h>
+
+namespace Web::WebAudio {
+
+// https://webaudio.github.io/web-audio-api/#AudioBufferSourceOptions
+struct AudioBufferSourceOptions {
+    JS::GCPtr<AudioBuffer> buffer;
+    float detune { 0 };
+    bool loop { false };
+    double loop_end { 0 };
+    double loop_start { 0 };
+    float playback_rate { 1 };
+};
+
+// https://webaudio.github.io/web-audio-api/#AudioBufferSourceNode
+class AudioBufferSourceNode : public AudioScheduledSourceNode {
+    WEB_PLATFORM_OBJECT(AudioBufferSourceNode, AudioScheduledSourceNode);
+    JS_DECLARE_ALLOCATOR(AudioBufferSourceNode);
+
+public:
+    virtual ~AudioBufferSourceNode() override;
+
+    static WebIDL::ExceptionOr<JS::NonnullGCPtr<AudioBufferSourceNode>> create(JS::Realm&, JS::NonnullGCPtr<BaseAudioContext>, AudioBufferSourceOptions const& = {});
+    static WebIDL::ExceptionOr<JS::NonnullGCPtr<AudioBufferSourceNode>> construct_impl(JS::Realm&, JS::NonnullGCPtr<BaseAudioContext>, AudioBufferSourceOptions const& = {});
+
+protected:
+    AudioBufferSourceNode(JS::Realm&, JS::NonnullGCPtr<BaseAudioContext>, AudioBufferSourceOptions const& = {});
+
+    virtual void initialize(JS::Realm&) override;
+    virtual void visit_edges(Cell::Visitor&) override;
+};
+
+}

+ 26 - 0
Userland/Libraries/LibWeb/WebAudio/AudioBufferSourceNode.idl

@@ -0,0 +1,26 @@
+#import <WebAudio/AudioBuffer.idl>
+#import <WebAudio/AudioParam.idl>
+#import <WebAudio/AudioScheduledSourceNode.idl>
+#import <WebAudio/BaseAudioContext.idl>
+
+dictionary AudioBufferSourceOptions {
+    AudioBuffer? buffer;
+    float detune = 0;
+    boolean loop = false;
+    double loopEnd = 0;
+    double loopStart = 0;
+    float playbackRate = 1;
+};
+
+// https://webaudio.github.io/web-audio-api/#AudioBufferSourceNode
+[Exposed=Window]
+interface AudioBufferSourceNode : AudioScheduledSourceNode {
+    constructor(BaseAudioContext context, optional AudioBufferSourceOptions options = {});
+    [FIXME] attribute AudioBuffer? buffer;
+    [FIXME] readonly attribute AudioParam playbackRate;
+    [FIXME] readonly attribute AudioParam detune;
+    [FIXME] attribute boolean loop;
+    [FIXME] attribute double loopStart;
+    [FIXME] attribute double loopEnd;
+    [FIXME] undefined start(optional double when = 0, optional double offset, optional double duration);
+};

+ 8 - 0
Userland/Libraries/LibWeb/WebAudio/BaseAudioContext.cpp

@@ -9,6 +9,7 @@
 #include <LibWeb/Bindings/Intrinsics.h>
 #include <LibWeb/HTML/EventNames.h>
 #include <LibWeb/WebAudio/AudioBuffer.h>
+#include <LibWeb/WebAudio/AudioBufferSourceNode.h>
 #include <LibWeb/WebAudio/BaseAudioContext.h>
 #include <LibWeb/WebAudio/DynamicsCompressorNode.h>
 #include <LibWeb/WebAudio/GainNode.h>
@@ -48,6 +49,13 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<AudioBuffer>> BaseAudioContext::create_buff
     return AudioBuffer::create(realm(), number_of_channels, length, sample_rate);
 }
 
+// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createbuffersource
+WebIDL::ExceptionOr<JS::NonnullGCPtr<AudioBufferSourceNode>> BaseAudioContext::create_buffer_source()
+{
+    // Factory method for a AudioBufferSourceNode.
+    return AudioBufferSourceNode::create(realm(), *this);
+}
+
 // https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createoscillator
 WebIDL::ExceptionOr<JS::NonnullGCPtr<OscillatorNode>> BaseAudioContext::create_oscillator()
 {

+ 1 - 0
Userland/Libraries/LibWeb/WebAudio/BaseAudioContext.h

@@ -48,6 +48,7 @@ public:
     static WebIDL::ExceptionOr<void> verify_audio_options_inside_nominal_range(JS::Realm&, WebIDL::UnsignedLong number_of_channels, WebIDL::UnsignedLong length, float sample_rate);
 
     WebIDL::ExceptionOr<JS::NonnullGCPtr<AudioBuffer>> create_buffer(WebIDL::UnsignedLong number_of_channels, WebIDL::UnsignedLong length, float sample_rate);
+    WebIDL::ExceptionOr<JS::NonnullGCPtr<AudioBufferSourceNode>> create_buffer_source();
     WebIDL::ExceptionOr<JS::NonnullGCPtr<OscillatorNode>> create_oscillator();
     WebIDL::ExceptionOr<JS::NonnullGCPtr<DynamicsCompressorNode>> create_dynamics_compressor();
     JS::NonnullGCPtr<GainNode> create_gain();

+ 2 - 1
Userland/Libraries/LibWeb/WebAudio/BaseAudioContext.idl

@@ -1,6 +1,7 @@
 #import <DOM/EventTarget.idl>
 #import <DOM/EventHandler.idl>
 #import <WebAudio/AudioBuffer.idl>
+#import <WebAudio/AudioBufferSourceNode.idl>
 #import <WebAudio/DynamicsCompressorNode.idl>
 #import <WebAudio/GainNode.idl>
 #import <WebAudio/OscillatorNode.idl>
@@ -27,7 +28,7 @@ interface BaseAudioContext : EventTarget {
     [FIXME] AnalyserNode createAnalyser ();
     [FIXME] BiquadFilterNode createBiquadFilter ();
     AudioBuffer createBuffer(unsigned long numberOfChannels, unsigned long length, float sampleRate);
-    [FIXME] AudioBufferSourceNode createBufferSource ();
+    AudioBufferSourceNode createBufferSource ();
     [FIXME] ChannelMergerNode createChannelMerger (optional unsigned long numberOfInputs = 6);
     [FIXME] ChannelSplitterNode createChannelSplitter (optional unsigned long numberOfOutputs = 6);
     [FIXME] ConstantSourceNode createConstantSource ();

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

@@ -310,6 +310,7 @@ libweb_js_bindings(WebAssembly/Module)
 libweb_js_bindings(WebAssembly/Table)
 libweb_js_bindings(WebAssembly/WebAssembly NAMESPACE)
 libweb_js_bindings(WebAudio/AudioBuffer)
+libweb_js_bindings(WebAudio/AudioBufferSourceNode)
 libweb_js_bindings(WebAudio/AudioContext)
 libweb_js_bindings(WebAudio/AudioNode)
 libweb_js_bindings(WebAudio/AudioParam)