FileDocCategorySizeDatePackage
AudioRecord.javaAPI DocAndroid 5.1 API37594Thu Mar 12 22:22:30 GMT 2015android.media

AudioRecord

public class AudioRecord extends Object
The AudioRecord class manages the audio resources for Java applications to record audio from the audio input hardware of the platform. This is achieved by "pulling" (reading) the data from the AudioRecord object. The application is responsible for polling the AudioRecord object in time using one of the following three methods: {@link #read(byte[],int, int)}, {@link #read(short[], int, int)} or {@link #read(ByteBuffer, int)}. The choice of which method to use will be based on the audio data storage format that is the most convenient for the user of AudioRecord.

Upon creation, an AudioRecord object initializes its associated audio buffer that it will fill with the new audio data. The size of this buffer, specified during the construction, determines how long an AudioRecord can record before "over-running" data that has not been read yet. Data should be read from the audio hardware in chunks of sizes inferior to the total recording buffer size.

Fields Summary
public static final int
STATE_UNINITIALIZED
indicates AudioRecord state is not successfully initialized.
public static final int
STATE_INITIALIZED
indicates AudioRecord state is ready to be used
public static final int
RECORDSTATE_STOPPED
indicates AudioRecord recording state is not recording
public static final int
RECORDSTATE_RECORDING
indicates AudioRecord recording state is recording
public static final int
SUCCESS
Denotes a successful operation.
public static final int
ERROR
Denotes a generic operation failure.
public static final int
ERROR_BAD_VALUE
Denotes a failure due to the use of an invalid value.
public static final int
ERROR_INVALID_OPERATION
Denotes 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_INVALIDCHANNELMASK
private static final int
AUDIORECORD_ERROR_SETUP_INVALIDFORMAT
private static final int
AUDIORECORD_ERROR_SETUP_INVALIDSOURCE
private static final int
AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED
private static final int
NATIVE_EVENT_MARKER
Event id denotes when record head has reached a previously set marker.
private static final int
NATIVE_EVENT_NEW_POS
Event id denotes when previously set update period has elapsed during recording.
private static final String
TAG
public static final String
SUBMIX_FIXED_VOLUME
private long
mNativeRecorderInJavaObj
Accessed by native methods: provides access to C++ AudioRecord object
private long
mNativeCallbackCookie
Accessed by native methods: provides access to the callback data.
private int
mSampleRate
The audio data sampling rate in Hz.
private int
mChannelCount
The number of input audio channels (1 is mono, 2 is stereo)
private int
mChannelMask
The audio channel mask
private int
mAudioFormat
The encoding of the audio samples.
private int
mRecordSource
Where the audio data is recorded from.
private int
mState
Indicates the state of the AudioRecord instance.
private int
mRecordingState
Indicates the recording state of the AudioRecord instance.
private final Object
mRecordingStateLock
Lock to make sure mRecordingState updates are reflecting the actual state of the object.
private OnRecordPositionUpdateListener
mPositionListener
The 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
mPositionListenerLock
Lock to protect position listener updates against event notifications
private NativeEventHandler
mEventHandler
Handler for marker events coming from the native code
private android.os.Looper
mInitializationLooper
Looper associated with the thread that creates the AudioRecord instance
private int
mNativeBufferSizeInBytes
Size of the native audio buffer.
private int
mSessionId
Audio session ID
private AudioAttributes
mAudioAttributes
AudioAttributes
private boolean
mIsSubmixFullVolume
private final android.os.IBinder
mICallBack
Constructors Summary
public AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)
Class constructor. Though some invalid parameters will result in an {@link IllegalArgumentException} exception, other errors do not. Thus you should call {@link #getState()} immediately after construction to confirm that the object is usable.

param
audioSource the recording source (also referred to as capture preset). See {@link MediaRecorder.AudioSource} for the capture preset definitions.
param
sampleRateInHz the sample rate expressed in Hertz. 44100Hz is currently the only rate that is guaranteed to work on all devices, but other rates such as 22050, 16000, and 11025 may work on some devices.
param
channelConfig describes the configuration of the audio channels. See {@link AudioFormat#CHANNEL_IN_MONO} and {@link AudioFormat#CHANNEL_IN_STEREO}. {@link AudioFormat#CHANNEL_IN_MONO} is guaranteed to work on all devices.
param
audioFormat the format in which the audio data is represented. See {@link AudioFormat#ENCODING_PCM_16BIT} and {@link AudioFormat#ENCODING_PCM_8BIT}
param
bufferSizeInBytes the total size (in bytes) of the buffer where audio data is written to during the recording. New audio data can be read from this buffer in smaller chunks than this size. See {@link #getMinBufferSize(int, int, int)} to determine the minimum required buffer size for the successful creation of an AudioRecord instance. Using values smaller than getMinBufferSize() will result in an initialization failure.
throws
java.lang.IllegalArgumentException


    //---------------------------------------------------------
    // Constructor, Finalize
    //--------------------
                                                                                                                                                                                                                                        
            
             
      
        this((new AudioAttributes.Builder())
                    .setInternalCapturePreset(audioSource)
                    .build(),
                (new AudioFormat.Builder())
                    .setChannelMask(getChannelMaskFromLegacyConfig(channelConfig,
                                        true/*allow legacy configurations*/))
                    .setEncoding(audioFormat)
                    .setSampleRate(sampleRateInHz)
                    .build(),
                bufferSizeInBytes,
                AudioManager.AUDIO_SESSION_ID_GENERATE);
    
public AudioRecord(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes, int sessionId)

hide
CANDIDATE FOR PUBLIC API Class constructor with {@link AudioAttributes} and {@link AudioFormat}.
param
attributes a non-null {@link AudioAttributes} instance. Use {@link AudioAttributes.Builder#setCapturePreset(int)} for configuring the capture preset for this instance.
param
format a non-null {@link AudioFormat} instance describing the format of the data that will be recorded through this AudioRecord. See {@link AudioFormat.Builder} for configuring the audio format parameters such as encoding, channel mask and sample rate.
param
bufferSizeInBytes the total size (in bytes) of the buffer where audio data is written to during the recording. New audio data can be read from this buffer in smaller chunks than this size. See {@link #getMinBufferSize(int, int, int)} to determine the minimum required buffer size for the successful creation of an AudioRecord instance. Using values smaller than getMinBufferSize() will result in an initialization failure.
param
sessionId ID of audio session the AudioRecord must be attached to, or {@link AudioManager#AUDIO_SESSION_ID_GENERATE} if the session isn't known at construction time. See also {@link AudioManager#generateAudioSessionId()} to obtain a session ID before construction.
throws
IllegalArgumentException

        mRecordingState = RECORDSTATE_STOPPED;

        if (attributes == null) {
            throw new IllegalArgumentException("Illegal null AudioAttributes");
        }
        if (format == null) {
            throw new IllegalArgumentException("Illegal null AudioFormat");
        }

        // remember which looper is associated with the AudioRecord instanciation
        if ((mInitializationLooper = Looper.myLooper()) == null) {
            mInitializationLooper = Looper.getMainLooper();
        }

        // is this AudioRecord using REMOTE_SUBMIX at full volume?
        if (attributes.getCapturePreset() == MediaRecorder.AudioSource.REMOTE_SUBMIX) {
            final AudioAttributes.Builder filteredAttr = new AudioAttributes.Builder();
            final Iterator<String> tagsIter = attributes.getTags().iterator();
            while (tagsIter.hasNext()) {
                final String tag = tagsIter.next();
                if (tag.equalsIgnoreCase(SUBMIX_FIXED_VOLUME)) {
                    mIsSubmixFullVolume = true;
                    Log.v(TAG, "Will record from REMOTE_SUBMIX at full fixed volume");
                } else { // SUBMIX_FIXED_VOLUME: is not to be propagated to the native layers
                    filteredAttr.addTag(tag);
                }
            }
            filteredAttr.setInternalCapturePreset(attributes.getCapturePreset());
            mAudioAttributes = filteredAttr.build();
        } else {
            mAudioAttributes = attributes;
        }

        int rate = 0;
        if ((format.getPropertySetMask()
                & AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE) != 0)
        {
            rate = format.getSampleRate();
        } else {
            rate = AudioSystem.getPrimaryOutputSamplingRate();
            if (rate <= 0) {
                rate = 44100;
            }
        }

        int encoding = AudioFormat.ENCODING_DEFAULT;
        if ((format.getPropertySetMask() & AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_ENCODING) != 0)
        {
            encoding = format.getEncoding();
        }

        audioParamCheck(attributes.getCapturePreset(), rate, encoding);

        mChannelCount = AudioFormat.channelCountFromInChannelMask(format.getChannelMask());
        mChannelMask = getChannelMaskFromLegacyConfig(format.getChannelMask(), false);

        audioBuffSizeCheck(bufferSizeInBytes);

        int[] session = new int[1];
        session[0] = sessionId;
        //TODO: update native initialization when information about hardware init failure
        //      due to capture device already open is available.
        int initResult = native_setup( new WeakReference<AudioRecord>(this),
                mAudioAttributes, mSampleRate, mChannelMask, mAudioFormat, mNativeBufferSizeInBytes,
                session);
        if (initResult != SUCCESS) {
            loge("Error code "+initResult+" when initializing native AudioRecord object.");
            return; // with mState == STATE_UNINITIALIZED
        }

        mSessionId = session[0];

        mState = STATE_INITIALIZED;
    
Methods Summary
private voidaudioBuffSizeCheck(int audioBufferSize)

        // NB: this section is only valid with PCM data.
        // To update when supporting compressed formats
        int frameSizeInBytes = mChannelCount
            * (AudioFormat.getBytesPerSample(mAudioFormat));
        if ((audioBufferSize % frameSizeInBytes != 0) || (audioBufferSize < 1)) {
            throw new IllegalArgumentException("Invalid audio buffer size.");
        }

        mNativeBufferSizeInBytes = audioBufferSize;
    
private voidaudioParamCheck(int audioSource, int sampleRateInHz, int audioFormat)


        //--------------
        // audio source
        if ( (audioSource < MediaRecorder.AudioSource.DEFAULT) ||
             ((audioSource > MediaRecorder.getAudioSourceMax()) &&
              (audioSource != MediaRecorder.AudioSource.FM_TUNER) &&
              (audioSource != MediaRecorder.AudioSource.HOTWORD)) )  {
            throw new IllegalArgumentException("Invalid audio source.");
        }
        mRecordSource = audioSource;

        //--------------
        // sample rate
        if ( (sampleRateInHz < 4000) || (sampleRateInHz > 48000) ) {
            throw new IllegalArgumentException(sampleRateInHz
                    + "Hz is not a supported sample rate.");
        }
        mSampleRate = sampleRateInHz;

        //--------------
        // 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:
            throw new IllegalArgumentException("Unsupported sample encoding."
                    + " Should be ENCODING_PCM_8BIT or ENCODING_PCM_16BIT.");
        }
    
protected voidfinalize()

        // will cause stop() to be called, and if appropriate, will handle fixed volume recording
        release();
    
public intgetAudioFormat()
Returns the configured audio data format. See {@link AudioFormat#ENCODING_PCM_16BIT} and {@link AudioFormat#ENCODING_PCM_8BIT}.

        return mAudioFormat;
    
public intgetAudioSessionId()
Returns the audio session ID.

return
the ID of the audio session this AudioRecord belongs to.

        return mSessionId;
    
public intgetAudioSource()
Returns the audio recording source.

see
MediaRecorder.AudioSource

        return mRecordSource;
    
public intgetChannelConfiguration()
Returns the configured channel configuration. See {@link AudioFormat#CHANNEL_IN_MONO} and {@link AudioFormat#CHANNEL_IN_STEREO}.

        return mChannelMask;
    
public intgetChannelCount()
Returns the configured number of channels.

        return mChannelCount;
    
private static intgetChannelMaskFromLegacyConfig(int inChannelConfig, boolean allowLegacyConfig)

        int mask;
        switch (inChannelConfig) {
        case AudioFormat.CHANNEL_IN_DEFAULT: // AudioFormat.CHANNEL_CONFIGURATION_DEFAULT
        case AudioFormat.CHANNEL_IN_MONO:
        case AudioFormat.CHANNEL_CONFIGURATION_MONO:
            mask = AudioFormat.CHANNEL_IN_MONO;
            break;
        case AudioFormat.CHANNEL_IN_STEREO:
        case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
            mask = AudioFormat.CHANNEL_IN_STEREO;
            break;
        case (AudioFormat.CHANNEL_IN_FRONT | AudioFormat.CHANNEL_IN_BACK):
            mask = inChannelConfig;
            break;
        default:
            throw new IllegalArgumentException("Unsupported channel configuration.");
        }

        if (!allowLegacyConfig && ((inChannelConfig == AudioFormat.CHANNEL_CONFIGURATION_MONO)
                || (inChannelConfig == AudioFormat.CHANNEL_CONFIGURATION_STEREO))) {
            // only happens with the constructor that uses AudioAttributes and AudioFormat
            throw new IllegalArgumentException("Unsupported deprecated configuration.");
        }

        return mask;
    
public static intgetMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat)
Returns the minimum buffer size required for the successful creation of an AudioRecord object, in byte units. 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. See {@link #AudioRecord(int, int, int, int, int)} for more information on valid configuration values.

param
sampleRateInHz the sample rate expressed in Hertz.
param
channelConfig describes the configuration of the audio channels. See {@link AudioFormat#CHANNEL_IN_MONO} and {@link AudioFormat#CHANNEL_IN_STEREO}
param
audioFormat the format in which the audio data is represented. See {@link AudioFormat#ENCODING_PCM_16BIT}.
return
{@link #ERROR_BAD_VALUE} if the recording parameters are not supported by the hardware, or an invalid parameter was passed, or {@link #ERROR} if the implementation was unable to query the hardware for its input properties, or the minimum buffer size expressed in bytes.
see
#AudioRecord(int, int, int, int, int)

        int channelCount = 0;
        switch (channelConfig) {
        case AudioFormat.CHANNEL_IN_DEFAULT: // AudioFormat.CHANNEL_CONFIGURATION_DEFAULT
        case AudioFormat.CHANNEL_IN_MONO:
        case AudioFormat.CHANNEL_CONFIGURATION_MONO:
            channelCount = 1;
            break;
        case AudioFormat.CHANNEL_IN_STEREO:
        case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
        case (AudioFormat.CHANNEL_IN_FRONT | AudioFormat.CHANNEL_IN_BACK):
            channelCount = 2;
            break;
        case AudioFormat.CHANNEL_INVALID:
        default:
            loge("getMinBufferSize(): Invalid channel configuration.");
            return ERROR_BAD_VALUE;
        }

        // PCM_8BIT is not supported at the moment
        if (audioFormat != AudioFormat.ENCODING_PCM_16BIT) {
            loge("getMinBufferSize(): Invalid audio format.");
            return ERROR_BAD_VALUE;
        }

        int size = native_get_min_buff_size(sampleRateInHz, channelCount, audioFormat);
        if (size == 0) {
            return ERROR_BAD_VALUE;
        }
        else if (size == -1) {
            return ERROR;
        }
        else {
            return size;
        }
    
public intgetNotificationMarkerPosition()
Returns the notification marker position expressed in frames.

        return native_get_marker_pos();
    
public intgetPositionNotificationPeriod()
Returns the notification update period expressed in frames.

        return native_get_pos_update_period();
    
public intgetRecordingState()
Returns the recording state of the AudioRecord instance.

see
AudioRecord#RECORDSTATE_STOPPED
see
AudioRecord#RECORDSTATE_RECORDING

        synchronized (mRecordingStateLock) {
            return mRecordingState;
        }
    
public intgetSampleRate()
Returns the configured audio data sample rate in Hz

        return mSampleRate;
    
public intgetState()
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.

see
AudioRecord#STATE_INITIALIZED
see
AudioRecord#STATE_UNINITIALIZED

        return mState;
    
private voidhandleFullVolumeRec(boolean starting)

        
        if (!mIsSubmixFullVolume) {
            return;
        }
        final IBinder b = ServiceManager.getService(android.content.Context.AUDIO_SERVICE);
        final IAudioService ias = IAudioService.Stub.asInterface(b);
        try {
            ias.forceRemoteSubmixFullVolume(starting, mICallBack);
        } catch (RemoteException e) {
            Log.e(TAG, "Error talking to AudioService when handling full submix volume", e);
        }
    
private static voidlogd(java.lang.String msg)

        Log.d(TAG, msg);
    
private static voidloge(java.lang.String msg)

        Log.e(TAG, msg);
    
private final native voidnative_finalize()

private final native intnative_get_marker_pos()

private static final native intnative_get_min_buff_size(int sampleRateInHz, int channelCount, int audioFormat)

private final native intnative_get_pos_update_period()

private final native intnative_read_in_byte_array(byte[] audioData, int offsetInBytes, int sizeInBytes)

private final native intnative_read_in_direct_buffer(java.lang.Object jBuffer, int sizeInBytes)

private final native intnative_read_in_short_array(short[] audioData, int offsetInShorts, int sizeInShorts)

private final native voidnative_release()

private final native intnative_set_marker_pos(int marker)

private final native intnative_set_pos_update_period(int updatePeriod)

private final native intnative_setup(java.lang.Object audiorecord_this, java.lang.Object attributes, int sampleRate, int channelMask, int audioFormat, int buffSizeInBytes, int[] sessionId)

private final native intnative_start(int syncEvent, int sessionId)

private final native voidnative_stop()

private static voidpostEventFromNative(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 intread(byte[] audioData, int offsetInBytes, int sizeInBytes)
Reads audio data from the audio hardware for recording into a buffer.

param
audioData the array to which the recorded audio data is written.
param
offsetInBytes index in audioData from which the data is written expressed in bytes.
param
sizeInBytes the number of requested bytes.
return
the number of bytes that were read or or {@link #ERROR_INVALID_OPERATION} if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes. The number of bytes will not exceed sizeInBytes.

        if (mState != STATE_INITIALIZED) {
            return ERROR_INVALID_OPERATION;
        }

        if ( (audioData == null) || (offsetInBytes < 0 ) || (sizeInBytes < 0)
                || (offsetInBytes + sizeInBytes < 0)  // detect integer overflow
                || (offsetInBytes + sizeInBytes > audioData.length)) {
            return ERROR_BAD_VALUE;
        }

        return native_read_in_byte_array(audioData, offsetInBytes, sizeInBytes);
    
public intread(short[] audioData, int offsetInShorts, int sizeInShorts)
Reads audio data from the audio hardware for recording into a buffer.

param
audioData the array to which the recorded audio data is written.
param
offsetInShorts index in audioData from which the data is written expressed in shorts.
param
sizeInShorts the number of requested shorts.
return
the number of shorts that were read or or {@link #ERROR_INVALID_OPERATION} if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes. The number of shorts will not exceed sizeInShorts.

        if (mState != STATE_INITIALIZED) {
            return ERROR_INVALID_OPERATION;
        }

        if ( (audioData == null) || (offsetInShorts < 0 ) || (sizeInShorts < 0)
                || (offsetInShorts + sizeInShorts < 0)  // detect integer overflow
                || (offsetInShorts + sizeInShorts > audioData.length)) {
            return ERROR_BAD_VALUE;
        }

        return native_read_in_short_array(audioData, offsetInShorts, sizeInShorts);
    
public intread(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. Note that the value returned by {@link java.nio.Buffer#position()} on this buffer is unchanged after a call to this method.

param
audioBuffer the direct buffer to which the recorded audio data is written.
param
sizeInBytes the number of requested bytes.
return
the number of bytes that were read or or {@link #ERROR_INVALID_OPERATION} if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes. The number of bytes will not exceed sizeInBytes.

        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 voidrelease()
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 intsetNotificationMarkerPosition(int markerInFrames)
Sets the marker position at which the listener is called, if set with {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener)} or {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener, Handler)}.

param
markerInFrames marker position expressed in frames
return
error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE}, {@link #ERROR_INVALID_OPERATION}

        if (mState == STATE_UNINITIALIZED) {
            return ERROR_INVALID_OPERATION;
        }
        return native_set_marker_pos(markerInFrames);
    
public intsetPositionNotificationPeriod(int periodInFrames)
Sets the period at which the listener is called, if set with {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener)} or {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener, Handler)}. It is possible for notifications to be lost if the period is too small.

param
periodInFrames update period expressed in frames
return
error code or success, see {@link #SUCCESS}, {@link #ERROR_INVALID_OPERATION}

        if (mState == STATE_UNINITIALIZED) {
            return ERROR_INVALID_OPERATION;
        }
        return native_set_pos_update_period(periodInFrames);
    
public voidsetRecordPositionUpdateListener(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.

param
listener

        setRecordPositionUpdateListener(listener, null);
    
public voidsetRecordPositionUpdateListener(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.

param
listener
param
handler the Handler that will receive the event notification messages.

        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 voidstartRecording()
Starts recording from the AudioRecord instance.

throws
IllegalStateException

        if (mState != STATE_INITIALIZED) {
            throw new IllegalStateException("startRecording() called on an "
                    + "uninitialized AudioRecord.");
        }

        // start recording
        synchronized(mRecordingStateLock) {
            if (native_start(MediaSyncEvent.SYNC_EVENT_NONE, 0) == SUCCESS) {
                handleFullVolumeRec(true);
                mRecordingState = RECORDSTATE_RECORDING;
            }
        }
    
public voidstartRecording(MediaSyncEvent syncEvent)
Starts recording from the AudioRecord instance when the specified synchronization event occurs on the specified audio session.

throws
IllegalStateException
param
syncEvent event that triggers the capture.
see
MediaSyncEvent

        if (mState != STATE_INITIALIZED) {
            throw new IllegalStateException("startRecording() called on an "
                    + "uninitialized AudioRecord.");
        }

        // start recording
        synchronized(mRecordingStateLock) {
            if (native_start(syncEvent.getType(), syncEvent.getAudioSessionId()) == SUCCESS) {
                handleFullVolumeRec(true);
                mRecordingState = RECORDSTATE_RECORDING;
            }
        }
    
public voidstop()
Stops recording.

throws
IllegalStateException

        if (mState != STATE_INITIALIZED) {
            throw new IllegalStateException("stop() called on an uninitialized AudioRecord.");
        }

        // stop recording
        synchronized(mRecordingStateLock) {
            handleFullVolumeRec(false);
            native_stop();
            mRecordingState = RECORDSTATE_STOPPED;
        }