Normalize Audio and Rect Height

Hi,

I’m trying to build a program which generates a waveform in the middle of the screen.
I want to map the height of my rectangle, the minimum height must be 0, and the maximum must not overpass 50 px.

The problem is that I can’t figure out how to map the frequency depending on the audio I’m uploading. If I upload a song the rectangles are too tall, whereas by using a voice the representation becomes flat.

import ddf.minim.analysis.*;
import ddf.minim.*;
import java.util.Date;

Minim minim;
AudioPlayer player;
FFT fft;

String[] filenames;
String nomeFile;
float c = 1.2;
float dist;
int larghezza;
float ma;

void setup() {
  size(400, 400);
  smooth();

  larghezza = round(width/60);
  dist = larghezza*2;

  String path = sketchPath("");
  filenames = listFileNames(path);

  minim = new Minim(this);

  for (int i = 0; i < filenames.length; i++) {
    if (filenames[i].endsWith("mp3")) { 
      nomeFile = filenames[i];
    }
  }

  player = minim.loadFile(nomeFile);
  fft = new FFT(player.bufferSize(), player.sampleRate());
  player.play();

  println(nomeFile + " is loaded");
}

void draw() {
  background(0);
  stroke(255);

  fft.forward(player.mix);

  /* START ---- Trying to equalize */
  float[] band = new float[fft.specSize()];
  for (int i = 0; i < fft.specSize(); i++) {
    band[i]=fft.getBand(i);
  }
  float max = max(band);
  float x = 1;

  if (max*c > 50) {
    x = max*c/50;
  }
  /* END ---- Trying to equalize */

  for (int i = 0; i < fft.specSize(); i++) {
    fill(255);
    strokeWeight(0.5);
    noStroke();
    rect(i*dist, height/2, larghezza, fft.getBand(i)*c/x);
    rect(i*dist, height/2, larghezza, fft.getBand(i)*-c/x);
  }
}

// This function returns all the files in a directory as an array of Strings  
String[] listFileNames(String dir) {
  File file = new File(dir);
  String names[] = file.list();
  return names;
}

With https://processing.org/reference/constrain_.html
you can make sure that values are never out of a given range.

That can help, but maybe you also want some kind of adaptive behavior. For instance, you could scale the values up and down depending on the maximum and minimum values from the last few seconds.

Or simpler, can you analyze the audio in advance (first pass) to figure out the maximum values, and then visualize it in a second pass?

1 Like

Hi, Thank you ! Yes I Introduced the constrain function, but I can’t get the maximum value of the few seconds and scale the values.