<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Pbhalas</id>
	<title>Expertiza_Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Pbhalas"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Pbhalas"/>
	<updated>2026-05-27T16:27:36Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=121104</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=121104"/>
		<updated>2018-12-07T00:59:31Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Build */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
[[File:initialsteps.png]]&lt;br /&gt;
[[File:Subsequentsteps.png]]&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source_node.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
* media/examples/constant_source.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::{AudioNodeEngine, AudioScheduledSourceNodeMessage, OnEndedCallback};&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo, ShouldPlay};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioScheduledSourceNode,AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
    start_at: Option&amp;lt;Tick&amp;gt;,&lt;br /&gt;
    stop_at: Option&amp;lt;Tick&amp;gt;,&lt;br /&gt;
    onended_callback: Option&amp;lt;OnEndedCallback&amp;gt;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset.into()),&lt;br /&gt;
            start_at: None,&lt;br /&gt;
            stop_at: None,&lt;br /&gt;
            onended_callback: None,&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
&lt;br /&gt;
        debug_assert!(inputs.len() == 0);&lt;br /&gt;
&lt;br /&gt;
        inputs.blocks.push(Default::default());&lt;br /&gt;
&lt;br /&gt;
        let (start_at, stop_at) = match self.should_play_at(info.frame) {&lt;br /&gt;
            ShouldPlay::No =&amp;gt; {&lt;br /&gt;
                return inputs;&lt;br /&gt;
            }&lt;br /&gt;
            ShouldPlay::Between(start, end) =&amp;gt; (start, end),&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            inputs.blocks[0].explicit_silence();&lt;br /&gt;
&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                let tick = frame.tick();&lt;br /&gt;
                if tick &amp;lt; start_at {&lt;br /&gt;
                    continue;&lt;br /&gt;
                } else if tick &amp;gt; stop_at {&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
    fn input_count(&amp;amp;self) -&amp;gt; u32{&lt;br /&gt;
        0&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    make_message_handler!(AudioScheduledSourceNode: handle_source_node_message);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; directory which realizes the implementation of Constant Source Node&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::constant_source_node::ConstantSourceNodeOptions;&lt;br /&gt;
use servo_media::audio::gain_node::GainNodeOptions;&lt;br /&gt;
use servo_media::audio::param::{ParamType, RampKind, UserAutomationEvent};&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
&lt;br /&gt;
    let mut cs_options = ConstantSourceNodeOptions::default();&lt;br /&gt;
    cs_options.offset = 0.;&lt;br /&gt;
    let cs = context.create_node(&lt;br /&gt;
        AudioNodeInit::ConstantSourceNode(cs_options.clone()),&lt;br /&gt;
        Default::default(),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    let mut gain_options = GainNodeOptions::default();&lt;br /&gt;
    gain_options.gain = 0.1;&lt;br /&gt;
    let gain = context.create_node(&lt;br /&gt;
&lt;br /&gt;
        AudioNodeInit::GainNode(gain_options.clone()),&lt;br /&gt;
&lt;br /&gt;
        Default::default(),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    let osc = context.create_node(&lt;br /&gt;
       AudioNodeInit::OscillatorNode(Default::default()),&lt;br /&gt;
       Default::default(),&lt;br /&gt;
   );&lt;br /&gt;
&lt;br /&gt;
   context.connect_ports(osc.output(0), gain.input(0));&lt;br /&gt;
   context.connect_ports(cs.output(0), gain.param(ParamType::Gain));&lt;br /&gt;
   context.connect_ports(gain.output(0), dest.input(0));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
&lt;br /&gt;
        gain,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::SetParam(&lt;br /&gt;
            ParamType::Offset,&lt;br /&gt;
            UserAutomationEvent::RampToValueAtTime(RampKind::Linear, 1., 1.5),&lt;br /&gt;
        ),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::SetParam(&lt;br /&gt;
            ParamType::Offset,&lt;br /&gt;
            UserAutomationEvent::RampToValueAtTime(RampKind::Linear, 0.1, 3.0),&lt;br /&gt;
        ),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::SetParam(&lt;br /&gt;
            ParamType::Offset,&lt;br /&gt;
            UserAutomationEvent::RampToValueAtTime(RampKind::Linear, 1., 4.5),&lt;br /&gt;
        ),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::SetParam(&lt;br /&gt;
            ParamType::Offset,&lt;br /&gt;
            UserAutomationEvent::RampToValueAtTime(RampKind::Linear, 0.1, 6.0),&lt;br /&gt;
        ),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(9000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
12/06- Completed the changes stated in the review for Constant Source Node example. The updated pull request can be accessed via [https://github.com/servo/media/pull/164 here]&lt;br /&gt;
&lt;br /&gt;
11/9- The formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
4) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./constant_source&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=121103</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=121103"/>
		<updated>2018-12-07T00:59:02Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Build */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
[[File:initialsteps.png]]&lt;br /&gt;
[[File:Subsequentsteps.png]]&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source_node.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
* media/examples/constant_source.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::{AudioNodeEngine, AudioScheduledSourceNodeMessage, OnEndedCallback};&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo, ShouldPlay};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioScheduledSourceNode,AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
    start_at: Option&amp;lt;Tick&amp;gt;,&lt;br /&gt;
    stop_at: Option&amp;lt;Tick&amp;gt;,&lt;br /&gt;
    onended_callback: Option&amp;lt;OnEndedCallback&amp;gt;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset.into()),&lt;br /&gt;
            start_at: None,&lt;br /&gt;
            stop_at: None,&lt;br /&gt;
            onended_callback: None,&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
&lt;br /&gt;
        debug_assert!(inputs.len() == 0);&lt;br /&gt;
&lt;br /&gt;
        inputs.blocks.push(Default::default());&lt;br /&gt;
&lt;br /&gt;
        let (start_at, stop_at) = match self.should_play_at(info.frame) {&lt;br /&gt;
            ShouldPlay::No =&amp;gt; {&lt;br /&gt;
                return inputs;&lt;br /&gt;
            }&lt;br /&gt;
            ShouldPlay::Between(start, end) =&amp;gt; (start, end),&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            inputs.blocks[0].explicit_silence();&lt;br /&gt;
&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                let tick = frame.tick();&lt;br /&gt;
                if tick &amp;lt; start_at {&lt;br /&gt;
                    continue;&lt;br /&gt;
                } else if tick &amp;gt; stop_at {&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
    fn input_count(&amp;amp;self) -&amp;gt; u32{&lt;br /&gt;
        0&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    make_message_handler!(AudioScheduledSourceNode: handle_source_node_message);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; directory which realizes the implementation of Constant Source Node&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::constant_source_node::ConstantSourceNodeOptions;&lt;br /&gt;
use servo_media::audio::gain_node::GainNodeOptions;&lt;br /&gt;
use servo_media::audio::param::{ParamType, RampKind, UserAutomationEvent};&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
&lt;br /&gt;
    let mut cs_options = ConstantSourceNodeOptions::default();&lt;br /&gt;
    cs_options.offset = 0.;&lt;br /&gt;
    let cs = context.create_node(&lt;br /&gt;
        AudioNodeInit::ConstantSourceNode(cs_options.clone()),&lt;br /&gt;
        Default::default(),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    let mut gain_options = GainNodeOptions::default();&lt;br /&gt;
    gain_options.gain = 0.1;&lt;br /&gt;
    let gain = context.create_node(&lt;br /&gt;
&lt;br /&gt;
        AudioNodeInit::GainNode(gain_options.clone()),&lt;br /&gt;
&lt;br /&gt;
        Default::default(),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    let osc = context.create_node(&lt;br /&gt;
       AudioNodeInit::OscillatorNode(Default::default()),&lt;br /&gt;
       Default::default(),&lt;br /&gt;
   );&lt;br /&gt;
&lt;br /&gt;
   context.connect_ports(osc.output(0), gain.input(0));&lt;br /&gt;
   context.connect_ports(cs.output(0), gain.param(ParamType::Gain));&lt;br /&gt;
   context.connect_ports(gain.output(0), dest.input(0));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
&lt;br /&gt;
        gain,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::SetParam(&lt;br /&gt;
            ParamType::Offset,&lt;br /&gt;
            UserAutomationEvent::RampToValueAtTime(RampKind::Linear, 1., 1.5),&lt;br /&gt;
        ),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::SetParam(&lt;br /&gt;
            ParamType::Offset,&lt;br /&gt;
            UserAutomationEvent::RampToValueAtTime(RampKind::Linear, 0.1, 3.0),&lt;br /&gt;
        ),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::SetParam(&lt;br /&gt;
            ParamType::Offset,&lt;br /&gt;
            UserAutomationEvent::RampToValueAtTime(RampKind::Linear, 1., 4.5),&lt;br /&gt;
        ),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::SetParam(&lt;br /&gt;
            ParamType::Offset,&lt;br /&gt;
            UserAutomationEvent::RampToValueAtTime(RampKind::Linear, 0.1, 6.0),&lt;br /&gt;
        ),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(9000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
12/06- Completed the changes stated in the review for Constant Source Node example. The updated pull request can be accessed via [https://github.com/servo/media/pull/164]&lt;br /&gt;
&lt;br /&gt;
11/9- The formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
4) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./constant_source&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=121096</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=121096"/>
		<updated>2018-12-07T00:27:15Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
[[File:initialsteps.png]]&lt;br /&gt;
[[File:Subsequentsteps.png]]&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source_node.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
* media/examples/constant_source.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::{AudioNodeEngine, AudioScheduledSourceNodeMessage, OnEndedCallback};&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo, ShouldPlay};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioScheduledSourceNode,AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
    start_at: Option&amp;lt;Tick&amp;gt;,&lt;br /&gt;
    stop_at: Option&amp;lt;Tick&amp;gt;,&lt;br /&gt;
    onended_callback: Option&amp;lt;OnEndedCallback&amp;gt;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset.into()),&lt;br /&gt;
            start_at: None,&lt;br /&gt;
            stop_at: None,&lt;br /&gt;
            onended_callback: None,&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
&lt;br /&gt;
        debug_assert!(inputs.len() == 0);&lt;br /&gt;
&lt;br /&gt;
        inputs.blocks.push(Default::default());&lt;br /&gt;
&lt;br /&gt;
        let (start_at, stop_at) = match self.should_play_at(info.frame) {&lt;br /&gt;
            ShouldPlay::No =&amp;gt; {&lt;br /&gt;
                return inputs;&lt;br /&gt;
            }&lt;br /&gt;
            ShouldPlay::Between(start, end) =&amp;gt; (start, end),&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            inputs.blocks[0].explicit_silence();&lt;br /&gt;
&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                let tick = frame.tick();&lt;br /&gt;
                if tick &amp;lt; start_at {&lt;br /&gt;
                    continue;&lt;br /&gt;
                } else if tick &amp;gt; stop_at {&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
    fn input_count(&amp;amp;self) -&amp;gt; u32{&lt;br /&gt;
        0&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    make_message_handler!(AudioScheduledSourceNode: handle_source_node_message);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; directory which realizes the implementation of Constant Source Node&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::constant_source_node::ConstantSourceNodeOptions;&lt;br /&gt;
use servo_media::audio::gain_node::GainNodeOptions;&lt;br /&gt;
use servo_media::audio::param::{ParamType, RampKind, UserAutomationEvent};&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
&lt;br /&gt;
    let mut cs_options = ConstantSourceNodeOptions::default();&lt;br /&gt;
    cs_options.offset = 0.;&lt;br /&gt;
    let cs = context.create_node(&lt;br /&gt;
        AudioNodeInit::ConstantSourceNode(cs_options.clone()),&lt;br /&gt;
        Default::default(),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    let mut gain_options = GainNodeOptions::default();&lt;br /&gt;
    gain_options.gain = 0.1;&lt;br /&gt;
    let gain = context.create_node(&lt;br /&gt;
&lt;br /&gt;
        AudioNodeInit::GainNode(gain_options.clone()),&lt;br /&gt;
&lt;br /&gt;
        Default::default(),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    let osc = context.create_node(&lt;br /&gt;
       AudioNodeInit::OscillatorNode(Default::default()),&lt;br /&gt;
       Default::default(),&lt;br /&gt;
   );&lt;br /&gt;
&lt;br /&gt;
   context.connect_ports(osc.output(0), gain.input(0));&lt;br /&gt;
   context.connect_ports(cs.output(0), gain.param(ParamType::Gain));&lt;br /&gt;
   context.connect_ports(gain.output(0), dest.input(0));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
&lt;br /&gt;
        gain,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::SetParam(&lt;br /&gt;
            ParamType::Offset,&lt;br /&gt;
            UserAutomationEvent::RampToValueAtTime(RampKind::Linear, 1., 1.5),&lt;br /&gt;
        ),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::SetParam(&lt;br /&gt;
            ParamType::Offset,&lt;br /&gt;
            UserAutomationEvent::RampToValueAtTime(RampKind::Linear, 0.1, 3.0),&lt;br /&gt;
        ),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::SetParam(&lt;br /&gt;
            ParamType::Offset,&lt;br /&gt;
            UserAutomationEvent::RampToValueAtTime(RampKind::Linear, 1., 4.5),&lt;br /&gt;
        ),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::SetParam(&lt;br /&gt;
            ParamType::Offset,&lt;br /&gt;
            UserAutomationEvent::RampToValueAtTime(RampKind::Linear, 0.1, 6.0),&lt;br /&gt;
        ),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(9000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
4) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./constant_source&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=121095</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=121095"/>
		<updated>2018-12-07T00:24:12Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Code Snippet */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
[[File:initialsteps.png]]&lt;br /&gt;
[[File:Subsequentsteps.png]]&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source_node.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
* media/examples/constant_source.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::{AudioNodeEngine, AudioScheduledSourceNodeMessage, OnEndedCallback};&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo, ShouldPlay};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioScheduledSourceNode,AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
    start_at: Option&amp;lt;Tick&amp;gt;,&lt;br /&gt;
    stop_at: Option&amp;lt;Tick&amp;gt;,&lt;br /&gt;
    onended_callback: Option&amp;lt;OnEndedCallback&amp;gt;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset.into()),&lt;br /&gt;
            start_at: None,&lt;br /&gt;
            stop_at: None,&lt;br /&gt;
            onended_callback: None,&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
&lt;br /&gt;
        debug_assert!(inputs.len() == 0);&lt;br /&gt;
&lt;br /&gt;
        inputs.blocks.push(Default::default());&lt;br /&gt;
&lt;br /&gt;
        let (start_at, stop_at) = match self.should_play_at(info.frame) {&lt;br /&gt;
            ShouldPlay::No =&amp;gt; {&lt;br /&gt;
                return inputs;&lt;br /&gt;
            }&lt;br /&gt;
            ShouldPlay::Between(start, end) =&amp;gt; (start, end),&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            inputs.blocks[0].explicit_silence();&lt;br /&gt;
&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                let tick = frame.tick();&lt;br /&gt;
                if tick &amp;lt; start_at {&lt;br /&gt;
                    continue;&lt;br /&gt;
                } else if tick &amp;gt; stop_at {&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
    fn input_count(&amp;amp;self) -&amp;gt; u32{&lt;br /&gt;
        0&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    make_message_handler!(AudioScheduledSourceNode: handle_source_node_message);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; directory which realizes the implementation of Constant Source Node&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::constant_source_node::ConstantSourceNodeOptions;&lt;br /&gt;
use servo_media::audio::gain_node::GainNodeOptions;&lt;br /&gt;
use servo_media::audio::param::{ParamType, RampKind, UserAutomationEvent};&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
&lt;br /&gt;
    let mut cs_options = ConstantSourceNodeOptions::default();&lt;br /&gt;
    cs_options.offset = 0.;&lt;br /&gt;
    let cs = context.create_node(&lt;br /&gt;
        AudioNodeInit::ConstantSourceNode(cs_options.clone()),&lt;br /&gt;
        Default::default(),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    let mut gain_options = GainNodeOptions::default();&lt;br /&gt;
    gain_options.gain = 0.1;&lt;br /&gt;
    let gain = context.create_node(&lt;br /&gt;
&lt;br /&gt;
        AudioNodeInit::GainNode(gain_options.clone()),&lt;br /&gt;
&lt;br /&gt;
        Default::default(),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    let osc = context.create_node(&lt;br /&gt;
       AudioNodeInit::OscillatorNode(Default::default()),&lt;br /&gt;
       Default::default(),&lt;br /&gt;
   );&lt;br /&gt;
&lt;br /&gt;
   context.connect_ports(osc.output(0), gain.input(0));&lt;br /&gt;
   context.connect_ports(cs.output(0), gain.param(ParamType::Gain));&lt;br /&gt;
   context.connect_ports(gain.output(0), dest.input(0));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
&lt;br /&gt;
        gain,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::SetParam(&lt;br /&gt;
            ParamType::Offset,&lt;br /&gt;
            UserAutomationEvent::RampToValueAtTime(RampKind::Linear, 1., 1.5),&lt;br /&gt;
        ),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::SetParam(&lt;br /&gt;
            ParamType::Offset,&lt;br /&gt;
            UserAutomationEvent::RampToValueAtTime(RampKind::Linear, 0.1, 3.0),&lt;br /&gt;
        ),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::SetParam(&lt;br /&gt;
            ParamType::Offset,&lt;br /&gt;
            UserAutomationEvent::RampToValueAtTime(RampKind::Linear, 1., 4.5),&lt;br /&gt;
        ),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        cs,&lt;br /&gt;
        AudioNodeMessage::SetParam(&lt;br /&gt;
            ParamType::Offset,&lt;br /&gt;
            UserAutomationEvent::RampToValueAtTime(RampKind::Linear, 0.1, 6.0),&lt;br /&gt;
        ),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(9000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=121094</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=121094"/>
		<updated>2018-12-07T00:19:39Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Files (to be) modified */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
[[File:initialsteps.png]]&lt;br /&gt;
[[File:Subsequentsteps.png]]&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source_node.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
* media/examples/constant_source.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120533</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120533"/>
		<updated>2018-11-21T01:17:07Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Code Snippet */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
[[File:initialsteps.png]]&lt;br /&gt;
[[File:Subsequentsteps.png]]&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120531</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120531"/>
		<updated>2018-11-21T01:16:38Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
[[File:initialsteps.png]]&lt;br /&gt;
[[File:Subsequentsteps.png]]&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120529</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120529"/>
		<updated>2018-11-21T01:15:38Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Subsequent Steps */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
[[File:initialsteps.png]]&lt;br /&gt;
[[File:Subsequentsteps.png]]&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Pull Request'''===&lt;br /&gt;
&lt;br /&gt;
The pull request used to incorporate our changes upstream is available [https://github.com/servo/media/pull/163 here]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Subsequentsteps.png&amp;diff=120526</id>
		<title>File:Subsequentsteps.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Subsequentsteps.png&amp;diff=120526"/>
		<updated>2018-11-21T01:14:55Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: uploaded a new version of &amp;amp;quot;File:Subsequentsteps.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Subsequentsteps.png&amp;diff=120521</id>
		<title>File:Subsequentsteps.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Subsequentsteps.png&amp;diff=120521"/>
		<updated>2018-11-21T01:11:20Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120520</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120520"/>
		<updated>2018-11-21T01:10:44Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Subsequent Steps */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
[[File:initialsteps.png]]&lt;br /&gt;
[[File:subsequentsteps.png]]&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Pull Request'''===&lt;br /&gt;
&lt;br /&gt;
The pull request used to incorporate our changes upstream is available [https://github.com/servo/media/pull/163 here]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Initialsteps.png&amp;diff=120516</id>
		<title>File:Initialsteps.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Initialsteps.png&amp;diff=120516"/>
		<updated>2018-11-21T01:08:19Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120513</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120513"/>
		<updated>2018-11-21T01:05:12Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Subsequent Steps */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:initial_steps.png|249x599px]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Pull Request'''===&lt;br /&gt;
&lt;br /&gt;
The pull request used to incorporate our changes upstream is available [https://github.com/servo/media/pull/163 here]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120511</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120511"/>
		<updated>2018-11-21T01:04:55Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Subsequent Steps */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:is.png|249x599px]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Pull Request'''===&lt;br /&gt;
&lt;br /&gt;
The pull request used to incorporate our changes upstream is available [https://github.com/servo/media/pull/163 here]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120509</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120509"/>
		<updated>2018-11-21T01:04:36Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Subsequent Steps */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:initial_steps.png|249x599px]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Pull Request'''===&lt;br /&gt;
&lt;br /&gt;
The pull request used to incorporate our changes upstream is available [https://github.com/servo/media/pull/163 here]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120504</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120504"/>
		<updated>2018-11-21T01:03:20Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Subsequent Steps */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:initial_steps.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Pull Request'''===&lt;br /&gt;
&lt;br /&gt;
The pull request used to incorporate our changes upstream is available [https://github.com/servo/media/pull/163 here]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120503</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120503"/>
		<updated>2018-11-21T01:02:36Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Subsequent Steps */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:initial_steps.png|200px]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Pull Request'''===&lt;br /&gt;
&lt;br /&gt;
The pull request used to incorporate our changes upstream is available [https://github.com/servo/media/pull/163 here]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120502</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120502"/>
		<updated>2018-11-21T01:02:16Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Subsequent Steps */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:initial_steps.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Pull Request'''===&lt;br /&gt;
&lt;br /&gt;
The pull request used to incorporate our changes upstream is available [https://github.com/servo/media/pull/163 here]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120501</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120501"/>
		<updated>2018-11-21T01:01:51Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Subsequent Steps */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:initial_steps.png|200x200px]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Pull Request'''===&lt;br /&gt;
&lt;br /&gt;
The pull request used to incorporate our changes upstream is available [https://github.com/servo/media/pull/163 here]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120500</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120500"/>
		<updated>2018-11-21T01:01:37Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Subsequent Steps */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:initial_steps.png|100x200px]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Pull Request'''===&lt;br /&gt;
&lt;br /&gt;
The pull request used to incorporate our changes upstream is available [https://github.com/servo/media/pull/163 here]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120497</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120497"/>
		<updated>2018-11-21T00:59:04Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Subsequent Steps */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:initial_steps.png|upright=default]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Pull Request'''===&lt;br /&gt;
&lt;br /&gt;
The pull request used to incorporate our changes upstream is available [https://github.com/servo/media/pull/163 here]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120496</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120496"/>
		<updated>2018-11-21T00:58:30Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:initial_steps.png|upright=0.5]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Pull Request'''===&lt;br /&gt;
&lt;br /&gt;
The pull request used to incorporate our changes upstream is available [https://github.com/servo/media/pull/163 here]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120495</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120495"/>
		<updated>2018-11-21T00:55:11Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:initial_steps.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Pull Request'''===&lt;br /&gt;
&lt;br /&gt;
The pull request used to incorporate our changes upstream is available [https://github.com/servo/media/pull/163 here]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120494</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120494"/>
		<updated>2018-11-21T00:50:24Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Pull Request'''===&lt;br /&gt;
&lt;br /&gt;
The pull request used to incorporate our changes upstream is available [https://github.com/servo/media/pull/163 here]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120493</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120493"/>
		<updated>2018-11-21T00:49:59Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Subsequent Steps= */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Pull Request'''===&lt;br /&gt;
&lt;br /&gt;
The pull request used to incorporate our changes upstream is available [https://github.com/servo/media/pull/163 here]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120492</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120492"/>
		<updated>2018-11-21T00:49:40Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
=='''Subsequent Steps'''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Pull Request'''===&lt;br /&gt;
&lt;br /&gt;
The pull request used to incorporate our changes upstream is available [https://github.com/servo/media/pull/163 here]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120491</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120491"/>
		<updated>2018-11-21T00:49:08Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design'''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps'''==&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
=='''Subsequent Steps'''==&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
=='''Files (to be) modified'''==&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Pull Request'''===&lt;br /&gt;
&lt;br /&gt;
The pull request used to incorporate our changes upstream is available [https://github.com/servo/media/pull/163 here]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120490</id>
		<title>M1852 Implement missing WebAudio node support</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=M1852_Implement_missing_WebAudio_node_support&amp;diff=120490"/>
		<updated>2018-11-21T00:47:55Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=='''Introduction'''== &lt;br /&gt;
&lt;br /&gt;
==='''Servo'''===&lt;br /&gt;
Servo is a modern, high-performance browser engine designed for both application and embedded use and written in the Rust programming language.&lt;br /&gt;
It is currently developed on 64bit OS X, 64bit Linux, and Android.&lt;br /&gt;
&lt;br /&gt;
More information about Servo is available [https://servo.org here]&lt;br /&gt;
&lt;br /&gt;
==='''Rust'''===&lt;br /&gt;
Rust is a systems programming language focuses on memory safety and concurrency. It is similar to C++ but ensures memory safety and high performance.&lt;br /&gt;
&lt;br /&gt;
More information about Rust can be found [https://www.rust-lang.org/en-US/ here]&lt;br /&gt;
&lt;br /&gt;
==='''Web Audio API'''===&lt;br /&gt;
The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources — with different types of channel layout — are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects.&lt;br /&gt;
&lt;br /&gt;
Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams (MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave.&lt;br /&gt;
&lt;br /&gt;
Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination (AudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio.&lt;br /&gt;
&lt;br /&gt;
A simple, typical workflow for web audio would look something like this:&lt;br /&gt;
&lt;br /&gt;
1. Create audio context&amp;lt;br&amp;gt;&lt;br /&gt;
2. Inside the context, create sources — such as &amp;lt;audio&amp;gt;, oscillator, stream&amp;lt;br&amp;gt;&lt;br /&gt;
3. Create effects nodes, such as reverb, biquad filter, panner, compressor&amp;lt;br&amp;gt;&lt;br /&gt;
4. Choose final destination of audio, for example your system speakers&amp;lt;br&amp;gt;&lt;br /&gt;
5. Connect the sources up to the effects, and the effects to the destination.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''== &lt;br /&gt;
Major browsers support the WebAudio standard which can be used to create complex media playback applications from low-level building blocks. Servo is a new, experimental browser that supports some of these building blocks (called audio nodes); the goal of this project is to to improve compatibility with web content that relies on the WebAudio API by implementing missing pieces of incomplete node types (OscillatorNode) along with entire missing nodes (ConstantSourceNode, StereoPannerNode, IIRFilterNode). Additional project information is available [https://github.com/servo/servo/wiki/WebAudio-nodes-student-project#implement-support-for-several-missing-webaudio-node-types here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Proposed Design''==&lt;br /&gt;
Our design and plan of work is split into two set of tasks- Initial steps and Subsequent steps.&lt;br /&gt;
&lt;br /&gt;
==='''Initial Steps''===&lt;br /&gt;
* To create a new example program- media/examples/oscillator.rs that exercises the different oscillator types&lt;br /&gt;
* To implement the processing algorithm for the different oscillator types like Sine, Square, Sawtooth, Triangle and a Custom wave based on user's input in media/audio/src/oscillator_node.rs so that the example programs in media/examples/oscillator.rs sound correct.&lt;br /&gt;
* To implement the missing ConstantSource node type in a new constant_source.rs file in the directory media/audio/src that produces a constant tone based a stored value that can be modified.&lt;br /&gt;
* To create the DOM interface for ConstantSourceNode and implement the createConstantSource API for BaseAudioContext&lt;br /&gt;
* To connect the DOM interface to the underlying backend node by processing the unimplemented message type.&lt;br /&gt;
&lt;br /&gt;
==='''Subsequent Steps''===&lt;br /&gt;
* To implement the backend for StereoPannerNode in the media crate by creating a new node. To create a runnable example for the same.&lt;br /&gt;
* To create the DOM interface for StereoPannerNode and implement the createStereoPannerNode API for BaseAudioContext&lt;br /&gt;
* To create the DOM interface for IIRFilterNode and implement the createIIRFilterNode API for BaseAudioContext.&lt;br /&gt;
* To implement the backend for IIRFilterNode based on the specification's processing model and create a runnable example&lt;br /&gt;
&lt;br /&gt;
==='''Files (to be) modified''===&lt;br /&gt;
* media/audio/src/oscillator_node.rs&lt;br /&gt;
* media/audio/src/constant_source.rs&lt;br /&gt;
* media/audio/src/node.rs&lt;br /&gt;
* media/audio/src/lib.rs&lt;br /&gt;
* media/audio/src/render_thread.rs&lt;br /&gt;
* media/audio/src/param.rs&lt;br /&gt;
* media/examples/oscillator.rs&lt;br /&gt;
&lt;br /&gt;
=='''Implementation'''==&lt;br /&gt;
Our current implementation involves audio processing for Sine, Square, Sawtooth and Triangle waveforms and we are working on generating the Custom wave. We created a oscillator.rs file which includes examples of the given waveforms. These waveforms can be visualized using the given image:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Waveform.jpg]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OscillatorType&amp;quot; variable is a string which has the name of the waveform associated with it. For each waveform, we calculate the value which is used by the OscilaterNode class to generate a wave. Each type of wave has a particular output. The output is a function of phase, with each waveform having its own function as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:Sine.png]]&amp;lt;/center&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SquareTriangleSawtooth.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Code Snippet'''===&lt;br /&gt;
The following changes have been done in the &amp;lt;code&amp;gt;oscillator_node.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory where the function to generate the waveforms is written&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             // Convert all our parameters to the target type for calculations&lt;br /&gt;
             let vol: f32 = 1.0;&lt;br /&gt;
             let sample_rate = info.sample_rate as f64;&lt;br /&gt;
             let two_pi = 2.0 * PI;&lt;br /&gt;
 &lt;br /&gt;
             // We're carrying a phase with up to 2pi around instead of working&lt;br /&gt;
             // on the sample offset. High sample offsets cause too much inaccuracy when&lt;br /&gt;
             // converted to floating point numbers and then iterated over in 1-steps&lt;br /&gt;
             //&lt;br /&gt;
             // Also, if the frequency changes the phase should not&lt;br /&gt;
             let mut step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
             while let Some(mut frame) = iter.next() {&lt;br /&gt;
                 let tick = frame.tick();&lt;br /&gt;
                 if tick &amp;lt; start_at {&lt;br /&gt;
                     continue&lt;br /&gt;
                 } else if tick &amp;gt; stop_at {&lt;br /&gt;
                     break;&lt;br /&gt;
                 }&lt;br /&gt;
 &lt;br /&gt;
                 if self.update_parameters(info, tick) {&lt;br /&gt;
                     step = two_pi * self.frequency.value() as f64 / sample_rate;&lt;br /&gt;
                 }&lt;br /&gt;
                 let mut value = vol;&lt;br /&gt;
&lt;br /&gt;
                 //Based on the type of wave, the value is calculated using the formulae for the respective waveform &lt;br /&gt;
                 match self.oscillator_type {&lt;br /&gt;
                     OscillatorType::Sine =&amp;gt; {&lt;br /&gt;
                         value = vol * f32::sin(NumCast::from(self.phase).unwrap());&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Square =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; two_pi {&lt;br /&gt;
                                     value = vol * 1.0;&lt;br /&gt;
                                 }&lt;br /&gt;
                                 else if self.phase &amp;gt; 0.0 &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                                     value = vol * (-1.0);&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Sawtooth =&amp;gt; {&lt;br /&gt;
                         value = vol * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                     }&lt;br /&gt;
 &lt;br /&gt;
                     OscillatorType::Triangle =&amp;gt; {&lt;br /&gt;
                         if self.phase &amp;gt;= 0. &amp;amp;&amp;amp; self.phase &amp;lt; PI/2.{&lt;br /&gt;
                             value = vol * 2.0 * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; PI {&lt;br /&gt;
                             value = vol * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= PI &amp;amp;&amp;amp; self.phase &amp;lt; (3.* PI/2.) {&lt;br /&gt;
                             value = vol * -1. * ( 1. - ( ( (self.phase as f64) - (PI/2.)) * (2./PI) ) as f32 );&lt;br /&gt;
                         }&lt;br /&gt;
                         else if self.phase &amp;gt;= 3.*PI/2. &amp;amp;&amp;amp; self.phase &amp;lt; 2.*PI {&lt;br /&gt;
                             value = vol * (-2.0) * ((self.phase as f64) / (PI)) as f32;&lt;br /&gt;
                         }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt; oscillator.rs &amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;media/examples/ &amp;lt;/code&amp;gt; directory has been created by us which generates objects and calls methods to run the different oscillator type examples&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
extern crate servo_media;&lt;br /&gt;
&lt;br /&gt;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorNodeOptions;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Sawtooth;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Triangle;&lt;br /&gt;
//use servo_media::audio::oscillator_node::OscillatorType::Sine;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Custom;&lt;br /&gt;
use servo_media::audio::oscillator_node::OscillatorType::Square;&lt;br /&gt;
use servo_media::ServoMedia;&lt;br /&gt;
use std::sync::Arc;&lt;br /&gt;
use std::{thread, time};&lt;br /&gt;
&lt;br /&gt;
fn run_example(servo_media: Arc&amp;lt;ServoMedia&amp;gt;) {&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let mut options = OscillatorNodeOptions::default();&lt;br /&gt;
    let osc1 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc1.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc1,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Square;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc2 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc2.output(0), dest.input(0));&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc2,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Sawtooth;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc3 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc3.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc3,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Triangle;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc4 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc4.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc4,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
    let _ = context.close();&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(1000));&lt;br /&gt;
&lt;br /&gt;
    options.oscillator_type = Custom;&lt;br /&gt;
    let context = servo_media.create_audio_context(Default::default());&lt;br /&gt;
    let dest = context.dest_node();&lt;br /&gt;
    let osc5 = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default());&lt;br /&gt;
    context.connect_ports(osc5.output(0), dest.input(0));&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
&lt;br /&gt;
    let _ = context.resume();&lt;br /&gt;
    context.message_node(&lt;br /&gt;
        osc5,&lt;br /&gt;
        AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),&lt;br /&gt;
    );&lt;br /&gt;
    thread::sleep(time::Duration::from_millis(3000));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    if let Ok(servo_media) = ServoMedia::get() {&lt;br /&gt;
        run_example(servo_media);&lt;br /&gt;
    } else {&lt;br /&gt;
        unreachable!();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After running the code, different sound patterns are created with respect to each waveform (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
We created the &amp;lt;code&amp;gt;constant_source.rs&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;audio/src/&amp;lt;/code&amp;gt; directory which has the function to generate a constant tone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
use block::Chunk;&lt;br /&gt;
use block::Tick;&lt;br /&gt;
use node::AudioNodeEngine;&lt;br /&gt;
use node::BlockInfo;&lt;br /&gt;
use node::{AudioNodeType, ChannelInfo};&lt;br /&gt;
use param::{Param, ParamType};&lt;br /&gt;
&lt;br /&gt;
#[derive(Copy, Clone, Debug)]&lt;br /&gt;
pub struct ConstantSourceNodeOptions {&lt;br /&gt;
    pub offset: f32,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Default for ConstantSourceNodeOptions {&lt;br /&gt;
    fn default() -&amp;gt; Self {&lt;br /&gt;
        ConstantSourceNodeOptions { offset: 1. }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#[derive(AudioNodeCommon)]&lt;br /&gt;
pub(crate) struct ConstantSourceNode {&lt;br /&gt;
    channel_info: ChannelInfo,&lt;br /&gt;
    offset: Param,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl ConstantSourceNode {&lt;br /&gt;
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -&amp;gt; Self {&lt;br /&gt;
        Self {&lt;br /&gt;
            channel_info,&lt;br /&gt;
            offset: Param::new(options.offset),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    pub fn update_parameters(&amp;amp;mut self, info: &amp;amp;BlockInfo, tick: Tick) -&amp;gt; bool {&lt;br /&gt;
        self.offset.update(info, tick)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl AudioNodeEngine for ConstantSourceNode {&lt;br /&gt;
    fn node_type(&amp;amp;self) -&amp;gt; AudioNodeType {&lt;br /&gt;
        AudioNodeType::ConstantSourceNode&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn process(&amp;amp;mut self, mut inputs: Chunk, info: &amp;amp;BlockInfo) -&amp;gt; Chunk {&lt;br /&gt;
        debug_assert!(inputs.len() == 1);&lt;br /&gt;
        inputs.blocks[0].explicit_silence();&lt;br /&gt;
      if inputs.blocks[0].is_silence() {&lt;br /&gt;
            return inputs;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
            let mut iter = inputs.blocks[0].iter();&lt;br /&gt;
            let mut offset = self.offset.value();&lt;br /&gt;
            while let Some(mut frame) = iter.next() {&lt;br /&gt;
                if self.update_parameters(info, frame.tick()) {&lt;br /&gt;
                    offset = self.offset.value();&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                frame.mutate_with(|sample, _| *sample = offset);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        inputs&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fn get_param(&amp;amp;mut self, id: ParamType) -&amp;gt; &amp;amp;mut Param {&lt;br /&gt;
        match id {&lt;br /&gt;
            ParamType::Offset =&amp;gt; &amp;amp;mut self.offset,&lt;br /&gt;
            _ =&amp;gt; panic!(&amp;quot;Unknown param {:?} for the offset&amp;quot;, id),&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Build'''==&lt;br /&gt;
&lt;br /&gt;
11/9- The the formatted changes have been committed as said in the review.The changes to the formatting can be seen [https://github.com/Avanthikaa/media/commit/5d8cdfc029daf69122c64f8bfcceaec6f80916a4 here]&lt;br /&gt;
&lt;br /&gt;
[[File:format_commit.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;&amp;lt;big&amp;gt;11/8- A Servo team member (@Manishearth) &amp;lt;b&amp;gt;approved&amp;lt;/b&amp;gt; the pull request and advised us to make some minor formatting changes.&amp;lt;/big&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:pullReq.png]]&lt;br /&gt;
&lt;br /&gt;
11/8- Submitted a pull request which contained the new oscillator.rs file having the examples of implementation of the different OscillatorType or waveforms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have opened our pull request and are working on getting it merged based on the reviews received. Please use our forked repository till the pull request is merged.&lt;br /&gt;
&lt;br /&gt;
Forked repository: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;https://github.com/servo/media&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone command using git:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;git clone https://github.com/servo/media.git&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the forked repo, please follow steps [https://github.com/servo/media#servo-media here] to do a build.&lt;br /&gt;
&lt;br /&gt;
Note that build may take up to 45 minutes, based on your system configuration.&lt;br /&gt;
&lt;br /&gt;
==='''Installing dependencies'''===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Installing Rust&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial step is to install Rust. You can do so by installing Rustup, version 1.8.0 or more recent.&lt;br /&gt;
&lt;br /&gt;
1. To install on Windows, download and run [https://win.rustup.rs/ rustup-init.exe] then follow the onscreen instructions.&lt;br /&gt;
&lt;br /&gt;
2. To install on other systems, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl https://sh.rustup.rs -sSf | sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other installation methds click [https://github.com/rust-lang-nursery/rustup.rs/#other-installation-methods here]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Debian-based Linuxes are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Run &amp;lt;code&amp;gt;./mach bootstrap.&amp;lt;/code&amp;gt; If this fails, run the commands below:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    sudo apt install git curl autoconf libx11-dev \&lt;br /&gt;
    libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \&lt;br /&gt;
    gperf g++ build-essential cmake virtualenv python-pip \&lt;br /&gt;
    libssl1.0-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \&lt;br /&gt;
    libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \&lt;br /&gt;
    libharfbuzz-dev ccache clang \&lt;br /&gt;
    libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev autoconf2.13&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If you using a version prior to Ubuntu 17.04 or Debian Sid, replace libssl1.0-dev with libssl-dev. Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in support/linux/gstreamer/gstreamer, or run ./mach bootstrap-gstreamer to set it up.&lt;br /&gt;
&lt;br /&gt;
If you are using Ubuntu 16.04 run export HARFBUZZ_SYS_NO_PKG_CONFIG=1 before building to avoid an error with harfbuzz.&lt;br /&gt;
&lt;br /&gt;
If you are on Ubuntu 14.04 and encountered errors on installing these dependencies involving libcheese, see #6158 for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:&lt;br /&gt;
&lt;br /&gt;
If virtualenv does not exist, try python-virtualenv.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Local build instructions for Windows environments are given below:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). &lt;br /&gt;
&lt;br /&gt;
The Windows x86-64 MSI installer is fine. You should change the installation to install the &amp;quot;Add python.exe to Path&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
2. Install virtualenv.&lt;br /&gt;
&lt;br /&gt;
In a normal Windows Shell (cmd.exe or &amp;quot;Command Prompt&amp;quot; from the start menu), do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;pip install virtualenv&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this does not work, you may need to reboot for the changed PATH settings (by the python installer) to take effect.&lt;br /&gt;
&lt;br /&gt;
3. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine).&lt;br /&gt;
&lt;br /&gt;
4. Install Visual Studio Community 2017 (https://www.visualstudio.com/vs/community/). &lt;br /&gt;
&lt;br /&gt;
You MUST add &amp;quot;Visual C++&amp;quot; to the list of installed components. It is not on by default. Visual Studio 2017 MUST installed to the default location or mach.bat will not find it.&lt;br /&gt;
&lt;br /&gt;
If you encountered errors with the environment above, do the following for a workaround:&lt;br /&gt;
&lt;br /&gt;
Download and install Build Tools for Visual Studio 2017&lt;br /&gt;
&lt;br /&gt;
Install python2.7 x86-x64 and virtualenv&lt;br /&gt;
&lt;br /&gt;
5. Run &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;mach.bat build -d&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; to build&lt;br /&gt;
&lt;br /&gt;
If you have troubles with x64 type prompt as mach.bat set by default:&lt;br /&gt;
&lt;br /&gt;
you may need to choose and launch the type manually, such as x86_x64 Cross Tools Command Prompt for VS 2017 in the Windows menu.)&lt;br /&gt;
&lt;br /&gt;
cd to/the/path/servo&lt;br /&gt;
&lt;br /&gt;
python mach build -d&lt;br /&gt;
&lt;br /&gt;
Build instructions for all other environments are available [https://github.com/servo/servo here]&lt;br /&gt;
&lt;br /&gt;
==='''Building locally'''===&lt;br /&gt;
&lt;br /&gt;
Once you complete the above steps to install dependencies, following are steps to build servo:&lt;br /&gt;
 &lt;br /&gt;
To build Servo in development mode. This is useful for development, but the resulting binary is very slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
./mach build --dev&lt;br /&gt;
./mach run tests/html/about-mozilla.html &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or on Windows MSVC, in a normal Command Prompt (cmd.exe):&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
git clone https://github.com/servo/servo&lt;br /&gt;
cd servo&lt;br /&gt;
mach.bat build --dev &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./mach build --release&lt;br /&gt;
./mach run --release tests/html/about-mozilla.html&lt;br /&gt;
Note: mach build will build both servo and libsimpleservo. To make compilation a bit faster, it's possible to only compile the servo binary: ./mach build --dev -p servo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Running a build'''===&lt;br /&gt;
&lt;br /&gt;
We can quickly verify if the servo build is working by running the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;'./mach run http://www.google.com'&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will open a browser instance rendering the Google homepage. &lt;br /&gt;
&lt;br /&gt;
This should be straightforward on any environment that has rendering support - Linus, Windows, MacOS, Android&lt;br /&gt;
&lt;br /&gt;
=='''Test Plan'''==&lt;br /&gt;
&lt;br /&gt;
'''Testing Approach'''&lt;br /&gt;
&lt;br /&gt;
As we have implemented the processing algorithm for oscillator different oscillator types, after running the rust file the user will be able to hear the different generated waveforms based on its type. (Sine, Square, Sawtooth, Triangle)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing Steps'''&lt;br /&gt;
&lt;br /&gt;
Please read and perform the actions on the Build and Verification sections properly before testing.&lt;br /&gt;
&lt;br /&gt;
1) Make sure you are in this directory: &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;target/debug&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Run the command &amp;lt;big&amp;gt;&amp;lt;code&amp;gt;./oscillator&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Different sounds  based on the type of oscillator (waveform) must be generated after definite interval of time.&lt;br /&gt;
&lt;br /&gt;
Examples for the different sound waves can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/d1/220_Hz_sine_wave.ogg Sine]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/9/92/Square_wave_1000.ogg Square]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://en.audiofanzine.com/medias/audio/#id:473859 Sawtooth]&lt;br /&gt;
&amp;lt;li&amp;gt;[https://upload.wikimedia.org/wikipedia/commons/d/df/220_Hz_anti-aliased_triangle_wave.ogg Triangle]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Pull Request'''===&lt;br /&gt;
&lt;br /&gt;
The pull request used to incorporate our changes upstream is available [https://github.com/servo/media/pull/163 here]&lt;br /&gt;
&lt;br /&gt;
=='''References'''==&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API&lt;br /&gt;
&lt;br /&gt;
https://webaudio.github.io/web-audio-api/&lt;br /&gt;
&lt;br /&gt;
https://doc.servo.org/servo/index.html  &lt;br /&gt;
&lt;br /&gt;
http://www.servo.org&lt;br /&gt;
&lt;br /&gt;
https://doc.rust-lang.org/rust-by-example/&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Initial_steps.png&amp;diff=120485</id>
		<title>File:Initial steps.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Initial_steps.png&amp;diff=120485"/>
		<updated>2018-11-21T00:45:52Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1835_Refactor_delayed_mailer_and_scheduled_task&amp;diff=119078</id>
		<title>E1835 Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1835_Refactor_delayed_mailer_and_scheduled_task&amp;diff=119078"/>
		<updated>2018-11-09T19:47:28Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Testing using RSPEC */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework. Expertiza allows the instructor to create new assignments, modify existing assignments and set deadlines. The instructor can also create a list of project topics that the students can sign up for.  Expertiza allows students to peer review submissions of other students as well as do teammate reviews. Students can form team on Expertiza to work on assignments and projects.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
* Used Sidekiq gem for asynchronous processing of email jobs&lt;br /&gt;
* Created a new mailer class- MailWorker that uses Sidekiq's queue to hold and process jobs&lt;br /&gt;
* Defined the perform method to extract the Email IDs of all participants of the corresponding assignment and send an email reminder&lt;br /&gt;
* Replaced the code that uses the existing DelayedMailer queue to incorporate Sidekiq's queue&lt;br /&gt;
* Added RSPEC test cases to test the creation of assignment deadlines and background Sidekiq email job&lt;br /&gt;
&lt;br /&gt;
== About Sidekiq ==&lt;br /&gt;
&lt;br /&gt;
Sidekiq is a background processing framework for Ruby. It allows to scale our application by performing work in the background. In particular it consists of three parts: Client, Redis and Server. The client runs in Ruby process and allows us to create jobs for processing later. Once a job is created, a Hash representing that job is created and serialized to a Json String. This String is pushed into a queue in Redis. Redis provides data storage for Sidekiq and holds all the job data. Each Sidekiq server process pulls jobs from the queue in Redis and processes them. &lt;br /&gt;
&lt;br /&gt;
== Current Implementation ==&lt;br /&gt;
&lt;br /&gt;
* Uses the 'delayed_job_active_record' gem for asynchronous processing of delayed jobs&lt;br /&gt;
::The current implementation uses Delayed::Job for implementing a Database based asynchronous priority queue system for storing the job queue of email reminders corresponding to various deadline types. &lt;br /&gt;
* Email reminders were sent to users corresponding to each deadline type&lt;br /&gt;
::The DelayedMailer class includes a perform method that finds Email IDs of the target users  corresponding to the deadline type. The subject and body of the email message is then constructed and the delayed_message method of Mailer class is used for sending the emails out to the users.&lt;br /&gt;
* Uses DelayedJob to enqueue email jobs &lt;br /&gt;
::The DelayedMailer object is enqueued into the DelayedJob queue using enqueue method. These jobs are meant to be executed as the deadline of the corresponding Email job approaches.&lt;br /&gt;
&lt;br /&gt;
== Drawbacks and Solutions ==&lt;br /&gt;
'''Problem 1''': The perform method in the DelayedMailer class contains a big case statement to check each kind of deadline&lt;br /&gt;
&lt;br /&gt;
The perform method in DelayedMailer class checks the deadline type individually using multiple if statements and populates the Email IDs of the target users by querying the database. Auxiliary methods like, for example, mail_signed_up_users is invoked which in turn calls the email_reminder method. &lt;br /&gt;
This makes the implementation very cumbersome and does not follow the principles of DRY code as the same email_reminder method is called multiple times under different conditions.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform&lt;br /&gt;
assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
   if !assignment.nil? &amp;amp;&amp;amp; !assignment.id.nil?&lt;br /&gt;
     if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
       mail_metareviewers&lt;br /&gt;
       team_mails = find_team_members_email&lt;br /&gt;
       email_reminder(team_mails, &amp;quot;teammate review&amp;quot;) unless team_mails.empty?&lt;br /&gt;
     end&lt;br /&gt;
     if self.deadline_type == &amp;quot;review&amp;quot;&lt;br /&gt;
       mail_reviewers # to all reviewers&lt;br /&gt;
     end&lt;br /&gt;
     if self.deadline_type == &amp;quot;submission&amp;quot;&lt;br /&gt;
       mail_signed_up_users # to all signed up users&lt;br /&gt;
     end&lt;br /&gt;
     if self.deadline_type == &amp;quot;drop_topic&amp;quot;&lt;br /&gt;
       if sign_up_topics?&lt;br /&gt;
         mail_signed_up_users # reminder to signed_up users of the assignment&lt;br /&gt;
       end&lt;br /&gt;
     end&lt;br /&gt;
     if self.deadline_type == &amp;quot;signup&amp;quot;&lt;br /&gt;
       if sign_up_topics?&lt;br /&gt;
         mail_assignment_participants # reminder to all participants&lt;br /&gt;
       end&lt;br /&gt;
     end&lt;br /&gt;
     if self.deadline_type == &amp;quot;team_formation&amp;quot;&lt;br /&gt;
       emails = get_one_member_team&lt;br /&gt;
       email_reminder(emails, self.deadline_type)&lt;br /&gt;
     end&lt;br /&gt;
     if self.deadline_type == &amp;quot;drop_one_member_topics&amp;quot;&lt;br /&gt;
       drop_one_member_topics if assignment.team_assignment?&lt;br /&gt;
     end&lt;br /&gt;
     drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
     perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Solution''': The implementation has been changed in such a way that all Participants belonging to the assignment under consideration receive emails irrespective of the deadline type. This is found out by querying the Participant table using assignment_id and retrieving the Email ID by linking it to the User table.&lt;br /&gt;
* The Participant table is queried using assignment_id&lt;br /&gt;
* For each participant, the Email ID is retrieved by linking the Participant and User table.&lt;br /&gt;
* The email reminders are sent collectively to all the email addresses from the previous step.&lt;br /&gt;
&lt;br /&gt;
'''Problem 2''':  Scalability Issue:  Delayed Job uses  SQL database for storing the jobs and processes them in a single-threaded process. It's simple to set up but the performance and scalability are not great. It is not suitable for processing 100,000s of jobs a day.&lt;br /&gt;
&lt;br /&gt;
'''Solution''': Sidekiq uses redis for storage which implements a distributed in-memory key-value database and processes jobs in a multithreaded process. It is efficient in terms of processing speed. The worker code needs to be thread safe.&lt;br /&gt;
&lt;br /&gt;
== New Implementation ==&lt;br /&gt;
* In the new implementation a new class MailWorker in app/mailers/mail_worker.rb  is created that uses the Sidekiq worker for the mailers queue. The three instance variables- assignment id, deadline type and due date are used in this class as well. &lt;br /&gt;
::* The perform method takes the above three parameters and calls the auxiliary method find_participant_emails. This method queries the Participant table to extract the Email IDs of the users participating in an assignment and returns the email list. &lt;br /&gt;
::* The email reminder method is unchanged from the previous implementation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sidekiq'&lt;br /&gt;
class MailWorker&lt;br /&gt;
 include Sidekiq::Worker&lt;br /&gt;
 # ActionMailer in Rail 4 submits jobs in mailers queue instead of default queue. Rails 5 and onwards&lt;br /&gt;
 # ActionMailer will submit mailer jobs to default queue. We need to remove the line below in that case!&lt;br /&gt;
 sidekiq_options queue: 'mailers'&lt;br /&gt;
 attr_accessor :assignment_id&lt;br /&gt;
 attr_accessor :deadline_type&lt;br /&gt;
 attr_accessor :due_at&lt;br /&gt;
 def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
   self.assignment_id = assignment_id&lt;br /&gt;
   self.deadline_type = deadline_type&lt;br /&gt;
   self.due_at = due_at&lt;br /&gt;
   assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
   participant_mails = find_participant_emails&lt;br /&gt;
   if [&amp;quot;drop_one_member_topics&amp;quot;, &amp;quot;drop_outstanding_reviews&amp;quot;, &amp;quot;compare_files_with_simicheck&amp;quot;].include?(self.deadline_type)&lt;br /&gt;
     drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
     drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
     perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
   else&lt;br /&gt;
     # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
     deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
     else&lt;br /&gt;
       self.deadline_type&lt;br /&gt;
     end&lt;br /&gt;
     email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
 def email_reminder(emails, deadline_type)&lt;br /&gt;
   assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
   subject = &amp;quot;Message regarding #{deadline_type} for assignment #{assignment.name}&amp;quot;&lt;br /&gt;
   body = &amp;quot;This is a reminder to complete #{deadline_type} for assignment #{assignment.name}. \&lt;br /&gt;
   Deadline is #{self.due_at}.If you have already done the  #{deadline_type}, Please ignore this mail.&amp;quot;&lt;br /&gt;
   emails.each do |mail|&lt;br /&gt;
     Rails.logger.info mail&lt;br /&gt;
   end&lt;br /&gt;
   @mail = Mailer.delayed_message(bcc: emails, subject: subject, body: body)&lt;br /&gt;
   @mail.deliver_now&lt;br /&gt;
 end&lt;br /&gt;
 def find_participant_emails&lt;br /&gt;
   emails = []&lt;br /&gt;
   participants = Participant.where(parent_id: self.assignment_id)&lt;br /&gt;
   participants.each do |participant|&lt;br /&gt;
     emails&amp;lt;&amp;lt;participant.user.email unless participant.user.nil?&lt;br /&gt;
   end&lt;br /&gt;
   emails&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* The app/models/assignment_form.rb is modified to make use of the Sidekiq's perform method to queue the job and process it when the deadline approaches. &lt;br /&gt;
::*The add_delayed_job method now uses Sidekiq's perform_in method to store the email job in the job queue and executes the email job after the time (in seconds) as specified in the first argument has elapsed. &lt;br /&gt;
::*The corresponding job_id is returned back for further processing.&lt;br /&gt;
::*The get_time_diff_btw_due_date_and_now method calculates the time after which the email has to be sent and is unchanged.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_to_delayed_queue&lt;br /&gt;
   duedates = AssignmentDueDate.where(parent_id: @assignment.id)&lt;br /&gt;
   duedates.each do |due_date|&lt;br /&gt;
     deadline_type = DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
     diff_btw_time_left_and_threshold, min_left = get_time_diff_btw_due_date_and_now(due_date)&lt;br /&gt;
     next unless diff_btw_time_left_and_threshold &amp;gt; 0&lt;br /&gt;
     delayed_job_id = add_delayed_job(@assignment, deadline_type, due_date, diff_btw_time_left_and_threshold)&lt;br /&gt;
     due_date.update_attribute(:delayed_job_id, delayed_job_id)&lt;br /&gt;
     # If the deadline type is review, add a delayed job to drop outstanding review&lt;br /&gt;
     add_delayed_job(@assignment, &amp;quot;drop_outstanding_reviews&amp;quot;, due_date, min_left) if deadline_type == &amp;quot;review&amp;quot;&lt;br /&gt;
     # If the deadline type is team_formation, add a delayed job to drop one member team&lt;br /&gt;
     next unless deadline_type == &amp;quot;team_formation&amp;quot; and @assignment.team_assignment?&lt;br /&gt;
     add_delayed_job(@assignment, &amp;quot;drop_one_member_topics&amp;quot;, due_date, min_left)&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def get_time_diff_btw_due_date_and_now(due_date)&lt;br /&gt;
   due_at = due_date.due_at.to_s(:db)&lt;br /&gt;
   Time.parse(due_at)&lt;br /&gt;
   due_at = Time.parse(due_at)&lt;br /&gt;
   time_left_in_min = find_min_from_now(due_at)&lt;br /&gt;
   diff_btw_time_left_and_threshold = time_left_in_min - due_date.threshold * 60&lt;br /&gt;
   [diff_btw_time_left_and_threshold, time_left_in_min]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 # add DelayedJob into queue and return it&lt;br /&gt;
 def add_delayed_job(assignment, deadline_type, due_date, min_left)&lt;br /&gt;
   delayed_job_id = MailWorker.perform_in(min_left*60, due_date.parent_id, deadline_type, due_date.due_at )&lt;br /&gt;
   change_item_type(delayed_job_id)&lt;br /&gt;
   delayed_job_id&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
== Testing using RSPEC ==&lt;br /&gt;
We modified the existing test cases to replace the delayed job queue with Sidekiq, to test all modifications we have done to the code of assignment_form class. We also added RSpec test for Sidekiq mailer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe MailWorker do&lt;br /&gt;
  let(:assignment) { build(:assignment, id: 1, name: &amp;quot;no assignment&amp;quot;, participants: [participant], teams: [team]) }&lt;br /&gt;
  let(:participant) { build(:participant, id: 1, parent_id: 1, user: user) }&lt;br /&gt;
  let(:team) { build(:assignment_team, id: 1, name: 'no team', users: [user], parent_id: 1) }&lt;br /&gt;
  let(:user) { build(:student, id: 1, email: 'psingh22@ncsu.edu') }&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  before(:each) do&lt;br /&gt;
    allow(Assignment).to receive(:find).with('1').and_return(assignment)&lt;br /&gt;
    allow(Participant).to receive(:where).with(parent_id: '1').and_return([participant])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe 'Tests mailer with sidekiq' do&lt;br /&gt;
    &lt;br /&gt;
    it &amp;quot;should send email to required email address with proper content&amp;quot; do&lt;br /&gt;
      Sidekiq::Testing.inline!&lt;br /&gt;
      MailWorker.perform_async(&amp;quot;1&amp;quot;, &amp;quot;metareview&amp;quot;, &amp;quot;2018-12-31 00:00:01&amp;quot;)&lt;br /&gt;
      email = ActionMailer::Base.deliveries.first&lt;br /&gt;
      expect(email.from[0]).to eq(&amp;quot;expertiza.development@gmail.com&amp;quot;)&lt;br /&gt;
      expect(email.bcc[0]).to eq(user.email)&lt;br /&gt;
      expect(email.subject).to eq('Message regarding teammate review for assignment '+ assignment.name)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;should expect the queue size of one&amp;quot; do&lt;br /&gt;
      Sidekiq::Testing.fake!&lt;br /&gt;
      MailWorker.perform_in(3.hours, &amp;quot;1&amp;quot;, &amp;quot;metareview&amp;quot;, &amp;quot;2018-12-31 00:00:01&amp;quot;)&lt;br /&gt;
      queue = Sidekiq::Queues[&amp;quot;mailers&amp;quot;]&lt;br /&gt;
      expect(queue.size).to eq(1)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The tests can be executed &amp;quot;rspec spec&amp;quot; command as shown below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
user-expertiza $rspec spec/sidekiq_mail_worker_spec.rb.&lt;br /&gt;
&lt;br /&gt;
Finished in 3.19 seconds&lt;br /&gt;
2 examples, 0 failures&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Testing from UI ==&lt;br /&gt;
1. To go to versions index page, type in the following url after logging in as instructor:&lt;br /&gt;
http://152.46.19.3:8080&lt;br /&gt;
&lt;br /&gt;
2. Create a new assignment and add the rubric and other necessary fields and add the late policy.&lt;br /&gt;
http://152.46.19.3:8080/assignments/new?private=0&lt;br /&gt;
&lt;br /&gt;
3. You can see the new jobs populated here&lt;br /&gt;
http://152.46.19.3:8080/sidekiq/scheduled&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/WintersLt/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[http://expertiza.ncsu.edu/ The live Expertiza website]&lt;br /&gt;
#[http://bit.ly/myexpertiza Demo link]&lt;br /&gt;
#[http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza project documentation wiki]&lt;br /&gt;
#[https://relishapp.com/rspec Rspec Documentation]&lt;br /&gt;
#[https://github.com/mperham/sidekiq/wiki Sidekiq Documentation]&lt;br /&gt;
#Clean Code: A handbook of agile software craftsmanship. Author: Robert C Martin&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1835_Refactor_delayed_mailer_and_scheduled_task&amp;diff=119074</id>
		<title>E1835 Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1835_Refactor_delayed_mailer_and_scheduled_task&amp;diff=119074"/>
		<updated>2018-11-09T19:25:36Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Testing using RSPEC */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework. Expertiza allows the instructor to create new assignments, modify existing assignments and set deadlines. The instructor can also create a list of project topics that the students can sign up for.  Expertiza allows students to peer review submissions of other students as well as do teammate reviews. Students can form team on Expertiza to work on assignments and projects.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
* Used Sidekiq gem for asynchronous processing of email jobs&lt;br /&gt;
* Created a new mailer class- MailWorker that uses Sidekiq's queue to hold and process jobs&lt;br /&gt;
* Defined the perform method to extract the Email IDs of all participants of the corresponding assignment and send an email reminder&lt;br /&gt;
* Replaced the code that uses the existing DelayedMailer queue to incorporate Sidekiq's queue&lt;br /&gt;
* Added RSPEC test cases to test the creation of assignment deadlines and background Sidekiq email job&lt;br /&gt;
&lt;br /&gt;
== About Sidekiq ==&lt;br /&gt;
&lt;br /&gt;
Sidekiq is a background processing framework for Ruby. It allows to scale our application by performing work in the background. In particular it consists of three parts: Client, Redis and Server. The client runs in Ruby process and allows us to create jobs for processing later. Once a job is created, a Hash representing that job is created and serialized to a Json String. This String is pushed into a queue in Redis. Redis provides data storage for Sidekiq and holds all the job data. Each Sidekiq server process pulls jobs from the queue in Redis and processes them. &lt;br /&gt;
&lt;br /&gt;
== Current Implementation ==&lt;br /&gt;
&lt;br /&gt;
* Uses the 'delayed_job_active_record' gem for asynchronous processing of delayed jobs&lt;br /&gt;
::The current implementation uses Delayed::Job for implementing a Database based asynchronous priority queue system for storing the job queue of email reminders corresponding to various deadline types. &lt;br /&gt;
* Email reminders were sent to users corresponding to each deadline type&lt;br /&gt;
::The DelayedMailer class includes a perform method that finds Email IDs of the target users  corresponding to the deadline type. The subject and body of the email message is then constructed and the delayed_message method of Mailer class is used for sending the emails out to the users.&lt;br /&gt;
* Uses DelayedJob to enqueue email jobs &lt;br /&gt;
::The DelayedMailer object is enqueued into the DelayedJob queue using enqueue method. These jobs are meant to be executed as the deadline of the corresponding Email job approaches.&lt;br /&gt;
&lt;br /&gt;
== Drawbacks and Solutions ==&lt;br /&gt;
'''Problem 1''': The perform method in the DelayedMailer class contains a big case statement to check each kind of deadline&lt;br /&gt;
&lt;br /&gt;
The perform method in DelayedMailer class checks the deadline type individually using multiple if statements and populates the Email IDs of the target users by querying the database. Auxiliary methods like, for example, mail_signed_up_users is invoked which in turn calls the email_reminder method. &lt;br /&gt;
This makes the implementation very cumbersome and does not follow the principles of DRY code as the same email_reminder method is called multiple times under different conditions.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform&lt;br /&gt;
assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
   if !assignment.nil? &amp;amp;&amp;amp; !assignment.id.nil?&lt;br /&gt;
     if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
       mail_metareviewers&lt;br /&gt;
       team_mails = find_team_members_email&lt;br /&gt;
       email_reminder(team_mails, &amp;quot;teammate review&amp;quot;) unless team_mails.empty?&lt;br /&gt;
     end&lt;br /&gt;
     if self.deadline_type == &amp;quot;review&amp;quot;&lt;br /&gt;
       mail_reviewers # to all reviewers&lt;br /&gt;
     end&lt;br /&gt;
     if self.deadline_type == &amp;quot;submission&amp;quot;&lt;br /&gt;
       mail_signed_up_users # to all signed up users&lt;br /&gt;
     end&lt;br /&gt;
     if self.deadline_type == &amp;quot;drop_topic&amp;quot;&lt;br /&gt;
       if sign_up_topics?&lt;br /&gt;
         mail_signed_up_users # reminder to signed_up users of the assignment&lt;br /&gt;
       end&lt;br /&gt;
     end&lt;br /&gt;
     if self.deadline_type == &amp;quot;signup&amp;quot;&lt;br /&gt;
       if sign_up_topics?&lt;br /&gt;
         mail_assignment_participants # reminder to all participants&lt;br /&gt;
       end&lt;br /&gt;
     end&lt;br /&gt;
     if self.deadline_type == &amp;quot;team_formation&amp;quot;&lt;br /&gt;
       emails = get_one_member_team&lt;br /&gt;
       email_reminder(emails, self.deadline_type)&lt;br /&gt;
     end&lt;br /&gt;
     if self.deadline_type == &amp;quot;drop_one_member_topics&amp;quot;&lt;br /&gt;
       drop_one_member_topics if assignment.team_assignment?&lt;br /&gt;
     end&lt;br /&gt;
     drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
     perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Solution''': The implementation has been changed in such a way that all Participants belonging to the assignment under consideration receive emails irrespective of the deadline type. This is found out by querying the Participant table using assignment_id and retrieving the Email ID by linking it to the User table.&lt;br /&gt;
* The Participant table is queried using assignment_id&lt;br /&gt;
* For each participant, the Email ID is retrieved by linking the Participant and User table.&lt;br /&gt;
* The email reminders are sent collectively to all the email addresses from the previous step.&lt;br /&gt;
&lt;br /&gt;
'''Problem 2''':  Scalability Issue:  Delayed Job uses  SQL database for storing the jobs and processes them in a single-threaded process. It's simple to set up but the performance and scalability are not great. It is not suitable for processing 100,000s of jobs a day.&lt;br /&gt;
&lt;br /&gt;
'''Solution''': Sidekiq uses redis for storage which implements a distributed in-memory key-value database and processes jobs in a multithreaded process. It is efficient in terms of processing speed. The worker code needs to be thread safe.&lt;br /&gt;
&lt;br /&gt;
== New Implementation ==&lt;br /&gt;
* In the new implementation a new class MailWorker in app/mailers/mail_worker.rb  is created that uses the Sidekiq worker for the mailers queue. The three instance variables- assignment id, deadline type and due date are used in this class as well. &lt;br /&gt;
::* The perform method takes the above three parameters and calls the auxiliary method find_participant_emails. This method queries the Participant table to extract the Email IDs of the users participating in an assignment and returns the email list. &lt;br /&gt;
::* The email reminder method is unchanged from the previous implementation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sidekiq'&lt;br /&gt;
class MailWorker&lt;br /&gt;
 include Sidekiq::Worker&lt;br /&gt;
 # ActionMailer in Rail 4 submits jobs in mailers queue instead of default queue. Rails 5 and onwards&lt;br /&gt;
 # ActionMailer will submit mailer jobs to default queue. We need to remove the line below in that case!&lt;br /&gt;
 sidekiq_options queue: 'mailers'&lt;br /&gt;
 attr_accessor :assignment_id&lt;br /&gt;
 attr_accessor :deadline_type&lt;br /&gt;
 attr_accessor :due_at&lt;br /&gt;
 def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
   self.assignment_id = assignment_id&lt;br /&gt;
   self.deadline_type = deadline_type&lt;br /&gt;
   self.due_at = due_at&lt;br /&gt;
   assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
   participant_mails = find_participant_emails&lt;br /&gt;
   if [&amp;quot;drop_one_member_topics&amp;quot;, &amp;quot;drop_outstanding_reviews&amp;quot;, &amp;quot;compare_files_with_simicheck&amp;quot;].include?(self.deadline_type)&lt;br /&gt;
     drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
     drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
     perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
   else&lt;br /&gt;
     # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
     deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
     else&lt;br /&gt;
       self.deadline_type&lt;br /&gt;
     end&lt;br /&gt;
     email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
 def email_reminder(emails, deadline_type)&lt;br /&gt;
   assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
   subject = &amp;quot;Message regarding #{deadline_type} for assignment #{assignment.name}&amp;quot;&lt;br /&gt;
   body = &amp;quot;This is a reminder to complete #{deadline_type} for assignment #{assignment.name}. \&lt;br /&gt;
   Deadline is #{self.due_at}.If you have already done the  #{deadline_type}, Please ignore this mail.&amp;quot;&lt;br /&gt;
   emails.each do |mail|&lt;br /&gt;
     Rails.logger.info mail&lt;br /&gt;
   end&lt;br /&gt;
   @mail = Mailer.delayed_message(bcc: emails, subject: subject, body: body)&lt;br /&gt;
   @mail.deliver_now&lt;br /&gt;
 end&lt;br /&gt;
 def find_participant_emails&lt;br /&gt;
   emails = []&lt;br /&gt;
   participants = Participant.where(parent_id: self.assignment_id)&lt;br /&gt;
   participants.each do |participant|&lt;br /&gt;
     emails&amp;lt;&amp;lt;participant.user.email unless participant.user.nil?&lt;br /&gt;
   end&lt;br /&gt;
   emails&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* The app/models/assignment_form.rb is modified to make use of the Sidekiq's perform method to queue the job and process it when the deadline approaches. &lt;br /&gt;
::*The add_delayed_job method now uses Sidekiq's perform_in method to store the email job in the job queue and executes the email job after the time (in seconds) as specified in the first argument has elapsed. &lt;br /&gt;
::*The corresponding job_id is returned back for further processing.&lt;br /&gt;
::*The get_time_diff_btw_due_date_and_now method calculates the time after which the email has to be sent and is unchanged.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_to_delayed_queue&lt;br /&gt;
   duedates = AssignmentDueDate.where(parent_id: @assignment.id)&lt;br /&gt;
   duedates.each do |due_date|&lt;br /&gt;
     deadline_type = DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
     diff_btw_time_left_and_threshold, min_left = get_time_diff_btw_due_date_and_now(due_date)&lt;br /&gt;
     next unless diff_btw_time_left_and_threshold &amp;gt; 0&lt;br /&gt;
     delayed_job_id = add_delayed_job(@assignment, deadline_type, due_date, diff_btw_time_left_and_threshold)&lt;br /&gt;
     due_date.update_attribute(:delayed_job_id, delayed_job_id)&lt;br /&gt;
     # If the deadline type is review, add a delayed job to drop outstanding review&lt;br /&gt;
     add_delayed_job(@assignment, &amp;quot;drop_outstanding_reviews&amp;quot;, due_date, min_left) if deadline_type == &amp;quot;review&amp;quot;&lt;br /&gt;
     # If the deadline type is team_formation, add a delayed job to drop one member team&lt;br /&gt;
     next unless deadline_type == &amp;quot;team_formation&amp;quot; and @assignment.team_assignment?&lt;br /&gt;
     add_delayed_job(@assignment, &amp;quot;drop_one_member_topics&amp;quot;, due_date, min_left)&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def get_time_diff_btw_due_date_and_now(due_date)&lt;br /&gt;
   due_at = due_date.due_at.to_s(:db)&lt;br /&gt;
   Time.parse(due_at)&lt;br /&gt;
   due_at = Time.parse(due_at)&lt;br /&gt;
   time_left_in_min = find_min_from_now(due_at)&lt;br /&gt;
   diff_btw_time_left_and_threshold = time_left_in_min - due_date.threshold * 60&lt;br /&gt;
   [diff_btw_time_left_and_threshold, time_left_in_min]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 # add DelayedJob into queue and return it&lt;br /&gt;
 def add_delayed_job(assignment, deadline_type, due_date, min_left)&lt;br /&gt;
   delayed_job_id = MailWorker.perform_in(min_left*60, due_date.parent_id, deadline_type, due_date.due_at )&lt;br /&gt;
   change_item_type(delayed_job_id)&lt;br /&gt;
   delayed_job_id&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
== Testing using RSPEC ==&lt;br /&gt;
We modified the existing test cases to replace the delayed job queue with Sidekiq, to test all modifications we have done to the code of assignment_form class.We also added RSpec test for Sidekiq mailer. The tests can be executed &amp;quot;rspec spec&amp;quot; command as shown below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
user-expertiza $rspec spec/sidekiq_mail_worker_spec.rb.&lt;br /&gt;
&lt;br /&gt;
Finished in 3.19 seconds&lt;br /&gt;
2 examples, 0 failures&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Testing from UI ==&lt;br /&gt;
1. To go to versions index page, type in the following url after logging in as instructor:&lt;br /&gt;
http://152.46.19.3:8080&lt;br /&gt;
&lt;br /&gt;
2. Create a new assignment and add the rubric and other necessary fields and add the late policy.&lt;br /&gt;
http://152.46.19.3:8080/assignments/new?private=0&lt;br /&gt;
&lt;br /&gt;
3. You can see the new jobs populated here&lt;br /&gt;
http://152.46.19.3:8080/sidekiq/scheduled&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/WintersLt/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[http://expertiza.ncsu.edu/ The live Expertiza website]&lt;br /&gt;
#[http://bit.ly/myexpertiza Demo link]&lt;br /&gt;
#[http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza project documentation wiki]&lt;br /&gt;
#[https://relishapp.com/rspec Rspec Documentation]&lt;br /&gt;
#[https://github.com/mperham/sidekiq/wiki Sidekiq Documentation]&lt;br /&gt;
#Clean Code: A handbook of agile software craftsmanship. Author: Robert C Martin&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1835_Refactor_delayed_mailer_and_scheduled_task&amp;diff=119073</id>
		<title>E1835 Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1835_Refactor_delayed_mailer_and_scheduled_task&amp;diff=119073"/>
		<updated>2018-11-09T19:24:26Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* Testing using RSPEC */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Expertiza ==&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework. Expertiza allows the instructor to create new assignments, modify existing assignments and set deadlines. The instructor can also create a list of project topics that the students can sign up for.  Expertiza allows students to peer review submissions of other students as well as do teammate reviews. Students can form team on Expertiza to work on assignments and projects.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
* Used Sidekiq gem for asynchronous processing of email jobs&lt;br /&gt;
* Created a new mailer class- MailWorker that uses Sidekiq's queue to hold and process jobs&lt;br /&gt;
* Defined the perform method to extract the Email IDs of all participants of the corresponding assignment and send an email reminder&lt;br /&gt;
* Replaced the code that uses the existing DelayedMailer queue to incorporate Sidekiq's queue&lt;br /&gt;
* Added RSPEC test cases to test the creation of assignment deadlines and background Sidekiq email job&lt;br /&gt;
&lt;br /&gt;
== About Sidekiq ==&lt;br /&gt;
&lt;br /&gt;
Sidekiq is a background processing framework for Ruby. It allows to scale our application by performing work in the background. In particular it consists of three parts: Client, Redis and Server. The client runs in Ruby process and allows us to create jobs for processing later. Once a job is created, a Hash representing that job is created and serialized to a Json String. This String is pushed into a queue in Redis. Redis provides data storage for Sidekiq and holds all the job data. Each Sidekiq server process pulls jobs from the queue in Redis and processes them. &lt;br /&gt;
&lt;br /&gt;
== Current Implementation ==&lt;br /&gt;
&lt;br /&gt;
* Uses the 'delayed_job_active_record' gem for asynchronous processing of delayed jobs&lt;br /&gt;
::The current implementation uses Delayed::Job for implementing a Database based asynchronous priority queue system for storing the job queue of email reminders corresponding to various deadline types. &lt;br /&gt;
* Email reminders were sent to users corresponding to each deadline type&lt;br /&gt;
::The DelayedMailer class includes a perform method that finds Email IDs of the target users  corresponding to the deadline type. The subject and body of the email message is then constructed and the delayed_message method of Mailer class is used for sending the emails out to the users.&lt;br /&gt;
* Uses DelayedJob to enqueue email jobs &lt;br /&gt;
::The DelayedMailer object is enqueued into the DelayedJob queue using enqueue method. These jobs are meant to be executed as the deadline of the corresponding Email job approaches.&lt;br /&gt;
&lt;br /&gt;
== Drawbacks and Solutions ==&lt;br /&gt;
'''Problem 1''': The perform method in the DelayedMailer class contains a big case statement to check each kind of deadline&lt;br /&gt;
&lt;br /&gt;
The perform method in DelayedMailer class checks the deadline type individually using multiple if statements and populates the Email IDs of the target users by querying the database. Auxiliary methods like, for example, mail_signed_up_users is invoked which in turn calls the email_reminder method. &lt;br /&gt;
This makes the implementation very cumbersome and does not follow the principles of DRY code as the same email_reminder method is called multiple times under different conditions.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform&lt;br /&gt;
assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
   if !assignment.nil? &amp;amp;&amp;amp; !assignment.id.nil?&lt;br /&gt;
     if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
       mail_metareviewers&lt;br /&gt;
       team_mails = find_team_members_email&lt;br /&gt;
       email_reminder(team_mails, &amp;quot;teammate review&amp;quot;) unless team_mails.empty?&lt;br /&gt;
     end&lt;br /&gt;
     if self.deadline_type == &amp;quot;review&amp;quot;&lt;br /&gt;
       mail_reviewers # to all reviewers&lt;br /&gt;
     end&lt;br /&gt;
     if self.deadline_type == &amp;quot;submission&amp;quot;&lt;br /&gt;
       mail_signed_up_users # to all signed up users&lt;br /&gt;
     end&lt;br /&gt;
     if self.deadline_type == &amp;quot;drop_topic&amp;quot;&lt;br /&gt;
       if sign_up_topics?&lt;br /&gt;
         mail_signed_up_users # reminder to signed_up users of the assignment&lt;br /&gt;
       end&lt;br /&gt;
     end&lt;br /&gt;
     if self.deadline_type == &amp;quot;signup&amp;quot;&lt;br /&gt;
       if sign_up_topics?&lt;br /&gt;
         mail_assignment_participants # reminder to all participants&lt;br /&gt;
       end&lt;br /&gt;
     end&lt;br /&gt;
     if self.deadline_type == &amp;quot;team_formation&amp;quot;&lt;br /&gt;
       emails = get_one_member_team&lt;br /&gt;
       email_reminder(emails, self.deadline_type)&lt;br /&gt;
     end&lt;br /&gt;
     if self.deadline_type == &amp;quot;drop_one_member_topics&amp;quot;&lt;br /&gt;
       drop_one_member_topics if assignment.team_assignment?&lt;br /&gt;
     end&lt;br /&gt;
     drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
     perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Solution''': The implementation has been changed in such a way that all Participants belonging to the assignment under consideration receive emails irrespective of the deadline type. This is found out by querying the Participant table using assignment_id and retrieving the Email ID by linking it to the User table.&lt;br /&gt;
* The Participant table is queried using assignment_id&lt;br /&gt;
* For each participant, the Email ID is retrieved by linking the Participant and User table.&lt;br /&gt;
* The email reminders are sent collectively to all the email addresses from the previous step.&lt;br /&gt;
&lt;br /&gt;
'''Problem 2''':  Scalability Issue:  Delayed Job uses  SQL database for storing the jobs and processes them in a single-threaded process. It's simple to set up but the performance and scalability are not great. It is not suitable for processing 100,000s of jobs a day.&lt;br /&gt;
&lt;br /&gt;
'''Solution''': Sidekiq uses redis for storage which implements a distributed in-memory key-value database and processes jobs in a multithreaded process. It is efficient in terms of processing speed. The worker code needs to be thread safe.&lt;br /&gt;
&lt;br /&gt;
== New Implementation ==&lt;br /&gt;
* In the new implementation a new class MailWorker in app/mailers/mail_worker.rb  is created that uses the Sidekiq worker for the mailers queue. The three instance variables- assignment id, deadline type and due date are used in this class as well. &lt;br /&gt;
::* The perform method takes the above three parameters and calls the auxiliary method find_participant_emails. This method queries the Participant table to extract the Email IDs of the users participating in an assignment and returns the email list. &lt;br /&gt;
::* The email reminder method is unchanged from the previous implementation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require 'sidekiq'&lt;br /&gt;
class MailWorker&lt;br /&gt;
 include Sidekiq::Worker&lt;br /&gt;
 # ActionMailer in Rail 4 submits jobs in mailers queue instead of default queue. Rails 5 and onwards&lt;br /&gt;
 # ActionMailer will submit mailer jobs to default queue. We need to remove the line below in that case!&lt;br /&gt;
 sidekiq_options queue: 'mailers'&lt;br /&gt;
 attr_accessor :assignment_id&lt;br /&gt;
 attr_accessor :deadline_type&lt;br /&gt;
 attr_accessor :due_at&lt;br /&gt;
 def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
   self.assignment_id = assignment_id&lt;br /&gt;
   self.deadline_type = deadline_type&lt;br /&gt;
   self.due_at = due_at&lt;br /&gt;
   assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
   participant_mails = find_participant_emails&lt;br /&gt;
   if [&amp;quot;drop_one_member_topics&amp;quot;, &amp;quot;drop_outstanding_reviews&amp;quot;, &amp;quot;compare_files_with_simicheck&amp;quot;].include?(self.deadline_type)&lt;br /&gt;
     drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
     drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
     perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
   else&lt;br /&gt;
     # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
     deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
     else&lt;br /&gt;
       self.deadline_type&lt;br /&gt;
     end&lt;br /&gt;
     email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
 def email_reminder(emails, deadline_type)&lt;br /&gt;
   assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
   subject = &amp;quot;Message regarding #{deadline_type} for assignment #{assignment.name}&amp;quot;&lt;br /&gt;
   body = &amp;quot;This is a reminder to complete #{deadline_type} for assignment #{assignment.name}. \&lt;br /&gt;
   Deadline is #{self.due_at}.If you have already done the  #{deadline_type}, Please ignore this mail.&amp;quot;&lt;br /&gt;
   emails.each do |mail|&lt;br /&gt;
     Rails.logger.info mail&lt;br /&gt;
   end&lt;br /&gt;
   @mail = Mailer.delayed_message(bcc: emails, subject: subject, body: body)&lt;br /&gt;
   @mail.deliver_now&lt;br /&gt;
 end&lt;br /&gt;
 def find_participant_emails&lt;br /&gt;
   emails = []&lt;br /&gt;
   participants = Participant.where(parent_id: self.assignment_id)&lt;br /&gt;
   participants.each do |participant|&lt;br /&gt;
     emails&amp;lt;&amp;lt;participant.user.email unless participant.user.nil?&lt;br /&gt;
   end&lt;br /&gt;
   emails&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* The app/models/assignment_form.rb is modified to make use of the Sidekiq's perform method to queue the job and process it when the deadline approaches. &lt;br /&gt;
::*The add_delayed_job method now uses Sidekiq's perform_in method to store the email job in the job queue and executes the email job after the time (in seconds) as specified in the first argument has elapsed. &lt;br /&gt;
::*The corresponding job_id is returned back for further processing.&lt;br /&gt;
::*The get_time_diff_btw_due_date_and_now method calculates the time after which the email has to be sent and is unchanged.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_to_delayed_queue&lt;br /&gt;
   duedates = AssignmentDueDate.where(parent_id: @assignment.id)&lt;br /&gt;
   duedates.each do |due_date|&lt;br /&gt;
     deadline_type = DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
     diff_btw_time_left_and_threshold, min_left = get_time_diff_btw_due_date_and_now(due_date)&lt;br /&gt;
     next unless diff_btw_time_left_and_threshold &amp;gt; 0&lt;br /&gt;
     delayed_job_id = add_delayed_job(@assignment, deadline_type, due_date, diff_btw_time_left_and_threshold)&lt;br /&gt;
     due_date.update_attribute(:delayed_job_id, delayed_job_id)&lt;br /&gt;
     # If the deadline type is review, add a delayed job to drop outstanding review&lt;br /&gt;
     add_delayed_job(@assignment, &amp;quot;drop_outstanding_reviews&amp;quot;, due_date, min_left) if deadline_type == &amp;quot;review&amp;quot;&lt;br /&gt;
     # If the deadline type is team_formation, add a delayed job to drop one member team&lt;br /&gt;
     next unless deadline_type == &amp;quot;team_formation&amp;quot; and @assignment.team_assignment?&lt;br /&gt;
     add_delayed_job(@assignment, &amp;quot;drop_one_member_topics&amp;quot;, due_date, min_left)&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def get_time_diff_btw_due_date_and_now(due_date)&lt;br /&gt;
   due_at = due_date.due_at.to_s(:db)&lt;br /&gt;
   Time.parse(due_at)&lt;br /&gt;
   due_at = Time.parse(due_at)&lt;br /&gt;
   time_left_in_min = find_min_from_now(due_at)&lt;br /&gt;
   diff_btw_time_left_and_threshold = time_left_in_min - due_date.threshold * 60&lt;br /&gt;
   [diff_btw_time_left_and_threshold, time_left_in_min]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 # add DelayedJob into queue and return it&lt;br /&gt;
 def add_delayed_job(assignment, deadline_type, due_date, min_left)&lt;br /&gt;
   delayed_job_id = MailWorker.perform_in(min_left*60, due_date.parent_id, deadline_type, due_date.due_at )&lt;br /&gt;
   change_item_type(delayed_job_id)&lt;br /&gt;
   delayed_job_id&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
== Testing using RSPEC ==&lt;br /&gt;
We modified the existing test cases to replace the delayed job queue with Sidekiq, to test all modifications we have done to the code of assignment_form class.We also added RSpec test for Sidekiq mailer. The tests can be executed &amp;quot;rpec spec&amp;quot; command as shown below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
user-expertiza $rspec spec/sidekiq_mail_worker_spec.rb.&lt;br /&gt;
&lt;br /&gt;
Finished in 3.19 seconds&lt;br /&gt;
2 examples, 0 failures&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Testing from UI ==&lt;br /&gt;
1. To go to versions index page, type in the following url after logging in as instructor:&lt;br /&gt;
http://152.46.19.3:8080&lt;br /&gt;
&lt;br /&gt;
2. Create a new assignment and add the rubric and other necessary fields and add the late policy.&lt;br /&gt;
http://152.46.19.3:8080/assignments/new?private=0&lt;br /&gt;
&lt;br /&gt;
3. You can see the new jobs populated here&lt;br /&gt;
http://152.46.19.3:8080/sidekiq/scheduled&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/WintersLt/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[http://expertiza.ncsu.edu/ The live Expertiza website]&lt;br /&gt;
#[http://bit.ly/myexpertiza Demo link]&lt;br /&gt;
#[http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza project documentation wiki]&lt;br /&gt;
#[https://relishapp.com/rspec Rspec Documentation]&lt;br /&gt;
#[https://github.com/mperham/sidekiq/wiki Sidekiq Documentation]&lt;br /&gt;
#Clean Code: A handbook of agile software craftsmanship. Author: Robert C Martin&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1835_Refactor_delayed_mailer_and_scheduled_task&amp;diff=118047</id>
		<title>E1835 Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1835_Refactor_delayed_mailer_and_scheduled_task&amp;diff=118047"/>
		<updated>2018-11-02T18:37:22Z</updated>

		<summary type="html">&lt;p&gt;Pbhalas: /* About Expertiza */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''About Expertiza''' ==&lt;/div&gt;</summary>
		<author><name>Pbhalas</name></author>
	</entry>
</feed>