在我的应用程序中,我正在计算录制用户命令时的声音强度。
点击图标我正在开始录音并在用户再次按下时停止录音。在我之间我正在显示图标上的语音命令的强度。
我正在使用的守则如下。
//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.
答案 0 :(得分: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();