mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Use new params impl (#4)
* AudioNodeType -> AudioNodeInit * Use new param type system, clean up
This commit is contained in:
parent
8f9a081ff0
commit
f0d04249f9
9 changed files with 113 additions and 146 deletions
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use dom::audiobuffer::AudioBuffer;
|
||||
use dom::audioparam::{AudioParam, AudioParamImpl};
|
||||
use dom::audioparam::AudioParam;
|
||||
use dom::audioscheduledsourcenode::AudioScheduledSourceNode;
|
||||
use dom::baseaudiocontext::BaseAudioContext;
|
||||
use dom::bindings::codegen::Bindings::AudioBufferSourceNodeBinding;
|
||||
|
@ -23,16 +23,10 @@ use dom::window::Window;
|
|||
use dom_struct::dom_struct;
|
||||
use servo_media::audio::buffer_source_node::AudioBufferSourceNodeMessage;
|
||||
use servo_media::audio::buffer_source_node::AudioBufferSourceNodeOptions;
|
||||
use servo_media::audio::context::AudioContext;
|
||||
use servo_media::audio::graph::NodeId;
|
||||
use servo_media::audio::node::{AudioNodeMessage, AudioNodeType};
|
||||
use servo_media::audio::param::{UserAutomationEvent, RampKind};
|
||||
use servo_media::audio::node::{AudioNodeMessage, AudioNodeInit};
|
||||
use servo_media::audio::param::ParamType;
|
||||
use std::cell::Cell;
|
||||
use std::f32;
|
||||
use std::rc::Rc;
|
||||
|
||||
audio_param_impl!(PlaybackRate, AudioBufferSourceNode, AudioBufferSourceNodeMessage, SetPlaybackRate);
|
||||
audio_param_impl!(Detune, AudioBufferSourceNode, AudioBufferSourceNodeMessage, SetDetune);
|
||||
|
||||
#[dom_struct]
|
||||
pub struct AudioBufferSourceNode {
|
||||
|
@ -57,22 +51,24 @@ impl AudioBufferSourceNode {
|
|||
node_options.channelCountMode = Some(ChannelCountMode::Max);
|
||||
node_options.channelInterpretation = Some(ChannelInterpretation::Speakers);
|
||||
let source_node = AudioScheduledSourceNode::new_inherited(
|
||||
AudioNodeType::AudioBufferSourceNode(options.into()),
|
||||
AudioNodeInit::AudioBufferSourceNode(options.into()),
|
||||
context,
|
||||
&node_options,
|
||||
0 /* inputs */,
|
||||
1 /* outputs */,
|
||||
);
|
||||
let node_id = source_node.node().node_id();
|
||||
let playback_rate = PlaybackRate::new(context.audio_context_impl(), node_id);
|
||||
let playback_rate = AudioParam::new(&window,
|
||||
Box::new(playback_rate),
|
||||
context,
|
||||
node_id,
|
||||
ParamType::PlaybackRate,
|
||||
AutomationRate::K_rate,
|
||||
*options.playbackRate,
|
||||
f32::MIN, f32::MAX);
|
||||
let detune = Detune::new(context.audio_context_impl(), node_id);
|
||||
let detune = AudioParam::new(&window,
|
||||
Box::new(detune),
|
||||
context,
|
||||
node_id,
|
||||
ParamType::Detune,
|
||||
AutomationRate::K_rate,
|
||||
*options.detune,
|
||||
f32::MIN, f32::MAX);
|
||||
|
|
|
@ -10,7 +10,7 @@ use dom::bindings::reflector::reflect_dom_object;
|
|||
use dom::bindings::root::DomRoot;
|
||||
use dom::globalscope::GlobalScope;
|
||||
use dom_struct::dom_struct;
|
||||
use servo_media::audio::node::AudioNodeType;
|
||||
use servo_media::audio::node::AudioNodeInit;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct AudioDestinationNode {
|
||||
|
@ -21,7 +21,7 @@ impl AudioDestinationNode {
|
|||
fn new_inherited(context: &BaseAudioContext,
|
||||
options: &AudioNodeOptions) -> AudioDestinationNode {
|
||||
AudioDestinationNode {
|
||||
node: AudioNode::new_inherited(AudioNodeType::DestinationNode,
|
||||
node: AudioNode::new_inherited(AudioNodeInit::DestinationNode,
|
||||
Some(context.destination_node()),
|
||||
context, options, 1, 1),
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ use dom::audioparam::AudioParam;
|
|||
use dom::eventtarget::EventTarget;
|
||||
use dom_struct::dom_struct;
|
||||
use servo_media::audio::graph::NodeId;
|
||||
use servo_media::audio::node::{AudioNodeMessage, AudioNodeType};
|
||||
use servo_media::audio::node::{AudioNodeMessage, AudioNodeInit};
|
||||
use std::cell::Cell;
|
||||
|
||||
// 32 is the minimum required by the spec for createBuffer() and the deprecated
|
||||
|
@ -33,7 +33,7 @@ pub struct AudioNode {
|
|||
}
|
||||
|
||||
impl AudioNode {
|
||||
pub fn new_inherited(node_type: AudioNodeType,
|
||||
pub fn new_inherited(node_type: AudioNodeInit,
|
||||
node_id: Option<NodeId>,
|
||||
context: &BaseAudioContext,
|
||||
options: &AudioNodeOptions,
|
||||
|
|
|
@ -2,31 +2,27 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use dom::baseaudiocontext::BaseAudioContext;
|
||||
use dom::bindings::codegen::Bindings::AudioParamBinding;
|
||||
use dom::bindings::codegen::Bindings::AudioParamBinding::{AudioParamMethods, AutomationRate};
|
||||
use dom::bindings::num::Finite;
|
||||
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||
use dom::bindings::root::DomRoot;
|
||||
use dom::bindings::trace::JSTraceable;
|
||||
use dom::bindings::root::{Dom, DomRoot};
|
||||
use dom::window::Window;
|
||||
use dom_struct::dom_struct;
|
||||
use malloc_size_of::MallocSizeOf;
|
||||
use servo_media::audio::param::RampKind;
|
||||
use servo_media::audio::graph::NodeId;
|
||||
use servo_media::audio::node::AudioNodeMessage;
|
||||
use servo_media::audio::param::{ParamType, RampKind, UserAutomationEvent};
|
||||
use std::cell::Cell;
|
||||
|
||||
pub trait AudioParamImpl: JSTraceable + MallocSizeOf {
|
||||
fn set_value(&self, value: f32);
|
||||
fn set_value_at_time(&self, value: f32, start_time: f64);
|
||||
fn ramp_to_value_at_time(&self, ramp_kind: RampKind, value: f32, end_time: f64);
|
||||
fn set_target_at_time(&self, value: f32, start_time: f64, time_constant: f32);
|
||||
fn cancel_scheduled_values(&self, cancel_time: f64);
|
||||
fn cancel_and_hold_at_time(&self, cancel_time: f64);
|
||||
}
|
||||
|
||||
#[dom_struct]
|
||||
pub struct AudioParam {
|
||||
reflector_: Reflector,
|
||||
param_impl: Box<AudioParamImpl>,
|
||||
context: Dom<BaseAudioContext>,
|
||||
#[ignore_malloc_size_of = "servo_media"]
|
||||
node: NodeId,
|
||||
#[ignore_malloc_size_of = "servo_media"]
|
||||
param: ParamType,
|
||||
automation_rate: Cell<AutomationRate>,
|
||||
default_value: f32,
|
||||
min_value: f32,
|
||||
|
@ -34,14 +30,18 @@ pub struct AudioParam {
|
|||
}
|
||||
|
||||
impl AudioParam {
|
||||
pub fn new_inherited(param_impl: Box<AudioParamImpl>,
|
||||
pub fn new_inherited(context: &BaseAudioContext,
|
||||
node: NodeId,
|
||||
param: ParamType,
|
||||
automation_rate: AutomationRate,
|
||||
default_value: f32,
|
||||
min_value: f32,
|
||||
max_value: f32) -> AudioParam {
|
||||
AudioParam {
|
||||
reflector_: Reflector::new(),
|
||||
param_impl,
|
||||
context: Dom::from_ref(context),
|
||||
node,
|
||||
param,
|
||||
automation_rate: Cell::new(automation_rate),
|
||||
default_value,
|
||||
min_value,
|
||||
|
@ -51,12 +51,14 @@ impl AudioParam {
|
|||
|
||||
#[allow(unrooted_must_root)]
|
||||
pub fn new(window: &Window,
|
||||
param_impl: Box<AudioParamImpl>,
|
||||
context: &BaseAudioContext,
|
||||
node: NodeId,
|
||||
param: ParamType,
|
||||
automation_rate: AutomationRate,
|
||||
default_value: f32,
|
||||
min_value: f32,
|
||||
max_value: f32) -> DomRoot<AudioParam> {
|
||||
let audio_param = AudioParam::new_inherited(param_impl, automation_rate,
|
||||
let audio_param = AudioParam::new_inherited(context, node, param, automation_rate,
|
||||
default_value, min_value, max_value);
|
||||
reflect_dom_object(Box::new(audio_param), window, AudioParamBinding::Wrap)
|
||||
}
|
||||
|
@ -78,7 +80,14 @@ impl AudioParamMethods for AudioParam {
|
|||
}
|
||||
|
||||
fn SetValue(&self, value: Finite<f32>) {
|
||||
self.param_impl.set_value(*value);
|
||||
self.context.audio_context_impl()
|
||||
.message_node(self.node,
|
||||
AudioNodeMessage::SetParam(self.param,
|
||||
UserAutomationEvent::SetValue(
|
||||
*value
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
fn DefaultValue(&self) -> Finite<f32> {
|
||||
|
@ -96,38 +105,80 @@ impl AudioParamMethods for AudioParam {
|
|||
fn SetValueAtTime(&self, value: Finite<f32>, start_time: Finite<f64>)
|
||||
-> DomRoot<AudioParam>
|
||||
{
|
||||
self.param_impl.set_value_at_time(*value, *start_time);
|
||||
self.context.audio_context_impl()
|
||||
.message_node(self.node,
|
||||
AudioNodeMessage::SetParam(self.param,
|
||||
UserAutomationEvent::SetValueAtTime(
|
||||
*value, *start_time
|
||||
)
|
||||
)
|
||||
);
|
||||
DomRoot::from_ref(self)
|
||||
}
|
||||
|
||||
fn LinearRampToValueAtTime(&self, value: Finite<f32>, end_time: Finite<f64>)
|
||||
-> DomRoot<AudioParam>
|
||||
{
|
||||
self.param_impl.ramp_to_value_at_time(RampKind::Linear, *value, *end_time);
|
||||
self.context.audio_context_impl()
|
||||
.message_node(self.node,
|
||||
AudioNodeMessage::SetParam(self.param,
|
||||
UserAutomationEvent::RampToValueAtTime(
|
||||
RampKind::Linear, *value, *end_time
|
||||
)
|
||||
)
|
||||
);
|
||||
DomRoot::from_ref(self)
|
||||
}
|
||||
|
||||
fn ExponentialRampToValueAtTime(&self, value: Finite<f32>, end_time: Finite<f64>)
|
||||
-> DomRoot<AudioParam>
|
||||
{
|
||||
self.param_impl.ramp_to_value_at_time(RampKind::Exponential, *value, *end_time);
|
||||
self.context.audio_context_impl()
|
||||
.message_node(self.node,
|
||||
AudioNodeMessage::SetParam(self.param,
|
||||
UserAutomationEvent::RampToValueAtTime(
|
||||
RampKind::Exponential, *value, *end_time
|
||||
)
|
||||
)
|
||||
);
|
||||
DomRoot::from_ref(self)
|
||||
}
|
||||
|
||||
fn SetTargetAtTime(&self, target: Finite<f32>, start_time: Finite<f64>, time_constant: Finite<f32>)
|
||||
-> DomRoot<AudioParam>
|
||||
{
|
||||
self.param_impl.set_target_at_time(*target, *start_time, *time_constant);
|
||||
self.context.audio_context_impl()
|
||||
.message_node(self.node,
|
||||
AudioNodeMessage::SetParam(self.param,
|
||||
UserAutomationEvent::SetTargetAtTime(
|
||||
*target, *start_time, (*time_constant).into()
|
||||
)
|
||||
)
|
||||
);
|
||||
DomRoot::from_ref(self)
|
||||
}
|
||||
|
||||
fn CancelScheduledValues(&self, cancel_time: Finite<f64>) -> DomRoot<AudioParam> {
|
||||
self.param_impl.cancel_scheduled_values(*cancel_time);
|
||||
self.context.audio_context_impl()
|
||||
.message_node(self.node,
|
||||
AudioNodeMessage::SetParam(self.param,
|
||||
UserAutomationEvent::CancelScheduledValues(
|
||||
*cancel_time
|
||||
)
|
||||
)
|
||||
);
|
||||
DomRoot::from_ref(self)
|
||||
}
|
||||
|
||||
fn CancelAndHoldAtTime(&self, cancel_time: Finite<f64>) -> DomRoot<AudioParam> {
|
||||
self.param_impl.cancel_and_hold_at_time(*cancel_time);
|
||||
self.context.audio_context_impl()
|
||||
.message_node(self.node,
|
||||
AudioNodeMessage::SetParam(self.param,
|
||||
UserAutomationEvent::CancelAndHoldAtTime(
|
||||
*cancel_time
|
||||
)
|
||||
)
|
||||
);
|
||||
DomRoot::from_ref(self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::AudioNodeBinding::AudioNodeOptions;
|
|||
use dom::bindings::error::{Error, Fallible};
|
||||
use dom::bindings::num::Finite;
|
||||
use dom_struct::dom_struct;
|
||||
use servo_media::audio::node::{AudioNodeMessage, AudioNodeType, AudioScheduledSourceNodeMessage};
|
||||
use servo_media::audio::node::{AudioNodeMessage, AudioNodeInit, AudioScheduledSourceNodeMessage};
|
||||
use std::cell::Cell;
|
||||
|
||||
#[dom_struct]
|
||||
|
@ -19,7 +19,7 @@ pub struct AudioScheduledSourceNode {
|
|||
}
|
||||
|
||||
impl AudioScheduledSourceNode {
|
||||
pub fn new_inherited(node_type: AudioNodeType,
|
||||
pub fn new_inherited(node_type: AudioNodeInit,
|
||||
context: &BaseAudioContext,
|
||||
options: &AudioNodeOptions,
|
||||
number_of_inputs: u32,
|
||||
|
|
|
@ -83,6 +83,7 @@ use profile_traits::time::ProfilerChan as TimeProfilerChan;
|
|||
use servo_media::audio::buffer_source_node::AudioBuffer;
|
||||
use servo_media::audio::context::AudioContext;
|
||||
use servo_media::audio::graph::NodeId;
|
||||
use servo_media::audio::param::ParamType;
|
||||
use script_layout_interface::OpaqueStyleAndLayoutData;
|
||||
use script_layout_interface::reporter::CSSErrorReporter;
|
||||
use script_layout_interface::rpc::LayoutRPC;
|
||||
|
@ -436,6 +437,7 @@ unsafe_no_jsmanaged_fields!(AudioGraph);
|
|||
unsafe_no_jsmanaged_fields!(AudioBuffer);
|
||||
unsafe_no_jsmanaged_fields!(AudioContext);
|
||||
unsafe_no_jsmanaged_fields!(NodeId);
|
||||
unsafe_no_jsmanaged_fields!(ParamType);
|
||||
|
||||
unsafe impl<'a> JSTraceable for &'a str {
|
||||
#[inline]
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use dom::audionode::AudioNode;
|
||||
use dom::audioparam::{AudioParam, AudioParamImpl};
|
||||
use dom::audioparam::AudioParam;
|
||||
use dom::baseaudiocontext::BaseAudioContext;
|
||||
use dom::bindings::codegen::Bindings::AudioParamBinding::AutomationRate;
|
||||
use dom::bindings::codegen::Bindings::AudioNodeBinding::AudioNodeOptions;
|
||||
|
@ -14,15 +14,10 @@ use dom::bindings::reflector::reflect_dom_object;
|
|||
use dom::bindings::root::{Dom, DomRoot};
|
||||
use dom::window::Window;
|
||||
use dom_struct::dom_struct;
|
||||
use servo_media::audio::context::AudioContext;
|
||||
use servo_media::audio::gain_node::{GainNodeMessage, GainNodeOptions};
|
||||
use servo_media::audio::graph::NodeId;
|
||||
use servo_media::audio::node::{AudioNodeMessage, AudioNodeType};
|
||||
use servo_media::audio::param::{UserAutomationEvent, RampKind};
|
||||
use servo_media::audio::gain_node::GainNodeOptions;
|
||||
use servo_media::audio::node::AudioNodeInit;
|
||||
use servo_media::audio::param::ParamType;
|
||||
use std::f32;
|
||||
use std::rc::Rc;
|
||||
|
||||
audio_param_impl!(Gain, GainNode, GainNodeMessage, SetGain);
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GainNode {
|
||||
|
@ -42,16 +37,17 @@ impl GainNode {
|
|||
node_options.channelCountMode = Some(ChannelCountMode::Max);
|
||||
node_options.channelInterpretation = Some(ChannelInterpretation::Speakers);
|
||||
let node = AudioNode::new_inherited(
|
||||
AudioNodeType::GainNode(gain_options.into()),
|
||||
AudioNodeInit::GainNode(gain_options.into()),
|
||||
None,
|
||||
context,
|
||||
&node_options,
|
||||
1, // inputs
|
||||
1, // outputs
|
||||
);
|
||||
let gain = Gain::new(context.audio_context_impl(), node.node_id());
|
||||
let gain = AudioParam::new(window,
|
||||
Box::new(gain),
|
||||
context,
|
||||
node.node_id(),
|
||||
ParamType::Gain,
|
||||
AutomationRate::A_rate,
|
||||
1., // default value
|
||||
f32::MIN, // min value
|
||||
|
|
|
@ -628,77 +628,4 @@ macro_rules! handle_potential_webgl_error {
|
|||
($context:expr, $call:expr) => {
|
||||
handle_potential_webgl_error!($context, $call, ());
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! audio_param_impl(
|
||||
($struct:ident, $node_type:ident, $message_type:ident, $setter:ident) => (
|
||||
#[derive(JSTraceable, MallocSizeOf)]
|
||||
struct $struct {
|
||||
#[ignore_malloc_size_of = "Rc"]
|
||||
context: Rc<AudioContext>,
|
||||
#[ignore_malloc_size_of = "servo_media"]
|
||||
node: NodeId,
|
||||
}
|
||||
|
||||
impl $struct {
|
||||
pub fn new(context: Rc<AudioContext>,
|
||||
node: NodeId) -> Self {
|
||||
Self {
|
||||
context,
|
||||
node,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AudioParamImpl for $struct {
|
||||
fn set_value(&self, value: f32) {
|
||||
self.set_value_at_time(value, self.context.current_time());
|
||||
}
|
||||
|
||||
fn set_value_at_time(&self, value: f32, start_time: f64) {
|
||||
self.context.message_node(
|
||||
self.node,
|
||||
AudioNodeMessage::$node_type($message_type::$setter(
|
||||
UserAutomationEvent::SetValueAtTime(value, start_time),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
fn ramp_to_value_at_time(&self, ramp_kind: RampKind, value: f32, end_time: f64) {
|
||||
self.context.message_node(
|
||||
self.node,
|
||||
AudioNodeMessage::$node_type($message_type::$setter(
|
||||
UserAutomationEvent::RampToValueAtTime(ramp_kind, value, end_time),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
fn set_target_at_time(&self, target: f32, start_time: f64, time_constant: f32) {
|
||||
self.context.message_node(
|
||||
self.node,
|
||||
AudioNodeMessage::$node_type($message_type::$setter(
|
||||
UserAutomationEvent::SetTargetAtTime(target, start_time, time_constant.into()),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
fn cancel_scheduled_values(&self, cancel_time: f64) {
|
||||
self.context.message_node(
|
||||
self.node,
|
||||
AudioNodeMessage::$node_type($message_type::$setter(
|
||||
UserAutomationEvent::CancelScheduledValues(cancel_time),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
fn cancel_and_hold_at_time(&self, cancel_time: f64) {
|
||||
self.context.message_node(
|
||||
self.node,
|
||||
AudioNodeMessage::$node_type($message_type::$setter(
|
||||
UserAutomationEvent::CancelAndHoldAtTime(cancel_time),
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
* License, v.2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use dom::audioparam::{AudioParam, AudioParamImpl};
|
||||
use dom::audioparam::AudioParam;
|
||||
use dom::audioscheduledsourcenode::AudioScheduledSourceNode;
|
||||
use dom::baseaudiocontext::BaseAudioContext;
|
||||
use dom::bindings::codegen::Bindings::AudioParamBinding::AutomationRate;
|
||||
|
@ -15,18 +15,11 @@ use dom::bindings::reflector::reflect_dom_object;
|
|||
use dom::bindings::root::{Dom, DomRoot};
|
||||
use dom::window::Window;
|
||||
use dom_struct::dom_struct;
|
||||
use servo_media::audio::context::AudioContext;
|
||||
use servo_media::audio::graph::NodeId;
|
||||
use servo_media::audio::node::{AudioNodeMessage, AudioNodeType};
|
||||
use servo_media::audio::node::AudioNodeInit;
|
||||
use servo_media::audio::oscillator_node::OscillatorNodeOptions as ServoMediaOscillatorOptions;
|
||||
use servo_media::audio::oscillator_node::OscillatorType as ServoMediaOscillatorType;
|
||||
use servo_media::audio::oscillator_node::OscillatorNodeMessage;
|
||||
use servo_media::audio::param::{UserAutomationEvent, RampKind};
|
||||
use servo_media::audio::param::ParamType;
|
||||
use std::f32;
|
||||
use std::rc::Rc;
|
||||
|
||||
audio_param_impl!(Frequency, OscillatorNode, OscillatorNodeMessage, SetFrequency);
|
||||
audio_param_impl!(Detune, OscillatorNode, OscillatorNodeMessage, SetDetune);
|
||||
|
||||
#[dom_struct]
|
||||
pub struct OscillatorNode {
|
||||
|
@ -48,21 +41,23 @@ impl OscillatorNode {
|
|||
node_options.channelCountMode = Some(ChannelCountMode::Max);
|
||||
node_options.channelInterpretation = Some(ChannelInterpretation::Speakers);
|
||||
let source_node = AudioScheduledSourceNode::new_inherited(
|
||||
AudioNodeType::OscillatorNode(oscillator_options.into()),
|
||||
AudioNodeInit::OscillatorNode(oscillator_options.into()),
|
||||
context,
|
||||
&node_options,
|
||||
0, /* inputs */
|
||||
1, /* outputs */
|
||||
);
|
||||
let node_id = source_node.node().node_id();
|
||||
let frequency = Frequency::new(context.audio_context_impl(), node_id);
|
||||
let frequency = AudioParam::new(window,
|
||||
Box::new(frequency),
|
||||
context,
|
||||
node_id,
|
||||
ParamType::Frequency,
|
||||
AutomationRate::A_rate,
|
||||
440., f32::MIN, f32::MAX);
|
||||
let detune = Detune::new(context.audio_context_impl(), node_id);
|
||||
let detune = AudioParam::new(window,
|
||||
Box::new(detune),
|
||||
context,
|
||||
node_id,
|
||||
ParamType::Detune,
|
||||
AutomationRate::A_rate,
|
||||
0., -440. / 2., 440. / 2.);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue