Can I acquire the largest FFT magnitude value without playing through the whole file?

#1

Trying to figure out how to convert the FFT units to an Amp value in processing proved to be very confusing and complex, but when I play through the whole file, I can find the maximum FFT output and just use that to calculate what I assume is the correct Amp. For example, FFTx/maxFFT gives me an Amp value that sounds right to my ears.

What I’m wondering is if I can just quickly find this max FFT output in the file rather than having to play through all of it.

0 Likes

#2

Are you referring to Processing Sound FFT, or minim FFT?

https://processing.org/reference/libraries/sound/FFT.html
http://code.compartmental.net/minim/javadoc/ddf/minim/analysis/FFT.html
http://code.compartmental.net/minim/fft_class_fft.html

Can you give a short example of what you are trying to do?

0 Likes

#3

I was just testing if I could replicate a sound file using a sine oscillator, which I got fairly close to (but limited by the draw frames and amount of oscillators I can run - about 185 at a time, also bands). I wanted to replicate the volume it plays at as well, so I tried to figure out how to use the value i get in the frequency bins of the FFT spectrum. So I have a value update throughout the clip with the highest FFT value. Then use that as the maximum volume. I was just wondering if I could acquire that maximum without having to play through the whole file.

Edit - example code:

import processing.sound.*;

SinOsc[] sine = new SinOsc[22000];
SoundFile file;

FFT fft;
int bands = 1024;
float[] spectrum = new float[bands];
float[] ampOl = new float[bands];

float maxAmp = 0;

void setup() {
  String audio ="Example.wav";
  file = new SoundFile(this, audio);
  file.amp(0.01);

  fft = new FFT(this, bands);
  fft.input(file);

  for (int i = 0; i < 22000; i++) {
    sine[i] = new SinOsc(this);
  }

}

void draw() {
if (file.isPlaying()){
  playSines(185);
  }

}

void playSines (int sineNum) {
  fft.analyze(spectrum);
  ampOl = sort(spectrum);
  int[] ampNy = new int[sineNum];
  for (int i = 0; i < sineNum; i++) {
    for (int j = 0; j < bands; j++) {
      if (spectrum[j] == ampOl[bands - 1 - i]){
        sine[i].stop();
        ampNy[i] = j * file.sampleRate()/(bands *2);
        //if (spectrum[j] > maxAmp) { maxAmp = spectrum[j]; println(maxAmp); }
        sine[i].play(ampNy[i], ampOl[bands - 1 - i]/0.0057671145); //0.0057671145 is maxAmp value
        
      }
    }
  }
  
}

void mouseReleased() {
  if (!file.isPlaying()) {
    file.play();
  }
}

I know this is a very incorrect way of doing what I want, but I’m still figuring this out… -_-’

0 Likes