p5.sound Library: Part 2

NOTE: This workshop is broken into 3 parts, due to come constraints with the number of canvases using the p5.sound library. Click to go back to the previous section of this workshop.

Using p5.sound library for sound analysis

p5.sound library provides many functions we can use to analyse and get data of an audio file or of microphone input.

Amplitude:

You can easily get the current amplitude of an audio file that is being played inside the p5 sketch using the p5.Amplitude object. The p5.Amplitude object keeps track of the volume of a sound, and we can get this number, that ranges between 0 and 1, using the getLevel() function. As we have seen before, for getting amplitude of the microphone input, the getLevel() function can be used directly with the p5.AudioIn object.

var amp;

function setup() {
  amp = new p5.Amplitude();
}

function draw() {
  var level = amp.getLevel();
}
                

When the getLevel() function is called inside the draw() function, it returns the volume of a sound at the given time of each frame. Below example uses the level variable to manipulate the width and height of an ellipse.

var sound;
var amp;

function preload() {
    sound = loadSound('assets/music/0.mp3');
}

function setup() {
    createCanvas(windowWidth, windowHeight);

    amp = new p5.Amplitude();
    noStroke();
}

function draw() {
    if (sound.isPlaying() == true) {
        background(0, 30);
    } else {
        background(255);
    }

    var level = amp.getLevel();
    ellipse(width / 2, height / 2, level * 500, level * 500);
}

function mousePressed() {
    if (sound.isPlaying() == true) {
        sound.pause();
    } else {
        sound.play();
    }
}
                

FFT:

FFT (Fast Fourier Transform) is an analysis algorithm that isolates individual audio frequencies within a waveform. The p5.FFT object can return two types of data in arrays via two different functions: waveform() and analyze()

  • waveform(): Returns an array of amplitude values (between -1.0 and 1.0) along the time domain (a sample of time)
  • analyze(): Returns an array of amplitude values (between 0 and 255) across the frequency spectrum.

Same as it was for p5.Amplitude, p5.FFT object can be created in setup() function, then used inside of draw() to continuously update the data to reflect the audio of the given frame.

var fft;

function setup() {
  fft = new p5.FFT();
}

function draw() {
  var waveform = fft.waveform();
  var spectrum = fft.analyze();
}
                

Below example code draws out waveforms using the waveform array. map() functions are used to translate a number of one range to another.

var sound;
var fft;

function preload() {
    sound = loadSound('assets/music/2.mp3');
}

function setup() {
    createCanvas(windowWidth, windowHeight);

    fft = new p5.FFT();
    noStroke();
}

function draw() {
    if (sound.isPlaying() == true) {
        background(0, 30);
        fill(255);

        var waveform = fft.waveform();
        for (var i = 0; i < waveform.length; i++) {
            var x = map(i, 0, waveform.length, 0, width);
            var y = map(waveform[i], -1, 1, height, 0);
            ellipse(x, y, 5, 5);
        }

    } else {
        background(255);
    }
}

function mousePressed() {
    if (sound.isPlaying() == true) {
        sound.pause();
    } else {
        sound.play();
    }
}
                

Below example code draws out a frequency spectrum using the spectrum array. map() functions are used here again to translate a number of one range to another.

var sound;
var fft;

function preload() {
    sound = loadSound('assets/music/2.mp3');
}

function setup() {
    createCanvas(windowWidth, windowHeight);

    fft = new p5.FFT();
    noStroke();
}

function draw() {
    if (sound.isPlaying() == true) {
        background(0, 30);
        fill(255);

        var spectrum = fft.analyze();
        for (var i = 0; i < spectrum.length; i += 10) {
            var x = map(i, 0, spectrum.length, 0, width);
            var y = map(spectrum[i], 0, 255, height, 0);
            ellipse(x, y, 5, 5);
        }

    } else {
        background(255);
    }
}

function mousePressed() {
    if (sound.isPlaying() == true) {
        sound.pause();
    } else {
        sound.play();
    }
}
                
Using p5.sound to generate sound

Click to proceed to the next section of this workshop.