From b36bd5d6775ca69345d98ce4a406bb714897bf07 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 9 Jul 2018 15:45:05 -0700 Subject: [PATCH 1/7] Add stubs for audio param methods --- servo-media/src/audio/buffer_source_node.rs | 2 ++ servo-media/src/audio/channel_node.rs | 4 ++++ servo-media/src/audio/destination_node.rs | 2 ++ servo-media/src/audio/gain_node.rs | 3 +++ servo-media/src/audio/node.rs | 7 +++++++ servo-media/src/audio/oscillator_node.rs | 4 ++++ servo-media/src/audio/param.rs | 7 +++++++ 7 files changed, 29 insertions(+) diff --git a/servo-media/src/audio/buffer_source_node.rs b/servo-media/src/audio/buffer_source_node.rs index 68455a54..5722cf8b 100644 --- a/servo-media/src/audio/buffer_source_node.rs +++ b/servo-media/src/audio/buffer_source_node.rs @@ -116,6 +116,8 @@ impl AudioBufferSourceNode { } impl AudioNodeEngine for AudioBufferSourceNode { + fn node_type(&self) -> &'static str { "AudioBufferSourceNode" } + fn input_count(&self) -> u32 { 0 } diff --git a/servo-media/src/audio/channel_node.rs b/servo-media/src/audio/channel_node.rs index 53a75eda..191c87e5 100644 --- a/servo-media/src/audio/channel_node.rs +++ b/servo-media/src/audio/channel_node.rs @@ -28,6 +28,8 @@ impl ChannelMergerNode { } impl AudioNodeEngine for ChannelMergerNode { + fn node_type(&self) -> &'static str { "ChannelMergerNode" } + fn process(&mut self, mut inputs: Chunk, _: &BlockInfo) -> Chunk { debug_assert!(inputs.len() == self.channels as usize); @@ -76,6 +78,8 @@ impl ChannelSplitterNode { } impl AudioNodeEngine for ChannelSplitterNode { + fn node_type(&self) -> &'static str { "ChannelSplitterNode" } + fn process(&mut self, mut inputs: Chunk, _: &BlockInfo) -> Chunk { debug_assert!(inputs.len() == 1); diff --git a/servo-media/src/audio/destination_node.rs b/servo-media/src/audio/destination_node.rs index 91bb0695..69483d3d 100644 --- a/servo-media/src/audio/destination_node.rs +++ b/servo-media/src/audio/destination_node.rs @@ -22,6 +22,8 @@ impl DestinationNode { } impl AudioNodeEngine for DestinationNode { + fn node_type(&self) -> &'static str { "DestinationNode" } + fn process(&mut self, inputs: Chunk, _: &BlockInfo) -> Chunk { self.chunk = Some(inputs); Chunk::default() diff --git a/servo-media/src/audio/gain_node.rs b/servo-media/src/audio/gain_node.rs index 595933ef..414e4fbd 100644 --- a/servo-media/src/audio/gain_node.rs +++ b/servo-media/src/audio/gain_node.rs @@ -47,6 +47,9 @@ impl GainNode { } impl AudioNodeEngine for GainNode { + + fn node_type(&self) -> &'static str { "GainNode" } + fn process(&mut self, mut inputs: Chunk, info: &BlockInfo) -> Chunk { debug_assert!(inputs.len() == 1); diff --git a/servo-media/src/audio/node.rs b/servo-media/src/audio/node.rs index dadddc97..54903ba6 100644 --- a/servo-media/src/audio/node.rs +++ b/servo-media/src/audio/node.rs @@ -1,3 +1,4 @@ +use audio::param::{Param, ParamType}; use audio::channel_node::ChannelNodeOptions; use audio::block::{Chunk, Tick}; use audio::buffer_source_node::{AudioBufferSourceNodeMessage, AudioBufferSourceNodeOptions}; @@ -83,6 +84,8 @@ pub trait AudioNodeCommon { /// This trait represents the common features of all audio nodes. pub trait AudioNodeEngine: Send + AudioNodeCommon { + fn node_type(&self) -> &'static str; + fn process(&mut self, inputs: Chunk, info: &BlockInfo) -> Chunk; fn message(&mut self, msg: AudioNodeMessage, sample_rate: f32) { @@ -131,6 +134,10 @@ pub trait AudioNodeEngine: Send + AudioNodeCommon { fn destination_data(&mut self) -> Option { None } + + fn get_param(&mut self, _: ParamType) -> &mut Param { + panic!("No params on node {}", self.node_type()) + } } #[derive(Clone, Debug)] diff --git a/servo-media/src/audio/oscillator_node.rs b/servo-media/src/audio/oscillator_node.rs index 535ecae5..c4fd5d1f 100644 --- a/servo-media/src/audio/oscillator_node.rs +++ b/servo-media/src/audio/oscillator_node.rs @@ -56,6 +56,7 @@ pub struct OscillatorNode { impl OscillatorNode { + pub fn new(options: OscillatorNodeOptions) -> Self { Self { channel_info: Default::default(), @@ -92,6 +93,9 @@ impl OscillatorNode { } impl AudioNodeEngine for OscillatorNode { + + fn node_type(&self) -> &'static str { "OscillatorNode" } + fn process(&mut self, mut inputs: Chunk, info: &BlockInfo) -> Chunk { // XXX Implement this properly and according to self.options // as defined in https://webaudio.github.io/web-audio-api/#oscillatornode diff --git a/servo-media/src/audio/param.rs b/servo-media/src/audio/param.rs index d0fc2ca4..9f1f74ff 100644 --- a/servo-media/src/audio/param.rs +++ b/servo-media/src/audio/param.rs @@ -1,6 +1,13 @@ use audio::block::Tick; use audio::node::BlockInfo; +#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] +pub enum ParamType { + Frequency, + Detune, + Gain, +} + /// An AudioParam. /// /// https://webaudio.github.io/web-audio-api/#AudioParam From c7124c7dbe40e6e35ee35cf1b7458797a2bc93c5 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 9 Jul 2018 15:58:02 -0700 Subject: [PATCH 2/7] Switch over to ParamIds for everything --- examples/params.rs | 45 ++++++++++++++---------- examples/params_settarget.rs | 23 ++++++------ examples/play.rs | 20 ++++++----- servo-media/src/audio/gain_node.rs | 21 +++++------ servo-media/src/audio/node.rs | 12 ++++--- servo-media/src/audio/oscillator_node.rs | 31 +++++++--------- 6 files changed, 77 insertions(+), 75 deletions(-) diff --git a/examples/params.rs b/examples/params.rs index 5b86cbf5..6c070dbb 100644 --- a/examples/params.rs +++ b/examples/params.rs @@ -1,9 +1,8 @@ extern crate servo_media; -use servo_media::audio::gain_node::{GainNodeMessage, GainNodeOptions}; +use servo_media::audio::gain_node::GainNodeOptions; use servo_media::audio::node::{AudioNodeMessage, AudioNodeType, AudioScheduledSourceNodeMessage}; -use servo_media::audio::oscillator_node::OscillatorNodeMessage; -use servo_media::audio::param::{RampKind, UserAutomationEvent}; +use servo_media::audio::param::{ParamType, RampKind, UserAutomationEvent}; use servo_media::ServoMedia; use std::sync::Arc; use std::{thread, time}; @@ -25,59 +24,67 @@ fn run_example(servo_media: Arc) { // 0.5s: Set frequency to 110Hz context.message_node( osc, - AudioNodeMessage::OscillatorNode(OscillatorNodeMessage::SetFrequency( + AudioNodeMessage::SetParam( + ParamType::Frequency, UserAutomationEvent::SetValueAtTime(110., 0.5), - )), + ), ); // 1s: Set frequency to 220Hz context.message_node( osc, - AudioNodeMessage::OscillatorNode(OscillatorNodeMessage::SetFrequency( + AudioNodeMessage::SetParam( + ParamType::Frequency, UserAutomationEvent::SetValueAtTime(220., 1.), - )), + ), ); // 0.75s: Set gain to 0.25 context.message_node( gain, - AudioNodeMessage::GainNode(GainNodeMessage::SetGain( + AudioNodeMessage::SetParam( + ParamType::Gain, UserAutomationEvent::SetValueAtTime(0.25, 0.75), - )), + ), ); // 0.75s - 1.5s: Exponentially ramp gain to 1 context.message_node( gain, - AudioNodeMessage::GainNode(GainNodeMessage::SetGain( + AudioNodeMessage::SetParam( + ParamType::Gain, UserAutomationEvent::RampToValueAtTime(RampKind::Exponential, 1., 1.5), - )), + ), ); // 0.75s - 1.75s: Linearly ramp frequency to 880Hz context.message_node( osc, - AudioNodeMessage::OscillatorNode(OscillatorNodeMessage::SetFrequency( + AudioNodeMessage::SetParam( + ParamType::Frequency, UserAutomationEvent::RampToValueAtTime(RampKind::Linear, 880., 1.75), - )), + ), ); // 1.75s - 2.5s: Exponentially ramp frequency to 110Hz context.message_node( osc, - AudioNodeMessage::OscillatorNode(OscillatorNodeMessage::SetFrequency( + AudioNodeMessage::SetParam( + ParamType::Frequency, UserAutomationEvent::RampToValueAtTime(RampKind::Exponential, 110., 2.5), - )), + ), ); // 2.75s: Exponentially approach 110Hz context.message_node( osc, - AudioNodeMessage::OscillatorNode(OscillatorNodeMessage::SetFrequency( + AudioNodeMessage::SetParam( + ParamType::Frequency, UserAutomationEvent::SetTargetAtTime(1100., 2.75, 1.1), - )), + ), ); // 3.3s: But actually stop at 3.3Hz and hold context.message_node( osc, - AudioNodeMessage::OscillatorNode(OscillatorNodeMessage::SetFrequency( + AudioNodeMessage::SetParam( + ParamType::Frequency, UserAutomationEvent::CancelAndHoldAtTime(3.3), - )), + ), ); thread::sleep(time::Duration::from_millis(5000)); } diff --git a/examples/params_settarget.rs b/examples/params_settarget.rs index 98e57624..4b8a5500 100644 --- a/examples/params_settarget.rs +++ b/examples/params_settarget.rs @@ -1,8 +1,7 @@ extern crate servo_media; use servo_media::audio::node::{AudioNodeMessage, AudioNodeType, AudioScheduledSourceNodeMessage}; -use servo_media::audio::oscillator_node::OscillatorNodeMessage; -use servo_media::audio::param::{RampKind, UserAutomationEvent}; +use servo_media::audio::param::{ParamType, RampKind, UserAutomationEvent}; use servo_media::ServoMedia; use std::sync::Arc; use std::{thread, time}; @@ -20,32 +19,36 @@ fn run_example(servo_media: Arc) { // 0.1s: Set frequency to 110Hz context.message_node( osc, - AudioNodeMessage::OscillatorNode(OscillatorNodeMessage::SetFrequency( + AudioNodeMessage::SetParam( + ParamType::Frequency, UserAutomationEvent::SetValueAtTime(110., 0.1), - )), + ), ); // 0.3s: Start increasing frequency to 440Hz exponentially with a time constant of 1 context.message_node( osc, - AudioNodeMessage::OscillatorNode(OscillatorNodeMessage::SetFrequency( + AudioNodeMessage::SetParam( + ParamType::Frequency, UserAutomationEvent::SetTargetAtTime(440., 0.3, 1.), - )), + ), ); // 1.5s: Start increasing frequency to 1760Hz exponentially // this event effectively doesn't happen, but instead sets a starting point // for the next ramp event context.message_node( osc, - AudioNodeMessage::OscillatorNode(OscillatorNodeMessage::SetFrequency( + AudioNodeMessage::SetParam( + ParamType::Frequency, UserAutomationEvent::SetTargetAtTime(1760., 1.5, 0.1), - )), + ), ); // 1.5s - 3s Linearly ramp down from the previous event (1.5s) to 110Hz context.message_node( osc, - AudioNodeMessage::OscillatorNode(OscillatorNodeMessage::SetFrequency( + AudioNodeMessage::SetParam( + ParamType::Frequency, UserAutomationEvent::RampToValueAtTime(RampKind::Linear, 110., 3.0), - )), + ), ); thread::sleep(time::Duration::from_millis(5000)); } diff --git a/examples/play.rs b/examples/play.rs index 09ead88c..8ad5701f 100644 --- a/examples/play.rs +++ b/examples/play.rs @@ -1,9 +1,8 @@ extern crate servo_media; -use servo_media::audio::gain_node::{GainNodeMessage, GainNodeOptions}; +use servo_media::audio::gain_node::{GainNodeOptions}; use servo_media::audio::node::{AudioNodeMessage, AudioNodeType, AudioScheduledSourceNodeMessage}; -use servo_media::audio::oscillator_node::OscillatorNodeMessage; -use servo_media::audio::param::UserAutomationEvent; +use servo_media::audio::param::{ParamType, UserAutomationEvent}; use servo_media::ServoMedia; use std::sync::Arc; use std::{thread, time}; @@ -30,23 +29,26 @@ fn run_example(servo_media: Arc) { // 0.5s: Set frequency to 110Hz context.message_node( osc, - AudioNodeMessage::OscillatorNode(OscillatorNodeMessage::SetFrequency( + AudioNodeMessage::SetParam( + ParamType::Frequency, UserAutomationEvent::SetValueAtTime(110., 0.5), - )), + ), ); // 1s: Set frequency to 220Hz context.message_node( osc, - AudioNodeMessage::OscillatorNode(OscillatorNodeMessage::SetFrequency( + AudioNodeMessage::SetParam( + ParamType::Frequency, UserAutomationEvent::SetValueAtTime(220., 1.), - )), + ), ); // 0.75s: Set gain to 0.25 context.message_node( gain, - AudioNodeMessage::GainNode(GainNodeMessage::SetGain( + AudioNodeMessage::SetParam( + ParamType::Gain, UserAutomationEvent::SetValueAtTime(0.25, 0.75), - )), + ), ); thread::sleep(time::Duration::from_millis(1200)); // 1.2s: Suspend processing diff --git a/servo-media/src/audio/gain_node.rs b/servo-media/src/audio/gain_node.rs index 414e4fbd..9e03bca5 100644 --- a/servo-media/src/audio/gain_node.rs +++ b/servo-media/src/audio/gain_node.rs @@ -3,12 +3,7 @@ use audio::block::Chunk; use audio::block::Tick; use audio::node::AudioNodeEngine; use audio::node::BlockInfo; -use audio::param::{Param, UserAutomationEvent}; - -#[derive(Debug, Clone)] -pub enum GainNodeMessage { - SetGain(UserAutomationEvent), -} +use audio::param::{Param, ParamType}; #[derive(Copy, Clone, Debug)] pub struct GainNodeOptions { @@ -38,12 +33,6 @@ impl GainNode { pub fn update_parameters(&mut self, info: &BlockInfo, tick: Tick) -> bool { self.gain.update(info, tick) } - - pub fn handle_message(&mut self, message: GainNodeMessage, sample_rate: f32) { - match message { - GainNodeMessage::SetGain(event) => self.gain.insert_event(event.to_event(sample_rate)), - } - } } impl AudioNodeEngine for GainNode { @@ -71,5 +60,11 @@ impl AudioNodeEngine for GainNode { inputs } - make_message_handler!(GainNode: handle_message); + + fn get_param(&mut self, id: ParamType) -> &mut Param { + match id { + ParamType::Gain => &mut self.gain, + _ => panic!("Unknown param {:?} for GainNode", id) + } + } } diff --git a/servo-media/src/audio/node.rs b/servo-media/src/audio/node.rs index 54903ba6..1465c06d 100644 --- a/servo-media/src/audio/node.rs +++ b/servo-media/src/audio/node.rs @@ -1,9 +1,9 @@ -use audio::param::{Param, ParamType}; +use audio::param::{Param, ParamType, UserAutomationEvent}; use audio::channel_node::ChannelNodeOptions; use audio::block::{Chunk, Tick}; use audio::buffer_source_node::{AudioBufferSourceNodeMessage, AudioBufferSourceNodeOptions}; -use audio::gain_node::{GainNodeMessage, GainNodeOptions}; -use audio::oscillator_node::{OscillatorNodeMessage, OscillatorNodeOptions}; +use audio::gain_node::GainNodeOptions; +use audio::oscillator_node::OscillatorNodeOptions; /// Type of AudioNodeEngine. #[derive(Debug, Clone)] @@ -93,6 +93,9 @@ pub trait AudioNodeEngine: Send + AudioNodeCommon { AudioNodeMessage::SetChannelCount(c) => self.set_channel_count(c), AudioNodeMessage::SetChannelMode(c) => self.set_channel_count_mode(c), AudioNodeMessage::SetChannelInterpretation(c) => self.set_channel_interpretation(c), + AudioNodeMessage::SetParam(id, event) => { + self.get_param(id).insert_event(event.to_event(sample_rate)) + } _ => self.message_specific(msg, sample_rate), } } @@ -144,11 +147,10 @@ pub trait AudioNodeEngine: Send + AudioNodeCommon { pub enum AudioNodeMessage { AudioBufferSourceNode(AudioBufferSourceNodeMessage), AudioScheduledSourceNode(AudioScheduledSourceNodeMessage), - GainNode(GainNodeMessage), - OscillatorNode(OscillatorNodeMessage), SetChannelCount(u8), SetChannelMode(ChannelCountMode), SetChannelInterpretation(ChannelInterpretation), + SetParam(ParamType, UserAutomationEvent) } /// This trait represents the common features of the source nodes such as diff --git a/servo-media/src/audio/oscillator_node.rs b/servo-media/src/audio/oscillator_node.rs index c4fd5d1f..73547189 100644 --- a/servo-media/src/audio/oscillator_node.rs +++ b/servo-media/src/audio/oscillator_node.rs @@ -1,15 +1,9 @@ use audio::node::ChannelInfo; use audio::block::{Chunk, Tick}; use audio::node::{AudioNodeEngine, AudioScheduledSourceNodeMessage, BlockInfo}; -use audio::param::{Param, UserAutomationEvent}; +use audio::param::{Param, ParamType}; use num_traits::cast::NumCast; -#[derive(Copy, Clone, Debug)] -pub enum OscillatorNodeMessage { - SetDetune(UserAutomationEvent), - SetFrequency(UserAutomationEvent), -} - #[derive(Copy, Clone, Debug)] pub struct PeriodicWaveOptions { // XXX https://webaudio.github.io/web-audio-api/#dictdef-periodicwaveoptions @@ -47,6 +41,7 @@ impl Default for OscillatorNodeOptions { pub struct OscillatorNode { channel_info: ChannelInfo, frequency: Param, + detune: Param, phase: f64, /// Time at which the source should start playing. start_at: Option, @@ -56,11 +51,11 @@ pub struct OscillatorNode { impl OscillatorNode { - pub fn new(options: OscillatorNodeOptions) -> Self { Self { channel_info: Default::default(), frequency: Param::new(options.freq.into()), + detune: Param::new(options.detune.into()), phase: 0., start_at: None, stop_at: None, @@ -71,15 +66,6 @@ impl OscillatorNode { self.frequency.update(info, tick) } - pub fn handle_message(&mut self, message: OscillatorNodeMessage, sample_rate: f32) { - match message { - OscillatorNodeMessage::SetFrequency(event) => { - self.frequency.insert_event(event.to_event(sample_rate)) - } - _ => () - } - } - pub fn handle_source_node_message(&mut self, message: AudioScheduledSourceNodeMessage, sample_rate: f32) { match message { AudioScheduledSourceNodeMessage::Start(when) => { @@ -155,6 +141,13 @@ impl AudioNodeEngine for OscillatorNode { 0 } - make_message_handler!(AudioScheduledSourceNode: handle_source_node_message, - OscillatorNode: handle_message); + fn get_param(&mut self, id: ParamType) -> &mut Param { + match id { + ParamType::Frequency => &mut self.frequency, + ParamType::Detune => &mut self.detune, + _ => panic!("Unknown param {:?} for OscillatorNode", id) + } + } + + make_message_handler!(AudioScheduledSourceNode: handle_source_node_message); } From 0c0a928ef528f6166f1843ce33fc1e09655b72b5 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 9 Jul 2018 16:12:10 -0700 Subject: [PATCH 3/7] cleanup: Make engines private --- servo-media/src/audio/buffer_source_node.rs | 2 +- servo-media/src/audio/channel_node.rs | 4 ++-- servo-media/src/audio/destination_node.rs | 2 +- servo-media/src/audio/gain_node.rs | 2 +- servo-media/src/audio/graph.rs | 15 +++++---------- servo-media/src/audio/node.rs | 4 ++-- servo-media/src/audio/oscillator_node.rs | 2 +- 7 files changed, 13 insertions(+), 18 deletions(-) diff --git a/servo-media/src/audio/buffer_source_node.rs b/servo-media/src/audio/buffer_source_node.rs index 5722cf8b..6963fe3b 100644 --- a/servo-media/src/audio/buffer_source_node.rs +++ b/servo-media/src/audio/buffer_source_node.rs @@ -48,7 +48,7 @@ impl Default for AudioBufferSourceNodeOptions { /// XXX Implement playbackRate and related bits #[derive(AudioScheduledSourceNode, AudioNodeCommon)] #[allow(dead_code)] -pub struct AudioBufferSourceNode { +pub(crate) struct AudioBufferSourceNode { channel_info: ChannelInfo, /// A data block holding the audio sample data to be played. buffer: Option, diff --git a/servo-media/src/audio/channel_node.rs b/servo-media/src/audio/channel_node.rs index 191c87e5..7b9022a5 100644 --- a/servo-media/src/audio/channel_node.rs +++ b/servo-media/src/audio/channel_node.rs @@ -9,7 +9,7 @@ pub struct ChannelNodeOptions { } #[derive(AudioNodeCommon)] -pub struct ChannelMergerNode { +pub(crate) struct ChannelMergerNode { channel_info: ChannelInfo, channels: u8 } @@ -61,7 +61,7 @@ impl AudioNodeEngine for ChannelMergerNode { } #[derive(AudioNodeCommon)] -pub struct ChannelSplitterNode { +pub(crate) struct ChannelSplitterNode { channel_info: ChannelInfo, } diff --git a/servo-media/src/audio/destination_node.rs b/servo-media/src/audio/destination_node.rs index 69483d3d..6e2f06fe 100644 --- a/servo-media/src/audio/destination_node.rs +++ b/servo-media/src/audio/destination_node.rs @@ -4,7 +4,7 @@ use audio::node::{AudioNodeEngine, BlockInfo}; use audio::block::Chunk; #[derive(AudioNodeCommon)] -pub struct DestinationNode { +pub(crate) struct DestinationNode { channel_info: ChannelInfo, chunk: Option } diff --git a/servo-media/src/audio/gain_node.rs b/servo-media/src/audio/gain_node.rs index 9e03bca5..931d492b 100644 --- a/servo-media/src/audio/gain_node.rs +++ b/servo-media/src/audio/gain_node.rs @@ -17,7 +17,7 @@ impl Default for GainNodeOptions { } #[derive(AudioNodeCommon)] -pub struct GainNode { +pub(crate) struct GainNode { channel_info: ChannelInfo, gain: Param, } diff --git a/servo-media/src/audio/graph.rs b/servo-media/src/audio/graph.rs index 266d38d1..efdb08ee 100644 --- a/servo-media/src/audio/graph.rs +++ b/servo-media/src/audio/graph.rs @@ -7,7 +7,7 @@ use petgraph::graph::DefaultIx; use petgraph::stable_graph::NodeIndex; use petgraph::stable_graph::StableGraph; use petgraph::visit::{DfsPostOrder, EdgeRef, Reversed}; -use std::cell::{Ref, RefCell, RefMut}; +use std::cell::{RefCell, RefMut}; use std::cmp; #[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash, Debug)] @@ -60,7 +60,7 @@ pub struct AudioGraph { dest_id: NodeId, } -pub struct Node { +pub(crate) struct Node { node: RefCell>, } @@ -71,7 +71,7 @@ pub struct Node { /// WebAudio allows for multiple connections to/from the same port /// however it does not allow for duplicate connections between pairs /// of ports -pub struct Edge { +pub(crate) struct Edge { connections: SmallVec<[Connection; 1]> } @@ -118,7 +118,7 @@ impl AudioGraph { } /// Create a node, obtain its id - pub fn add_node(&mut self, node: Box) -> NodeId { + pub(crate) fn add_node(&mut self, node: Box) -> NodeId { NodeId(self.graph.add_node(Node::new(node))) } @@ -361,14 +361,9 @@ impl AudioGraph { /// Obtain a mutable reference to a node - pub fn node_mut(&self, ix: NodeId) -> RefMut> { + pub(crate) fn node_mut(&self, ix: NodeId) -> RefMut> { self.graph[ix.0].node.borrow_mut() } - - /// Obtain an immutable reference to a node - pub fn node(&self, ix: NodeId) -> Ref> { - self.graph[ix.0].node.borrow() - } } impl Node { diff --git a/servo-media/src/audio/node.rs b/servo-media/src/audio/node.rs index 1465c06d..3df12749 100644 --- a/servo-media/src/audio/node.rs +++ b/servo-media/src/audio/node.rs @@ -76,14 +76,14 @@ impl Default for ChannelInfo { } -pub trait AudioNodeCommon { +pub(crate) trait AudioNodeCommon { fn channel_info(&self) -> &ChannelInfo; fn channel_info_mut(&mut self) -> &mut ChannelInfo; } /// This trait represents the common features of all audio nodes. -pub trait AudioNodeEngine: Send + AudioNodeCommon { +pub(crate) trait AudioNodeEngine: Send + AudioNodeCommon { fn node_type(&self) -> &'static str; fn process(&mut self, inputs: Chunk, info: &BlockInfo) -> Chunk; diff --git a/servo-media/src/audio/oscillator_node.rs b/servo-media/src/audio/oscillator_node.rs index 73547189..07fc4a2a 100644 --- a/servo-media/src/audio/oscillator_node.rs +++ b/servo-media/src/audio/oscillator_node.rs @@ -38,7 +38,7 @@ impl Default for OscillatorNodeOptions { } #[derive(AudioScheduledSourceNode, AudioNodeCommon)] -pub struct OscillatorNode { +pub(crate) struct OscillatorNode { channel_info: ChannelInfo, frequency: Param, detune: Param, From f6d71860f28f9aedcb5624ef7d40e9ad152cfefd Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 9 Jul 2018 16:13:05 -0700 Subject: [PATCH 4/7] cleanup: Rename AudioNodeType to AudioNodeInit --- examples/android/lib/src/lib.rs | 6 +++--- examples/audio_decoder.rs | 4 ++-- examples/channels.rs | 10 +++++----- examples/channelsum.rs | 12 ++++++------ examples/params.rs | 6 +++--- examples/params_settarget.rs | 4 ++-- examples/play.rs | 6 +++--- examples/play_noise.rs | 4 ++-- servo-media/src/audio/context.rs | 4 ++-- servo-media/src/audio/node.rs | 2 +- servo-media/src/audio/render_thread.rs | 18 +++++++++--------- 11 files changed, 38 insertions(+), 38 deletions(-) diff --git a/examples/android/lib/src/lib.rs b/examples/android/lib/src/lib.rs index 169f1993..fd5ada04 100644 --- a/examples/android/lib/src/lib.rs +++ b/examples/android/lib/src/lib.rs @@ -2,7 +2,7 @@ extern crate servo_media; use servo_media::audio::gain_node::GainNodeOptions; use servo_media::audio::graph::AudioGraph; -use servo_media::audio::node::{AudioNodeMessage, AudioNodeType}; +use servo_media::audio::node::{AudioNodeMessage, AudioNodeInit}; use servo_media::audio::oscillator_node::OscillatorNodeMessage; use servo_media::ServoMedia; @@ -13,14 +13,14 @@ struct AudioStream { impl AudioStream { pub fn new() -> Self { let graph = ServoMedia::get().unwrap().create_audio_graph(); - graph.create_node(AudioNodeType::OscillatorNode(Default::default())); + graph.create_node(AudioNodeInit::OscillatorNode(Default::default())); graph.message_node( 0, AudioNodeMessage::OscillatorNode(OscillatorNodeMessage::Start(0.)), ); let mut options = GainNodeOptions::default(); options.gain = 0.5; - graph.create_node(AudioNodeType::GainNode(options)); + graph.create_node(AudioNodeInit::GainNode(options)); Self { graph } } diff --git a/examples/audio_decoder.rs b/examples/audio_decoder.rs index c8d0f986..f9b62a35 100644 --- a/examples/audio_decoder.rs +++ b/examples/audio_decoder.rs @@ -2,7 +2,7 @@ extern crate servo_media; use servo_media::audio::buffer_source_node::AudioBufferSourceNodeMessage; use servo_media::audio::decoder::AudioDecoderCallbacks; -use servo_media::audio::node::{AudioNodeMessage, AudioNodeType, AudioScheduledSourceNodeMessage}; +use servo_media::audio::node::{AudioNodeMessage, AudioNodeInit, AudioScheduledSourceNodeMessage}; use servo_media::ServoMedia; use std::env; use std::fs::File; @@ -43,7 +43,7 @@ fn run_example(servo_media: Arc) { println!("Decoding audio"); receiver.recv().unwrap(); println!("Audio decoded"); - let buffer_source = context.create_node(AudioNodeType::AudioBufferSourceNode(Default::default())); + let buffer_source = context.create_node(AudioNodeInit::AudioBufferSourceNode(Default::default())); let dest = context.dest_node(); context.connect_ports(buffer_source.output(0), dest.input(0)); context.message_node( diff --git a/examples/channels.rs b/examples/channels.rs index 2a051e2a..149bd9d1 100644 --- a/examples/channels.rs +++ b/examples/channels.rs @@ -2,7 +2,7 @@ extern crate servo_media; use servo_media::audio::channel_node::ChannelNodeOptions; use servo_media::audio::gain_node::GainNodeOptions; -use servo_media::audio::node::{AudioNodeMessage, AudioNodeType, AudioScheduledSourceNodeMessage}; +use servo_media::audio::node::{AudioNodeMessage, AudioNodeInit, AudioScheduledSourceNodeMessage}; use servo_media::ServoMedia; use std::sync::Arc; use std::{thread, time}; @@ -10,14 +10,14 @@ use std::{thread, time}; fn run_example(servo_media: Arc) { let context = servo_media.create_audio_context(Default::default()); let mut options = Default::default(); - let osc = context.create_node(AudioNodeType::OscillatorNode(options)); + let osc = context.create_node(AudioNodeInit::OscillatorNode(options)); options.freq = 213.; - let osc2 = context.create_node(AudioNodeType::OscillatorNode(options)); + let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options)); let mut options = GainNodeOptions::default(); options.gain = 0.7; - let gain = context.create_node(AudioNodeType::GainNode(options)); + let gain = context.create_node(AudioNodeInit::GainNode(options)); let options = ChannelNodeOptions { channels: 2 }; - let merger = context.create_node(AudioNodeType::ChannelMergerNode(options)); + let merger = context.create_node(AudioNodeInit::ChannelMergerNode(options)); let dest = context.dest_node(); context.connect_ports(osc.output(0), gain.input(0)); diff --git a/examples/channelsum.rs b/examples/channelsum.rs index 48eb6861..89769bb4 100644 --- a/examples/channelsum.rs +++ b/examples/channelsum.rs @@ -2,7 +2,7 @@ extern crate servo_media; use servo_media::audio::channel_node::ChannelNodeOptions; use servo_media::audio::gain_node::GainNodeOptions; -use servo_media::audio::node::{AudioNodeMessage, AudioNodeType, AudioScheduledSourceNodeMessage}; +use servo_media::audio::node::{AudioNodeMessage, AudioNodeInit, AudioScheduledSourceNodeMessage}; use servo_media::ServoMedia; use std::sync::Arc; use std::{thread, time}; @@ -10,17 +10,17 @@ use std::{thread, time}; fn run_example(servo_media: Arc) { let context = servo_media.create_audio_context(Default::default()); let mut options = Default::default(); - let osc = context.create_node(AudioNodeType::OscillatorNode(options)); + let osc = context.create_node(AudioNodeInit::OscillatorNode(options)); options.freq = 213.; - let osc2 = context.create_node(AudioNodeType::OscillatorNode(options)); + let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options)); options.freq = 100.; - let osc3 = context.create_node(AudioNodeType::OscillatorNode(options)); + let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options)); let mut options = GainNodeOptions::default(); options.gain = 0.7; - let gain = context.create_node(AudioNodeType::GainNode(options)); + let gain = context.create_node(AudioNodeInit::GainNode(options)); let options = ChannelNodeOptions { channels: 2 }; - let merger = context.create_node(AudioNodeType::ChannelMergerNode(options)); + let merger = context.create_node(AudioNodeInit::ChannelMergerNode(options)); let dest = context.dest_node(); context.connect_ports(osc.output(0), merger.input(0)); diff --git a/examples/params.rs b/examples/params.rs index 6c070dbb..769edfa5 100644 --- a/examples/params.rs +++ b/examples/params.rs @@ -1,7 +1,7 @@ extern crate servo_media; use servo_media::audio::gain_node::GainNodeOptions; -use servo_media::audio::node::{AudioNodeMessage, AudioNodeType, AudioScheduledSourceNodeMessage}; +use servo_media::audio::node::{AudioNodeMessage, AudioNodeInit, AudioScheduledSourceNodeMessage}; use servo_media::audio::param::{ParamType, RampKind, UserAutomationEvent}; use servo_media::ServoMedia; use std::sync::Arc; @@ -10,10 +10,10 @@ use std::{thread, time}; fn run_example(servo_media: Arc) { let context = servo_media.create_audio_context(Default::default()); let dest = context.dest_node(); - let osc = context.create_node(AudioNodeType::OscillatorNode(Default::default())); + let osc = context.create_node(AudioNodeInit::OscillatorNode(Default::default())); let mut options = GainNodeOptions::default(); options.gain = 0.5; - let gain = context.create_node(AudioNodeType::GainNode(options)); + let gain = context.create_node(AudioNodeInit::GainNode(options)); context.connect_ports(osc.output(0), gain.input(0)); context.connect_ports(gain.output(0), dest.input(0)); let _ = context.resume(); diff --git a/examples/params_settarget.rs b/examples/params_settarget.rs index 4b8a5500..448f6c56 100644 --- a/examples/params_settarget.rs +++ b/examples/params_settarget.rs @@ -1,6 +1,6 @@ extern crate servo_media; -use servo_media::audio::node::{AudioNodeMessage, AudioNodeType, AudioScheduledSourceNodeMessage}; +use servo_media::audio::node::{AudioNodeMessage, AudioNodeInit, AudioScheduledSourceNodeMessage}; use servo_media::audio::param::{ParamType, RampKind, UserAutomationEvent}; use servo_media::ServoMedia; use std::sync::Arc; @@ -9,7 +9,7 @@ use std::{thread, time}; fn run_example(servo_media: Arc) { let context = servo_media.create_audio_context(Default::default()); let dest = context.dest_node(); - let osc = context.create_node(AudioNodeType::OscillatorNode(Default::default())); + let osc = context.create_node(AudioNodeInit::OscillatorNode(Default::default())); context.connect_ports(osc.output(0), dest.input(0)); let _ = context.resume(); context.message_node( diff --git a/examples/play.rs b/examples/play.rs index 8ad5701f..2785c5d2 100644 --- a/examples/play.rs +++ b/examples/play.rs @@ -1,7 +1,7 @@ extern crate servo_media; use servo_media::audio::gain_node::{GainNodeOptions}; -use servo_media::audio::node::{AudioNodeMessage, AudioNodeType, AudioScheduledSourceNodeMessage}; +use servo_media::audio::node::{AudioNodeMessage, AudioNodeInit, AudioScheduledSourceNodeMessage}; use servo_media::audio::param::{ParamType, UserAutomationEvent}; use servo_media::ServoMedia; use std::sync::Arc; @@ -9,10 +9,10 @@ use std::{thread, time}; fn run_example(servo_media: Arc) { let context = servo_media.create_audio_context(Default::default()); - let osc = context.create_node(AudioNodeType::OscillatorNode(Default::default())); + let osc = context.create_node(AudioNodeInit::OscillatorNode(Default::default())); let mut options = GainNodeOptions::default(); options.gain = 0.5; - let gain = context.create_node(AudioNodeType::GainNode(options)); + let gain = context.create_node(AudioNodeInit::GainNode(options)); let dest = context.dest_node(); context.connect_ports(osc.output(0), gain.input(0)); context.connect_ports(gain.output(0), dest.input(0)); diff --git a/examples/play_noise.rs b/examples/play_noise.rs index 66e0998e..f2ee4aef 100644 --- a/examples/play_noise.rs +++ b/examples/play_noise.rs @@ -2,14 +2,14 @@ extern crate rand; extern crate servo_media; use servo_media::audio::buffer_source_node::AudioBufferSourceNodeMessage; -use servo_media::audio::node::{AudioNodeMessage, AudioNodeType, AudioScheduledSourceNodeMessage}; +use servo_media::audio::node::{AudioNodeMessage, AudioNodeInit, AudioScheduledSourceNodeMessage}; use servo_media::ServoMedia; use std::sync::Arc; use std::{thread, time}; fn run_example(servo_media: Arc) { let context = servo_media.create_audio_context(Default::default()); - let buffer_source = context.create_node(AudioNodeType::AudioBufferSourceNode(Default::default())); + let buffer_source = context.create_node(AudioNodeInit::AudioBufferSourceNode(Default::default())); let dest = context.dest_node(); context.connect_ports(buffer_source.output(0), dest.input(0)); let mut buffers = vec![Vec::with_capacity(4096), Vec::with_capacity(4096)]; diff --git a/servo-media/src/audio/context.rs b/servo-media/src/audio/context.rs index 254ce785..64d8a42b 100644 --- a/servo-media/src/audio/context.rs +++ b/servo-media/src/audio/context.rs @@ -1,6 +1,6 @@ use audio::decoder::{AudioDecoder, AudioDecoderCallbacks, AudioDecoderOptions}; use audio::graph::{AudioGraph, InputPort, NodeId, OutputPort, PortId}; -use audio::node::{AudioNodeMessage, AudioNodeType}; +use audio::node::{AudioNodeMessage, AudioNodeInit}; use audio::render_thread::AudioRenderThread; use audio::render_thread::AudioRenderThreadMsg; use std::cell::Cell; @@ -154,7 +154,7 @@ impl AudioContext { rx.recv().unwrap() } - pub fn create_node(&self, node_type: AudioNodeType) -> NodeId { + pub fn create_node(&self, node_type: AudioNodeInit) -> NodeId { let (tx, rx) = mpsc::channel(); let _ = self.sender .send(AudioRenderThreadMsg::CreateNode(node_type, tx)); diff --git a/servo-media/src/audio/node.rs b/servo-media/src/audio/node.rs index 3df12749..e22fe6f1 100644 --- a/servo-media/src/audio/node.rs +++ b/servo-media/src/audio/node.rs @@ -7,7 +7,7 @@ use audio::oscillator_node::OscillatorNodeOptions; /// Type of AudioNodeEngine. #[derive(Debug, Clone)] -pub enum AudioNodeType { +pub enum AudioNodeInit { AnalyserNode, BiquadFilterNode, AudioBuffer, diff --git a/servo-media/src/audio/render_thread.rs b/servo-media/src/audio/render_thread.rs index 2f5c6689..45a9fda5 100644 --- a/servo-media/src/audio/render_thread.rs +++ b/servo-media/src/audio/render_thread.rs @@ -6,7 +6,7 @@ use audio::destination_node::DestinationNode; use audio::gain_node::GainNode; use audio::graph::{AudioGraph, NodeId, PortId, InputPort, OutputPort}; use audio::node::BlockInfo; -use audio::node::{AudioNodeEngine, AudioNodeMessage, AudioNodeType}; +use audio::node::{AudioNodeEngine, AudioNodeMessage, AudioNodeInit}; use audio::oscillator_node::OscillatorNode; use audio::sink::AudioSink; use std::sync::mpsc::{Receiver, Sender}; @@ -16,7 +16,7 @@ use backends::gstreamer::audio_sink::GStreamerAudioSink; #[derive(Debug)] pub enum AudioRenderThreadMsg { - CreateNode(AudioNodeType, Sender), + CreateNode(AudioNodeInit, Sender), ConnectPorts(PortId, PortId), MessageNode(NodeId, AudioNodeMessage), Resume(Sender), @@ -71,14 +71,14 @@ impl AudioRenderThread { make_render_thread_state_change!(suspend, Suspended, stop); - fn create_node(&mut self, node_type: AudioNodeType) -> NodeId { + fn create_node(&mut self, node_type: AudioNodeInit) -> NodeId { let node: Box = match node_type { - AudioNodeType::AudioBufferSourceNode(options) => Box::new(AudioBufferSourceNode::new(options)), - AudioNodeType::DestinationNode => Box::new(DestinationNode::new()), - AudioNodeType::GainNode(options) => Box::new(GainNode::new(options)), - AudioNodeType::OscillatorNode(options) => Box::new(OscillatorNode::new(options)), - AudioNodeType::ChannelMergerNode(options) => Box::new(ChannelMergerNode::new(options)), - AudioNodeType::ChannelSplitterNode(options) => Box::new(ChannelSplitterNode::new(options)), + AudioNodeInit::AudioBufferSourceNode(options) => Box::new(AudioBufferSourceNode::new(options)), + AudioNodeInit::DestinationNode => Box::new(DestinationNode::new()), + AudioNodeInit::GainNode(options) => Box::new(GainNode::new(options)), + AudioNodeInit::OscillatorNode(options) => Box::new(OscillatorNode::new(options)), + AudioNodeInit::ChannelMergerNode(options) => Box::new(ChannelMergerNode::new(options)), + AudioNodeInit::ChannelSplitterNode(options) => Box::new(ChannelSplitterNode::new(options)), _ => unimplemented!(), }; self.graph.add_node(node) From 0c02f4f28ed829808613674f8cc7e60629bed286 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 9 Jul 2018 16:17:52 -0700 Subject: [PATCH 5/7] cleanup: Add AudioNodeType that's a bare enum --- servo-media/src/audio/buffer_source_node.rs | 4 +-- servo-media/src/audio/channel_node.rs | 5 ++-- servo-media/src/audio/destination_node.rs | 5 ++-- servo-media/src/audio/gain_node.rs | 4 +-- servo-media/src/audio/node.rs | 31 +++++++++++++++++++-- servo-media/src/audio/oscillator_node.rs | 4 +-- 6 files changed, 39 insertions(+), 14 deletions(-) diff --git a/servo-media/src/audio/buffer_source_node.rs b/servo-media/src/audio/buffer_source_node.rs index 6963fe3b..132ff1aa 100644 --- a/servo-media/src/audio/buffer_source_node.rs +++ b/servo-media/src/audio/buffer_source_node.rs @@ -1,4 +1,4 @@ -use audio::node::ChannelInfo; +use audio::node::{AudioNodeType, ChannelInfo}; use audio::block::{Block, Chunk, Tick, FRAMES_PER_BLOCK}; use audio::node::{AudioNodeEngine, AudioScheduledSourceNodeMessage, BlockInfo}; use audio::param::{Param, UserAutomationEvent}; @@ -116,7 +116,7 @@ impl AudioBufferSourceNode { } impl AudioNodeEngine for AudioBufferSourceNode { - fn node_type(&self) -> &'static str { "AudioBufferSourceNode" } + fn node_type(&self) -> AudioNodeType { AudioNodeType::AudioBufferSourceNode } fn input_count(&self) -> u32 { 0 diff --git a/servo-media/src/audio/channel_node.rs b/servo-media/src/audio/channel_node.rs index 7b9022a5..4d3b126b 100644 --- a/servo-media/src/audio/channel_node.rs +++ b/servo-media/src/audio/channel_node.rs @@ -1,4 +1,5 @@ use audio::block::FRAMES_PER_BLOCK_USIZE; +use audio::node::AudioNodeType; use audio::node::{AudioNodeEngine, ChannelCountMode, ChannelInfo, ChannelInterpretation}; use audio::block::{Block, Chunk}; use audio::node::BlockInfo; @@ -28,7 +29,7 @@ impl ChannelMergerNode { } impl AudioNodeEngine for ChannelMergerNode { - fn node_type(&self) -> &'static str { "ChannelMergerNode" } + fn node_type(&self) -> AudioNodeType { AudioNodeType::ChannelMergerNode } fn process(&mut self, mut inputs: Chunk, _: &BlockInfo) -> Chunk { debug_assert!(inputs.len() == self.channels as usize); @@ -78,7 +79,7 @@ impl ChannelSplitterNode { } impl AudioNodeEngine for ChannelSplitterNode { - fn node_type(&self) -> &'static str { "ChannelSplitterNode" } + fn node_type(&self) -> AudioNodeType { AudioNodeType::ChannelSplitterNode } fn process(&mut self, mut inputs: Chunk, _: &BlockInfo) -> Chunk { debug_assert!(inputs.len() == 1); diff --git a/servo-media/src/audio/destination_node.rs b/servo-media/src/audio/destination_node.rs index 6e2f06fe..7fe3757e 100644 --- a/servo-media/src/audio/destination_node.rs +++ b/servo-media/src/audio/destination_node.rs @@ -1,5 +1,4 @@ -use audio::node::ChannelInfo; -use audio::node::ChannelCountMode; +use audio::node::{AudioNodeType, ChannelCountMode, ChannelInfo}; use audio::node::{AudioNodeEngine, BlockInfo}; use audio::block::Chunk; @@ -22,7 +21,7 @@ impl DestinationNode { } impl AudioNodeEngine for DestinationNode { - fn node_type(&self) -> &'static str { "DestinationNode" } + fn node_type(&self) -> AudioNodeType { AudioNodeType::DestinationNode } fn process(&mut self, inputs: Chunk, _: &BlockInfo) -> Chunk { self.chunk = Some(inputs); diff --git a/servo-media/src/audio/gain_node.rs b/servo-media/src/audio/gain_node.rs index 931d492b..498fd3db 100644 --- a/servo-media/src/audio/gain_node.rs +++ b/servo-media/src/audio/gain_node.rs @@ -1,4 +1,4 @@ -use audio::node::ChannelInfo; +use audio::node::{AudioNodeType, ChannelInfo}; use audio::block::Chunk; use audio::block::Tick; use audio::node::AudioNodeEngine; @@ -37,7 +37,7 @@ impl GainNode { impl AudioNodeEngine for GainNode { - fn node_type(&self) -> &'static str { "GainNode" } + fn node_type(&self) -> AudioNodeType { AudioNodeType::GainNode } fn process(&mut self, mut inputs: Chunk, info: &BlockInfo) -> Chunk { debug_assert!(inputs.len() == 1); diff --git a/servo-media/src/audio/node.rs b/servo-media/src/audio/node.rs index e22fe6f1..1dfdde48 100644 --- a/servo-media/src/audio/node.rs +++ b/servo-media/src/audio/node.rs @@ -5,7 +5,7 @@ use audio::buffer_source_node::{AudioBufferSourceNodeMessage, AudioBufferSourceN use audio::gain_node::GainNodeOptions; use audio::oscillator_node::OscillatorNodeOptions; -/// Type of AudioNodeEngine. +/// Information required to construct an audio node #[derive(Debug, Clone)] pub enum AudioNodeInit { AnalyserNode, @@ -29,6 +29,31 @@ pub enum AudioNodeInit { WaveShaperNode, } +/// Type of AudioNodeEngine. +#[derive(Debug, Clone, Copy)] +pub enum AudioNodeType { + AnalyserNode, + BiquadFilterNode, + AudioBuffer, + AudioBufferSourceNode, + ChannelMergerNode, + ChannelSplitterNode, + ConstantSourceNode, + ConvolverNode, + DelayNode, + DestinationNode, + DynamicsCompressionNode, + GainNode, + IIRFilterNode, + OscillatorNode, + PannerNode, + PeriodicWave, + ScriptProcessorNode, + StereoPannerNode, + WaveShaperNode, +} + + #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum ChannelCountMode { Max, @@ -84,7 +109,7 @@ pub(crate) trait AudioNodeCommon { /// This trait represents the common features of all audio nodes. pub(crate) trait AudioNodeEngine: Send + AudioNodeCommon { - fn node_type(&self) -> &'static str; + fn node_type(&self) -> AudioNodeType; fn process(&mut self, inputs: Chunk, info: &BlockInfo) -> Chunk; @@ -139,7 +164,7 @@ pub(crate) trait AudioNodeEngine: Send + AudioNodeCommon { } fn get_param(&mut self, _: ParamType) -> &mut Param { - panic!("No params on node {}", self.node_type()) + panic!("No params on node {:?}", self.node_type()) } } diff --git a/servo-media/src/audio/oscillator_node.rs b/servo-media/src/audio/oscillator_node.rs index 07fc4a2a..2b7b7515 100644 --- a/servo-media/src/audio/oscillator_node.rs +++ b/servo-media/src/audio/oscillator_node.rs @@ -1,4 +1,4 @@ -use audio::node::ChannelInfo; +use audio::node::{AudioNodeType, ChannelInfo}; use audio::block::{Chunk, Tick}; use audio::node::{AudioNodeEngine, AudioScheduledSourceNodeMessage, BlockInfo}; use audio::param::{Param, ParamType}; @@ -80,7 +80,7 @@ impl OscillatorNode { impl AudioNodeEngine for OscillatorNode { - fn node_type(&self) -> &'static str { "OscillatorNode" } + fn node_type(&self) -> AudioNodeType { AudioNodeType::OscillatorNode } fn process(&mut self, mut inputs: Chunk, info: &BlockInfo) -> Chunk { // XXX Implement this properly and according to self.options From afba935ff09907cff2ad7d33fbb9a401014666f3 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 9 Jul 2018 16:17:52 -0700 Subject: [PATCH 6/7] Make AudioBufferSourceNode use new params --- servo-media/src/audio/buffer_source_node.rs | 20 ++++++++++---------- servo-media/src/audio/param.rs | 1 + 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/servo-media/src/audio/buffer_source_node.rs b/servo-media/src/audio/buffer_source_node.rs index 132ff1aa..3b7a2dcb 100644 --- a/servo-media/src/audio/buffer_source_node.rs +++ b/servo-media/src/audio/buffer_source_node.rs @@ -1,15 +1,13 @@ use audio::node::{AudioNodeType, ChannelInfo}; use audio::block::{Block, Chunk, Tick, FRAMES_PER_BLOCK}; use audio::node::{AudioNodeEngine, AudioScheduledSourceNodeMessage, BlockInfo}; -use audio::param::{Param, UserAutomationEvent}; +use audio::param::{Param, ParamType}; /// Control messages directed to AudioBufferSourceNodes. #[derive(Debug, Clone)] pub enum AudioBufferSourceNodeMessage { /// Set the data block holding the audio sample data to be played. SetBuffer(Option), - SetPlaybackRate(UserAutomationEvent), - SetDetune(UserAutomationEvent), } /// This specifies options for constructing an AudioBufferSourceNode. @@ -89,17 +87,11 @@ impl AudioBufferSourceNode { } } - pub fn handle_message(&mut self, message: AudioBufferSourceNodeMessage, sample_rate: f32) { + pub fn handle_message(&mut self, message: AudioBufferSourceNodeMessage, _: f32) { match message { AudioBufferSourceNodeMessage::SetBuffer(buffer) => { self.buffer = buffer; }, - AudioBufferSourceNodeMessage::SetPlaybackRate(event) => { - self.playback_rate.insert_event(event.to_event(sample_rate)); - }, - AudioBufferSourceNodeMessage::SetDetune(event) => { - self.detune.insert_event(event.to_event(sample_rate)); - } } } @@ -176,6 +168,14 @@ impl AudioNodeEngine for AudioBufferSourceNode { inputs } + fn get_param(&mut self, id: ParamType) -> &mut Param { + match id { + ParamType::PlaybackRate => &mut self.playback_rate, + ParamType::Detune => &mut self.detune, + _ => panic!("Unknown param {:?} for AudioBufferSourceNode", id) + } + } + make_message_handler!(AudioBufferSourceNode: handle_message, AudioScheduledSourceNode: handle_source_node_message); } diff --git a/servo-media/src/audio/param.rs b/servo-media/src/audio/param.rs index 9f1f74ff..63ca6ca0 100644 --- a/servo-media/src/audio/param.rs +++ b/servo-media/src/audio/param.rs @@ -6,6 +6,7 @@ pub enum ParamType { Frequency, Detune, Gain, + PlaybackRate } /// An AudioParam. From 74c4b35aa198498018b900d82ecd3f4c7a7a972e Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 9 Jul 2018 17:20:16 -0700 Subject: [PATCH 7/7] Add SetValue event --- servo-media/src/audio/param.rs | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/servo-media/src/audio/param.rs b/servo-media/src/audio/param.rs index 63ca6ca0..ea3782a2 100644 --- a/servo-media/src/audio/param.rs +++ b/servo-media/src/audio/param.rs @@ -117,6 +117,12 @@ impl Param { } pub(crate) fn insert_event(&mut self, event: AutomationEvent) { + if let AutomationEvent::SetValue(val) = event { + self.val = val; + self.event_start_value = val; + return; + } + let time = event.time(); let result = self.events.binary_search_by(|e| e.time().cmp(&time)); @@ -156,6 +162,7 @@ pub enum RampKind { /// https://webaudio.github.io/web-audio-api/#dfn-automation-event pub(crate) enum AutomationEvent { + SetValue(f32), SetValueAtTime(f32, Tick), RampToValueAtTime(RampKind, f32, Tick), SetTargetAtTime(f32, Tick, /* time constant, units of Tick */ f64), @@ -168,6 +175,7 @@ pub(crate) enum AutomationEvent { /// An AutomationEvent that uses times in s instead of Ticks pub enum UserAutomationEvent { + SetValue(f32), SetValueAtTime(f32, /* time */ f64), RampToValueAtTime(RampKind, f32, /* time */ f64), SetTargetAtTime(f32, f64, /* time constant, units of s */ f64), @@ -179,6 +187,7 @@ pub enum UserAutomationEvent { impl UserAutomationEvent { pub(crate) fn to_event(self, rate: f32) -> AutomationEvent { match self { + UserAutomationEvent::SetValue(val) => AutomationEvent::SetValue(val), UserAutomationEvent::SetValueAtTime(val, time) => AutomationEvent::SetValueAtTime(val, Tick::from_time(time, rate)), UserAutomationEvent::RampToValueAtTime(kind, val, time) => @@ -202,8 +211,8 @@ impl AutomationEvent { AutomationEvent::RampToValueAtTime(_, _, tick) => tick, AutomationEvent::SetTargetAtTime(_, start, _) => start, AutomationEvent::CancelAndHoldAtTime(t) => t, - AutomationEvent::CancelScheduledValues(..) => - unreachable!("CancelScheduledValues should never appear in the timeline"), + AutomationEvent::CancelScheduledValues(..) | AutomationEvent::SetValue(..) => + unreachable!("CancelScheduledValues/SetValue should never appear in the timeline"), } } @@ -213,8 +222,8 @@ impl AutomationEvent { AutomationEvent::RampToValueAtTime(_, _, tick) => Some(tick), AutomationEvent::SetTargetAtTime(..) => None, AutomationEvent::CancelAndHoldAtTime(t) => Some(t), - AutomationEvent::CancelScheduledValues(..) => - unreachable!("CancelScheduledValues should never appear in the timeline"), + AutomationEvent::CancelScheduledValues(..) | AutomationEvent::SetValue(..) => + unreachable!("CancelScheduledValues/SetValue should never appear in the timeline"), } } @@ -224,8 +233,8 @@ impl AutomationEvent { AutomationEvent::RampToValueAtTime(..) => None, AutomationEvent::SetTargetAtTime(_, start, _) => Some(start), AutomationEvent::CancelAndHoldAtTime(t) => Some(t), - AutomationEvent::CancelScheduledValues(..) => - unreachable!("CancelScheduledValues should never appear in the timeline"), + AutomationEvent::CancelScheduledValues(..) | AutomationEvent::SetValue(..) => + unreachable!("CancelScheduledValues/SetValue should never appear in the timeline"), } } @@ -284,8 +293,8 @@ impl AutomationEvent { AutomationEvent::CancelAndHoldAtTime(..) => { false } - AutomationEvent::CancelScheduledValues(..) => - unreachable!("CancelScheduledValues should never appear in the timeline"), + AutomationEvent::CancelScheduledValues(..) | AutomationEvent::SetValue(..) => + unreachable!("CancelScheduledValues/SetValue should never appear in the timeline"), } } }