I wanted to filter out the voice of a singer in a song. I've gotten close with this, still get pops, clicks and tweets from the track though.
Hopefully, someone will find this useful. Created from examples out of Minim.
Left click sets the lower cutoff frequency, right sets upper. Middle button sets the amplitude cutoff.
Remember to replace 'yourmusic.mp3' with your own mp3 file.
Quote:
import ddf.minim.*;
import ddf.minim.effects.*;
import ddf.minim.analysis.*;
AudioPlayer groove;
AttenEffect ateffect;
int bsize=512;
FFT dispfft; //For display after filtering
void setup() {
size(512, 200);
// always start Minim first
Minim.start(this);
//Load an mp3 file
groove = Minim.loadFile("yourmusic.mp3", bsize);
groove.loop(); //repeat
//Used for displaying output frequencies
dispfft = new FFT(bsize, 44100);
dispfft.window(FFT.HAMMING); //choose a windowing method
//Create a filter and attach it to the audio output
ateffect = new AttenEffect();
groove.addEffect(ateffect);
}
void mousePressed() {
//Lower cutoff freq
if (mouseButton == LEFT) {ateffect.lower = mouseX;}
//Upper cutoff freq
if (mouseButton == RIGHT) {ateffect.upper = mouseX;}
//Amplitude cutoff
if (mouseButton == CENTER) {ateffect.peak = (height - mouseY) / 4;}
println(ateffect.lower);
println(ateffect.upper);
println(ateffect.peak);
}
void draw() {
background(0);
stroke(255);
//Get output frequencies after filtering
dispfft.forward(groove.left);
//Draw output waveform
for(int i = 0; i < groove.bufferSize() - 1; i++) {
line(i, 50 - groove.left.get(i)*50, i+1, 50 - groove.left.get(i+1)*50);
line(i, 150 - groove.right.get(i)*50, i+1, 150 - groove.right.get(i+1)*50);
line(i, height, i, height - dispfft.getBand(i)*4);
}
//Show the region to pass, vertical=amplitude, horizontal=frequency
fill(0,255,0,32);
rect(ateffect.lower, 0, ateffect.upper - ateffect.lower, height - (ateffect.peak*4));
}
void stop() {
// always close Minim audio classes when you are done with them
groove.close();
super.stop();
}
//
class AttenEffect implements AudioEffect {
int lower=0, upper=2000, peak=0;
void process(float[] samp) {
FFT fft;
fft = new FFT(samp.length, 44100);
fft.forward(samp);
for (int i=0; i<fft.specSize(); i++) {
if ((i<lower) || (i>upper)) {
//clip if below lower freq or above upper freq limits
fft.setBand(i, 0);
} else if (fft.getBand(i)<peak) {
//attenuate if above threshold
fft.scaleBand(i, 0.2);
}
}
//send the filtered audio to the output
fft.inverse(samp);
}
void process(float[] left, float[] right) {
process(left);
process(right);
}
}