Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented Oscillator node example to exercise different oscillator types #163

Merged
merged 7 commits into from Nov 9, 2018

Added example oscillator node file, and code to handle sine, sawtooth…

…, and square waves
  • Loading branch information
arvindmohan9683 committed Nov 8, 2018
commit 5318fc601d2435d8c2d1c5bf59f1b7bdd28968e4
@@ -6,9 +6,20 @@ use param::{Param, ParamType};

#[derive(Copy, Clone, Debug)]
pub struct PeriodicWaveOptions {
// XXX https://webaudio.github.io/web-audio-api/#dictdef-periodicwaveoptions
// https://webaudio.github.io/web-audio-api/#dictdef-periodicwaveoptions
pub real: [f32; 2],
pub imag: [f32; 2],
}
impl Default for PeriodicWaveOptions {
fn default() -> Self {
PeriodicWaveOptions {
real: [0.,0.],
imag: [0.,1.],
}
}
}


#[derive(Copy, Clone, Debug)]
pub enum OscillatorType {
Sine,
@@ -18,6 +29,8 @@ pub enum OscillatorType {
Custom,
}



#[derive(Copy, Clone, Debug)]
pub struct OscillatorNodeOptions {
pub oscillator_type: OscillatorType,
@@ -37,9 +50,12 @@ impl Default for OscillatorNodeOptions {
}
}



#[derive(AudioScheduledSourceNode, AudioNodeCommon)]
pub(crate) struct OscillatorNode {
channel_info: ChannelInfo,
oscillator_type: OscillatorType,
frequency: Param,
detune: Param,
phase: f64,
@@ -55,6 +71,7 @@ impl OscillatorNode {
pub fn new(options: OscillatorNodeOptions, channel_info: ChannelInfo) -> Self {
Self {
channel_info,
oscillator_type: options.oscillator_type,
frequency: Param::new(options.freq.into()),
detune: Param::new(options.detune.into()),
phase: 0.,
@@ -67,6 +84,8 @@ impl OscillatorNode {
pub fn update_parameters(&mut self, info: &BlockInfo, tick: Tick) -> bool {
self.frequency.update(info, tick)
}


}

impl AudioNodeEngine for OscillatorNode {
@@ -117,8 +136,46 @@ impl AudioNodeEngine for OscillatorNode {
if self.update_parameters(info, tick) {
step = two_pi * self.frequency.value() as f64 / sample_rate;
}
let value = vol * f32::sin(NumCast::from(self.phase).unwrap());
frame.mutate_with(|sample, _| *sample = value);
let mut value = vol;
println!("{:?}",self.phase );
match self.oscillator_type {
OscillatorType::Sine => {
println!("Sine\n");
value = vol * f32::sin(NumCast::from(self.phase).unwrap());
}

OscillatorType::Square => {
println!("Square\n");
if self.phase >= PI && self.phase < two_pi {
value = vol * 1.0;
}
else if self.phase > 0.0 && self.phase < PI {
value = vol * (-1.0);
}
else {
value = 0.;
}
}

OscillatorType::Custom => {
println!("custom\n");

}

OscillatorType::Sawtooth => {
println!("Sawtooth\n");
value = vol * ( (self.phase as f64) / (PI)) as f32;
}

OscillatorType::Triangle => {
println!("Triangle\n");


}
}


frame.mutate_with(|sample, _| *sample = value);

self.phase += step;
if self.phase >= two_pi {
@@ -135,6 +192,7 @@ impl AudioNodeEngine for OscillatorNode {

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),
@@ -2,7 +2,8 @@ extern crate servo_media;

use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};
use servo_media::audio::oscillator_node::OscillatorNodeOptions;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;
use servo_media::audio::oscillator_node::OscillatorType::Square;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;
use servo_media::audio::param::{ParamType, RampKind, UserAutomationEvent};
use servo_media::ServoMedia;
use std::sync::Arc;
@@ -12,27 +13,20 @@ fn run_example(servo_media: Arc<ServoMedia>) {
let context = servo_media.create_audio_context(Default::default());
let dest = context.dest_node();
let mut options = OscillatorNodeOptions::default();
options.freq = 150.;
//options.oscillator_type = Sawtooth;

options.oscillator_type = Sawtooth;

let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());
options.oscillator_type = Triangle;
//options.freq = 800.;
let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());
context.connect_ports(osc1.output(0), dest.input(0));

let _ = context.resume();
context.message_node(
osc1,
AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),
);

thread::sleep(time::Duration::from_millis(3000));
context.connect_ports(osc2.output(0), dest.input(0));
context.message_node(
osc2,
AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),
);

thread::sleep(time::Duration::from_millis(3000));

}

fn main() {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.