Search code examples
javasignal-processingfftaudio-fingerprintingwindowing

How do I apply the hanning function to my audio sample?


I am a university student. I am developing a music identification system for my final year project. According to the "Robust Audio Fingerprint Extraction Algorithm Based on 2-D Chroma" research paper, the following functions should need to be included in my system.

Capture Audio Signal ----> Framing Window (hanning window) -----> FFT ----->

High Pass Filter -----> etc.....

I was able to code for Audio Capture function and I was applied the FFT API as well to the code. But I am confused about how to apply the hanning window function to my the my code. Please can someone help me to do this function? Tell me where do I need to add this function and how do I need to add it to the code.

Here is the my Audio capturing code and applying FFT code:

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

These links are providing hanning window algorithm and code snippets:

WindowFunction.java

Hanning - MATLAB

The following code I have used to apply hanning function to the my application and it works for me....

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

Solution

  • At first, I think you should consider having your FFT length fixed. If I understand your code correctly, you are now using some kind of minimum buffer size also as the FFT length. FFT length has huge effect on the performance and resolution of your calculation.

    Your link to WindowFunction.java can generate you an array, that should be the same length as your FFT length (blockSize in your case, I think). You should then multiply each sample of your buffer with the value returned from the WindowFunction that has the same id in the array.

    This should be done before the FFT.