- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我需要使用梳状滤波器/变换来检测java中wav文件的基频。我还需要实现 ZCR,但这很容易。
现在我有这个:
int best = 0, best_step = 0;
for (int step = 3; step < 400; ++step) {
int sum = 0;
for (i = 1; i < 10 && i * step < spectrum.length; ++i) {
for (int di = 0; di < i; ++di) {
sum += spectrum[i * step + di] / i;
}
}
sum *= 100;
comb.add(sum);
}
int sum = 0;
for (i = 0; i < comb.size(); ++i) {
sum = comb.get(i); // 3 * comb[i] - comb[i-1] - comb[i+1];
System.out.println(i + " - " + sum);
if (sum > best) {
best_step = i;
best = sum;
}
}
我的问题是这段代码检测到错误的频率。 ;( 我已经搜索了算法/实现(任何语言),但没有找到任何东西。
注意,我不能使用自相关等。它必须是梳状滤波。
编辑:对我的代码的更多解释:
我加载一个 wav 文件并将帧放入数组帧中。然后我对其进行 fft 并获得 Complex 数组(名为 widmo)(处理复数的简单结构)。
现在我将复数的绝对值放入数组频谱中:
double[] spectrum = new double[widmo.length];
for (i = 0; i + 1 < widmo.length; ++i) {
spectrum[i] = widmo[i].abs();
}
ArrayList<Integer> comb = new ArrayList<Integer>();
int best = 0, best_step = 0;
for (int step = 3; step < 400; ++step) {
int sum = 0;
for (i = 1; i < 10 && i * step < spectrum.length; ++i) {
for (int di = 0; di < i; ++di) {
sum += spectrum[i * step + di] / i;
}
}
// sum /= step + 100; // ta linijka pozwala usunąć sporo
// niespodziewanych skoków częstotliwości
sum *= 100;
comb.add(sum);
}
int sum = 0;
for (i = 0; i < comb.size(); ++i) {
sum = comb.get(i); // 3 * comb[i] - comb[i-1] - comb[i+1];
// ctx.fillRect(i, canvas.height, 1, -sum);
System.out.println(i + " - " + sum);
// tmp.add(new freqTime(sum,));
if (sum > best) {
best_step = i;
best = sum;
}
}
System.out.println();
System.out.println(best_step);
System.out.println(4 * 44100);
System.out.println((frames.length / numChanels));
System.out.println(best_step * 44100
/ (frames.length / numChanels));
最后一个 println
应该显示我的基频,但事实并非如此。
我从我的 friend 那里得到了这个 JavaScript 代码。
最佳答案
我明白了(我想:P)。最后一个 println 给出了基本频率:)。也许有人会需要它,甚至改进它:)
ArrayList<double[]> okna = new ArrayList<>();
ArrayList<freqTime> lista = new ArrayList<freqTime>();
int po2 = (int) Math.pow(2,
Integer.parseInt((String) potega2Input.getText()));
po2 /= 2;
double[] triangles = new double[po2];
double maxWykres = 0;
int licznik = 0;
int licznik2 = 0;
int T = frames.length;
boolean wykresFlaga = false;
for (int k = 0; k < T; k += po2) {
licznik = 0;
licznik2 = 0;
double[] tmp = new double[po2];
Complex[] zespolone = new Complex[po2];
for (int i = k; i < k + po2; i++) {
if (i < T) {
tmp[licznik] = frames[i];
zespolone[licznik] = new Complex(frames[i], 0);
licznik2 = licznik;
} else {
tmp[licznik] = frames[licznik2];
zespolone[licznik] = zespolone[licznik2];
}
licznik++;
}
okna.add(tmp);
FFT fft = new FFT();
zespolone = fft.fft(zespolone);
double maxF = 0;
double maxFI = 0;
double maxH = findMaxComp(zespolone);
double[] doWykresu = new double[zespolone.length];
for (int a = 2; a < 100; a++) {
for (int i = 0; i < po2; i++) {
doWykresu[i] = zespolone[i].abs();
triangles[i] = Math.abs(i % (2 * a) - a)
* (maxH) / a;
// triangles[i] = Math.abs(i % (2 * a) - a) * (maxH)
// / a;
}
double sumT = 0;
for (int i = 0; i < po2 / 2; i++) {
sumT += triangles[i] * doWykresu[i];
}
if (sumT > maxF) {
maxF = sumT;
maxFI = a;
}
}
//
// maxFI /= 2;
//
if (wykresFlaga == false) {
maxWykres = maxH;
}
for (int i = 0; i < po2; i++) {
doWykresu[i] = zespolone[i].abs();
triangles[i] = Math.abs(i % (2 * maxFI) - maxFI)
* (maxWykres) / maxFI;
}
if (wykresFlaga == false) {
System.out.println("Max w widmie: " + maxWykres);
new Wykres(doWykresu, 1, triangles);
wykresFlaga = true;
}
// System.out.println((2 * 44100 / po2) * maxFI);
System.out.println((float) (44100 / (float) po2)
* 2*(float) maxFI + " Znalzione a: " + maxFI);
lista.add(new freqTime(
(int) ((float) (44100 / (float) po2) *2* (float) maxFI),
(double) ((double) po2 / 44100)));
/*
* System.out.println((44100 / po2) * maxFI + " " + maxFI +
* " " + maxFI / 44100 + " " + 44100 / (maxFI / po2 * 44100)
* + " " + 44100 * maxFI / T);
*/
// System.out.println(zespolone[(int) maxFI/2].abs());
}
关于java - 使用梳状滤波器检测基频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10968240/
我发布了我的第一个网站 ( www.dirkwolthuis.nl)。这是一个包含大量图像和元素的单页网站。在我的 mac 上的 chrome 中,它加载正常并且可以滚动。在 iPad 或 iPhon
我想要一个四分之一圆形的容器,想想整个披萨的四分之一。 我如何实现这一目标?基本上我想将它放在右下角位置的另一个容器顶部,圆形部分朝内,角度当然匹配右下角形成底部容器的位置,使用堆栈小部件。 谢谢。
我刚刚发现了“blockly”,这正是我一直在寻找的将我的 webApp 提升到一个新水平的方法。我遇到的问题是我不太明白如何启动 python 或 js 代码变量。 这是我的 block : Blo
之前回答的问题似乎没有回答我的问题 "Blocky" Perlin noise 我尽量简化以使我的代码易于阅读和理解。 我不使用置换表,而是使用 mt19937 生成器。 我使用 SFML using
我正在使用 blockly 开发代码编辑器,我的页面目前有用于在 block View 和代码 View 之间切换的选项卡,有点像一些所见即所得的编辑器。现在,Blockly 已经有了很多从 bloc
我无法渲染 2d block 状 map 。 这是二维 map 数组的创建方式: map = new Block[w * h]; block 类包含 2 个变量 - 大小(H:100px、W:100p
据我所知,我已经正确嵌入了 @font-face 字体(我已经检查并仔细检查),但我在 IE8 上出现了以前从未经历过的奇怪行为。 在 IE8 上,字体会一闪而过,呈现完美,然后又变得非常 block
我是一名优秀的程序员,十分优秀!