Processing Beginner Article 7

Sound with Minim

Play, loop, and react to audio in Processing using the Minim library for playback and microphone input.

⏱ 19 min Minim sound audio microphone AudioPlayer amplitude

Installing Minim

Minim is the most widely-used audio library for Processing. Install it through the Contribution Manager:

  1. Open Processing and go to Sketch → Import Library → Manage Libraries.
  2. Search for Minim.
  3. Click Install and wait for the download to finish.
  4. Restart Processing.

Minim is now available in every sketch.

Basic playback

To play an audio file, place it in the data/ folder of your sketch and then use Minim and AudioPlayer:

import ddf.minim.*;

Minim minim;
AudioPlayer player;

void setup() {
  size(400, 200);
  minim  = new Minim(this);                // 'this' gives Minim access to the sketch
  player = minim.loadFile("sound.mp3");    // file must be in data/
  player.play();
}

void draw() {
  background(20);
  fill(255);
  textAlign(CENTER, CENTER);
  textSize(16);
  text("Playing: " + player.position() / 1000.0 + " s", width / 2, height / 2);
}

// Always stop Minim when the sketch closes
void stop() {
  player.close();
  minim.stop();
  super.stop();
}

minim.loadFile() supports MP3, WAV, AIFF, and OGG files. Processing loads the file once and keeps it in memory.

Looping, volume, and pan

// Loop the file indefinitely
player.loop();

// Loop a specific number of times (0 = play once, n = n+1 total plays)
player.loop(3);

// Stop the loop and let the current playthrough finish
player.endLoop();

// Volume: 0.0 (silent) to 1.0 (full)
player.setGain(-6.0f);   // Minim uses dB; 0 = unity gain, negative = quieter

// Pan: -1.0 (hard left) to 1.0 (hard right)
player.setPan(0.5f);     // 50 % right

// Pause and resume
player.pause();
player.play();

// Jump to a position (milliseconds)
player.skip(3000);       // jump 3 seconds forward
player.rewind();         // jump to beginning

AudioInput: microphone access

AudioInput captures live audio from the default system microphone (or any audio interface):

import ddf.minim.*;

Minim minim;
AudioInput mic;

void setup() {
  size(600, 200);
  minim = new Minim(this);
  mic   = minim.getLineIn(Minim.MONO, 512);  // MONO, buffer size 512 samples
}

void draw() {
  background(20);

  // Draw the raw waveform
  stroke(80, 200, 255);
  strokeWeight(1.5);
  noFill();

  float step = (float) width / mic.bufferSize();
  for (int i = 0; i < mic.bufferSize() - 1; i++) {
    float x1 = i * step;
    float y1 = height / 2 + mic.left.get(i) * height * 0.4;
    float x2 = (i + 1) * step;
    float y2 = height / 2 + mic.left.get(i + 1) * height * 0.4;
    line(x1, y1, x2, y2);
  }
}

void stop() {
  mic.close();
  minim.stop();
  super.stop();
}

mic.left is an AudioBuffer containing the most recent audio samples. Each value in the buffer is a float between -1 and 1 representing the waveform.

Reading amplitude (volume level)

Amplitude is the average absolute value of the samples — a simple measure of loudness:

import ddf.minim.*;
import ddf.minim.analysis.*;

Minim minim;
AudioInput mic;

void setup() {
  size(600, 400);
  minim = new Minim(this);
  mic   = minim.getLineIn(Minim.MONO, 512);
}

void draw() {
  background(10);

  // Calculate RMS amplitude manually
  float sum = 0;
  for (int i = 0; i < mic.bufferSize(); i++) {
    float s = mic.left.get(i);
    sum += s * s;
  }
  float rms = sqrt(sum / mic.bufferSize());

  // Map amplitude to a visual size
  float sz = map(rms, 0, 0.5, 10, min(width, height) * 0.9);
  float bright = map(rms, 0, 0.5, 50, 255);

  noStroke();
  fill(bright, bright * 0.4, 255 - bright * 0.3);
  ellipse(width / 2, height / 2, sz, sz);

  // Text readout
  fill(255);
  textAlign(LEFT, TOP);
  textSize(14);
  text("RMS: " + nf(rms, 1, 3), 10, 10);
}

void stop() {
  mic.close();
  minim.stop();
  super.stop();
}

Reacting to sound: full example

This sketch combines a pre-loaded music track with a microphone-driven visual. For the track-driven version, replace the mic input with a player and use the player’s buffer:

import ddf.minim.*;

Minim minim;
AudioPlayer player;
int NUM_BARS = 64;

void setup() {
  size(800, 400);
  minim  = new Minim(this);
  player = minim.loadFile("music.mp3", 1024);  // 1024-sample buffer
  player.loop();
}

void draw() {
  background(10, 10, 15, 80);   // slight trail

  float barW = (float) width / NUM_BARS;

  for (int i = 0; i < NUM_BARS; i++) {
    // Sample at evenly-spaced points in the audio buffer
    int bufIdx = (int) map(i, 0, NUM_BARS, 0, player.bufferSize() - 1);
    float sample = abs(player.left.get(bufIdx));

    float barH  = map(sample, 0, 1, 4, height * 0.85);
    float hue   = map(i, 0, NUM_BARS, 180, 320);

    colorMode(HSB, 360, 100, 100);
    fill(hue, 80, map(sample, 0, 1, 40, 100));
    noStroke();
    rect(i * barW, height - barH, barW - 1, barH);
  }

  colorMode(RGB, 255);
}

void stop() {
  player.close();
  minim.stop();
  super.stop();
}

Replace music.mp3 with any file in your data/ folder. The bars light up in proportion to the instantaneous amplitude at each position in the audio buffer — a basic but satisfying waveform visualiser.

Key takeaways

  • Install Minim once via Sketch → Import Library → Manage Libraries.
  • minim.loadFile() loads a sound file; put the file in your data/ folder.
  • player.play(), .loop(), .pause(), .rewind() control playback.
  • minim.getLineIn() opens the microphone; buffer values are floats between -1 and 1.
  • Compute RMS amplitude to get a single loudness number suitable for driving visuals.
  • Always call player.close() and minim.stop() inside stop() to avoid resource leaks.