5

我现在很难过。我一直在环顾四周并尝试音频比较。我找到了相当多的材料,以及对不同库和方法的大量参考。

到目前为止,我已经采用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();

然后执行FFT

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;
}

在这一点上,我尝试到处记录:转换前的音频字节、复杂值和 FFT 结果。

问题:无论我记录什么值,每个 wav 文件的 log.txt 都是完全不同的。我不明白。鉴于我从 large.wav 中获取了 small.wav(并且它们具有所有相同的属性),原始 wav byte[] 数据...或 Complex[][] fft 数据之间应该有非常大的相似性。 ..或到目前为止的东西..

如果在这些计算的任何时候数据甚至不接近相似, 我怎么可能尝试比较这些文件。

我知道我在音频分析方面缺少相当多的知识,这就是我向董事会寻求帮助的原因!感谢您提供的任何信息、帮助或修复!

4

5 回答 5

2

你看过MARF吗?它是一个用于音频识别的有据可查的 Java 库。

它用于识别说话者(用于转录或保护软件),但应该能够使用相同的功能对音频样本进行分类。我不熟悉它,但看起来你想使用FeatureExtraction类从每个音频样本中提取一组特征,然后创建一个唯一的 id。

于 2012-08-08T16:43:12.367 回答
1

对于 16 位音频,3e-05 与零并没有什么不同。因此,零文件与零文件几乎相同(可能会因一些微小的舍入错误而丢失相等性。)

添加:为了进行比较,请使用一些 Java 绘图库读取并绘制两个波形中每一个的一部分,当它们通过大部分(接近)零的部分时。

于 2012-07-23T03:13:49.543 回答
0

我不知道你是如何比较两个音频文件的,但是,看到一些提供音乐识别的服务(如 TrackId 或 MotoID),这些服务会从你听到的音乐中抽取一小部分样本(10-20 秒),然后在他们的服务器中处理它们,我推测他们有很长或更少的样本,并且他们有一个数据库(或动态计算)该样本的模式(在你的情况下是傅里叶变换),在你的情况下,你可能需要将您的长音频文件分成比您的样本数据更小或更小的块,在第一种情况下,您可能会发现一个与样本数据中的模式更相似的特定块,在第二种情况下,您的较小块可能会重新编码您的一部分样本数据,您可以计算样本数据属于相应音频文件的概率。

于 2012-08-08T17:26:46.860 回答
0

我认为为了调试你最好尝试使用 matlab 来绘制。由于 matlab 在处理这个问题上要强大得多。

您对文件使用“wavread”,并使用“stft”来获得短时间傅立叶变换,这是一个复数矩阵。然后简单地用 abs(Matrix) 来获得每个复数的大小。使用 imshow(abs(Matrix),[]) 显示图像。

我不知道您如何比较整个文件和 30s 剪辑(通过查看 stft 图像?)

于 2012-08-08T05:29:13.493 回答
0

我认为您正在研究Acoustic Fingerprinting 这很难,并且有图书馆可以做到这一点。如果你想自己实现它,是一份关于 shazam 算法的白皮书。

于 2012-08-08T17:56:59.570 回答