Skip to content

Instantly share code, notes, and snippets.

@LCamel
Created July 22, 2011 02:47
Show Gist options
  • Select an option

  • Save LCamel/1098784 to your computer and use it in GitHub Desktop.

Select an option

Save LCamel/1098784 to your computer and use it in GitHub Desktop.
import java.io.OutputStream;
import java.util.concurrent.atomic.AtomicBoolean;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Handler;
import android.util.Log;
public class MyAudioRecord {
private static final String TAG = MyAudioRecord.class.getName();
private static final int SAMPLE_RATE = QueuePlayer.SAMPLE_RATE;
private static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO;
private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT; // 看系統. 本來我們實驗的 Hero 最低只能 16 bit, 不能 8 bit
private static final int MIN_BUFFER_SIZE = AudioRecord.getMinBufferSize(
SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT); // on hero : 4096 bytes
private static final int AUDIO_RECORD_BUFFER_SIZE = MIN_BUFFER_SIZE * 10; // 看原廠 AudioRecordTest 中有 * 10
private static final int OUR_16BIT_BUFFER_SIZE = MIN_BUFFER_SIZE * 2;
//private static final int OUR_8BIT_BUFFER_SIZE = OUR_16BIT_BUFFER_SIZE / 2;
private Thread t;
private AtomicBoolean shouldStop = new AtomicBoolean(false);
// non-blocking, 叫了就開始錄
// maxMillis 是最大錄製的秒數 (粗略的, 防止爆掉用的)
// 外面記得要在 stopListener 裏面做事, 包含關閉 output stream
public MyAudioRecord(final OutputStream os, final long maxMillis, final Handler handler, final Runnable stopListener) {
Log.v(TAG, "SAMPLE_RATE: " + SAMPLE_RATE + " CHANNEL_CONFIG: "
+ CHANNEL_CONFIG + " AUDIO_FORMAT: " + AUDIO_FORMAT);
Log.v(TAG, "MIN_BUFFER_SIZE: " + MIN_BUFFER_SIZE
+ " AUDIO_RECORD_BUFFER_SIZE: " + AUDIO_RECORD_BUFFER_SIZE
+ " OUR_16BIT_BUFFER_SIZE: " + OUR_16BIT_BUFFER_SIZE
);
//+ " OUR_8BIT_BUFFER_SIZE: " + OUR_8BIT_BUFFER_SIZE);
final byte[] our16BitBuffer = new byte[OUR_16BIT_BUFFER_SIZE];
//final byte[] our8BitBuffer = new byte[OUR_8BIT_BUFFER_SIZE];
final AudioRecord ar = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, SAMPLE_RATE,
CHANNEL_CONFIG, AUDIO_FORMAT, AUDIO_RECORD_BUFFER_SIZE);
t = new Thread() {
public void run() {
Log.v(TAG, "run() >>>>");
try {
long stopNano = System.nanoTime() + maxMillis * 1000 * 1000;
ar.startRecording();
while (true) {
if (shouldStop.get() == true || System.nanoTime() >= stopNano) {
ar.stop();
ar.release();
handler.post(stopListener); // TODO: 沒檢查傳回值, 放失敗就算了(?)
break;
}
int bytesRead = ar.read(our16BitBuffer, 0, our16BitBuffer.length);
//Log.v(TAG, "bytesRead: " + bytesRead);
os.write(our16BitBuffer, 0, bytesRead);
// // convert 16 to 8
// int j = 0;
// for (int i = 1; i < bytesRead; i += 2, j += 1) {
// our8BitBuffer[j] = our16BitBuffer[i];
// our8BitBuffer[j] ^= (1 << 7);
// }
//
// os.write(our8BitBuffer, 0, j);
}
} catch (Exception e) {
e.printStackTrace();
}
Log.v(TAG, "run() <<<<");
}
};
t.start();
}
// non-blocking, return 時不見得真的停了, 該在傳進來的 listener 中作.
public void stop() {
shouldStop.set(true);
// 在此就不 t.join 了
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment