Search code examples
c#androidxamarinfftaudio-recording

Android AudioRecord - Best way to get the FFT without libraries


I'm looking for the fastest way to get the current mic input as a 512 bin byte/short/float array. Since I'm developing in Xamarin I can't rely on Android libraries, so I have to transform the raw data myself. This is the current state:

minBufferSize = AudioRecord.GetMinBufferSize(8000,ChannelIn.Mono,Encoding.Pcm16bit);
audioRecord = new AudioRecord(AudioSource.Mic,8000,ChannelIn.Mono,Encoding.Pcm16bit, minBufferSize); 
audioRecord.StartRecording();

And in mainloop that runs at 20 Hz it reads the data like this

short[] audiodata = new short[512];
byte[] byteAudioData = new byte[1024];
audioRecord.Read(byteAudioData, 0, 1024);

The step that's missing is getting the raw byte data into the actual fft.

Edit1: After implementing the calculateFFT(byte[] signal) method of the first comment this is how the processed audio signal looks so far, seems unusable: Audio Data

Edit2: Found a way to do it via a c# lib, check answer.


Solution

  • Found it, the easiest way to get this done is via the Accord library

    The method could look like this:

    public double[] FFT(double[] data){
        double[] fft = new double[data.Length]; // this is where we will store the output (fft)
        Complex[] fftComplex = new Complex[data.Length]; // the FFT function requires complex format
        for (int i = 0; i < data.Length; i++)
            fftComplex[i] = new Complex(data[i], 0.0); // make it complex format
        Accord.Math.FourierTransform.FFT(fftComplex, Accord.Math.FourierTransform.Direction.Forward);
        for (int i = 0; i < data.Length; i++)
            fft[i] = fftComplex[i].Magnitude;
        return fft;
    }