【发布时间】:2023-03-08 08:33:01
【问题描述】:
我正在使用带有 Beads 库的 Processing 3 来分析多个样本,但是每次我对相同的数据运行分析时,我都会得到非常不同的结果。以下是样本和分析设置:
import beads.*;
import org.jaudiolibs.beads.*;
AudioContext ac;
GranularSamplePlayer sample;
Gain gain;
ShortFrameSegmenter sfs;
FFT fft;
PowerSpectrum ps;
Frequency f;
SpectralPeaks sp;
float[][] meanHarmonics;
int numPeaks = 6;
void setup() {
size(1600, 900);
ac = new AudioContext();
ac.start();
println(dataPath("") + "1.wav");
sample = new GranularSamplePlayer(ac, SampleManager.sample(dataPath("") + "\\1.wav"));
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);
int startTime = millis();
int loops = 0;
float meanFrequency = 0.0;
while(millis() - startTime < 1500) {
loops++;
if(loops == 1) {
sample.start(0);
}
Float inputFrequency = f.getFeatures();
if(inputFrequency != null) {
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];
}
}
}
}
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();
}
我在设定的时间内运行 FFT,在此期间我将频率对象和 SpectralPeaks 功能返回的频率相加。 最后,我将累积的频率和幅度相除以获得平均值。我还尝试通过找到幅度最大的频率来找到 SpectralPeaks 数组中的基频。 但是每次我运行我的程序时,我都会从 SpectralPeaks 和 Frequency 中得到不同的结果(并且它们的值也彼此不同)。 以下是一些示例值:
第一次运行:
光谱峰特征:
914.84863 0.040409338
844.96295 0.033234257
816.0808 0.027509697
664.9141 0.022158746
633.3232 0.019597264
501.93716 0.01606628
基本谱峰:914.84863
频率:1028.1572
第二次运行,相同的样本:
光谱峰特征:
1023.4123 0.03913592
1109.2562 0.031178929
967.0786 0.026673868
721.2698 0.021666735
629.9294 0.018046249
480.82416 0.014858524
基本谱峰:1023.4123
频率:1069.3387
另外,Frequency返回的值往往是NaN,我不明白为什么会这样。
【问题讨论】:
-
你没有随机的东西吗?哦,好吧,你会的
-
什么意思?
-
在 panGlide 你有这个 random.nextFloat() 你的输入每次都会改变
-
谢谢,我把它改成了常数,但我仍然得到不同的值和 NaN。
-
请debug your code 并将您的问题缩小到minimal reproducible example。您在代码中至少调用了一个随机函数,这将为您提供不同的结果。但是,在您将问题缩小到minimal reproducible example 之前,很难为您提供帮助。
标签: java processing signal-processing fft