package com.mogujie.tt.audio.biz; import com.mogujie.tt.config.HandlerConstant; import com.mogujie.tt.config.SysConstant; import com.mogujie.tt.log.Logger; import com.mogujie.tt.support.audio.SpeexEncoder; import com.mogujie.tt.task.TaskCallback; import com.mogujie.tt.ui.activity.MessageActivity; import android.media.AudioFormat; import android.media.AudioRecord; import android.media.MediaRecorder; import android.os.Message; public class AudioRecordHandler implements Runnable { private Logger log = Logger.getLogger(AudioRecordHandler.class); private volatile boolean isRecording; private final Object mutex = new Object(); private static final int frequency = 8000; private static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; public static int packagesize = 160;// 320 private String fileName = null; private static float recordTime = 0; private long startTime = 0; private long endTime = 0; private long maxVolumeStart = 0; private long maxVolumeEnd = 0; private static AudioRecord recordInstance = null; private TaskCallback mCallback = null; private Logger logger = Logger.getLogger(AudioPlayerHandler.class); public AudioRecordHandler(String fileName, TaskCallback callback) { super(); this.fileName = fileName; this.mCallback = callback; } public void run() { try { logger.d("chat#audio#in audio thread"); SpeexEncoder encoder = new SpeexEncoder(this.fileName, mCallback); Thread encodeThread = new Thread(encoder); encoder.setRecording(true); logger.d("chat#audio#encoder thread starts"); encodeThread.start(); synchronized (mutex) { while (!this.isRecording) { try { mutex.wait(); } catch (InterruptedException e) { throw new IllegalStateException("Wait() interrupted!", e); } } } android.os.Process .setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); int bufferRead = 0; int bufferSize = AudioRecord.getMinBufferSize(frequency, AudioFormat.CHANNEL_IN_MONO, audioEncoding); short[] tempBuffer = new short[packagesize]; try { if (null == recordInstance) { recordInstance = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency, AudioFormat.CHANNEL_IN_MONO, audioEncoding, bufferSize); } recordInstance.startRecording(); recordTime = 0; startTime = System.currentTimeMillis(); maxVolumeStart = System.currentTimeMillis(); while (this.isRecording) { endTime = System.currentTimeMillis(); recordTime = (float) ((endTime - startTime) / 1000.0f); if (recordTime >= SysConstant.MAX_SOUND_RECORD_TIME) { MessageActivity.getUiHandler().sendEmptyMessage( HandlerConstant.RECORD_AUDIO_TOO_LONG); break; } bufferRead = recordInstance.read(tempBuffer, 0, packagesize); if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) { throw new IllegalStateException( "read() returned AudioRecord.ERROR_INVALID_OPERATION"); } else if (bufferRead == AudioRecord.ERROR_BAD_VALUE) { throw new IllegalStateException( "read() returned AudioRecord.ERROR_BAD_VALUE"); } else if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) { throw new IllegalStateException( "read() returned AudioRecord.ERROR_INVALID_OPERATION"); } log.d("chat#audio#put data into encoder collector...."); encoder.putData(tempBuffer, bufferRead); maxVolumeEnd = System.currentTimeMillis(); setMaxVolume(tempBuffer, bufferRead); } } catch (Exception e) { logger.e(e.getMessage()); } finally { encoder.setRecording(false); if (recordInstance != null) { recordInstance.stop(); recordInstance.release(); recordInstance = null; } else { } } } catch (Exception e) { logger.e(e.getMessage()); } } private void setMaxVolume(short[] buffer, int readLen) { try { if (maxVolumeEnd - maxVolumeStart < 100) { return; } maxVolumeStart = maxVolumeEnd; int max = 0; for (int i = 0; i < readLen; i++) { if (Math.abs(buffer[i]) > max) { max = Math.abs(buffer[i]); } } Message Msg = new Message(); Msg.what = HandlerConstant.RECEIVE_MAX_VOLUME; Msg.obj = max; MessageActivity.getUiHandler().sendMessage(Msg); } catch (Exception e) { logger.e(e.getMessage()); } } public float getRecordTime() { return recordTime; } public void setRecordTime(float len) { recordTime = len; } public void setRecording(boolean isRec) { synchronized (mutex) { this.isRecording = isRec; if (this.isRecording) { mutex.notify(); } } } public boolean isRecording() { synchronized (mutex) { return isRecording; } } }