on Writings, Web Audio API, Tutorials, Code

Creating a sound analyser with the Web Audio API

We left off having loaded the audio using the analyseAudio object. Now we're going to explore the setUpAnalyser() function which will starts off the sound analysing process. setUpAnalyser sets up everything we need to analyse the music:

  • it creates a separate processor node required for the analysis 
  • sets up the sound buffer for playing the track, and also loops the song
  • makes sure the analyseBoost function is called when the track is playing

Overview

There's 4 steps to this tutorial:

  • Step 1 will create a processor node used for processing music
  • Step 2 creates the sound analyser
  • Step 3 uses the sound buffer to play the music
  • Step 4 calls makes sure the sound is analysed when processed

Step 1: What is a script processor node?

The first thing to do is create a script processor which is used for direct audio processing in JavaScript. To create the processor node, audio context has a handy function: createScriptProcessor(bufferSize, numberOfInputChannels, numberOfOutputChannels); . I have used it as follows:

var scriptProcessorNode = this.audioCtx.createScriptProcessor(2048, 1, 1);  

 We then set the processor node's buffer to the one passed into the setUpAnalyser function, and connect it using audio context's destination property:

//set buffer  
scriptProcessorNode.buffer = buffer;  
//connect
scriptProcessorNode.connect(this.audioCtx.destination);

Step 2: Create the sound analyser using Audio Context

Actually creating the analyser is very simple. We just use the audio context's createAnalyser() function (line 2). After that, we set a few of the analyser's properties:

//create analyser  
this.analyser = this.audioCtx.createAnalyser();  
//set analyser properties
this.analyser.smoothingTimeConstant = 0.6;  
this.analyser.fftSize = 512;  
this.analyser.connect(scriptProcessorNodes);

Step 3: The source buffer lets the music play

Next, we make use of our original source buffer, which had previously been instantiated in the constructor like so:

this.source = this.audioCtx.createBufferSource();

The source property is used to play the music, so we set it's buffer property, and connect it using the audio context destination (just like with the processor node). Additionally, we can set the loop property to true so that the song repeats instead of stopping at the end:

//set buffer  
this.source.buffer = buffer;  
//connect
this.source.connect(this.audioCtx.destination);  
//set looping
this.source.loop = true;  
//connect using analyser
this.source.connect(this.analyser);

Step 4: The last step :)

The final part of this function triggers analyseBoost(), which is used to analyse the track whilst it plays:

scriptProcessorNode.onaudioprocess = function(e) {  
              audioAnalyserInstance.analyseBoost();
           }

Overall

The overall function should look like this:

setUpAnalyser:function(buffer){

         var audioAnalyserInstance = this;
         var scriptProcessorNode = this.audioCtx.createScriptProcessor(2048, 1, 1);
          scriptProcessorNode.buffer = buffer;
          scriptProcessorNode.connect(this.audioCtx.destination);

          this.analyser = this.audioCtx.createAnalyser();
          this.analyser.smoothingTimeConstant = 0.6;
          this.analyser.fftSize = 512;
          this.analyser.connect(scriptProcessorNodes);

          this.source.buffer = buffer;
          this.source.connect(this.audioCtx.destination);
          this.source.loop = true;
          this.source.connect(this.analyser);

          scriptProcessorNode.onaudioprocess = function(e) {
              audioAnalyserInstance.analyseBoost();
           }


    }

Nice one.

The next part of this series will use the analyser created in this tutorial to detect the beat of the music.