gpt4 book ai didi

java - 从 wav 文件中提取频率

转载 作者:行者123 更新时间:2023-11-30 06:22:01 25 4
gpt4 key购买 nike

我正在尝试从 wav 文件中提取频率,但看起来出了问题。

首先,我从文件中提取字节,然后对其应用 FFT,最后找到大小。

似乎我做错了什么,因为输出不接近实际值。下面是代码。

try{

File log = new File("files/log.txt");
if(!log.exists()) log.createNewFile();
PrintStream ps = new PrintStream(log);

File f = new File("files/5000.wav");
FileInputStream fis = new FileInputStream(f);
int length = (int)f.length();
length = (int)nearestPow2(length);
double[] ibr = new double[length]; //== real
double[] ibi = new double[length]; //== imaginary
int i = 0;
int l=0;
//fis.skip(44);
byte[] b = new byte[1024];
while((l=fis.read(b))!=-1){
try{

for(int j=0; j<1024; j++){
ibr[i] = b[j];
ibi[i] = 0;
i++;
}
}catch(Exception e){}
}

double[] ftb = FFTBase.fft(ibr, ibi, true);
double[] mag = new double[ftb.length/2];
double mxMag = 0;
long avgMg = 0;
int reqIndex = 512; //== no need to go till end
for(i=1;i<ibi.length; i++){
ibr[i] = ftb[i*2];
ibi[i] = ftb[i*2+1];
mag[i] = Math.sqrt(ibr[i]*ibr[i]+ibi[i]*ibi[i]);
avgMg += mag[i];
if(mag[i]>mxMag) mxMag = mag[i];
ps.println(mag[i]);
}
avgMg = avgMg/ibi.length;
ps.println("MAx===="+mxMag);
ps.println("Average===="+avgMg);

}catch(Exception e){e.printStackTrace();}

当我为 5KHZ 文件运行此代码时,这些是我得到的值。 https://pastebin.com/R3V0QU4G

这不是完整的输出,但有些相似。

谢谢

最佳答案

不幸的是,仅通过快速傅里叶变换并搜索“最响亮”的频率或类似的东西来提取频率或“音调”是不可能的。至少如果您尝试从音乐信号中提取它的话。

还有不同种类的音调。大部分乐器(即吉他或我们的声音)都会产生谐波声音,这些声音由遵循特定模式的多个频率组成。

但也有一些音调只有一个峰值/频率(即口哨声)

此外,您通常还必须处理根本没有音调的信号中的噪声。这可能是背景噪音,也可能是由仪器本身产生的。例如,吉他在起音阶段有非常大的噪音部分。

您可以使用不同的方法,即不同的算法来查找这些信号的音高,具体取决于其类型。

如果我们停留在频域 (fft) 中并假设我们想要分析谐波,则可以使用双向失配算法,该算法使用统计模式匹配来查找谐波并猜测谐波基频,即我们耳朵感知为音调的频率。

可以在此处找到示例实现:https://github.com/ausmauricio/audio_dsp该存储库是 coursera 上音频信号处理完整类(class)的一部分,也许这会有所帮助。

关于java - 从 wav 文件中提取频率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47928905/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com