如何使用 java 从 pcm 字节数组 .wav 文件中获取频率和音高?

Posted

技术标签:

【中文标题】如何使用 java 从 pcm 字节数组 .wav 文件中获取频率和音高?【英文标题】:How to get frequency and pitch from a pcm byte array .wav file using java? 【发布时间】:2017-04-02 07:43:46 【问题描述】:

我目前是新手,所以请保持简单以便我理解。

我有一个项目,我必须将声音分类为好、坏或中性。我的计划是获取样本数据集的所有频率和音高,并使用 SVM 对其进行训练。

为了得到所有 .wav 文件的音高和频率。我完成了从音频文件中查找 PCM 数据的代码。现在我应该如何将这些数据应用于快速傅里叶变换算法以获取频率?在将字节数组应用于 FFT 算法之前,是否还有其他需要考虑的事项?

这是我将 wav 文件转换为 pcm 字节数组的代码:

int totalFramesRead = 0;
File fileIn = new File(inputFile);
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;
        
        return audioBytes[];
    

【问题讨论】:

我认为您需要考虑代表单个音频样本的字节数。如今,大多数音频文件将是每个样本 16 位。 *** 上已经有很多类似的问题,答案很好——试试searching for jtransforms+audio。 您的 FFT 库可能需要浮点数——查看它的输入要求并相应地转换波形数据。 【参考方案1】:

在 FFT 之后或之外,还有很多需要考虑的因素,因为 FFT 频率峰值不一定是音调频率。查找音高检测/估计算法,而不是仅使用 FFT 幅度。

【讨论】:

以上是关于如何使用 java 从 pcm 字节数组 .wav 文件中获取频率和音高?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Android SDK 从原始 PCM 数据创建 WAV 文件

如何使用 fread 和 fwrite 从文件中读取 pcm 样本?

音频处理WAV 文件格式分析 ( 逐个字节解析文件头 | 相关字段的计算公式 )

如何使用 node.js 将 .pcm 文件转换为 wav 文件?

Java - 将 16 位有符号 pcm 音频数据数组转换为双精度数组

从 PCM 转换为 WAV。是不是可以?