We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hello,
I'm writing a program which takes the FFT of various files in a folder and then writes the FFT data to a text file for a machine learning algorithim. However, for many of the files I process, I get zero out for all bands causing me to lose lots of potential data.
I'm also getting the error of "JavaSound Minim Error: Error Reading from File - Stream Closed" on many of the files, though I'm not sure if it affects the FFT data.
Here's my code (I'm new to coding so I'm open to pointers on my code too):
import ddf.minim.analysis.*;
import ddf.minim.*;
import java.io.*;
Minim       minim;
AudioPlayer player;
FFT         fft;
FileWriter fw;
int counter = 0;
void setup()
{
 minim = new Minim(this);
 try 
 {
     //create .txt file to record data
     fw = new FileWriter("audioRawData.txt");
     //run data() which reads .wav files and outputs FFT data to text file
    data();
 }
 catch (IOException e) 
 {
 }
}
 void data()
{
  try 
  {
  //list files in a directory given by filePath  
  String filePath = "";  
  File[] files = new File(filePath).listFiles();
  //loop thru files
  for(File file : files) 
  {
   //get name of file
   String fileName = file.getName();
   //only process if .wav file
   if (fileName.contains(".wav"))
   {
     //counter to keep track
     counter = counter + 1 ;
     //print counter and file name to keep track of what's being processed
     println(counter);
     println(fileName);
     //load file in Minim and play using AudioPlayer
     player = minim.loadFile(filePath + fileName);
     player.play();
     //create new FFT and use Hamming window
     fft = new FFT(player.bufferSize(), player.sampleRate());
     fft.window(FFT.HAMMING);
     //some files might be stereo, so use mix channel
     fft.forward(player.mix);
     //since all files in the directory are true, write 1 before the FFT data
     fw.write("1 ");
     //go through FFT using loop
     for(int i = 0; i < fft.specSize(); i++)
      {
         //write FFT with band number in front of it, convert to dB
         fw.write((i + 1) + ":" + 20 * log( 2 * fft.getBand(i) / fft.timeSize() ) + " ");
     }
       //create new line to start next file data on
       fw.write("\n");
       //close the player to avoid running out of memory
       player.close();
  }
  }
  //close and flush writer when done
  print("Done Writing!");
  fw.close();
  fw.flush();
 }
catch (IOException e) 
{
}
//terminate program when done 
exit();
}
Answers
Try this modified example. It loads the wav files in your current data directory, then it traverses the list playing one by one ad saving the processed FFT data in your txt file.
Kf
Thanks for the answer, but some files are still returning zero for the FFT even though there is data in the .wav file. Half of the files I processed using your code still returned zero.
can you post one of the failing files, or a mp3 of it anyway because a wav will be too big.
i have a feeling that you are using fft forward wrongly. you can't just call it once, needs to be once for each frame of the input. normally the draw() loop manages that, but you don't have a draw().
kf's is better because it is looping over the file. but it's doing it in realtime and i wonder if you can do better by not playing the file, just calling forward()
either way i'm getting a file with lots of -Infinity in it 8(
As an exercise, you could check what FFT output gives you zero or infinity and then save that specific buffer into a csv for example. Even better, if you save the buffer and the FFT and then have a look at the data and make some sense of it. If you provide the files, I could do some R or octave magic.
Kf
Hello, thanks for all your responses, but I found a fix by not using the AudioPlayer and instead using the AudioRecordingStream to load my data.
I used this code: https://github.com/ddf/Minim/blob/master/examples/Analysis/offlineAnalysis/offlineAnalysis.pde
I believe that the problem was something to do with the AudioPlayer loading my files wrong, but I'm still not 100% sure why the code didn't work.