diff --git a/Userland/Libraries/LibWeb/WebAudio/BaseAudioContext.cpp b/Userland/Libraries/LibWeb/WebAudio/BaseAudioContext.cpp index f9bfce66c46..5743109773d 100644 --- a/Userland/Libraries/LibWeb/WebAudio/BaseAudioContext.cpp +++ b/Userland/Libraries/LibWeb/WebAudio/BaseAudioContext.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2023, Luke Wilde + * Copyright (c) 2024, Shannon Booth * * SPDX-License-Identifier: BSD-2-Clause */ @@ -33,4 +34,24 @@ WebIDL::CallbackType* BaseAudioContext::onstatechange() return event_handler_attribute(HTML::EventNames::statechange); } +// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createbuffer +WebIDL::ExceptionOr BaseAudioContext::verify_audio_options_inside_nominal_range(JS::Realm& realm, WebIDL::UnsignedLong number_of_channels, WebIDL::UnsignedLong length, float sample_rate) +{ + // A NotSupportedError exception MUST be thrown if any of the arguments is negative, zero, or outside its nominal range. + + if (number_of_channels == 0) + return WebIDL::NotSupportedError::create(realm, "Number of channels must not be '0'"_fly_string); + + if (number_of_channels > MAX_NUMBER_OF_CHANNELS) + return WebIDL::NotSupportedError::create(realm, "Number of channels is greater than allowed range"_fly_string); + + if (length == 0) + return WebIDL::NotSupportedError::create(realm, "Length of buffer must be at least 1"_fly_string); + + if (sample_rate < MIN_SAMPLE_RATE || sample_rate > MAX_SAMPLE_RATE) + return WebIDL::NotSupportedError::create(realm, "Sample rate is outside of allowed range"_fly_string); + + return {}; +} + } diff --git a/Userland/Libraries/LibWeb/WebAudio/BaseAudioContext.h b/Userland/Libraries/LibWeb/WebAudio/BaseAudioContext.h index a9e80dcd12b..36cb826c37e 100644 --- a/Userland/Libraries/LibWeb/WebAudio/BaseAudioContext.h +++ b/Userland/Libraries/LibWeb/WebAudio/BaseAudioContext.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2023, Luke Wilde + * Copyright (c) 2024, Shannon Booth * * SPDX-License-Identifier: BSD-2-Clause */ @@ -8,6 +9,7 @@ #include #include +#include namespace Web::WebAudio { @@ -18,6 +20,17 @@ class BaseAudioContext : public DOM::EventTarget { public: virtual ~BaseAudioContext() override; + // https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createbuffer-numberofchannels + // > An implementation MUST support at least 32 channels. + // Other browsers appear to only allow 32 channels - so let's limit ourselves to that too. + static constexpr WebIDL::UnsignedLong MAX_NUMBER_OF_CHANNELS { 32 }; + + // https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createbuffer-samplerate + // > An implementation MUST support sample rates in at least the range 8000 to 96000. + // This doesn't seem consistent between browsers. We use what firefox accepts from testing BaseAudioContext.createAudioBuffer. + static constexpr float MIN_SAMPLE_RATE { 8000 }; + static constexpr float MAX_SAMPLE_RATE { 192000 }; + float sample_rate() const { return m_sample_rate; } double current_time() const { return m_current_time; } Bindings::AudioContextState state() const { return m_control_thread_state; } @@ -29,6 +42,8 @@ public: void set_control_state(Bindings::AudioContextState state) { m_control_thread_state = state; } void set_rendering_state(Bindings::AudioContextState state) { m_rendering_thread_state = state; } + static WebIDL::ExceptionOr verify_audio_options_inside_nominal_range(JS::Realm&, WebIDL::UnsignedLong number_of_channels, WebIDL::UnsignedLong length, float sample_rate); + protected: explicit BaseAudioContext(JS::Realm&);