0

我是一名大学生。我正在为我最后一年的项目开发一个音乐识别系统。根据“Robust Audio Fingerprint Extraction Algorithm Based on 2-D Chroma”研究论文,我的系统中应该需要包含以下功能。

捕获音频信号---->成帧窗口(汉宁窗口)-----> FFT ----->

高通滤波器 -----> 等.....

我能够为音频捕获功能编写代码,并且我也将 FFT API 应用于代码。但是我对如何将汉宁窗口函数应用于我的代码感到困惑。请问有人可以帮我做这个功能吗?告诉我需要在哪里添加此函数以及如何将其添加到代码中。

这是我的音频捕获代码和应用 FFT 代码:

  private class RecordAudio extends AsyncTask<Void, double[], Void> {
    @Override
    protected Void doInBackground(Void... params) {
        started = true;
        try {
            DataOutputStream dos = new DataOutputStream(
                    new BufferedOutputStream(new FileOutputStream(
                            recordingFile)));
            int bufferSize = AudioRecord.getMinBufferSize(frequency,
                    channelConfiguration, audioEncoding);
            audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
                    frequency, channelConfiguration, audioEncoding,
                    bufferSize);

            short[] buffer = new short[blockSize];
            double[] toTransform = new double[blockSize];
            long t = System.currentTimeMillis();
            long end = t + 15000;
            audioRecord.startRecording();
            double[] w = new double[blockSize];

            while (started && System.currentTimeMillis() < end) {
                int bufferReadResult = audioRecord.read(buffer, 0,
                        blockSize);
                for (int i = 0; i < blockSize && i < bufferReadResult; i++) {
                    toTransform[i] = (double) buffer[i] / 32768.0;
                    dos.writeShort(buffer[i]);
                }
                // new part
                toTransform = hanning (toTransform);
                transformer.ft(toTransform);
                publishProgress(toTransform);
            }
            audioRecord.stop();
            dos.close();
        } catch (Throwable t) {
            Log.e("AudioRecord", "Recording Failed");
        }
        return null;
    }

这些链接提供汉宁窗算法和代码片段:

WindowFunction.java

汉宁 - MATLAB

我用来将 hanning 函数应用于我的应用程序的以下代码对我有用....

public double[] hanningWindow(double[] recordedData) {

    // iterate until the last line of the data buffer
    for (int n = 1; n < recordedData.length; n++) {
        // reduce unnecessarily performed frequency part of each and every frequency
        recordedData[n] *= 0.5 * (1 - Math.cos((2 * Math.PI * n)
                / (recordedData.length - 1)));
    }
    // return modified buffer to the FFT function
    return recordedData;
}
4

1 回答 1

1

首先,我认为您应该考虑固定 FFT 长度。如果我正确理解您的代码,您现在使用某种最小缓冲区大小也作为 FFT 长度。FFT 长度对计算的性能和分辨率有很大影响。

您到 WindowFunction.java 的链接可以为您生成一个数组,该数组的长度应与您的 FFT 长度(我认为在您的情况下为 blockSize)相同。然后,您应该将缓冲区的每个样本与从数组中具有相同 id 的 WindowFunction 返回的值相乘。

这应该在 FFT 之前完成。

于 2015-01-29T21:35:50.187 回答