Wav阅读器和java处理器,并在基本的Wav问题中进行声音识别



我想做一个音乐识别系统。我担心我可能不会像我应该的那样阅读wav样本,而且,我可能会应用错误的窗口大小来制作fft和其他。

如果你能帮我的话,那就太好了。

首先,我有一些关于Wavs音频处理的问题。

1) Wav有标题,对吗?那么下面的代码能正确读取wav文件吗?

private static byte[] getAudioBytes(String path_to_audio) throws IOException, UnsupportedAudioFileException{
    File audio_file = new File(path_to_audio);
    //
    AudioInputStream audio_input_stream = AudioSystem
            .getAudioInputStream(audio_file);
    byte audio[] = new byte[(int) audio_file.length()];
    audio_input_stream.read(audio);
    return audio;
}

1.1)如果有一个标题,我怎么读它,它们的字段是什么?(我对我在网上看到的不同标题感到困惑)

2)另一个问题,我猜,wav文件的记录有一个默认的帧大小。我说的对吗?

2.1)我必须将每帧发送到FFT。如果我使用不同的帧大小发送样本到FFT,这将检索错误的结果,对吗?

2.2)如果不同的帧大小检索错误的结果,我如何使用更大的帧,以获得更好的频率精度?(例如,假设原始文件有1024个样本帧,而我想使用4096个样本帧大小)

3)在我的示例wav文件和原始文件中使用相同的位深度会很好,对吧?

4)如果它是16位深度,我必须在java中使用short,对吗?

在我的代码中,我读取帧中有4096个样本,而不考虑记录帧的大小。我看到了一些歌曲识别的例子,但他们没有解释太多细节,只是说他们使用4096作为帧大小。我试着搜索这类信息,发现一点信息,所以我在这里寻求帮助。

提前感谢

Wav有一个标题。对吧?

是的。关于原始位级wav文件结构的一个很好的参考可以在WAVE格式规范中找到。

那么下面的代码能正确读取wav文件吗?

它将正确读取支持的wav文件的wav头(准备处理UnsupportedAudioFileException为不太常见的扩展),并提取原始编码形式的音频数据(即你仍然要解码原始数据自己获得有意义的样本)。但是请注意,由于audio_file.length()包含头大小,因此此代码分配的缓冲区大于所需的缓冲区大小,而数据缓冲区读取没有(即数据缓冲区仅填充编码样本)。

如果有标题,我如何读取它,它们的字段是什么?(我对我在网上看到的不同标题感到困惑)

在WAVE格式规范中指示的报头字段已经被AudioInputStream读取,然后分配AudioFormat的相关字段(例如encoding, channels等)。请注意,这不是一个精确的一对一映射,因为AudioFormat是与其他音频文件类型共享的通用表示,但它通常是您真正需要关心的。这个AudioFormat可以通过audio_input_stream.getFormat()访问。如果你想专门查看文件头的位结构(或者只是想折磨自己),你也可以直接使用FileInputStream

录制的wav文件有一个默认的帧大小。我说的对吗?

不完全是。AudioInputStream在wav文件的情况下使用的"帧"对应于单个时间瞬间,其中包括与通道数量一样多的样本(例如,一个帧将是单声道文件的单个样本和立体声文件的2个样本)。这样一个帧的大小总是隐含在wav报头的各个字段中(如通道数,每个采样的字节数等),并适用于整个流。此外,数据被打包为通道交错样本的连续块,因此没有额外的分离成更大的样本块。

我必须将每一帧发送到FFT。如果我使用不同的帧大小发送样本到FFT,这将检索错误的结果,对吗?

如果你发送一个多通道(例如立体声)wav文件的所有通道到一个单一的FFT,那么你很可能得到的结果不符合你的期望。然而,一旦你分离了通道,你就可以自由地执行FFT与你自己选择的任何长度(仍然得到合理的结果)。

如果不同的帧大小检索错误的结果,我如何使用更大的帧,以获得更好的频率精度?(例如,假设原始文件有1024个样本帧,而我想使用4096个样本帧大小)

由于一旦您对通道进行去交错处理,每个通道实际上只有一个数据块,因此您不能直接使用与可用数据大小相同大小的FFT大小的唯一情况是,如果原始文件的样本少于您希望使用的FFT长度。但是,您仍然可以通过零填充文件样本来执行更大的FFT。

在我的示例wav文件和原始文件中使用相同的位深度会很好,对吧?

这取决于你的具体应用要求。输入文件位深度通常是给定的,您对此几乎无能为力。您通常会控制输出文件位深度。请记住,截断样本以使用较小的位深度是一种有损操作。因此,在整个处理过程中保留尽可能多的位,在最后进行截断通常是一个好主意。例如,如果输出是较长处理链中的中间结果,则可以选择使用比输入更大的位深度来输出。

如果它是16位深度,我必须在java中使用short。对吧?

正确的。

最新更新