We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I am trying to use the Beads ShortFrameSegmenter and FFT in order to determine the pitch and harmonics of a sample but each time I run my sketch I get different results. Here's my code
import beads.*;
import org.jaudiolibs.beads.*;
import java.util.Timer;
import java.util.TimerTask;
AudioContext ac;
GranularSamplePlayer sample;
Gain gain;
ShortFrameSegmenter sfs;
FFT fft;
PowerSpectrum ps;
Frequency f;
SpectralPeaks sp;
float[][] meanHarmonics;
int numPeaks = 6;
int loops = 0;
double meanFrequency = 0.0;
Timer t = new Timer();
boolean finished = false;
void setup() {
size(1600, 900);
ac = new AudioContext();
ac.start();
sample = new GranularSamplePlayer(ac, SampleManager.sample(dataPath("") + "\\C2.mp3"));
gain = new Gain(ac, 1, 1);
// input chaining
gain.addInput(sample);
ac.out.addInput(gain);
// setup analysis
// break audio into more manageable chunks
sfs = new ShortFrameSegmenter(ac);
sfs.addInput(sample);
// fast fourier transform to analyse the harmonic spectrum
fft = new FFT();
sfs.addListener(fft);
// PowerSpectrum turns the raw FFT output into proper audio data.
ps = new PowerSpectrum();
fft.addListener(ps);
// Frequency tries to determine the strongest frequency in the wave
// which is the fundamental that determines the pitch of the sound
f = new Frequency(44100.0f);
ps.addListener(f);
// Listens for harmonics
sp = new SpectralPeaks(ac, numPeaks);
ps.addListener(sp);
meanHarmonics = new float[numPeaks][2];
// initialise meanHarmonics
for (int i = 0; i < numPeaks; i++) {
for (int j = 0; j < 2; j++) {
meanHarmonics[i][j] = 0;
}
}
ac.out.addDependent(sfs);
t.scheduleAtFixedRate(new TimerTask() {
public void run() {
loops++;
if (loops == 1) {
sample.start(0);
} else if (loops >= 1500) {
finished = true;
t.cancel();
}
Float inputFrequency = f.getFeatures();
if (inputFrequency != null && inputFrequency != Float.NaN) {
println(inputFrequency);
meanFrequency += inputFrequency;
}
float[][] harmonics = sp.getFeatures();
if (harmonics != null) {
for (int feature = 0; feature < numPeaks; feature++) {
// harmonic must be in human audible range
// and its amplitude must be large enough to be audible
if (harmonics[feature][0] < 20000.0 && harmonics[feature][1] > 0.01) {
// average out the frequencies
meanHarmonics[feature][0] += harmonics[feature][0];
// average out the amplitudes
meanHarmonics[feature][1] += harmonics[feature][1];
}
}
}
}
}
, 0, 1);
while (!finished) {
print("");
}
float maxAmp = 0.0;
float freq = 0.0;
sample.pause(true);
meanFrequency /= loops;
println(meanFrequency);
for (int feature = 0; feature < numPeaks; feature++) {
meanHarmonics[feature][0] /= loops;
meanHarmonics[feature][1] /= loops;
if (meanHarmonics[feature][1] > maxAmp) {
freq = meanHarmonics[feature][0];
maxAmp = meanHarmonics[feature][1];
}
println(meanHarmonics[feature][0] + " " + meanHarmonics[feature][1]);
}
println(freq + " " + meanFrequency);
println();
}
For every run I do I get different values for the harmonics' frequencies and amplitudes as well as the meanFrequency value, which is often NaN. I've also noticed that when printing the inputFrequency on each iteration its values are not entirely accurate especially in the lower end of the frequency spectrum. I've tested this both with complex samples and simple sine waves.
StackOverflow question: https://stackoverflow.com/questions/48769181/getting-different-results-each-time-i-run-fft-with-processing-and-beads