diff --git a/Userland/Libraries/LibWeb/WebAudio/AudioDestinationNode.cpp b/Userland/Libraries/LibWeb/WebAudio/AudioDestinationNode.cpp index 5a76d78aba9..43d31fe265d 100644 --- a/Userland/Libraries/LibWeb/WebAudio/AudioDestinationNode.cpp +++ b/Userland/Libraries/LibWeb/WebAudio/AudioDestinationNode.cpp @@ -7,9 +7,11 @@ #include #include +#include #include #include #include +#include namespace Web::WebAudio { @@ -45,4 +47,25 @@ void AudioDestinationNode::visit_edges(Cell::Visitor& visitor) Base::visit_edges(visitor); } +// https://webaudio.github.io/web-audio-api/#dom-audionode-channelcount +WebIDL::ExceptionOr AudioDestinationNode::set_channel_count(WebIDL::UnsignedLong channel_count) +{ + // The behavior depends on whether the destination node is the destination of an AudioContext + // or OfflineAudioContext: + + // AudioContext: The channel count MUST be between 1 and maxChannelCount. An IndexSizeError + // exception MUST be thrown for any attempt to set the count outside this range. + if (is(*context())) { + if (channel_count < 1 || channel_count > max_channel_count()) + return WebIDL::IndexSizeError::create(realm(), "Channel index is out of range"_fly_string); + } + + // OfflineAudioContext: The channel count cannot be changed. An InvalidStateError exception MUST + // be thrown for any attempt to change the value. + if (is(*context())) + return WebIDL::InvalidStateError::create(realm(), "Cannot change channel count in an OfflineAudioContext"_fly_string); + + return AudioNode::set_channel_count(channel_count); +} + } diff --git a/Userland/Libraries/LibWeb/WebAudio/AudioDestinationNode.h b/Userland/Libraries/LibWeb/WebAudio/AudioDestinationNode.h index d2fcfe0709a..0a1c1aad736 100644 --- a/Userland/Libraries/LibWeb/WebAudio/AudioDestinationNode.h +++ b/Userland/Libraries/LibWeb/WebAudio/AudioDestinationNode.h @@ -25,6 +25,7 @@ public: WebIDL::UnsignedLong max_channel_count(); WebIDL::UnsignedLong number_of_inputs() override { return 1; } WebIDL::UnsignedLong number_of_outputs() override { return 1; } + WebIDL::ExceptionOr set_channel_count(WebIDL::UnsignedLong) override; static JS::NonnullGCPtr construct_impl(JS::Realm&, JS::NonnullGCPtr); diff --git a/Userland/Libraries/LibWeb/WebAudio/AudioNode.cpp b/Userland/Libraries/LibWeb/WebAudio/AudioNode.cpp index fcb3284cce2..9580d53d8ca 100644 --- a/Userland/Libraries/LibWeb/WebAudio/AudioNode.cpp +++ b/Userland/Libraries/LibWeb/WebAudio/AudioNode.cpp @@ -101,15 +101,13 @@ void AudioNode::disconnect(JS::NonnullGCPtr destination_param, WebID // https://webaudio.github.io/web-audio-api/#dom-audionode-channelcount WebIDL::ExceptionOr AudioNode::set_channel_count(WebIDL::UnsignedLong channel_count) { - (void)channel_count; - return WebIDL::NotSupportedError::create(realm(), "FIXME: Implement AudioNode::set_channel_count(channel_count)"_fly_string); -} + // If this value is set to zero or to a value greater than the implementation’s maximum number + // of channels the implementation MUST throw a NotSupportedError exception. + if (channel_count == 0 || channel_count > BaseAudioContext::MAX_NUMBER_OF_CHANNELS) + return WebIDL::NotSupportedError::create(realm(), "Invalid channel count"_fly_string); -// https://webaudio.github.io/web-audio-api/#dom-audionode-channelcount -WebIDL::UnsignedLong AudioNode::channel_count() -{ - dbgln("FIXME: Implement AudioNode::channel_count()"); - return 2; + m_channel_count = channel_count; + return {}; } // https://webaudio.github.io/web-audio-api/#dom-audionode-channelcountmode diff --git a/Userland/Libraries/LibWeb/WebAudio/AudioNode.h b/Userland/Libraries/LibWeb/WebAudio/AudioNode.h index 1f09f0ab7d5..5cdd3c7c511 100644 --- a/Userland/Libraries/LibWeb/WebAudio/AudioNode.h +++ b/Userland/Libraries/LibWeb/WebAudio/AudioNode.h @@ -53,8 +53,10 @@ public: // https://webaudio.github.io/web-audio-api/#dom-audionode-numberofoutputs virtual WebIDL::UnsignedLong number_of_outputs() = 0; - WebIDL::ExceptionOr set_channel_count(WebIDL::UnsignedLong); - WebIDL::UnsignedLong channel_count(); + // https://webaudio.github.io/web-audio-api/#dom-audionode-channelcount + virtual WebIDL::ExceptionOr set_channel_count(WebIDL::UnsignedLong); + virtual WebIDL::UnsignedLong channel_count() const { return m_channel_count; } + WebIDL::ExceptionOr set_channel_count_mode(Bindings::ChannelCountMode); Bindings::ChannelCountMode channel_count_mode(); WebIDL::ExceptionOr set_channel_interpretation(Bindings::ChannelInterpretation); @@ -68,6 +70,7 @@ protected: private: JS::NonnullGCPtr m_context; + WebIDL::UnsignedLong m_channel_count { 2 }; Bindings::ChannelCountMode m_channel_count_mode { Bindings::ChannelCountMode::Max }; Bindings::ChannelInterpretation m_channel_interpretation { Bindings::ChannelInterpretation::Speakers }; };