import ddf.minim.analysis.*;
import ddf.minim.*;
import ddf.minim.signals.*;
import ddf.minim.effects.*;
import java.io.File;   
import javax.swing.JFileChooser;
import ddf.minim.ugens.*;
 
float GUIthresh = 0.67;
Minim minim;
PImage logo;
PImage hpfhand;
PImage lpfhand;
PFont small;
PFont huge;
int hugefont = 80;
AudioOutput out;
AudioPlayer song;
AudioSignal as;
float pitchmu = 1;
ddf.minim.analysis.FFT fft;
int spectrumScale = 5; // pixels per FFT bin
IIRFilter fil;
LowPassFS fil2;
float centerFreq;
float bandwidth;
float height3;
String filename;
int filtype = 1;
JFileChooser fileChooser;
 
void setup()
{
       fileChooser = new JFileChooser();
 
  size(600, 300, P3D);
  logo = loadImage("logo.png");
  hpfhand =loadImage("hpf.png");
  lpfhand = loadImage("lpf.png");
  minim = new Minim(this);
    openSong();
  small = createFont("Arial",14,true);
  huge = createFont("Arial", 12);
 
 
  out = minim.getLineOut(Minim.STEREO);
 
  fft = new ddf.minim.analysis.FFT(out.bufferSize(), out.sampleRate());
  fft.window(ddf.minim.analysis.FFT.HAMMING);
 
 
 
  centerFreq = 440;
  bandwidth = 20;
 
  fil = new LowPassFS(centerFreq, song.sampleRate());
  song.addEffect(fil);
}
 
void draw()
{
  background(0);
  stroke(154,202,235);
 
  image(logo, width/2-logo.width/2, 0, logo.width/2, logo.height/2);
 
 
  for(int i = 0; i < out.bufferSize() - 1; i++)
  {
    float x1 = map(i, 0, out.bufferSize(), 0, width);
    float x2 = map(i+1, 0, out.bufferSize(), 0, width);
    line(x1, 140 + song.left.get(i)*50, x2, 140 + song.left.get(i+1)*50);
   // line(x1, 150 + song.right.get(i)*50, x2, 150 + song.right.get(i+1)*50);
  }
 
 
  fft.forward(out.mix);
  fft.forward(song.mix);
 // fill(100,400,255);
  noStroke();
  /*
  for(int i = 0; i < fft.specSize(); i++)
  {
    // draw the line for frequency band i using dB scale
    float val = 4*(20*((float)Math.log10(fft.getBand(i))));
    rect(i*spectrumScale, height, spectrumScale, -Math.round(val));
  }
  */
 
  height3 = height/3;
  for(int i = 0; i < fft.specSize(); i++)
    {
 
 
      float valcu = 4*(20*((float)Math.log10(fil.frequency())));
      float val = 4*(20*((float)Math.log10(fft.getBand(i))));
      fill(255,0, 255*i/fft.specSize());
      if (song.isPlaying())
      rect(i*spectrumScale, height+30, spectrumScale, -Math.round(val));
 
     //line(i, height3, i, height3 - fft.getBand(i)*spectrumScale);
      //line(i, height, i, height - val);
      //float x1 = map(i, 0, val, 0, width);
    //float x2 = map(i+1, 0, val, 0, width);
    //line(i, Math.round(val), i+1, Math.round(val));
 
 
 
    }
      String filstr = "";
       switch(filtype){
         case 1: filstr = "LOWPASS"; break;
         case 0: filstr = "HIGHPASS"; break;
         case 2: break;
       }
 
       fill(255);  textFont(small,14);                  // STEP 3 Specify font to be used
 
 
       text(filstr +" Cutoff @ " + Math.round(fil.frequency()) + " Hz", mouseX*(int(mouseX<(GUIthresh*width))) + int(mouseX>(GUIthresh*width))*width*GUIthresh, mouseY  );
 
        fill(255);
 
       text("Instructions: Press H/L for\n HPF/LPF, move mouse to\nchange f_cutoff, [/] to skip,\n O to open a new track,\n space to play/pause", width*0.5, 35);
 
       if (filtype == 1) {
         image(lpfhand, width-lpfhand.width/3 -10, 10, lpfhand.width/3, lpfhand.width/3);
 
       }
 
       else if (filtype == 0) {
         image(hpfhand, width-hpfhand.width/3 -10, 10, hpfhand.height/3, hpfhand.width/3);
 
       }
 
 
}
 
void mouseMoved()
{
  centerFreq = map(mouseX, 0, width, 0, song.sampleRate()/(spectrumScale));
  fil.setFreq(centerFreq);
  float bpfQ = 100 - map(mouseY, 0, height, 0, 98);  // lowest Q is 100-98 = 2;
 // bandwidth = centerFreq/bpfQ;
  //float bpfQ = 100 - map(mouseY, 0, height, 0, 98);
  //fil.setBandWidth(bandwidth);
 
 
}
 
 
void keyPressed() /// NOT USING
{
  SineWave mySine;
  Osc osc1;
 
  float pitch = 0;
 
 // if (key == )
 
  //else if (key == )
 
  switch(key) {
 
 
    /*case 'a': pitch = 262; break;
    case 'w': pitch = 277; break;
    case 's': pitch = 294; break;
    case 'e': pitch = 311; break;
    case 'd': pitch = 330; break;
    case 'f': pitch = 349; break;
    case 't': pitch = 370; break;
    case 'g': pitch = 392; break;
    case 'y': pitch = 415; break;
    case 'h': pitch = 440; break;
    case 'u': pitch = 466; break;
    case 'j': pitch = 494; break;
    case 'k': pitch = 523; break;
    case 'o': pitch = 554; break;
    case 'l': pitch = 587; break;
    case 'p': pitch = 622; break;
    case ';': pitch = 659; break;
    */
  }
 
   if (pitch > 0) {
      osc1 = new Osc(pitch*pitchmu, 0.2, "saw");
 
   }
 
 
 
 
 
 
}
void keyReleased()
{
   //Pitch Controls
  if (key == 'z' && pitchmu > 0.25) {
    pitchmu = pitchmu/2;
  } else if (key == 'x' && pitchmu < 8) {
    pitchmu = pitchmu*2;
  }
  else if (key == 'h') { //hp
      fil = new HighPassSP(centerFreq, song.sampleRate());
      filtype = 0;
      song.clearEffects();
        song.addEffect(fil);
 
 
  }
  else if (key == 'l') { // lp
     fil = new LowPassFS(centerFreq, song.sampleRate());
     filtype = 1;
           song.clearEffects();
 
       song.addEffect(fil);
 
  }
   else if (key == ' ') { //hp
 
       if (song.isPlaying())
         song.pause();
       else
         song.play();
 
 
 
  }
 
  else if (key == '[') {
        song.skip(-3000);
 
   song.rewind(); 
  }
  else if (key == ']') {
          song.skip(3000);
 
  }
 
  else if (key == 'o') { //hp
       song.close();
       setup();
 
  }
 
}
 
int openSong() {
 
   if (song != null)
     System.out.println("hi");
  fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
  int result = fileChooser.showOpenDialog(null);
    File selectedFile = fileChooser.getSelectedFile();
    //System.out.println("Selected file: " + selectedFile.getAbsolutePath());
    filename = selectedFile.getAbsolutePath();
   song = minim.loadFile(filename, 1024);
  song.loop(); 
 
  return result;
}
 
 
 
void stop()
{
  out.close();
  minim.stop();
 song.close();
  super.stop();
}
 
 
class Osc implements AudioSignal
{
     private float freq;
     private float level;
     private float alph;
     private Oscillator exc;
 
     Osc(float pitch, float amplitude, String waveform)
     {  
         freq = pitch;
         level = amplitude;
         exc = new SineWave(freq, level, out.sampleRate());
         alph = 0.9;  // Decay constant for the envelope
         out.addSignal(this);
 
         if (waveform.equals("sine"))
         {
           exc = new SineWave(freq, level, out.sampleRate());
         }
         else if (waveform.equals("saw"))
         {
            exc = new SawWave(freq, level, out.sampleRate());
 
         }
         else {
          exc = new PulseWave(freq, level, out.sampleRate());
 
         }
 
     }
 
     void updateLevel()
     {
         // Called once per buffer to decay the amplitude away
         level = level * alph;
         exc.setAmp(level);
 
         if (level < 0.01) {
             out.removeSignal(this);
         }
         // this will lead to destruction of the object, since the only active 
         // reference to it is from the LineOut
     }
 
     void generate(float [] samp)
     {
         // generate the next buffer's worth of sinusoid
         exc.generate(samp);
         // decay the amplitude a little bit more
         updateLevel();
     }
 
    // AudioSignal requires both mono and stereo generate functions
    void generate(float [] sampL, float [] sampR)
    {
        exc.generate(sampL, sampR);
        updateLevel();
    }
 
}

Alumni Liaison

Ph.D. 2007, working on developing cool imaging technologies for digital cameras, camera phones, and video surveillance cameras.

Buyue Zhang