package root.gast.audio.record; import java.io.IOException; import root.gast.audio.util.AudioUtil; import root.gast.audio.util.RecorderErrorLoggerListener; import android.media.MediaRecorder; import android.os.AsyncTask; import android.util.Log; /** * Records {@link MediaRecorder#getMaxAmplitude()} * @author gmilette * */ public class MaxAmplitudeRecorder { private static final String TAG = "MaxAmplitudeRecorder"; private static final long DEFAULT_CLIP_TIME = 1000; private long clipTime = DEFAULT_CLIP_TIME; private AmplitudeClipListener clipListener; private boolean continueRecording; private MediaRecorder recorder; private String tmpAudioFile; private AsyncTask task; /** * * @param clipTime * time to wait in between maxAmplitude checks * @param tmpAudioFile * should be a file where the MediaRecorder class can write * temporary audio data * @param clipListener * called periodically to analyze the max amplitude * @param task * stop recording if this task is canceled */ public MaxAmplitudeRecorder(long clipTime, String tmpAudioFile, AmplitudeClipListener clipListener, AsyncTask task) { this.clipTime = clipTime; this.clipListener = clipListener; this.tmpAudioFile = tmpAudioFile; this.task = task; } /** * start recording maximum amplitude and passing it to the * {@link #clipListener} <br> * @throws {@link IllegalStateException} if there is trouble creating * the recorder * @throws {@link IOException} if the SD card is not available * @throws {@link RuntimeException} if audio recording channel is occupied * @return true if {@link #clipListener} succeeded in detecting something * false if it failed or the recording stopped for some other reason */ public boolean startRecording() throws IOException { Log.d(TAG, "recording maxAmplitude"); recorder = AudioUtil.prepareRecorder(tmpAudioFile); // when an error occurs just stop recording recorder.setOnErrorListener(new MediaRecorder.OnErrorListener() { @Override public void onError(MediaRecorder mr, int what, int extra) { // log it new RecorderErrorLoggerListener().onError(mr, what, extra); // stop recording stopRecording(); } }); //possible RuntimeException if Audio recording channel is occupied recorder.start(); continueRecording = true; boolean heard = false; recorder.getMaxAmplitude(); while (continueRecording) { Log.d(TAG, "waiting while recording..."); waitClipTime(); if (task != null) { Log.d(TAG, "continue recording: " + continueRecording + " cancelled after waiting? " + task.isCancelled()); } //in case external code stopped this while read was happening if ((!continueRecording) || ((task != null) && task.isCancelled())) { break; } int maxAmplitude = recorder.getMaxAmplitude(); Log.d(TAG, "current max amplitude: " + maxAmplitude); heard = clipListener.heard(maxAmplitude); if (heard) { stopRecording(); } } Log.d(TAG, "stopped recording max amplitude"); done(); return heard; } private void waitClipTime() { try { Thread.sleep(clipTime); } catch (InterruptedException e) { Log.d(TAG, "interrupted"); } } /** * stop recorder and clean up resources */ public void done() { Log.d(TAG, "stop recording on done"); if (recorder != null) { try { recorder.stop(); } catch (Exception e) { Log.d(TAG, "failed to stop"); return; } recorder.release(); } } public boolean isRecording() { return continueRecording; } public void stopRecording() { continueRecording = false; } }