我目前难倒。我一直在环顾四周,试验音频比较。我发现了相当多的材料,并且有大量的参考文献和方法来实现它。
截至目前,我已经使用 Audacity 并导出了一个名为“long.wav”的3分钟wav文件,然后将其前30秒分成一个名为“short.wav”的文件。我想通过线路的某处我可以通过java在每个视觉上记录(log.txt)数据,并且应该能够在值中看到至少一些视觉上的相似性....这里是一些代码
主要方法:
int totalFramesRead = 0;
File fileIn = new File(filePath);
BufferedWriter writer = new BufferedWriter(new FileWriter(outPath));
writer.flush();
writer.write("");
try {
AudioInputStream audioInputStream =
AudioSystem.getAudioInputStream(fileIn);
int bytesPerFrame =
audioInputStream.getFormat().getFrameSize();
if (bytesPerFrame == AudioSystem.NOT_SPECIFIED) {
// some audio formats may have unspecified frame size
// in that case we may read any amount of bytes
bytesPerFrame = 1;
}
// Set an arbitrary buffer size of 1024 frames.
int numBytes = 1024 * bytesPerFrame;
byte[] audioBytes = new byte[numBytes];
try {
int numBytesRead = 0;
int numFramesRead = 0;
// Try to read numBytes bytes from the file.
while ((numBytesRead =
audioInputStream.read(audioBytes)) != -1) {
// Calculate the number of frames actually read.
numFramesRead = numBytesRead / bytesPerFrame;
totalFramesRead += numFramesRead;
// Here, do something useful with the audio data that's
// now in the audioBytes array...
if(totalFramesRead <= 4096 * 100)
{
Complex[][] results = PerformFFT(audioBytes);
int[][] lines = GetKeyPoints(results);
DumpToFile(lines, writer);
}
}
} catch (Exception ex) {
// Handle the error...
}
audioInputStream.close();
} catch (Exception e) {
// Handle the error...
}
writer.close();
然后 PerformFFT :
public static Complex[][] PerformFFT(byte[] data) throws IOException
{
final int totalSize = data.length;
int amountPossible = totalSize/Harvester.CHUNK_SIZE;
//When turning into frequency domain we'll need complex numbers:
Complex[][] results = new Complex[amountPossible][];
//For all the chunks:
for(int times = 0;times < amountPossible; times++) {
Complex[] complex = new Complex[Harvester.CHUNK_SIZE];
for(int i = 0;i < Harvester.CHUNK_SIZE;i++) {
//Put the time domain data into a complex number with imaginary part as 0:
complex[i] = new Complex(data[(times*Harvester.CHUNK_SIZE)+i], 0);
}
//Perform FFT analysis on the chunk:
results[times] = FFT.fft(complex);
}
return results;
}
此时我已尝试在任何地方进行记录:变换前的audioBytes,复杂值和FFT结果。
问题:无论我记录什么值,每个wav文件的log.txt都完全不同。我不明白。鉴于我从large.wav获取了small.wav(并且它们具有所有相同的属性),原始wav byte [] data ...或Complex [] [] fft数据之间应该存在非常大的相似性。 ......或者到目前为止的东西......
如果在这些计算的任何时刻数据都不接近相似,我怎么可能尝试比较这些文件。
我知道我在音频分析方面缺少相当多的知识,这就是我来到董事会寻求帮助的原因!感谢您提供的任何信息,帮助或修复!!
答案 0 :(得分:2)
你看过MARF了吗?它是一个用于音频识别的文档齐全的Java库。
它用于识别扬声器(用于转录或保护软件),但应该能够使用相同的功能对音频样本进行分类。我不熟悉它,但看起来你想要使用FeatureExtraction类从每个音频样本中提取一系列特征,然后创建一个唯一的id。
答案 1 :(得分:1)
对于16位音频,3e-05并非与零完全不同。因此,零文件与零文件几乎相同(可能由于一些微小的舍入错误而缺少相等性。)
增加: 为了便于比较,使用一些Java绘图库读入并绘制两个波形中的每一个的一部分,当它们超过大部分(接近)零的部分时。
答案 2 :(得分:0)
我认为对于调试你最好尝试用matlab绘制出来。因为matlab在处理这个问题时要强大得多。
你使用&#34; wavread&#34;到文件,&#34; stft&#34;获得短时傅立叶变换,这是一个复数矩阵。然后简单地用abs(Matrix)来得到每个复数的大小。用imshow显示图像(abs(Matrix),[])。
我不知道你如何比较整个文件和30s剪辑(通过查看stft图像?)
答案 3 :(得分:0)
我不知道你是如何比较两个音频文件的,但是,看到一些提供音乐识别的服务(如TrackId或MotoID),这些服务会收集你听到的一小部分音乐样本(10-20秒) ),然后在他们的服务器中处理它们,我推测他们有长或更少的样本,并且他们有一个数据库(或在运行中计算)模式(在你的情况下是傅立叶变换),在你的情况下,您可能需要以比样本数据更大或更小的块来中断长音频文件,在第一种情况下,您可能会发现一个特定的块,它类似于样本数据中的模式,在第二种情况下,您的较小块可能会重新排序部分样本数据,您可以计算样本数据属于相应音频文件的概率。
答案 4 :(得分:0)
我认为你在看Acoustic Fingerprinting 这很难,还有库可以做到。 如果您想自己实现它,this是关于shazam算法的白皮书。