1

在我的应用程序中,我正在计算记录用户命令时的声音强度。

Onclick 图标我开始录音并在用户再次按下它时停止它。在两者之间,我在图标上显示语音命令的强度。

我正在使用的代码如下所示。

//Calling this method when the user clicks on the button
public void startRec() {
    mStatus = true;
    System.out.println("Starting");
    timer = new Timer(); 
    timer.scheduleAtFixedRate(new TimerTask() 
        { 
            public void run() 
            { 
                detectVoice();  // display the data
            } 
        }, delay, period); 
    //audioRecorder.startRecording();
}
//Calling this method when the user clicks on the button again.
public void stopRec() {
    mStatus = false;
    System.out.println("Stoping");
    if (audioRecorder != null)
    {
        if (isRecording())
        {
            cancelRecording();
        }
        try {
            audioRecorder.stop();
            audioRecorder.release();
            timer.cancel();
            timer.purge();
        } catch(IllegalStateException e) {
            e.printStackTrace();
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
    }
}

//This is the method for calculating the voice intensity
private boolean detectVoice() {

    // Get the minimum buffer size required for the successful creation of an AudioRecord object. 
    int bufferSizeInBytes = 512;/*AudioRecord.getMinBufferSize( RECORDER_SAMPLERATE,
            RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING);*/ 

    // Initialize Audio Recorder.
    audioRecorder = new AudioRecord( MediaRecorder.AudioSource.DEFAULT,
            RECORDER_SAMPLERATE,RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING,8192);

    short[] audioBuffer     =  new short[bufferSizeInBytes];
    //short[] buf = new short[bufferSizeInBytes];
    int numberOfReadBytes   = 0; 
    boolean recording       = false;
    float tempFloatBuffer[] = new float[3];
    int tempIndex           = 0;
    continueRecording = true;

    // Start Recording.
    audioRecorder.startRecording();

    // While data come from microphone. 
    while(isRecording()) {
        float totalAbsValue = 0.0f;
        short sample        = 0; 
        numberOfReadBytes = audioRecorder.read( audioBuffer, 0, audioBuffer.length );

        // Analyze Sound.
        for( int i=0; i<numberOfReadBytes; i+=2 ) 
        {
            sample = (short)( (audioBuffer[i]) | audioBuffer[i + 1]);
            if(sample!=0) {
                totalAbsValue += Math.abs( sample ) / (numberOfReadBytes);
            }
        }

        // Analyze temp buffer.
        tempFloatBuffer[tempIndex%3] = totalAbsValue;
        float temp                   = 0.0f;
        for( int i=0; i<3; ++i )
            temp += tempFloatBuffer[i];
        System.out.println("Temp :"+temp);          
        if( (temp >= 0 && temp <= 350) && recording == true ) {
            Log.d("TAG", "Voice Detected.");
            voiceDetected = true;
            //recording = false;
            break;
        }
    } 
    stopRecording();
    return voiceDetected;
}

public void stopRecording() {
    Log.d(TAG, "done");
    if (audioRecorder != null)
    {
        if (isRecording())
        {
            Log.d(TAG, "Recording is true");
            cancelRecording();
        }
        try {
            audioRecorder.stop();
            audioRecorder.release();

        } catch(IllegalStateException e) {
            e.printStackTrace();
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
    }
}

public boolean isRecording() {
    return continueRecording;
}

public void cancelRecording() {
    Log.d("TAG", "CancelRecording");
    continueRecording = false;
}

但是,如果我再次启动语音检测,那么我会遇到异常并且应用程序崩溃了。下面给出了例外情况

01-01 00:56:48.710: ERROR/AudioRecord(1519): Could not get audio input for record source 1
01-01 00:56:48.710: ERROR/AudioRecord-JNI(1519): Error creating AudioRecord instance: initialization check failed.
01-01 00:56:48.710: ERROR/AudioRecord-Java(1519): [ android.media.AudioRecord ] Error code -20 when initializing native AudioRecord object.
01-01 00:56:48.710: WARN/dalvikvm(1519): threadid=15: thread exiting with uncaught exception (group=0x40b3e1f8)
01-01 00:56:48.710: ERROR/CameraBaseActivity(1519): uncaughtException.
01-01 00:56:48.843: ERROR/CameraBaseActivity(1519):     at android.media.AudioRecord.startRecording(AudioRecord.java:516)
01-01 00:56:48.843: ERROR/CameraBaseActivity(1519):     at com.android.VoiceIntensity.detectVoice(VoiceIntensity.java:142)
01-01 00:56:48.843: ERROR/CameraBaseActivity(1519):     at com.android.VoiceIntensity.access$000(VoiceIntensity.java:12)
01-01 00:56:48.843: ERROR/CameraBaseActivity(1519):     at com.android.VoiceIntensity$1.run(VoiceIntensity.java:96)
01-01 00:56:48.843: ERROR/CameraBaseActivity(1519):     at java.util.Timer$TimerImpl.run(Timer.java:284)
01-01 00:56:48.843: ERROR/CameraBaseActivity(1519): java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.
01-01 00:56:48.843: ERROR/CameraBaseActivity(1519): uncaughtException.
01-01 00:56:48.843: ERROR/CameraBaseActivity(1519): uncaughtException : other thread.
4

1 回答 1

1

也许您AudioRecord不喜欢您提供的初始化设置。

所以替换

audioRecorder = new AudioRecord( MediaRecorder.AudioSource.DEFAULT,
            RECORDER_SAMPLERATE,RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING,8192);

经过

private static int[] mSampleRates = new int[] { 8000, 11025, 22050, 44100 };
public AudioRecord findAudioRecord() {
    for (int rate : mSampleRates) {
        for (short audioFormat : new short[] { AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT }) {
            for (short channelConfig : new short[] { AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO }) {
                try {
                    Log.d(C.TAG, "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: "
                            + channelConfig);
                    int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat);

                    if (bufferSize != AudioRecord.ERROR_BAD_VALUE) {
                        // check if we can instantiate and have a success
                        AudioRecord recorder = new AudioRecord(AudioSource.DEFAULT, rate, channelConfig, audioFormat, bufferSize);

                        if (recorder.getState() == AudioRecord.STATE_INITIALIZED)
                            return recorder;
                    }
                } catch (Exception e) {
                    Log.e(C.TAG, rate + "Exception, keep trying.",e);
                }
            }
        }
    }
    return null;
}

AudioRecord recorder = findAudioRecord();
于 2012-06-27T06:47:53.133 回答