javascripthtmlaudiohtml5-audiosynthesizer

How can I sythesize a sine audio wave with JS?


I would like to try making a synth using JavaScript, but I can't find any basic examples on how to do so.

What I have figured out from research is that it appears to be possible and that you should use a Canvas Pixel Array rather than normal ECMA arrays

I've also found info in MDN Audio, and I have seen audio elements used for continuous playback by web radio players before, although I couldn't figure out how.

My goal is to make something which allows me to synthesize continuous sin waves and play them using my keyboard without using pre-made samples.

EDIT: One of the comments below pointed me in the right direction. I'm currently working on a solution, but if you would like to post one as well, feel free.


Solution

  • Here is a basic example from which anyone should be able to figure out how to play sine waves with their keyboard:

    <script type="text/javascript">
        //WARNING: VERY LOUD.  TURN DOWN YOUR SPEAKERS BEFORE TESTING
    
        // create web audio api context
        var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    
        // create Oscillator node
        var oscillator = audioCtx.createOscillator();
    
        oscillator.type = 'sine';
        oscillator.frequency.value = 750; // value in hertz
        oscillator.connect(audioCtx.destination);
        oscillator.start();
    
        //uncomment for fun
        // setInterval(changeFreq, 100);
    
        //choose a random interval from a list of consonant ratios
        var intervals = [1.0, 0.5, 0.3333, 1.5, 1.3333, 2.0, 2.25]
        function changeFreq() {
            var intervalIndex = ~~(Math.random() * intervals.length);
            var noteFreq = oscillator.frequency.value * intervals[intervalIndex];
    
            //because this is random, make an effort to keep it in comfortable frequency range.
            if(noteFreq > 1600) 
                noteFreq *= 0.5;
            else if(noteFreq < 250) 
                noteFreq *= 2;
    
    
            oscillator.frequency.value = noteFreq;
        }
    </script>
    
    <body>
    <button onclick="changeFreq()">Change Places!</button>
    </body>