Search code examples
javaandroidandroid-audiorecord

How do I record audio and locate a certain frequency in Android (java)


I know that there are many questions about this, but none of them give a clear answer. The following is the code I'm using to try and make this work.

package com.nonexistent.rs.sometestthing;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {


    public static int calculate(int sampleRate, short [] audioData){

        int numSamples = audioData.length;
        int numCrossing = 0;
        for (int p = 0; p < numSamples-1; p++)
        {
            if ((audioData[p] > 0 && audioData[p + 1] <= 0) ||
                    (audioData[p] < 0 && audioData[p + 1] >= 0))
            {
                numCrossing++;
            }
        }

        float numSecondsRecorded = (float)numSamples/(float)sampleRate;
        float numCycles = numCrossing/2;
        float frequency = numCycles/numSecondsRecorded;

        return (int)frequency;
    }
    public void getpitch(View v){
        int channel_config = AudioFormat.CHANNEL_IN_MONO;
        int format = AudioFormat.ENCODING_PCM_16BIT;
        int sampleSize = 8000;
        int bufferSize = AudioRecord.getMinBufferSize(sampleSize, channel_config, format);
        AudioRecord audioInput = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleSize, channel_config, format, bufferSize);
        TextView txtview = (TextView)findViewById(R.id.text);





        short[] audioBuffer = new short[bufferSize];
        audioInput.startRecording();
        audioInput.read(audioBuffer, 0, bufferSize);
        //recorder.startRecording();
        //recorder.read(audioBuffer, 0, bufferSize);
        txtview.setText(""+calculate(8000,audioBuffer));
    }

}

So that's all my code, and it mostly works. The problem is that the textview displays 0 after I click a button. (You can see that the function getpitch() responds to a click on a button.) Also, the calculate() function is from another similar question, though it doesn't work.

I'm fairly sure that it does start recording, and does write it to the array. Problem is, I don't know how to analyze that array to get a frequency, or rather, find a certain frequency.

Anyone know how? Please try not to give extremely complex answers, as I am very new to this.


Solution

  • I ended up fixing this by increasing the buffer size to 176000 bytes and multiplying that number by the number of seconds I wanted to record. I also added a stop() and a release() call. The frequency measuring part is wildly inaccurate (a little less than 1/2 the frequency I tested with) , but it probably could be calibrated for.