【问题标题】:Crashing Application while calculating the intensity of voice计算语音强度时应用程序崩溃
【发布时间】:2012-06-27 06:39:37
【问题描述】:

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

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

我使用的代码如下。

//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.

【问题讨论】:

    标签: android voice-recognition audiorecord


    【解决方案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();
    

    【讨论】:

    • 我正在尝试这个。请让我知道 findAudioRecord() 实际上在做什么?
    • 这个函数初始化 AudioRecord!让我知道它是否工作。
    • 当我使用一个对象时它工作正常。我的应用程序中有两个 AudioRecord 对象。我可以同时开始录制这两个对象吗?
    • 不,不可能!一次您只能使用一个。如果它解决了您的问题,请关闭问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多