Fields Summary |
---|
public static final int | STATE_UNINITIALIZEDindicates AudioRecord state is not successfully initialized. |
public static final int | STATE_INITIALIZEDindicates AudioRecord state is ready to be used |
public static final int | RECORDSTATE_STOPPEDindicates AudioRecord recording state is not recording |
public static final int | RECORDSTATE_RECORDINGindicates AudioRecord recording state is recording |
public static final int | SUCCESSDenotes a successful operation. |
public static final int | ERRORDenotes a generic operation failure. |
public static final int | ERROR_BAD_VALUEDenotes a failure due to the use of an invalid value. |
public static final int | ERROR_INVALID_OPERATIONDenotes a failure due to the improper use of a method. |
private static final int | AUDIORECORD_ERROR_SETUP_ZEROFRAMECOUNT |
private static final int | AUDIORECORD_ERROR_SETUP_INVALIDCHANNELCOUNT |
private static final int | AUDIORECORD_ERROR_SETUP_INVALIDFORMAT |
private static final int | AUDIORECORD_ERROR_SETUP_INVALIDSTREAMTYPE |
private static final int | AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED |
private static final int | NATIVE_EVENT_MARKEREvent id denotes when record head has reached a previously set marker. |
private static final int | NATIVE_EVENT_NEW_POSEvent id denotes when previously set update period has elapsed during recording. |
private static final String | TAG |
private int | mNativeRecorderInJavaObjAccessed by native methods: provides access to C++ AudioRecord object |
private static final int | SOURCE_DEFAULTAccessed by native methods: provides access to record source constants |
private static final int | SOURCE_MIC |
private int | mNativeCallbackCookieAccessed by native methods: provides access to the callback data. |
private int | mSampleRateThe audio data sampling rate in Hz. |
private int | mChannelCountThe number of input audio channels (1 is mono, 2 is stereo) |
private int | mChannelConfigurationThe current audio channel configuration |
private int | mAudioFormatThe encoding of the audio samples. |
private int | mRecordSourceWhere the audio data is recorded from. |
private int | mStateIndicates the state of the AudioRecord instance. |
private int | mRecordingStateIndicates the recording state of the AudioRecord instance. |
private Object | mRecordingStateLockLock to make sure mRecordingState updates are reflecting the actual state of the object. |
private OnRecordPositionUpdateListener | mPositionListenerThe listener the AudioRecord notifies when the record position reaches a marker
or for periodic updates during the progression of the record head. |
private final Object | mPositionListenerLockLock to protect position listener updates against event notifications |
private NativeEventHandler | mEventHandlerHandler for marker events coming from the native code |
private android.os.Looper | mInitializationLooperLooper associated with the thread that creates the AudioRecord instance |
private int | mNativeBufferSizeInBytesSize of the native audio buffer. |
Methods Summary |
---|
private void | audioBuffSizeCheck(int audioBufferSize)
// NB: this section is only valid with PCM data.
// To update when supporting compressed formats
int frameSizeInBytes = mChannelCount
* (mAudioFormat == AudioFormat.ENCODING_PCM_8BIT ? 1 : 2);
if ((audioBufferSize % frameSizeInBytes != 0) || (audioBufferSize < 1)) {
throw (new IllegalArgumentException("Invalid audio buffer size."));
}
mNativeBufferSizeInBytes = audioBufferSize;
|
private void | audioParamCheck(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat)
//--------------
// audio source
if ( (audioSource != MediaRecorder.AudioSource.DEFAULT)
&& (audioSource != MediaRecorder.AudioSource.MIC) ) {
throw (new IllegalArgumentException("Invalid audio source."));
} else {
mRecordSource = audioSource;
}
//--------------
// sample rate
if ( (sampleRateInHz < 4000) || (sampleRateInHz > 48000) ) {
throw (new IllegalArgumentException(sampleRateInHz
+ "Hz is not a supported sample rate."));
} else {
mSampleRate = sampleRateInHz;
}
//--------------
// channel config
switch (channelConfig) {
case AudioFormat.CHANNEL_CONFIGURATION_DEFAULT:
case AudioFormat.CHANNEL_CONFIGURATION_MONO:
mChannelCount = 1;
mChannelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
break;
case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
mChannelCount = 2;
mChannelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
break;
default:
mChannelCount = 0;
mChannelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_INVALID;
throw (new IllegalArgumentException("Unsupported channel configuration."));
}
//--------------
// audio format
switch (audioFormat) {
case AudioFormat.ENCODING_DEFAULT:
mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
break;
case AudioFormat.ENCODING_PCM_16BIT:
case AudioFormat.ENCODING_PCM_8BIT:
mAudioFormat = audioFormat;
break;
default:
mAudioFormat = AudioFormat.ENCODING_INVALID;
throw (new IllegalArgumentException("Unsupported sample encoding."
+ " Should be ENCODING_PCM_8BIT or ENCODING_PCM_16BIT."));
}
|
protected void | finalize()
native_finalize();
|
public int | getAudioFormat()Returns the configured audio data format. See {@link AudioFormat#ENCODING_PCM_16BIT}
and {@link AudioFormat#ENCODING_PCM_8BIT}.
return mAudioFormat;
|
public int | getAudioSource()Returns the audio recording source.
return mRecordSource;
|
public int | getChannelConfiguration()Returns the configured channel configuration.
See {@link AudioFormat#CHANNEL_CONFIGURATION_MONO}
and {@link AudioFormat#CHANNEL_CONFIGURATION_STEREO}.
return mChannelConfiguration;
|
public int | getChannelCount()Returns the configured number of channels.
return mChannelCount;
|
public static int | getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat)Returns the minimum buffer size required for the successful creation of an AudioRecord
object.
Note that this size doesn't guarantee a smooth recording under load, and higher values
should be chosen according to the expected frequency at which the AudioRecord instance
will be polled for new data.
int channelCount = 0;
switch(channelConfig) {
case AudioFormat.CHANNEL_CONFIGURATION_DEFAULT:
case AudioFormat.CHANNEL_CONFIGURATION_MONO:
channelCount = 1;
break;
case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
channelCount = 2;
break;
case AudioFormat.CHANNEL_CONFIGURATION_INVALID:
default:
loge("getMinBufferSize(): Invalid channel configuration.");
return AudioRecord.ERROR_BAD_VALUE;
}
// PCM_8BIT is not supported at the moment
if (audioFormat != AudioFormat.ENCODING_PCM_16BIT) {
loge("getMinBufferSize(): Invalid audio format.");
return AudioRecord.ERROR_BAD_VALUE;
}
int size = native_get_min_buff_size(sampleRateInHz, channelCount, audioFormat);
if (size == 0) {
return AudioRecord.ERROR_BAD_VALUE;
}
else if (size == -1) {
return AudioRecord.ERROR;
}
else {
return size;
}
|
public int | getNotificationMarkerPosition()Returns the notification marker position expressed in frames.
return native_get_marker_pos();
|
public int | getPositionNotificationPeriod()Returns the notification update period expressed in frames.
return native_get_pos_update_period();
|
public int | getRecordingState()Returns the recording state of the AudioRecord instance.
return mRecordingState;
|
public int | getSampleRate()Returns the configured audio data sample rate in Hz
return mSampleRate;
|
public int | getState()Returns the state of the AudioRecord instance. This is useful after the
AudioRecord instance has been created to check if it was initialized
properly. This ensures that the appropriate hardware resources have been
acquired.
return mState;
|
private static void | logd(java.lang.String msg)
Log.d(TAG, "[ android.media.AudioRecord ] " + msg);
|
private static void | loge(java.lang.String msg)
Log.e(TAG, "[ android.media.AudioRecord ] " + msg);
|
private final native void | native_finalize()
|
private final native int | native_get_marker_pos()
|
private static final native int | native_get_min_buff_size(int sampleRateInHz, int channelCount, int audioFormat)
|
private final native int | native_get_pos_update_period()
|
private final native int | native_read_in_byte_array(byte[] audioData, int offsetInBytes, int sizeInBytes)
|
private final native int | native_read_in_direct_buffer(java.lang.Object jBuffer, int sizeInBytes)
|
private final native int | native_read_in_short_array(short[] audioData, int offsetInShorts, int sizeInShorts)
|
private final native void | native_release()
|
private final native int | native_set_marker_pos(int marker)
|
private final native int | native_set_pos_update_period(int updatePeriod)
|
private final native int | native_setup(java.lang.Object audiorecord_this, int recordSource, int sampleRate, int nbChannels, int audioFormat, int buffSizeInBytes)
|
private final native void | native_start()
|
private final native void | native_stop()
|
private static void | postEventFromNative(java.lang.Object audiorecord_ref, int what, int arg1, int arg2, java.lang.Object obj)
//logd("Event posted from the native side: event="+ what + " args="+ arg1+" "+arg2);
AudioRecord recorder = (AudioRecord)((WeakReference)audiorecord_ref).get();
if (recorder == null) {
return;
}
if (recorder.mEventHandler != null) {
Message m =
recorder.mEventHandler.obtainMessage(what, arg1, arg2, obj);
recorder.mEventHandler.sendMessage(m);
}
|
public int | read(byte[] audioData, int offsetInBytes, int sizeInBytes)Reads audio data from the audio hardware for recording into a buffer.
if (mState != STATE_INITIALIZED) {
return ERROR_INVALID_OPERATION;
}
if ( (audioData == null) || (offsetInBytes < 0 ) || (sizeInBytes < 0)
|| (offsetInBytes + sizeInBytes > audioData.length)) {
return ERROR_BAD_VALUE;
}
return native_read_in_byte_array(audioData, offsetInBytes, sizeInBytes);
|
public int | read(short[] audioData, int offsetInShorts, int sizeInShorts)Reads audio data from the audio hardware for recording into a buffer.
if (mState != STATE_INITIALIZED) {
return ERROR_INVALID_OPERATION;
}
if ( (audioData == null) || (offsetInShorts < 0 ) || (sizeInShorts < 0)
|| (offsetInShorts + sizeInShorts > audioData.length)) {
return ERROR_BAD_VALUE;
}
return native_read_in_short_array(audioData, offsetInShorts, sizeInShorts);
|
public int | read(java.nio.ByteBuffer audioBuffer, int sizeInBytes)Reads audio data from the audio hardware for recording into a direct buffer. If this buffer
is not a direct buffer, this method will always return 0.
if (mState != STATE_INITIALIZED) {
return ERROR_INVALID_OPERATION;
}
if ( (audioBuffer == null) || (sizeInBytes < 0) ) {
return ERROR_BAD_VALUE;
}
return native_read_in_direct_buffer(audioBuffer, sizeInBytes);
|
public void | release()Releases the native AudioRecord resources.
The object can no longer be used and the reference should be set to null
after a call to release()
try {
stop();
} catch(IllegalStateException ise) {
// don't raise an exception, we're releasing the resources.
}
native_release();
mState = STATE_UNINITIALIZED;
|
public int | setNotificationMarkerPosition(int markerInFrames)Sets the marker position at which the listener is called, if set with
{@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener)} or
{@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener, Handler)}.
return native_set_marker_pos(markerInFrames);
|
public int | setPositionNotificationPeriod(int periodInFrames)Sets the period at which the listener is called, if set with
{@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener)} or
{@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener, Handler)}.
return native_set_pos_update_period(periodInFrames);
|
public void | setRecordPositionUpdateListener(android.media.AudioRecord$OnRecordPositionUpdateListener listener)Sets the listener the AudioRecord notifies when a previously set marker is reached or
for each periodic record head position update.
setRecordPositionUpdateListener(listener, null);
|
public void | setRecordPositionUpdateListener(android.media.AudioRecord$OnRecordPositionUpdateListener listener, android.os.Handler handler)Sets the listener the AudioRecord notifies when a previously set marker is reached or
for each periodic record head position update.
Use this method to receive AudioRecord events in the Handler associated with another
thread than the one in which you created the AudioTrack instance.
synchronized (mPositionListenerLock) {
mPositionListener = listener;
if (listener != null) {
if (handler != null) {
mEventHandler = new NativeEventHandler(this, handler.getLooper());
} else {
// no given handler, use the looper the AudioRecord was created in
mEventHandler = new NativeEventHandler(this, mInitializationLooper);
}
} else {
mEventHandler = null;
}
}
|
public void | startRecording()Starts recording from the AudioRecord instance.
if (mState != STATE_INITIALIZED) {
throw(new IllegalStateException("startRecording() called on an "
+"uninitialized AudioRecord."));
}
// start recording
synchronized(mRecordingStateLock) {
native_start();
mRecordingState = RECORDSTATE_RECORDING;
}
|
public void | stop()Stops recording.
if (mState != STATE_INITIALIZED) {
throw(new IllegalStateException("stop() called on an uninitialized AudioRecord."));
}
// stop recording
synchronized(mRecordingStateLock) {
native_stop();
mRecordingState = RECORDSTATE_STOPPED;
}
|