Quantcast
Channel: Processing Forum
Viewing all articles
Browse latest Browse all 1768

Re : How to generate a simple waveform of an entire sound file?

$
0
0
I got there in the end, here's a code dump if anybody ever needs it
It's based on one of the Minim samples

  1. /**
  2.   * This sketch demonstrates two ways to accomplish offline (non-realtime) analysis of an audio file.<br>
  3.   * The first method, which uses an AudioSample, is what you see running.<br>
  4.   * The second method, which uses an AudioRecordingStream and is only available in Minim Beta 2.1.0 and beyond,<br>
  5.   * can be viewed by looking at the offlineAnalysis.pde file.
  6.   * <p>
  7.   * For more information about Minim and additional features, visit http://code.compartmental.net/minim/
  8.   *
  9.   */

  10. import ddf.minim.*;
  11. import ddf.minim.analysis.*;
  12. import ddf.minim.spi.*;

  13. Minim minim;
  14. float[][] spectra;

  15. void setup()
  16. {
  17.   size(1000, 1000, P3D);

  18.   minim = new Minim(this);
  19.   
  20.   // There are two ways you can do offline analysis:
  21.   // 1. Loading audio data fully into memory using an AudioSample and then analyzing a channel
  22.   analyzeUsingAudioSample();
  23.   
  24.   // 2. Loading an AudioRecordingStream and reading in a buffer at a time.
  25.   //    This second option is available starting with Minim Beta 2.1.0
  26.   //analyzeUsingAudioRecordingStream();
  27. }

  28. void analyzeUsingAudioSample()
  29. {
  30.    //AudioSample jingle = minim.loadSample("bump.mp3", 2048);
  31.    AudioSample jingle = minim.loadSample("keys riffs.ogg.mp3", 2048);
  32.    
  33.   // get the left channel of the audio as a float array
  34.   // getChannel is defined in the interface BuffereAudio, 
  35.   // which also defines two constants to use as an argument
  36.   // BufferedAudio.LEFT and BufferedAudio.RIGHT
  37.   float[] leftChannel = jingle.getChannel(AudioSample.LEFT);
  38.   
  39.   // then we create an array we'll copy sample data into for the FFT object
  40.   // this should be as large as you want your FFT to be. generally speaking, 1024 is probably fine.
  41.   int fftSize = 1024;
  42.   float[] fftSamples = new float[fftSize];
  43.   FFT fft = new FFT( fftSize, jingle.sampleRate() );
  44.   
  45.   // now we'll analyze the samples in chunks
  46.   int totalChunks = (leftChannel.length / fftSize) + 1;
  47.   
  48.   // allocate a 2-dimentional array that will hold all of the spectrum data for all of the chunks.
  49.   // the second dimension if fftSize/2 because the spectrum size is always half the number of samples analyzed.
  50.   spectra = new float[totalChunks][fftSize/2];
  51.   
  52.   for(int chunkIdx = 0; chunkIdx < totalChunks; ++chunkIdx)
  53.   {
  54.     int chunkStartIndex = chunkIdx * fftSize;
  55.    
  56.     // the chunk size will always be fftSize, except for the 
  57.     // last chunk, which will be however many samples are left in source
  58.     int chunkSize = min( leftChannel.length - chunkStartIndex, fftSize );
  59.    
  60.     // copy first chunk into our analysis array
  61.     arraycopy( leftChannel, // source of the copy
  62.                chunkStartIndex, // index to start in the source
  63.                fftSamples, // destination of the copy
  64.                0, // index to copy to
  65.                chunkSize // how many samples to copy
  66.               );
  67.       
  68.     // if the chunk was smaller than the fftSize, we need to pad the analysis buffer with zeroes        
  69.     if ( chunkSize < fftSize )
  70.     {
  71.       // we use a system call for this
  72.       Arrays.fill( fftSamples, chunkSize, fftSamples.length - 1, 0.0 );
  73.     }
  74.     
  75.     // now analyze this buffer
  76.     fft.forward( fftSamples );
  77.    
  78.     // and copy the resulting spectrum into our spectra array
  79.     for(int i = 0; i < 512; ++i)
  80.     {
  81.       spectra[chunkIdx][i] = fft.getBand(i);
  82.     }
  83.   }
  84.   
  85.   jingle.close(); 
  86. }

  87. void draw()
  88. {
  89.   // jump back to start position when we get to the end
  90.   
  91.   background(0);
  92.   stroke(255);
  93.   
  94.   // render the spectra going back into the screen
  95.   float scaleMod = (float(width) / float(spectra.length));
  96.   println("--");
  97.   println(width);
  98.   println(spectra.length);
  99.   println(scaleMod);
  100.   
  101.   for(int s = 0; s < spectra.length; s++)
  102.   {
  103.     stroke(255);
  104.     int i =0;
  105.     float total = 0; 
  106.     for(i = 0; i < spectra[s].length-1; i++)
  107.     {
  108.         total += spectra[s][i];
  109.     }
  110.     total = total / 10;
  111.     line(s*scaleMod,total+height/2,s*scaleMod,-total+height/2);
  112.   }
  113.   stroke(255,0,0);
  114.   line(spectra.length * scaleMod, 1000, spectra.length *scaleMod, 0+300);
  115. }



Viewing all articles
Browse latest Browse all 1768

Trending Articles