public void setup() {
    int window_height = 220;
    size((int) (window_height * 5.12f), 220);
    canvas = createGraphics((int) (window_height * 5.12f) / 2, 220, JAVA2D);

    textMode(SCREEN);
    textFont(createFont("SanSerif", 12));

    minim = new Minim(this);

    in = minim.getLineIn(Minim.MONO, buffer_size, sample_rate);

    // create an FFT object that has a time-domain buffer
    // the same size as line-in's sample buffer
    fft = new FFT(in.bufferSize(), in.sampleRate());
    // Tapered window important for log-domain display
    fft.window(FFT.HAMMING);

    // initialize peak-hold structures
    peaksize = 1 + Math.round(fft.specSize() / binsperband);
    peaks = new float[peaksize];
    peak_age = new int[peaksize];

    particles = new Particle[fft.specSize()];
    for (int i = 0; i < fft.specSize(); i++) particles[i] = new Particle(i);
  }
 private void drawParticles() {
   pushStyle();
   colorMode(RGB, 255);
   // background(0);
   popStyle();
   for (int i = 0; i < fft.specSize() - 1; i++) {
     float val = dB_scale * (20 * ((float) Math.log10(fft.getBand(i))));
     if (fft.getBand(i) == 0) {
       val = -200;
     } // avoid log(0)
     particles[i].update(val);
     particles[i].render();
   }
 }
  private void drawSavedValues() {
    background(0);
    // now draw current spectrum
    for (int i = 0; i < saved_freqs.length; i++) {
      int[] c = calculated_color(i);
      stroke(c[0], c[1], c[2]);
      noFill();
      int x1 =
          (int)
              map(
                  legend_width + i,
                  legend_width,
                  legend_width + spectrum_width,
                  legend_width,
                  width);
      line(x1, spectrum_height, x1, saved_freqs[i]);
      int x2 = x1 + 1;
      line(x2, spectrum_height, x2, saved_freqs[i]);
    }

    int[] color_waveform = calculated_color(loudest_freq);
    stroke(color_waveform[0], color_waveform[1], color_waveform[2]);
    for (int i = 0; i < saved_buffer.length - 1; i++) {
      line(i + 50, height / 2 + saved_buffer[i] * 50, i + 51, height / 2 + saved_buffer[i] * 50);
    }

    drawParticles();

    if (drawScale) {
      // add legend
      // frequency axis
      fill(255);
      stroke(255);
      int y = spectrum_height;
      line(legend_width, y, legend_width + spectrum_width, y); // horizontal line
      // x,y address of text is immediately to the left of the middle of the letters
      textAlign(CENTER, TOP);
      for (float freq = 0.0f; freq < in.sampleRate() / 2; freq += 2000.0) {
        int x = legend_width + (fft.freqToIndex(freq) * 2); // which bin holds this frequency
        line(x, y, x, y + 4); // tick mark
        text(Math.round(freq / 1000) + "kHz", x, y + 5); // add text label
      }

      // level axis

      int x = legend_width;
      line(x, 0, x, spectrum_height); // vertictal line
      textAlign(RIGHT, CENTER);
      for (float level = -100.0f; level < 100.0; level += 20.0) {
        y = spectrum_height - (int) (dB_scale * (level + gain));
        line(x, y, x - 3, y);
        text((int) level + " dB", x - 5, y);
      }
    }

    canvas.endDraw();
    image(canvas, 0, 0, width, height); // draw canvas streched to sketch dimensions		
  }
  public void draw() {
    canvas.beginDraw();
    if (paused) {
      drawSavedValues();
      return;
    }
    // clear window
    // background(0);
    fill(0, fill_amount); // semi-transparent white
    rect(0, 0, width, height);
    fill(random(255));
    // perform a forward FFT on the samples in input buffer
    fft.forward(in.mix);
    loudest_freq = 0;
    loudest_db = -1000;

    // now draw current spectrum
    for (int i = 0; i < spectrum_width; i++) {
      // draw the line for frequency band i using dB scale
      float val = dB_scale * (20 * ((float) Math.log10(fft.getBand(i))) + gain);
      if (fft.getBand(i) == 0) {
        val = -200;
      } // avoid log(0)
      int y = spectrum_height - Math.round(val);
      y = y > spectrum_height ? spectrum_height : y;

      if (i > 20 && val > loudest_db) {
        loudest_db = (int) val;
        loudest_freq = i;
      }

      int[] c = calculated_color(i);
      stroke(c[0], c[1], c[2]);
      noFill();
      int x1 =
          (int)
              map(
                  legend_width + i,
                  legend_width,
                  legend_width + spectrum_width,
                  legend_width,
                  width);
      // int x1 = legend_width + i;
      int x2 = x1 + 1;
      if (i < 520) {
        line(x1, spectrum_height, x1, y);
        line(x2, spectrum_height, x2, y);
      }
      saved_freqs[i] = y;
    }

    int[] color_waveform = calculated_color(loudest_freq);
    println(
        "Peak: "
            + loudest_freq
            + " dB: "
            + loudest_db
            + " Color "
            + color_waveform[0]
            + " "
            + color_waveform[1]
            + " "
            + color_waveform[2]);
    stroke(color_waveform[0], color_waveform[1], color_waveform[2]);
    drawWaveForm();

    drawParticles();

    // level axis
    if (drawScale) {
      // add legend
      // frequency axis
      fill(255);
      stroke(255);
      int y = spectrum_height;
      // line(legend_width,y,legend_width+spectrum_width,y); // horizontal line
      // x,y address of text is immediately to the left of the middle of the letters
      textAlign(CENTER, TOP);
      for (float freq = 0.0f; freq < in.sampleRate() / 2; freq += 2000.0) {
        int x = legend_width + (fft.freqToIndex(freq) * 2); // which bin holds this frequency

        line(x, y, x, y + 4); // tick mark
        text(Math.round(freq / 1000) + "kHz", x, y + 5); // add text label
      }

      int x = legend_width;
      line(x, 0, x, spectrum_height); // vertictal line
      textAlign(RIGHT, CENTER);
      for (float level = -100.0f; level < 100.0; level += 20.0) {
        y = spectrum_height - (int) (dB_scale * (level + gain));
        line(x, y, x - 3, y);
        text((int) level + " dB", x - 5, y);
      }
    }
    drawArcs();
    canvas.endDraw();
    image(canvas, 0, 0, width, height); // draw canvas streched to sketch dimensions		
  }