webaudio: Throw when setting invalid automationRate on AudioBufferSourceNode (#26469)

This commit is contained in:
Shamir Khodzha 2024-02-28 22:24:08 +01:00 committed by GitHub
parent 5c87fe940e
commit 201cdbab17
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 56 additions and 22 deletions

View file

@ -10,7 +10,7 @@ use js::rust::HandleObject;
use servo_media::audio::buffer_source_node::{ use servo_media::audio::buffer_source_node::{
AudioBufferSourceNodeMessage, AudioBufferSourceNodeOptions, AudioBufferSourceNodeMessage, AudioBufferSourceNodeOptions,
}; };
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage}; use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioNodeType};
use servo_media::audio::param::ParamType; use servo_media::audio::param::ParamType;
use crate::dom::audiobuffer::AudioBuffer; use crate::dom::audiobuffer::AudioBuffer;
@ -61,6 +61,7 @@ impl AudioBufferSourceNode {
&window, &window,
context, context,
node_id, node_id,
AudioNodeType::AudioBufferSourceNode,
ParamType::PlaybackRate, ParamType::PlaybackRate,
AutomationRate::K_rate, AutomationRate::K_rate,
*options.playbackRate, *options.playbackRate,
@ -71,6 +72,7 @@ impl AudioBufferSourceNode {
&window, &window,
context, context,
node_id, node_id,
AudioNodeType::AudioBufferSourceNode,
ParamType::Detune, ParamType::Detune,
AutomationRate::K_rate, AutomationRate::K_rate,
*options.detune, *options.detune,

View file

@ -5,6 +5,7 @@
use std::f32; use std::f32;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use servo_media::audio::node::AudioNodeType;
use servo_media::audio::param::{ParamDir, ParamType}; use servo_media::audio::param::{ParamDir, ParamType};
use crate::dom::audioparam::AudioParam; use crate::dom::audioparam::AudioParam;
@ -41,6 +42,7 @@ impl AudioListener {
window, window,
context, context,
node, node,
AudioNodeType::AudioListenerNode,
ParamType::Position(ParamDir::X), ParamType::Position(ParamDir::X),
AutomationRate::A_rate, AutomationRate::A_rate,
0., // default value 0., // default value
@ -51,6 +53,7 @@ impl AudioListener {
window, window,
context, context,
node, node,
AudioNodeType::AudioListenerNode,
ParamType::Position(ParamDir::Y), ParamType::Position(ParamDir::Y),
AutomationRate::A_rate, AutomationRate::A_rate,
0., // default value 0., // default value
@ -61,6 +64,7 @@ impl AudioListener {
window, window,
context, context,
node, node,
AudioNodeType::AudioListenerNode,
ParamType::Position(ParamDir::Z), ParamType::Position(ParamDir::Z),
AutomationRate::A_rate, AutomationRate::A_rate,
0., // default value 0., // default value
@ -71,6 +75,7 @@ impl AudioListener {
window, window,
context, context,
node, node,
AudioNodeType::AudioListenerNode,
ParamType::Forward(ParamDir::X), ParamType::Forward(ParamDir::X),
AutomationRate::A_rate, AutomationRate::A_rate,
0., // default value 0., // default value
@ -81,6 +86,7 @@ impl AudioListener {
window, window,
context, context,
node, node,
AudioNodeType::AudioListenerNode,
ParamType::Forward(ParamDir::Y), ParamType::Forward(ParamDir::Y),
AutomationRate::A_rate, AutomationRate::A_rate,
0., // default value 0., // default value
@ -91,6 +97,7 @@ impl AudioListener {
window, window,
context, context,
node, node,
AudioNodeType::AudioListenerNode,
ParamType::Forward(ParamDir::Z), ParamType::Forward(ParamDir::Z),
AutomationRate::A_rate, AutomationRate::A_rate,
-1., // default value -1., // default value
@ -101,6 +108,7 @@ impl AudioListener {
window, window,
context, context,
node, node,
AudioNodeType::AudioListenerNode,
ParamType::Up(ParamDir::X), ParamType::Up(ParamDir::X),
AutomationRate::A_rate, AutomationRate::A_rate,
0., // default value 0., // default value
@ -111,6 +119,7 @@ impl AudioListener {
window, window,
context, context,
node, node,
AudioNodeType::AudioListenerNode,
ParamType::Up(ParamDir::Y), ParamType::Up(ParamDir::Y),
AutomationRate::A_rate, AutomationRate::A_rate,
1., // default value 1., // default value
@ -121,6 +130,7 @@ impl AudioListener {
window, window,
context, context,
node, node,
AudioNodeType::AudioListenerNode,
ParamType::Up(ParamDir::Z), ParamType::Up(ParamDir::Z),
AutomationRate::A_rate, AutomationRate::A_rate,
0., // default value 0., // default value

View file

@ -7,7 +7,7 @@ use std::sync::mpsc;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use servo_media::audio::graph::NodeId; use servo_media::audio::graph::NodeId;
use servo_media::audio::node::AudioNodeMessage; use servo_media::audio::node::{AudioNodeMessage, AudioNodeType};
use servo_media::audio::param::{ParamRate, ParamType, RampKind, UserAutomationEvent}; use servo_media::audio::param::{ParamRate, ParamType, RampKind, UserAutomationEvent};
use crate::dom::baseaudiocontext::BaseAudioContext; use crate::dom::baseaudiocontext::BaseAudioContext;
@ -29,6 +29,9 @@ pub struct AudioParam {
node: NodeId, node: NodeId,
#[ignore_malloc_size_of = "servo_media"] #[ignore_malloc_size_of = "servo_media"]
#[no_trace] #[no_trace]
node_type: AudioNodeType,
#[ignore_malloc_size_of = "servo_media"]
#[no_trace]
param: ParamType, param: ParamType,
automation_rate: Cell<AutomationRate>, automation_rate: Cell<AutomationRate>,
default_value: f32, default_value: f32,
@ -40,6 +43,7 @@ impl AudioParam {
pub fn new_inherited( pub fn new_inherited(
context: &BaseAudioContext, context: &BaseAudioContext,
node: NodeId, node: NodeId,
node_type: AudioNodeType,
param: ParamType, param: ParamType,
automation_rate: AutomationRate, automation_rate: AutomationRate,
default_value: f32, default_value: f32,
@ -50,6 +54,7 @@ impl AudioParam {
reflector_: Reflector::new(), reflector_: Reflector::new(),
context: Dom::from_ref(context), context: Dom::from_ref(context),
node, node,
node_type,
param, param,
automation_rate: Cell::new(automation_rate), automation_rate: Cell::new(automation_rate),
default_value, default_value,
@ -63,6 +68,7 @@ impl AudioParam {
window: &Window, window: &Window,
context: &BaseAudioContext, context: &BaseAudioContext,
node: NodeId, node: NodeId,
node_type: AudioNodeType,
param: ParamType, param: ParamType,
automation_rate: AutomationRate, automation_rate: AutomationRate,
default_value: f32, default_value: f32,
@ -72,6 +78,7 @@ impl AudioParam {
let audio_param = AudioParam::new_inherited( let audio_param = AudioParam::new_inherited(
context, context,
node, node,
node_type,
param, param,
automation_rate, automation_rate,
default_value, default_value,
@ -109,12 +116,24 @@ impl AudioParamMethods for AudioParam {
} }
// https://webaudio.github.io/web-audio-api/#dom-audioparam-automationrate // https://webaudio.github.io/web-audio-api/#dom-audioparam-automationrate
fn SetAutomationRate(&self, automation_rate: AutomationRate) { fn SetAutomationRate(&self, automation_rate: AutomationRate) -> Fallible<()> {
// > AudioBufferSourceNode
// > The AudioParams playbackRate and detune MUST be "k-rate". An InvalidStateError must be
// > thrown if the rate is changed to "a-rate".
if automation_rate == AutomationRate::A_rate &&
self.node_type == AudioNodeType::AudioBufferSourceNode &&
(self.param == ParamType::Detune || self.param == ParamType::PlaybackRate)
{
return Err(Error::InvalidState);
}
self.automation_rate.set(automation_rate); self.automation_rate.set(automation_rate);
self.message_node(AudioNodeMessage::SetParamRate( self.message_node(AudioNodeMessage::SetParamRate(
self.param, self.param,
automation_rate.into(), automation_rate.into(),
)); ));
Ok(())
} }
// https://webaudio.github.io/web-audio-api/#dom-audioparam-value // https://webaudio.github.io/web-audio-api/#dom-audioparam-value

View file

@ -10,7 +10,7 @@ use js::rust::HandleObject;
use servo_media::audio::biquad_filter_node::{ use servo_media::audio::biquad_filter_node::{
BiquadFilterNodeMessage, BiquadFilterNodeOptions, FilterType, BiquadFilterNodeMessage, BiquadFilterNodeOptions, FilterType,
}; };
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage}; use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioNodeType};
use servo_media::audio::param::ParamType; use servo_media::audio::param::ParamType;
use crate::dom::audionode::AudioNode; use crate::dom::audionode::AudioNode;
@ -62,6 +62,7 @@ impl BiquadFilterNode {
window, window,
context, context,
node.node_id(), node.node_id(),
AudioNodeType::BiquadFilterNode,
ParamType::Gain, ParamType::Gain,
AutomationRate::A_rate, AutomationRate::A_rate,
options.gain, // default value options.gain, // default value
@ -72,6 +73,7 @@ impl BiquadFilterNode {
window, window,
context, context,
node.node_id(), node.node_id(),
AudioNodeType::BiquadFilterNode,
ParamType::Q, ParamType::Q,
AutomationRate::A_rate, AutomationRate::A_rate,
options.q, // default value options.q, // default value
@ -82,6 +84,7 @@ impl BiquadFilterNode {
window, window,
context, context,
node.node_id(), node.node_id(),
AudioNodeType::BiquadFilterNode,
ParamType::Frequency, ParamType::Frequency,
AutomationRate::A_rate, AutomationRate::A_rate,
options.frequency, // default value options.frequency, // default value
@ -92,6 +95,7 @@ impl BiquadFilterNode {
window, window,
context, context,
node.node_id(), node.node_id(),
AudioNodeType::BiquadFilterNode,
ParamType::Detune, ParamType::Detune,
AutomationRate::A_rate, AutomationRate::A_rate,
options.detune, // default value options.detune, // default value

View file

@ -7,7 +7,7 @@ use std::f32;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use js::rust::HandleObject; use js::rust::HandleObject;
use servo_media::audio::constant_source_node::ConstantSourceNodeOptions as ServoMediaConstantSourceOptions; use servo_media::audio::constant_source_node::ConstantSourceNodeOptions as ServoMediaConstantSourceOptions;
use servo_media::audio::node::AudioNodeInit; use servo_media::audio::node::{AudioNodeInit, AudioNodeType};
use servo_media::audio::param::ParamType; use servo_media::audio::param::ParamType;
use crate::dom::audioparam::AudioParam; use crate::dom::audioparam::AudioParam;
@ -48,6 +48,7 @@ impl ConstantSourceNode {
window, window,
context, context,
node_id, node_id,
AudioNodeType::ConstantSourceNode,
ParamType::Offset, ParamType::Offset,
AutomationRate::A_rate, AutomationRate::A_rate,
*options.offset, *options.offset,

View file

@ -7,7 +7,7 @@ use std::f32;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use js::rust::HandleObject; use js::rust::HandleObject;
use servo_media::audio::gain_node::GainNodeOptions; use servo_media::audio::gain_node::GainNodeOptions;
use servo_media::audio::node::AudioNodeInit; use servo_media::audio::node::{AudioNodeInit, AudioNodeType};
use servo_media::audio::param::ParamType; use servo_media::audio::param::ParamType;
use crate::dom::audionode::AudioNode; use crate::dom::audionode::AudioNode;
@ -51,6 +51,7 @@ impl GainNode {
window, window,
context, context,
node.node_id(), node.node_id(),
AudioNodeType::GainNode,
ParamType::Gain, ParamType::Gain,
AutomationRate::A_rate, AutomationRate::A_rate,
*options.gain, // default value *options.gain, // default value

View file

@ -7,7 +7,7 @@ use std::f32;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use js::rust::HandleObject; use js::rust::HandleObject;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage}; use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioNodeType};
use servo_media::audio::oscillator_node::{ use servo_media::audio::oscillator_node::{
OscillatorNodeMessage, OscillatorNodeOptions as ServoMediaOscillatorOptions, OscillatorNodeMessage, OscillatorNodeOptions as ServoMediaOscillatorOptions,
OscillatorType as ServoMediaOscillatorType, OscillatorType as ServoMediaOscillatorType,
@ -60,6 +60,7 @@ impl OscillatorNode {
window, window,
context, context,
node_id, node_id,
AudioNodeType::OscillatorNode,
ParamType::Frequency, ParamType::Frequency,
AutomationRate::A_rate, AutomationRate::A_rate,
440., 440.,
@ -70,6 +71,7 @@ impl OscillatorNode {
window, window,
context, context,
node_id, node_id,
AudioNodeType::OscillatorNode,
ParamType::Detune, ParamType::Detune,
AutomationRate::A_rate, AutomationRate::A_rate,
0., 0.,

View file

@ -7,7 +7,7 @@ use std::f32;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use js::rust::HandleObject; use js::rust::HandleObject;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage}; use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioNodeType};
use servo_media::audio::panner_node::{ use servo_media::audio::panner_node::{
DistanceModel, PannerNodeMessage, PannerNodeOptions, PanningModel, DistanceModel, PannerNodeMessage, PannerNodeOptions, PanningModel,
}; };
@ -98,6 +98,7 @@ impl PannerNode {
window, window,
context, context,
id, id,
AudioNodeType::PannerNode,
ParamType::Position(ParamDir::X), ParamType::Position(ParamDir::X),
AutomationRate::A_rate, AutomationRate::A_rate,
options.position_x, // default value options.position_x, // default value
@ -108,6 +109,7 @@ impl PannerNode {
window, window,
context, context,
id, id,
AudioNodeType::PannerNode,
ParamType::Position(ParamDir::Y), ParamType::Position(ParamDir::Y),
AutomationRate::A_rate, AutomationRate::A_rate,
options.position_y, // default value options.position_y, // default value
@ -118,6 +120,7 @@ impl PannerNode {
window, window,
context, context,
id, id,
AudioNodeType::PannerNode,
ParamType::Position(ParamDir::Z), ParamType::Position(ParamDir::Z),
AutomationRate::A_rate, AutomationRate::A_rate,
options.position_z, // default value options.position_z, // default value
@ -128,6 +131,7 @@ impl PannerNode {
window, window,
context, context,
id, id,
AudioNodeType::PannerNode,
ParamType::Orientation(ParamDir::X), ParamType::Orientation(ParamDir::X),
AutomationRate::A_rate, AutomationRate::A_rate,
options.orientation_x, // default value options.orientation_x, // default value
@ -138,6 +142,7 @@ impl PannerNode {
window, window,
context, context,
id, id,
AudioNodeType::PannerNode,
ParamType::Orientation(ParamDir::Y), ParamType::Orientation(ParamDir::Y),
AutomationRate::A_rate, AutomationRate::A_rate,
options.orientation_y, // default value options.orientation_y, // default value
@ -148,6 +153,7 @@ impl PannerNode {
window, window,
context, context,
id, id,
AudioNodeType::PannerNode,
ParamType::Orientation(ParamDir::Z), ParamType::Orientation(ParamDir::Z),
AutomationRate::A_rate, AutomationRate::A_rate,
options.orientation_z, // default value options.orientation_z, // default value

View file

@ -4,7 +4,7 @@
use dom_struct::dom_struct; use dom_struct::dom_struct;
use js::rust::HandleObject; use js::rust::HandleObject;
use servo_media::audio::node::AudioNodeInit; use servo_media::audio::node::{AudioNodeInit, AudioNodeType};
use servo_media::audio::param::ParamType; use servo_media::audio::param::ParamType;
use servo_media::audio::stereo_panner::StereoPannerOptions as ServoMediaStereoPannerOptions; use servo_media::audio::stereo_panner::StereoPannerOptions as ServoMediaStereoPannerOptions;
@ -59,6 +59,7 @@ impl StereoPannerNode {
window, window,
context, context,
node_id, node_id,
AudioNodeType::StereoPannerNode,
ParamType::Pan, ParamType::Pan,
AutomationRate::A_rate, AutomationRate::A_rate,
*options.pan, *options.pan,

View file

@ -14,7 +14,7 @@ enum AutomationRate {
[Exposed=Window] [Exposed=Window]
interface AudioParam { interface AudioParam {
attribute float value; attribute float value;
attribute AutomationRate automationRate; [SetterThrows] attribute AutomationRate automationRate;
readonly attribute float defaultValue; readonly attribute float defaultValue;
readonly attribute float minValue; readonly attribute float minValue;
readonly attribute float maxValue; readonly attribute float maxValue;

View file

@ -2,12 +2,6 @@
[< [AudioBufferSourceNode\] 2 out of 4 assertions were failed.] [< [AudioBufferSourceNode\] 2 out of 4 assertions were failed.]
expected: FAIL expected: FAIL
[X Set AudioBufferSourceNode.detune.automationRate to "a-rate" did not throw an exception.]
expected: FAIL
[X Set AudioBufferSourceNode.playbackRate.automationRate to "a-rate" did not throw an exception.]
expected: FAIL
[Executing "DelayNode"] [Executing "DelayNode"]
expected: FAIL expected: FAIL

View file

@ -5,12 +5,6 @@
[Executing "DynamicsCompressorNode"] [Executing "DynamicsCompressorNode"]
expected: FAIL expected: FAIL
[X Set AudioBufferSourceNode.detune.automationRate to "a-rate" did not throw an exception.]
expected: FAIL
[X Set AudioBufferSourceNode.playbackRate.automationRate to "a-rate" did not throw an exception.]
expected: FAIL
[< [AudioBufferSourceNode\] 2 out of 4 assertions were failed.] [< [AudioBufferSourceNode\] 2 out of 4 assertions were failed.]
expected: FAIL expected: FAIL