使用AudioRecord.read并始终获得具有最大幅度的缓冲区

时间:2018-05-17 17:22:36

标签: android

我试图录制音频并检测静音以停止录制和写入文件。以下是此处已提供的代码段: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
    }

问题是我无法检测信号中的静音。每当我读取缓冲区时,我得到的值大于32000或小于-32000(我将其解释为信号的最大可能幅度,因为缓冲区由短整数值组成),即使存在静音,因此阈值这决定了什么是&#34;噪音&#34;什么是总是达到沉默,而searchThreshold函数永远不会返回-1。

有没有人经历过同样的事?我正在使用Samsung S5设备进行测试。

提前致谢

1 个答案:

答案 0 :(得分:0)

实际上,缓冲区中接近32000或-32000的值表示静音,当检测到信号时,值趋于零。所以我把searchThreshold函数中的条件反转如下,我实现了我想要的。

    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
    }