From e5b1ae6c97209eee1c1b67274caa3a81d8aa107e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Tue, 26 Jun 2018 13:03:18 +0200 Subject: [PATCH 1/4] A rendering thread is either running or suspended --- servo-media/src/audio/render_thread.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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) => { From 06643d7cccb020f641ce95834644348ee7a81ac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Tue, 26 Jun 2018 15:09:46 +0200 Subject: [PATCH 2/4] Getters for some AudioNode properties --- servo-media/src/audio/macros.rs | 3 +++ servo-media/src/audio/node.rs | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/servo-media/src/audio/macros.rs b/servo-media/src/audio/macros.rs index 6958b47b..71896219 100644 --- a/servo-media/src/audio/macros.rs +++ b/servo-media/src/audio/macros.rs @@ -4,6 +4,9 @@ macro_rules! make_message_handler( 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::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(), _ => (), } }); diff --git a/servo-media/src/audio/node.rs b/servo-media/src/audio/node.rs index ff8b63fb..0d01a0e6 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 { @@ -89,6 +90,9 @@ pub trait AudioNodeEngine: Send { } pub enum AudioNodeMessage { + GetInputCount(Sender), + GetOutputCount(Sender), + GetChannelCount(Sender), AudioBufferSourceNode(AudioBufferSourceNodeMessage), GainNode(GainNodeMessage), OscillatorNode(OscillatorNodeMessage), From fa6172a2166bf9e5123df2d5dacef7c26e07d777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Tue, 26 Jun 2018 16:34:05 +0200 Subject: [PATCH 3/4] Expose a way to send messages to AudioScheduledSourceNodes --- examples/audio_decoder.rs | 4 ++-- examples/channels.rs | 7 +++---- examples/params.rs | 4 ++-- examples/params_settarget.rs | 4 ++-- examples/play.rs | 6 +++--- examples/play_noise.rs | 4 ++-- servo-media/src/audio/buffer_source_node.rs | 20 +++++++++++--------- servo-media/src/audio/gain_node.rs | 2 +- servo-media/src/audio/macros.rs | 8 ++++++-- servo-media/src/audio/node.rs | 14 +++++++++++--- servo-media/src/audio/oscillator_node.rs | 16 ++++++++++------ 11 files changed, 53 insertions(+), 36 deletions(-) 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 71896219..3e36721f 100644 --- a/servo-media/src/audio/macros.rs +++ b/servo-media/src/audio/macros.rs @@ -1,9 +1,13 @@ #[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(), diff --git a/servo-media/src/audio/node.rs b/servo-media/src/audio/node.rs index 0d01a0e6..2006282f 100644 --- a/servo-media/src/audio/node.rs +++ b/servo-media/src/audio/node.rs @@ -90,11 +90,12 @@ pub trait AudioNodeEngine: Send { } pub enum AudioNodeMessage { - GetInputCount(Sender), - GetOutputCount(Sender), - GetChannelCount(Sender), AudioBufferSourceNode(AudioBufferSourceNodeMessage), + AudioScheduledSourceNode(AudioScheduledSourceNodeMessage), GainNode(GainNodeMessage), + GetChannelCount(Sender), + GetInputCount(Sender), + GetOutputCount(Sender), OscillatorNode(OscillatorNodeMessage), } @@ -109,3 +110,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); } From 65de8bcfe54b1333583faa154cf5c5c558a4a9be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Tue, 26 Jun 2018 17:26:23 +0200 Subject: [PATCH 4/4] Expose more getters for AudioNode properties --- servo-media/src/audio/macros.rs | 19 +++++++++++++------ servo-media/src/audio/node.rs | 2 ++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/servo-media/src/audio/macros.rs b/servo-media/src/audio/macros.rs index 3e36721f..cc1271fb 100644 --- a/servo-media/src/audio/macros.rs +++ b/servo-media/src/audio/macros.rs @@ -2,15 +2,22 @@ macro_rules! make_message_handler( ( $( - $node:ident: $handler:ident - ),+ + $node:ident: $handler:ident + ),+ ) => ( fn message(&mut self, msg: ::audio::node::AudioNodeMessage, sample_rate: f32) { match msg { $(::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::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(), _ => (), } }); @@ -37,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 2006282f..356c7521 100644 --- a/servo-media/src/audio/node.rs +++ b/servo-media/src/audio/node.rs @@ -94,6 +94,8 @@ pub enum AudioNodeMessage { AudioScheduledSourceNode(AudioScheduledSourceNodeMessage), GainNode(GainNodeMessage), GetChannelCount(Sender), + GetChannelCountMode(Sender), + GetChannelInterpretation(Sender), GetInputCount(Sender), GetOutputCount(Sender), OscillatorNode(OscillatorNodeMessage),