Question

I'm trying to figure out a way to have cleaner, efficient code for a web audio project i've been working on. the code I have right now is this:

//OSCILLATOR INFO//
// Oscillator Pitch is in Hz.
// Oscillator Detune is in Cents & can be positive or negative values. 
// 1 Octave = double/half the note frequency in Hz. (A3 = 220Hz; A4 = 440Hz; A5 = 880Hz)
// 1 Octave = 1200 Cents. 100 Cents per Semitone. (A3 - A4 = 1200 Cents; A4 - A5 = 1200 Cents)
// 12 Semitones per Octave.
// (A-440Hz detuned by 100 cents = A#; detuned by -100 cents = Ab)
//JQUERY SET UP//
//WEB AUDIO SET UP//
//used start web audio
var ctx = new webkitAudioContext();
speakers = ctx.destination;
var osc1 = ctx.createOscillator();
var osc2 = ctx.createOscillator();
var osc3 = ctx.createOscillator();
$(document).ready(function () {
    //WAVEFORM OBJECTS - used to set the value of "cur_wave_osc" under Waveform sliders.//
    var wF = {
        0: "Sine",
        1: "Square",
        2: "Sawtooth",
        3: "Triangle"
    };
    //PLAY_PAUSE BUTTONS - used to play & pause the oscillators.//
    //OSC1 PLAY_PAUSE//
    $('#play_pause_osc1').click(function () {
        if ($(this).val() == "Play Osc1") {
            $(this).val("Pause");
            oscillator1Start();
        } else {
            $(this).val("Play Osc1");
            osc1.disconnect();
        }
    });
    //OSC2 PLAY_PAUSE//
    $('#play_pause_osc2').click(function () {
        if ($(this).val() == "Play Osc2") {
            $(this).val("Pause");
            oscillator2Start();
        } else {
            $(this).val("Play Osc2");
            osc2.disconnect();
        }
    });
    //OSC3 PLAY_PAUSE//
    $('#play_pause_osc3').click(function () {
        if ($(this).val() == "Play Osc3") {
            $(this).val("Pause");
            oscillator3Start();
        } else {
            $(this).val("Play Osc3");
            osc3.disconnect();
        }
    });
    //GAIN SLIDERS - used for controlling osc volume.//
    //OSC1_GAIN//
    $(function () {
        $("#osc1_vol").slider({
            min: 0,
            max: 1,
            value: 0.5,
            step: 0.01,
            slide: function (event, ui) {
                $("#cur_vol_osc1").val(ui.value);
                gainNode1.gain.value = $("#cur_vol_osc1").val();
            }
        });
        $("#cur_vol_osc1").val($("#osc1_vol").slider("value"));
    });
    //OSC2_GAIN//
    $(function () {
        $("#osc2_vol").slider({
            min: 0,
            max: 1,
            value: 0.5,
            step: 0.01,
            slide: function (event, ui) {
                $("#cur_vol_osc2").val(ui.value);
                gainNode2.gain.value = $("#cur_vol_osc2").val();
            }
        });
        $("#cur_vol_osc2").val($("#osc2_vol").slider("value"));
    });
    //OSC3_GAIN//
    $(function () {
        $("#osc3_vol").slider({
            min: 0,
            max: 1,
            value: 0.5,
            step: 0.01,
            slide: function (event, ui) {
                $("#cur_vol_osc3").val(ui.value);
                gainNode3.gain.value = $("#cur_vol_osc3").val();
            }
        });
        $("#cur_vol_osc3").val($("#osc3_vol").slider("value"));
    });
    //PITCH SLIDERS - used for controlling osc pitch.//
    //OSC1_PITCH//
    $(function () {
        $("#osc1_pitch").slider({
            min: 0,
            max: 25000,
            value: 440,
            step: 1,
            slide: function (event, ui) {
                $("#cur_pitch_osc1").val(ui.value);
                osc1.frequency.value = $("#cur_pitch_osc1").val();
            }
        });
        $("#cur_pitch_osc1").val($("#osc1_pitch").slider("value"));
    });
    //OSC2_PITCH//
    $(function () {
        $("#osc2_pitch").slider({
            min: 0,
            max: 25000,
            value: 440,
            step: 1,
            slide: function (event, ui) {
                $("#cur_pitch_osc2").val(ui.value);
                osc2.frequency.value = $("#cur_pitch_osc2").val();
            }
        });
        $("#cur_pitch_osc2").val($("#osc2_pitch").slider("value"));
    });
    //OSC3_PITCH//
    $(function () {
        $("#osc3_pitch").slider({
            min: 0,
            max: 25000,
            value: 440,
            step: 1,
            slide: function (event, ui) {
                $("#cur_pitch_osc3").val(ui.value);
                osc3.frequency.value = $("#cur_pitch_osc3").val();
            }
        });
        $("#cur_pitch_osc3").val($("#osc3_pitch").slider("value"));
    });
    //DETUNE SLIDER - used for controlling osc detune.//
    //OSC1_DETUNE//
    $(function () {
        $("#osc1_detune").slider({
            min: -4800,
            max: 4800,
            value: 0,
            step: 1,
            slide: function (event, ui) {
                $("#cur_detune_osc1").val(ui.value);
                osc1.detune.value = $("#cur_detune_osc1").val();
            }
        });
        $("#cur_detune_osc1").val($("#osc1_detune").slider("value"));
    });
    //OSC2_DETUNE//
    $(function () {
        $("#osc2_detune").slider({
            min: -4800,
            max: 4800,
            value: 0,
            step: 1,
            slide: function (event, ui) {
                $("#cur_detune_osc2").val(ui.value);
                osc2.detune.value = $("#cur_detune_osc2").val();
            }
        });
        $("#cur_detune_osc2").val($("#osc2_detune").slider("value"));
    });
    //OSC3_DETUNE//
    $(function () {
        $("#osc3_detune").slider({
            min: -4800,
            max: 4800,
            value: 0,
            step: 1,
            slide: function (event, ui) {
                $("#cur_detune_osc3").val(ui.value);
                osc3.detune.value = $("#cur_detune_osc3").val();
            }
        });
        $("#cur_detune_osc3").val($("#osc3_detune").slider("value"));
    });
    //WAVEFORM SLIDERS - used for selecting osc waveform.//
    //OSC1_WAVEFORM//
    $(function () {
        $("#osc1_wave").slider({
            min: 0,
            max: 3,
            value: 0,
            step: 1,
            slide: function (event, ui) {
                $("#cur_wave_osc1").val(wF[ui.value]);
            }
        });
        $("#cur_wave_osc1").val("Sine");
        osc1.type = $("#osc1_wave").slider("value");
    });
    //OSC2_WAVEFORM//
    $(function () {
        $("#osc2_wave").slider({
            min: 0,
            max: 3,
            value: 0,
            step: 1,
            slide: function (event, ui) {
                $("#cur_wave_osc2").val(wF[ui.value]);
            }
        });
        $("#cur_wave_osc2").val("Sine");
        osc2.type = $("#osc2_wave").slider("value");
    });
    //OSC3_WAVEFORM//
    $(function () {
        $("#osc3_wave").slider({
            min: 0,
            max: 3,
            value: 0,
            step: 1,
            slide: function (event, ui) {
                $("#cur_wave_osc3").val(wF[ui.value]);
            }
        });
        $("#cur_wave_osc3").val("Sine");
        osc3.type = $("#osc3_wave").slider("value");
    });
});
//CREATE OSCILLATORS//
//OSC1//
function oscillator1Start() {
    //creates the osc
    osc1 = ctx.createOscillator();
    //sets waveform
    osc1.type = $("#osc1_wave").slider("value"); //0 = sine, 1 = square, 2 = saw, 3 = triangle, 4 = custom
    //sets frequency
    osc1.frequency.value;
    //sets detune
    osc1.detune.value;
    //creates a gain node
    gainNode1 = ctx.createGainNode();
    //connects osc to gain node
    osc1.connect(gainNode1);
    //connects gain node to speakers
    gainNode1.connect(speakers);
    //sets gain value
    gainNode1.gain.value;
    //plays the osc
    osc1.start(0);
}
//OSC2//
function oscillator2Start() {
    //creates the osc
    osc2 = ctx.createOscillator();
    //sets waveform
    osc2.type; //0 = sine, 1 = square, 2 = saw, 3 = triangle, 4 = custom
    //sets frequency
    osc2.frequency.value;
    //sets detune
    osc2.detune.value;
    //creates a gain node
    gainNode2 = ctx.createGainNode();
    //connects osc to gain node
    osc2.connect(gainNode2);
    //connects gain node to speakers
    gainNode2.connect(speakers);
    //sets gain value
    gainNode2.gain.value;
    //plays the osc
    osc2.start(0);
}
//OSC3//
function oscillator3Start() {
    //creates the osc
    osc3 = ctx.createOscillator();
    //sets waveform
    osc3.type; //0 = sine, 1 = square, 2 = saw, 3 = triangle, 4 = custom
    //sets frequency
    osc3.frequency.value;
    //sets detune
    osc3.detune.value;
    //creates a gain node
    gainNode3 = ctx.createGainNode();
    //connects osc to gain node
    osc3.connect(gainNode3);
    //connects gain node to speakers
    gainNode3.connect(speakers);
    //sets gain value
    gainNode3.gain.value;
    //plays the osc
    osc3.start(0);
}

it seems like I have a lot of repetitive code so I was considering making some constructors for things like creating a a new osc or play/pause button. The problem I'm running into though, is since my oscillator controls are controlled via jquery how would i still use my jQuery sliders, buttons in the constructors?

This is as far as I've gotten:

var ctx = new webkitAudioContext();
//object constructor
function Osc(type,freq,detune,gain)
{
    this.create = new ctx.createOscillator();
    this.type = type; //0 = sine, 1 = square, 2 = saw, 3 = triangle, 4 = custom
    this.freq = freq;
    this.detune = detune;
    this.gain = gain;
    this.changeType = changeType;
    function changeType(type)
    {
        this.type = type;
    };
    this.changeFreq = changeFreq;
    function changeFreq(freq)
    {
        this.freq = freq;
    };
}
Était-ce utile?

La solution

See if this can help you get started. What I did was simply demonstrate how to append DOM elements that can trigger oscillators from an object created from a constructor. I also only added one oscillator parameter (frequency/pitch) as I figure you could just duplicate the pattern for whatever oscillator params you want (type,filter, etc). One thing about the below code is the internal DOM appending could use an abstraction in and of itself. So to really do this right you might have to create a group of mini-abstractions that all work together under one constructor. At least that's the way I see it.

EDIT *I created a version with JQuery UI pitch slider here and edited the code below to include this:* http://jsfiddle.net/ay4nL/

HTML

<div id="app"> </div>

CSS

.button{
    width:100px;
    height:100px;
    background-color:orange;
}

Javascript

 $(function(){

    context = new webkitAudioContext();

    function Osc(name,buttonName){ 

        /******* Dom Element creation & appending stuff********/
          this.buttonName = buttonName;

        if(typeof(this.button)==='undefined') {
            this.button  =   document.createElement('div');
        };



        this.button.className = buttonName;
        this.button.id = name +"_" +buttonName;
        var app = document.getElementById("app");
        $( "#app" ).append(this.button );


        if(typeof(this.pitchSlider)==='undefined') {
            this.pitchSlider = document.createElement('div');
        };


        this.pitchSlider.className = "pitchSlider";
        this.pitchSlider.id = name +"_" +"pitchSlider";
        console.log(this.pitchSlider.id);
        var pitchSlider = document.getElementById(this.pitchSlider.id); 
        $("#"+this.button.id).append(this.pitchSlider); 


        /**** Oscillator creation and trigger stuff *****/
        var freqValueStorage = 100;

        this.button.onmousedown = function(){
        this.name = context.createOscillator(),  
        this.name.type = 2;      
        this.name.frequency.value = freqValueStorage;
        this.name.connect(context.destination);
        this.name.start(0);  


        };

        this.button.onmouseup = function ()    {  
        this.name.stop(0); 


        };


        /**** JQuery UI slider for pitch/frequency ****/
         if(typeof(this.sliderParams )==='undefined') {
            this.sliderParams = {
            'orientation': "vertical",
            'range': "min",
            'min': .5,
            'max': 100,
            'animate': true,
            'step': 0.01,
            'slide': function(event, ui) {  
               freqValueStorage = ui.value;   

            },

            stop: function( event, ui ) {}

        };

        $('#'+ this.pitchSlider.id ).slider(this.sliderParams);


        };

    };
});

    osc = new Osc('osc','button');



    console.log(osc.button);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top