diff --git a/examples/audio_decoder.rs b/examples/audio_decoder.rs index e3ee8b52..b2701478 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}; +use servo_media::audio::node::{AudioNodeMessage, AudioNodeType, AudioScheduledSourceNodeMessage}; use servo_media::ServoMedia; use std::env; use std::fs::File; @@ -48,7 +48,7 @@ fn run_example(servo_media: Arc) { context.connect_ports(buffer_source.output(0), dest.input(0)); context.message_node( buffer_source, - AudioNodeMessage::AudioBufferSourceNode(AudioBufferSourceNodeMessage::Start(0.)), + AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)), ); context.message_node( buffer_source, diff --git a/examples/channels.rs b/examples/channels.rs index df97eb93..3b96622c 100644 --- a/examples/channels.rs +++ b/examples/channels.rs @@ -2,8 +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}; -use servo_media::audio::oscillator_node::OscillatorNodeMessage; +use servo_media::audio::node::{AudioNodeMessage, AudioNodeType, AudioScheduledSourceNodeMessage}; use servo_media::ServoMedia; use std::sync::Arc; use std::{thread, time}; @@ -27,11 +26,11 @@ fn run_example(servo_media: Arc) { context.connect_ports(merger.output(0), dest.input(0)); context.message_node( osc, - AudioNodeMessage::OscillatorNode(OscillatorNodeMessage::Start(0.)), + AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)), ); context.message_node( osc2, - AudioNodeMessage::OscillatorNode(OscillatorNodeMessage::Start(0.)), + AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)), ); let _ = context.resume(); diff --git a/examples/params.rs b/examples/params.rs index bac4c41f..5b86cbf5 100644 --- a/examples/params.rs +++ b/examples/params.rs @@ -1,7 +1,7 @@ extern crate servo_media; use servo_media::audio::gain_node::{GainNodeMessage, GainNodeOptions}; -use servo_media::audio::node::{AudioNodeMessage, AudioNodeType}; +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::ServoMedia; @@ -20,7 +20,7 @@ fn run_example(servo_media: Arc) { let _ = context.resume(); context.message_node( osc, - AudioNodeMessage::OscillatorNode(OscillatorNodeMessage::Start(0.)), + AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)), ); // 0.5s: Set frequency to 110Hz context.message_node( diff --git a/examples/params_settarget.rs b/examples/params_settarget.rs index 83f142b1..98e57624 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}; +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::ServoMedia; @@ -15,7 +15,7 @@ fn run_example(servo_media: Arc) { let _ = context.resume(); context.message_node( osc, - AudioNodeMessage::OscillatorNode(OscillatorNodeMessage::Start(0.)), + AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)), ); // 0.1s: Set frequency to 110Hz context.message_node( diff --git a/examples/play.rs b/examples/play.rs index 88e53054..09ead88c 100644 --- a/examples/play.rs +++ b/examples/play.rs @@ -1,7 +1,7 @@ extern crate servo_media; use servo_media::audio::gain_node::{GainNodeMessage, GainNodeOptions}; -use servo_media::audio::node::{AudioNodeMessage, AudioNodeType}; +use servo_media::audio::node::{AudioNodeMessage, AudioNodeType, AudioScheduledSourceNodeMessage}; use servo_media::audio::oscillator_node::OscillatorNodeMessage; use servo_media::audio::param::UserAutomationEvent; use servo_media::ServoMedia; @@ -19,11 +19,11 @@ fn run_example(servo_media: Arc) { context.connect_ports(gain.output(0), dest.input(0)); context.message_node( osc, - AudioNodeMessage::OscillatorNode(OscillatorNodeMessage::Start(0.)), + AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)), ); context.message_node( osc, - AudioNodeMessage::OscillatorNode(OscillatorNodeMessage::Stop(3.)), + AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Stop(3.)), ); assert_eq!(context.current_time(), 0.); let _ = context.resume(); diff --git a/examples/play_noise.rs b/examples/play_noise.rs index 0168ab40..2f3dd096 100644 --- a/examples/play_noise.rs +++ b/examples/play_noise.rs @@ -2,7 +2,7 @@ extern crate rand; extern crate servo_media; use servo_media::audio::buffer_source_node::AudioBufferSourceNodeMessage; -use servo_media::audio::node::{AudioNodeMessage, AudioNodeType}; +use servo_media::audio::node::{AudioNodeMessage, AudioNodeType, AudioScheduledSourceNodeMessage}; use servo_media::ServoMedia; use std::sync::Arc; use std::{thread, time}; @@ -18,7 +18,7 @@ fn run_example(servo_media: Arc) { } context.message_node( buffer_source, - AudioNodeMessage::AudioBufferSourceNode(AudioBufferSourceNodeMessage::Start(0.)), + AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)), ); context.message_node( buffer_source, diff --git a/servo-media/src/audio/buffer_source_node.rs b/servo-media/src/audio/buffer_source_node.rs index cda6e9a7..2d7e0848 100644 --- a/servo-media/src/audio/buffer_source_node.rs +++ b/servo-media/src/audio/buffer_source_node.rs @@ -1,6 +1,6 @@ use audio::node::ChannelCountMode; use audio::block::{Chunk, Tick, FRAMES_PER_BLOCK}; -use audio::node::{AudioNodeEngine, BlockInfo}; +use audio::node::{AudioNodeEngine, AudioScheduledSourceNodeMessage, BlockInfo}; use audio::param::Param; /// Control messages directed to AudioBufferSourceNodes. @@ -8,10 +8,6 @@ pub enum AudioBufferSourceNodeMessage { /// Set the data block holding the audio sample data to be played. // XXX handle channels SetBuffer(Vec), - /// Schedules a sound to playback at an exact time. - Start(f64), - /// Schedules a sound to stop playback at an exact time. - Stop(f64), } /// This specifies options for constructing an AudioBufferSourceNode. @@ -88,15 +84,20 @@ 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 = Some(buffer); } - AudioBufferSourceNodeMessage::Start(when) => { + } + } + + pub fn handle_source_node_message(&mut self, message: AudioScheduledSourceNodeMessage, sample_rate: f32) { + match message { + AudioScheduledSourceNodeMessage::Start(when) => { self.start(Tick::from_time(when, sample_rate)); } - AudioBufferSourceNodeMessage::Stop(when) => { + AudioScheduledSourceNodeMessage::Stop(when) => { self.stop(Tick::from_time(when, sample_rate)); } } @@ -150,5 +151,6 @@ impl AudioNodeEngine for AudioBufferSourceNode { inputs } - make_message_handler!(AudioBufferSourceNode); + make_message_handler!(AudioBufferSourceNode: handle_message, + AudioScheduledSourceNode: handle_source_node_message); } diff --git a/servo-media/src/audio/gain_node.rs b/servo-media/src/audio/gain_node.rs index dbec327e..15855eae 100644 --- a/servo-media/src/audio/gain_node.rs +++ b/servo-media/src/audio/gain_node.rs @@ -67,5 +67,5 @@ impl AudioNodeEngine for GainNode { ChannelCountMode::Max } - make_message_handler!(GainNode); + make_message_handler!(GainNode: handle_message); } diff --git a/servo-media/src/audio/macros.rs b/servo-media/src/audio/macros.rs index 6958b47b..cc1271fb 100644 --- a/servo-media/src/audio/macros.rs +++ b/servo-media/src/audio/macros.rs @@ -1,9 +1,23 @@ #[macro_export] macro_rules! make_message_handler( - ($node:ident) => ( + ( + $( + $node:ident: $handler:ident + ),+ + ) => ( fn message(&mut self, msg: ::audio::node::AudioNodeMessage, sample_rate: f32) { match msg { - ::audio::node::AudioNodeMessage::$node(m) => self.handle_message(m, sample_rate), + $(::audio::node::AudioNodeMessage::$node(m) => self.$handler(m, sample_rate)),+, + ::audio::node::AudioNodeMessage::GetInputCount(tx) => + tx.send(self.input_count()).unwrap(), + ::audio::node::AudioNodeMessage::GetOutputCount(tx) => + tx.send(self.output_count()).unwrap(), + ::audio::node::AudioNodeMessage::GetChannelCount(tx) => + tx.send(self.channel_count()).unwrap(), + ::audio::node::AudioNodeMessage::GetChannelCountMode(tx) => + tx.send(self.channel_count_mode()).unwrap(), + ::audio::node::AudioNodeMessage::GetChannelInterpretation(tx) => + tx.send(self.channel_interpretation()).unwrap(), _ => (), } }); @@ -30,5 +44,5 @@ macro_rules! make_render_thread_state_change( self.state = ProcessingState::$state; self.sink.$sink_method() } + ); ); -); diff --git a/servo-media/src/audio/node.rs b/servo-media/src/audio/node.rs index ff8b63fb..356c7521 100644 --- a/servo-media/src/audio/node.rs +++ b/servo-media/src/audio/node.rs @@ -3,6 +3,7 @@ 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 std::sync::mpsc::Sender; /// Type of AudioNodeEngine. pub enum AudioNodeType { @@ -90,7 +91,13 @@ pub trait AudioNodeEngine: Send { pub enum AudioNodeMessage { AudioBufferSourceNode(AudioBufferSourceNodeMessage), + AudioScheduledSourceNode(AudioScheduledSourceNodeMessage), GainNode(GainNodeMessage), + GetChannelCount(Sender), + GetChannelCountMode(Sender), + GetChannelInterpretation(Sender), + GetInputCount(Sender), + GetOutputCount(Sender), OscillatorNode(OscillatorNodeMessage), } @@ -105,3 +112,10 @@ pub trait AudioScheduledSourceNode { /// Returns true if the scheduling request is processed successfully. fn stop(&mut self, tick: Tick) -> bool; } + +pub enum AudioScheduledSourceNodeMessage { + /// Schedules a sound to playback at an exact time. + Start(f64), + /// Schedules a sound to stop playback at an exact time. + Stop(f64), +} diff --git a/servo-media/src/audio/oscillator_node.rs b/servo-media/src/audio/oscillator_node.rs index f6080f88..baacc213 100644 --- a/servo-media/src/audio/oscillator_node.rs +++ b/servo-media/src/audio/oscillator_node.rs @@ -1,13 +1,11 @@ use audio::node::ChannelCountMode; use audio::block::{Chunk, Tick}; -use audio::node::{AudioNodeEngine, BlockInfo}; +use audio::node::{AudioNodeEngine, AudioScheduledSourceNodeMessage, BlockInfo}; use audio::param::{Param, UserAutomationEvent}; use num_traits::cast::NumCast; pub enum OscillatorNodeMessage { SetFrequency(UserAutomationEvent), - Start(f64), - Stop(f64), } #[derive(Copy, Clone)] @@ -72,10 +70,15 @@ impl OscillatorNode { OscillatorNodeMessage::SetFrequency(event) => { self.frequency.insert_event(event.to_event(sample_rate)) } - OscillatorNodeMessage::Start(when) => { + } + } + + pub fn handle_source_node_message(&mut self, message: AudioScheduledSourceNodeMessage, sample_rate: f32) { + match message { + AudioScheduledSourceNodeMessage::Start(when) => { self.start(Tick::from_time(when, sample_rate)); } - OscillatorNodeMessage::Stop(when) => { + AudioScheduledSourceNodeMessage::Stop(when) => { self.stop(Tick::from_time(when, sample_rate)); } } @@ -146,5 +149,6 @@ impl AudioNodeEngine for OscillatorNode { ChannelCountMode::Max } - make_message_handler!(OscillatorNode); + make_message_handler!(AudioScheduledSourceNode: handle_source_node_message, + OscillatorNode: handle_message); } diff --git a/servo-media/src/audio/render_thread.rs b/servo-media/src/audio/render_thread.rs index de8af3c5..c80091c1 100644 --- a/servo-media/src/audio/render_thread.rs +++ b/servo-media/src/audio/render_thread.rs @@ -64,8 +64,6 @@ impl AudioRenderThread { make_render_thread_state_change!(suspend, Suspended, stop); - make_render_thread_state_change!(close, Closed, stop); - fn create_node(&mut self, node_type: AudioNodeType) -> NodeId { let node: Box = match node_type { AudioNodeType::AudioBufferSourceNode(options) => Box::new(AudioBufferSourceNode::new(options)), @@ -110,7 +108,7 @@ impl AudioRenderThread { let _ = tx.send(context.suspend()); } AudioRenderThreadMsg::Close(tx) => { - let _ = tx.send(context.close()); + let _ = tx.send(context.suspend()); break_loop = true; } AudioRenderThreadMsg::GetCurrentTime(response) => {