Using AudioRecord.read and always getting buffer with maximum amplitudes

I'm trying to record audio and detect silence to stop recording and write file. Below is the code snippet already available here: Android audio capture silence detection

public class RecordAudio extends AsyncTask<Void, Double, Void> {

    @Override
    protected Void doInBackground(Void... arg0) {
        Log.w(TAG, "doInBackground");
        try {

            String filename = getTempFilename();

            try {
                os = new FileOutputStream(filename);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }


            bufferSize = AudioRecord.getMinBufferSize(frequency,
                    channelConfiguration, audioEncoding);

            AudioRecord audioRecord = new AudioRecord( MediaRecorder.AudioSource.MIC, frequency,
                    channelConfiguration, audioEncoding, bufferSize);

            short[] buffer = new short[bufferSize];

            audioRecord.startRecording();

            while (started) {
                int bufferReadResult = audioRecord.read(buffer, 0,bufferSize);

                if(AudioRecord.ERROR_INVALID_OPERATION != bufferReadResult){
                    //check signal
                    //put a threshold
                    int foundPeak = searchThreshold(buffer,threshold);
                    if (foundPeak >- 1) { //found signal
                        //record signal

                        byte[] byteBuffer =ShortToByte(buffer,bufferReadResult);
                        try {
                            os.write(byteBuffer);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    } else {//count the time
                        //don't save signal

                        Log.d(TAG, "Silence...");

                    }

                } else {
                    Toast.makeText(getBaseContext(), "Error!!!!", Toast.LENGTH_SHORT).show();
                }
            }

            audioRecord.stop();


            //close file
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            copyWaveFile(getTempFilename(),getFilename());
            deleteTempFile();


        } catch (Throwable t) {
            t.printStackTrace();
            Log.e("AudioRecord", "Recording Failed");

        }
        return null;

    }

    byte [] ShortToByte(short [] input, int elements) {
        int short_index, byte_index;
        int iterations = elements; //input.length;
        byte [] buffer = new byte[iterations * 2];

        short_index = byte_index = 0;

        for(/*NOP*/; short_index != iterations; /*NOP*/)
        {
            buffer[byte_index]     = (byte) (input[short_index] & 0x00FF);
            buffer[byte_index + 1] = (byte) ((input[short_index] & 0xFF00) >> 8);

            ++short_index; byte_index += 2;
        }

        return buffer;
    }


    int searchThreshold(short[]arr,short thr){
        int peakIndex;
        int arrLen=arr.length;
        for (peakIndex=0;peakIndex<arrLen;peakIndex++){
            if ((arr[peakIndex]>=thr) || (arr[peakIndex]<=-thr)){

                Log.d(TAG, String.valueOf(arr[peakIndex]) + " - " + String.valueOf(peakIndex));
                return peakIndex;
            }
        }
        return -1; //not found
    }

The problem is I'm not able to detect silence in the signal. Every time I read the buffer I get values greater than 32000 or less than -32000 (which I interpreted as maximum possible amplitudes for the signal, since the buffer is made up of short integer values), even when there is silence, so the threshold that determines what is "noise" and what is silence is always reached, and the searchThreshold function never returns -1.

Did anyone experience the same? I'm using a Samsung S5 device for tests.

Thanks in advance

Upvotes: 0

Views: 611

Answers (1)

In fact, values near 32000 or -32000 in buffer represents silence, and the values tends to zero when signal is detected. So I inverted the conditions inside searchThreshold function as below and I achieved what I was looking for.

    int searchThreshold(short[]arr,short thr_upper, short thr_lower){
        int peakIndex;
        int arrLen=arr.length;
        for (peakIndex=0;peakIndex<arrLen;peakIndex++){

            if ((arr[peakIndex] <= thr_upper) && (arr[peakIndex] >= thr_lower )){

                return peakIndex;
            }
        }
        return -1; //not found
    }

Upvotes: 1

Related Questions