Hi,
I am new to Android and has been trying to find out if Android 1.5 on HTC magic is able to put system to sleep while collecting audio data through microphone.
What I am trying to accomplish is to continously collecting audio (PCM 16bit at 8K Hz) from microphone as long as possible. I have tested with AudioRecord class and is able to record audio continously for 7 hours before battery running out. 7 hours is good but not enough.
I noticed that during recording, although screen is turned off automatically, the system is never put into sleep mode. I wish sleep mode will allow recording go much longer. I found out by comparing SystemClock.uptimeMillis() and System.currentTimeMillis() before and after recording.
However as I reviewed David Sparks presentation at Google I/O (Google I/O - Mastering the Android Media Framework). David suggested at the end of the presentation that system should be automatically go to sleep mode while AudioRecord is collecting data into the preconfigured buffer(1 M bytes in my example). There are two problems I was facing while trying a simple recording 8k PCM 16bit using buffer of 1 Mbytes.
1. AudioRecord.setPositionNotificationPeriod() or AudioReocrd.setNotificationMarkerPosition() does not seem to work. I wish to periodically wake up to retrieve data by calling AudioRecord.read().
However, I do not get call back at all as I configured. Eventually AudioRecord stopped when record buffer overflowed. Below is the code.
2. With problem 1, I have to call AudioRecord.read() in a while loop from a separate thread. When I read(), the thread will block on the read() until read buffer is filled. During the block, I hope the system may go to sleep mode. My program works and audio data were successfully read but system never went to sleep during the block.
I appreciate any help that either prove or disapprove my idea of putting system into sleep while recording audio continously.
Alex
public class AsyncAudioRecorder {
public static final int DEFAULT_SAMPLE_RATE = 8000;
private static final int DEFAULT_BUFFER_SIZE = 1000000;
private static final int CALLBACK_PERIOD = 500;
private final AudioRecord recorder;
private int runningOffset = 0;
byte[] bytes = new byte[DEFAULT_BUFFER_SIZE];
private AsyncAudioRecorder(int sampleRate) {
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, DEFAULT_BUFFER_SIZE);
recorder.setRecordPositionUpdateListener(mNotification);
int retval = recorder.setPositionNotificationPeriod(CALLBACK_PERIOD);
Log.d("setPeriodNotificationPeriod",Integer.toString(retval));
int notificationPeriod = recorder.getPositionNotificationPeriod();
Log.d("getPeriodNotificationPeriod", Integer.toString(notificationPeriod));
retval = recorder.setNotificationMarkerPosition(1000);
Log.d("setNotificationMarkerPosition",Integer.toString(retval));
int notificationMarker = recorder.getNotificationMarkerPosition();
Log.d("getNotificationMarkerPosition", Integer.toString(notificationMarker));
//read once, doesn't help
int byteCount = recorder.read(bytes, 0, DEFAULT_BUFFER_SIZE);
Log.d(this.getClass().getSimpleName(), "Bytes read: " + Integer.toString(byteCount));
}
public AudioRecord.OnRecordPositionUpdateListener mNotification = new
AudioRecord.OnRecordPositionUpdateListener() {
@Override
public void onMarkerReached(AudioRecord argRecorder) {
try{
Log.d(this.getClass().getSimpleName(), "onMarkerReached Called");
int byteCount = argRecorder.read(bytes, runningOffset, DEFAULT_BUFFER_SIZE);
runningOffset = runningOffset + byteCount;
Log.d(this.getClass().getSimpleName(), "Bytes read: " + Integer.toString(byteCount));
}
catch (Exception e){
Log.e(this.getClass().getSimpleName(), "error in onMarkerReached");
}
}
@Override
public void onPeriodicNotification(AudioRecord argRecorder) {
try
{
Log.d(this.getClass().getSimpleName(), "onPeriodicNotification Called");
int byteCount = argRecorder.read(bytes, runningOffset, DEFAULT_BUFFER_SIZE);
runningOffset = runningOffset + byteCount;
Log.d(this.getClass().getSimpleName(), "Bytes read: " + Integer.toString(byteCount));
}
catch (Exception e){
Log.e(this.getClass().getSimpleName(), "error in onPeriodicNotification");
}
}
};
public void start() {
try{
recorder.startRecording();
}
catch (Exception e)
{
Log.e(this.getClass().getSimpleName(), "Error while starting the recording!");
}
}
public void stop() {
try{
recorder.stop();
recorder.release();
}
catch (Exception e){
Log.e(this.getClass().getSimpleName(), "Error while starting the recording!");
}
}
}
I am new to Android and has been trying to find out if Android 1.5 on HTC magic is able to put system to sleep while collecting audio data through microphone.
What I am trying to accomplish is to continously collecting audio (PCM 16bit at 8K Hz) from microphone as long as possible. I have tested with AudioRecord class and is able to record audio continously for 7 hours before battery running out. 7 hours is good but not enough.
I noticed that during recording, although screen is turned off automatically, the system is never put into sleep mode. I wish sleep mode will allow recording go much longer. I found out by comparing SystemClock.uptimeMillis() and System.currentTimeMillis() before and after recording.
However as I reviewed David Sparks presentation at Google I/O (Google I/O - Mastering the Android Media Framework). David suggested at the end of the presentation that system should be automatically go to sleep mode while AudioRecord is collecting data into the preconfigured buffer(1 M bytes in my example). There are two problems I was facing while trying a simple recording 8k PCM 16bit using buffer of 1 Mbytes.
1. AudioRecord.setPositionNotificationPeriod() or AudioReocrd.setNotificationMarkerPosition() does not seem to work. I wish to periodically wake up to retrieve data by calling AudioRecord.read().
However, I do not get call back at all as I configured. Eventually AudioRecord stopped when record buffer overflowed. Below is the code.
2. With problem 1, I have to call AudioRecord.read() in a while loop from a separate thread. When I read(), the thread will block on the read() until read buffer is filled. During the block, I hope the system may go to sleep mode. My program works and audio data were successfully read but system never went to sleep during the block.
I appreciate any help that either prove or disapprove my idea of putting system into sleep while recording audio continously.
Alex
public class AsyncAudioRecorder {
public static final int DEFAULT_SAMPLE_RATE = 8000;
private static final int DEFAULT_BUFFER_SIZE = 1000000;
private static final int CALLBACK_PERIOD = 500;
private final AudioRecord recorder;
private int runningOffset = 0;
byte[] bytes = new byte[DEFAULT_BUFFER_SIZE];
private AsyncAudioRecorder(int sampleRate) {
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, DEFAULT_BUFFER_SIZE);
recorder.setRecordPositionUpdateListener(mNotification);
int retval = recorder.setPositionNotificationPeriod(CALLBACK_PERIOD);
Log.d("setPeriodNotificationPeriod",Integer.toString(retval));
int notificationPeriod = recorder.getPositionNotificationPeriod();
Log.d("getPeriodNotificationPeriod", Integer.toString(notificationPeriod));
retval = recorder.setNotificationMarkerPosition(1000);
Log.d("setNotificationMarkerPosition",Integer.toString(retval));
int notificationMarker = recorder.getNotificationMarkerPosition();
Log.d("getNotificationMarkerPosition", Integer.toString(notificationMarker));
//read once, doesn't help
int byteCount = recorder.read(bytes, 0, DEFAULT_BUFFER_SIZE);
Log.d(this.getClass().getSimpleName(), "Bytes read: " + Integer.toString(byteCount));
}
public AudioRecord.OnRecordPositionUpdateListener mNotification = new
AudioRecord.OnRecordPositionUpdateListener() {
@Override
public void onMarkerReached(AudioRecord argRecorder) {
try{
Log.d(this.getClass().getSimpleName(), "onMarkerReached Called");
int byteCount = argRecorder.read(bytes, runningOffset, DEFAULT_BUFFER_SIZE);
runningOffset = runningOffset + byteCount;
Log.d(this.getClass().getSimpleName(), "Bytes read: " + Integer.toString(byteCount));
}
catch (Exception e){
Log.e(this.getClass().getSimpleName(), "error in onMarkerReached");
}
}
@Override
public void onPeriodicNotification(AudioRecord argRecorder) {
try
{
Log.d(this.getClass().getSimpleName(), "onPeriodicNotification Called");
int byteCount = argRecorder.read(bytes, runningOffset, DEFAULT_BUFFER_SIZE);
runningOffset = runningOffset + byteCount;
Log.d(this.getClass().getSimpleName(), "Bytes read: " + Integer.toString(byteCount));
}
catch (Exception e){
Log.e(this.getClass().getSimpleName(), "error in onPeriodicNotification");
}
}
};
public void start() {
try{
recorder.startRecording();
}
catch (Exception e)
{
Log.e(this.getClass().getSimpleName(), "Error while starting the recording!");
}
}
public void stop() {
try{
recorder.stop();
recorder.release();
}
catch (Exception e){
Log.e(this.getClass().getSimpleName(), "Error while starting the recording!");
}
}
}