Loading api/current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -14669,6 +14669,7 @@ package android.media { method public int getState(); method public int read(byte[], int, int); method public int read(short[], int, int); method public int read(float[], int, int, int); method public int read(java.nio.ByteBuffer, int); method public void release(); method public int setNotificationMarkerPosition(int); Loading @@ -14681,6 +14682,8 @@ package android.media { field public static final int ERROR = -1; // 0xffffffff field public static final int ERROR_BAD_VALUE = -2; // 0xfffffffe field public static final int ERROR_INVALID_OPERATION = -3; // 0xfffffffd field public static final int READ_BLOCKING = 0; // 0x0 field public static final int READ_NON_BLOCKING = 1; // 0x1 field public static final int RECORDSTATE_RECORDING = 3; // 0x3 field public static final int RECORDSTATE_STOPPED = 1; // 0x1 field public static final int STATE_INITIALIZED = 1; // 0x1 api/system-current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -15876,6 +15876,7 @@ package android.media { method public int getState(); method public int read(byte[], int, int); method public int read(short[], int, int); method public int read(float[], int, int, int); method public int read(java.nio.ByteBuffer, int); method public void release(); method public int setNotificationMarkerPosition(int); Loading @@ -15888,6 +15889,8 @@ package android.media { field public static final int ERROR = -1; // 0xffffffff field public static final int ERROR_BAD_VALUE = -2; // 0xfffffffe field public static final int ERROR_INVALID_OPERATION = -3; // 0xfffffffd field public static final int READ_BLOCKING = 0; // 0x0 field public static final int READ_NON_BLOCKING = 1; // 0x1 field public static final int RECORDSTATE_RECORDING = 3; // 0x3 field public static final int RECORDSTATE_STOPPED = 1; // 0x1 field public static final int STATE_INITIALIZED = 1; // 0x1 core/jni/android_media_AudioRecord.cpp +53 −0 Original line number Diff line number Diff line Loading @@ -440,6 +440,57 @@ static jint android_media_AudioRecord_readInShortArray(JNIEnv *env, jobject thi return (jint) readSize; } // ---------------------------------------------------------------------------- static jint android_media_AudioRecord_readInFloatArray(JNIEnv *env, jobject thiz, jfloatArray javaAudioData, jint offsetInFloats, jint sizeInFloats, jboolean isReadBlocking) { // get the audio recorder from which we'll read new audio samples sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == NULL) { ALOGE("Unable to retrieve AudioRecord object"); return (jint)AUDIO_JAVA_INVALID_OPERATION; } if (javaAudioData == NULL) { ALOGE("Invalid Java array to store recorded audio"); return (jint)AUDIO_JAVA_BAD_VALUE; } // get the pointer to where we'll record the audio // NOTE: We may use GetPrimitiveArrayCritical() when the JNI implementation changes in such // a way that it becomes much more efficient. When doing so, we will have to prevent the // AudioSystem callback to be called while in critical section (in case of media server // process crash for instance) jfloat *recordBuff = (jfloat *)env->GetFloatArrayElements(javaAudioData, NULL); if (recordBuff == NULL) { ALOGE("Error retrieving destination for recorded audio data"); return (jint)AUDIO_JAVA_BAD_VALUE; } // read the new audio data from the native AudioRecord object const size_t sizeInBytes = sizeInFloats * sizeof(float); ssize_t readSize = lpRecorder->read(recordBuff + offsetInFloats, sizeInBytes); env->ReleaseFloatArrayElements(javaAudioData, recordBuff, 0); if (readSize < 0) { ALOGE_IF(readSize != WOULD_BLOCK, "Error %zd during AudioRecord native read", readSize); switch (readSize) { case WOULD_BLOCK: return (jint)0; case BAD_VALUE: return (jint)AUDIO_JAVA_BAD_VALUE; default: // may be possible for other errors such as // NO_INIT to happen if restoreRecord_l fails. case INVALID_OPERATION: return (jint)AUDIO_JAVA_INVALID_OPERATION; } } return (jint)(readSize / sizeof(float)); } // ---------------------------------------------------------------------------- static jint android_media_AudioRecord_readInDirectBuffer(JNIEnv *env, jobject thiz, jobject jBuffer, jint sizeInBytes) { Loading Loading @@ -574,6 +625,8 @@ static JNINativeMethod gMethods[] = { "([BII)I", (void *)android_media_AudioRecord_readInByteArray}, {"native_read_in_short_array", "([SII)I", (void *)android_media_AudioRecord_readInShortArray}, {"native_read_in_float_array", "([FIIZ)I", (void *)android_media_AudioRecord_readInFloatArray}, {"native_read_in_direct_buffer","(Ljava/lang/Object;I)I", (void *)android_media_AudioRecord_readInDirectBuffer}, {"native_set_marker_pos","(I)I", (void *)android_media_AudioRecord_set_marker_pos}, Loading media/java/android/media/AudioRecord.java +83 −19 Original line number Diff line number Diff line Loading @@ -16,10 +16,13 @@ package android.media; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; import java.nio.ByteBuffer; import java.util.Iterator; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; import android.os.Binder; Loading Loading @@ -109,6 +112,26 @@ public class AudioRecord /** @hide */ public final static String SUBMIX_FIXED_VOLUME = "fixedVolume"; /** @hide */ @IntDef({ READ_BLOCKING, READ_NON_BLOCKING }) @Retention(RetentionPolicy.SOURCE) public @interface ReadMode {} /** * The read mode indicating the read operation will block until all data * requested has been read. */ public final static int READ_BLOCKING = 0; /** * The read mode indicating the read operation will return immediately after * reading as much audio data as possible without blocking. */ public final static int READ_NON_BLOCKING = 1; //--------------------------------------------------------- // Used exclusively by native code //-------------------- Loading Loading @@ -144,6 +167,7 @@ public class AudioRecord * The encoding of the audio samples. * @see AudioFormat#ENCODING_PCM_8BIT * @see AudioFormat#ENCODING_PCM_16BIT * @see AudioFormat#ENCODING_PCM_FLOAT */ private int mAudioFormat; /** Loading Loading @@ -212,9 +236,9 @@ public class AudioRecord * 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 audioFormat the format in which the audio data is to be returned. * See {@link AudioFormat#ENCODING_PCM_8BIT}, {@link AudioFormat#ENCODING_PCM_16BIT}, * and {@link AudioFormat#ENCODING_PCM_FLOAT}. * @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 Loading Loading @@ -559,13 +583,14 @@ public class AudioRecord case AudioFormat.ENCODING_DEFAULT: mAudioFormat = AudioFormat.ENCODING_PCM_16BIT; break; case AudioFormat.ENCODING_PCM_FLOAT: 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."); + " Should be ENCODING_PCM_8BIT, ENCODING_PCM_16BIT, or ENCODING_PCM_FLOAT."); } } Loading @@ -573,7 +598,8 @@ public class AudioRecord // Convenience method for the contructor's audio buffer size check. // preconditions: // mChannelCount is valid // mAudioFormat is AudioFormat.ENCODING_PCM_8BIT OR AudioFormat.ENCODING_PCM_16BIT // mAudioFormat is AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT, // or AudioFormat.ENCODING_PCM_FLOAT // postcondition: // mNativeBufferSizeInBytes is valid (multiple of frame size, positive) private void audioBuffSizeCheck(int audioBufferSize) throws IllegalArgumentException { Loading Loading @@ -632,8 +658,8 @@ public class AudioRecord } /** * Returns the configured audio data format. See {@link AudioFormat#ENCODING_PCM_16BIT} * and {@link AudioFormat#ENCODING_PCM_8BIT}. * Returns the configured audio data format. See {@link AudioFormat#ENCODING_PCM_8BIT}, * {@link AudioFormat#ENCODING_PCM_16BIT}, and {@link AudioFormat#ENCODING_PCM_FLOAT}. */ public int getAudioFormat() { return mAudioFormat; Loading Loading @@ -732,12 +758,6 @@ public class AudioRecord 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; Loading Loading @@ -841,11 +861,13 @@ public class AudioRecord // Audio data supply //-------------------- /** * Reads audio data from the audio hardware for recording into a buffer. * Reads audio data from the audio hardware for recording into a byte array. * The format specified in the AudioRecord constructor should be * {@link AudioFormat#ENCODING_PCM_8BIT} to correspond to the data in the array. * @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} * @return the number of bytes that were read 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. Loading @@ -866,11 +888,13 @@ public class AudioRecord /** * Reads audio data from the audio hardware for recording into a buffer. * Reads audio data from the audio hardware for recording into a short array. * The format specified in the AudioRecord constructor should be * {@link AudioFormat#ENCODING_PCM_16BIT} to correspond to the data in the array. * @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} * @return the number of shorts that were read 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. Loading @@ -889,18 +913,55 @@ public class AudioRecord return native_read_in_short_array(audioData, offsetInShorts, sizeInShorts); } /** * Reads audio data from the audio hardware for recording into a float array. * The format specified in the AudioRecord constructor should be * {@link AudioFormat#ENCODING_PCM_FLOAT} to correspond to the data in the array. * @param audioData the array to which the recorded audio data is written. * @param offsetInFloats index in audioData from which the data is written. * @param sizeInFloats the number of requested floats. * @param readMode one of {@link #READ_BLOCKING}, {@link #READ_NON_BLOCKING}. * <BR>With {@link #READ_BLOCKING}, the read will block until all the requested data * is read. * <BR>With {@link #READ_NON_BLOCKING}, the read will return immediately after * reading as much audio data as possible without blocking. * @return the number of floats that were read 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 floats will not exceed sizeInFloats. */ public int read(float[] audioData, int offsetInFloats, int sizeInFloats, @ReadMode int readMode) { if (mState != STATE_INITIALIZED) { return ERROR_INVALID_OPERATION; } if ( (audioData == null) || (offsetInFloats < 0 ) || (sizeInFloats < 0) || (offsetInFloats + sizeInFloats < 0) // detect integer overflow || (offsetInFloats + sizeInFloats > audioData.length)) { return ERROR_BAD_VALUE; } return native_read_in_float_array(audioData, offsetInFloats, sizeInFloats, readMode == READ_BLOCKING); } /** * 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. * The representation of the data in the buffer will depend on the format specified in * the AudioRecord constructor, and will be native endian. * @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} * @param sizeInBytes the number of requested bytes. It is recommended but not enforced * that the number of bytes requested be a multiple of the frame size (sample size in * bytes multiplied by the channel count). * @return the number of bytes that were read 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. * The number of bytes read will truncated to be a multiple of the frame size. */ public int read(ByteBuffer audioBuffer, int sizeInBytes) { if (mState != STATE_INITIALIZED) { Loading Loading @@ -1101,6 +1162,9 @@ public class AudioRecord private native final int native_read_in_short_array(short[] audioData, int offsetInShorts, int sizeInShorts); private native final int native_read_in_float_array(float[] audioData, int offsetInFloats, int sizeInFloats, boolean isBlocking); private native final int native_read_in_direct_buffer(Object jBuffer, int sizeInBytes); private native final int native_set_marker_pos(int marker); Loading Loading
api/current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -14669,6 +14669,7 @@ package android.media { method public int getState(); method public int read(byte[], int, int); method public int read(short[], int, int); method public int read(float[], int, int, int); method public int read(java.nio.ByteBuffer, int); method public void release(); method public int setNotificationMarkerPosition(int); Loading @@ -14681,6 +14682,8 @@ package android.media { field public static final int ERROR = -1; // 0xffffffff field public static final int ERROR_BAD_VALUE = -2; // 0xfffffffe field public static final int ERROR_INVALID_OPERATION = -3; // 0xfffffffd field public static final int READ_BLOCKING = 0; // 0x0 field public static final int READ_NON_BLOCKING = 1; // 0x1 field public static final int RECORDSTATE_RECORDING = 3; // 0x3 field public static final int RECORDSTATE_STOPPED = 1; // 0x1 field public static final int STATE_INITIALIZED = 1; // 0x1
api/system-current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -15876,6 +15876,7 @@ package android.media { method public int getState(); method public int read(byte[], int, int); method public int read(short[], int, int); method public int read(float[], int, int, int); method public int read(java.nio.ByteBuffer, int); method public void release(); method public int setNotificationMarkerPosition(int); Loading @@ -15888,6 +15889,8 @@ package android.media { field public static final int ERROR = -1; // 0xffffffff field public static final int ERROR_BAD_VALUE = -2; // 0xfffffffe field public static final int ERROR_INVALID_OPERATION = -3; // 0xfffffffd field public static final int READ_BLOCKING = 0; // 0x0 field public static final int READ_NON_BLOCKING = 1; // 0x1 field public static final int RECORDSTATE_RECORDING = 3; // 0x3 field public static final int RECORDSTATE_STOPPED = 1; // 0x1 field public static final int STATE_INITIALIZED = 1; // 0x1
core/jni/android_media_AudioRecord.cpp +53 −0 Original line number Diff line number Diff line Loading @@ -440,6 +440,57 @@ static jint android_media_AudioRecord_readInShortArray(JNIEnv *env, jobject thi return (jint) readSize; } // ---------------------------------------------------------------------------- static jint android_media_AudioRecord_readInFloatArray(JNIEnv *env, jobject thiz, jfloatArray javaAudioData, jint offsetInFloats, jint sizeInFloats, jboolean isReadBlocking) { // get the audio recorder from which we'll read new audio samples sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == NULL) { ALOGE("Unable to retrieve AudioRecord object"); return (jint)AUDIO_JAVA_INVALID_OPERATION; } if (javaAudioData == NULL) { ALOGE("Invalid Java array to store recorded audio"); return (jint)AUDIO_JAVA_BAD_VALUE; } // get the pointer to where we'll record the audio // NOTE: We may use GetPrimitiveArrayCritical() when the JNI implementation changes in such // a way that it becomes much more efficient. When doing so, we will have to prevent the // AudioSystem callback to be called while in critical section (in case of media server // process crash for instance) jfloat *recordBuff = (jfloat *)env->GetFloatArrayElements(javaAudioData, NULL); if (recordBuff == NULL) { ALOGE("Error retrieving destination for recorded audio data"); return (jint)AUDIO_JAVA_BAD_VALUE; } // read the new audio data from the native AudioRecord object const size_t sizeInBytes = sizeInFloats * sizeof(float); ssize_t readSize = lpRecorder->read(recordBuff + offsetInFloats, sizeInBytes); env->ReleaseFloatArrayElements(javaAudioData, recordBuff, 0); if (readSize < 0) { ALOGE_IF(readSize != WOULD_BLOCK, "Error %zd during AudioRecord native read", readSize); switch (readSize) { case WOULD_BLOCK: return (jint)0; case BAD_VALUE: return (jint)AUDIO_JAVA_BAD_VALUE; default: // may be possible for other errors such as // NO_INIT to happen if restoreRecord_l fails. case INVALID_OPERATION: return (jint)AUDIO_JAVA_INVALID_OPERATION; } } return (jint)(readSize / sizeof(float)); } // ---------------------------------------------------------------------------- static jint android_media_AudioRecord_readInDirectBuffer(JNIEnv *env, jobject thiz, jobject jBuffer, jint sizeInBytes) { Loading Loading @@ -574,6 +625,8 @@ static JNINativeMethod gMethods[] = { "([BII)I", (void *)android_media_AudioRecord_readInByteArray}, {"native_read_in_short_array", "([SII)I", (void *)android_media_AudioRecord_readInShortArray}, {"native_read_in_float_array", "([FIIZ)I", (void *)android_media_AudioRecord_readInFloatArray}, {"native_read_in_direct_buffer","(Ljava/lang/Object;I)I", (void *)android_media_AudioRecord_readInDirectBuffer}, {"native_set_marker_pos","(I)I", (void *)android_media_AudioRecord_set_marker_pos}, Loading
media/java/android/media/AudioRecord.java +83 −19 Original line number Diff line number Diff line Loading @@ -16,10 +16,13 @@ package android.media; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; import java.nio.ByteBuffer; import java.util.Iterator; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; import android.os.Binder; Loading Loading @@ -109,6 +112,26 @@ public class AudioRecord /** @hide */ public final static String SUBMIX_FIXED_VOLUME = "fixedVolume"; /** @hide */ @IntDef({ READ_BLOCKING, READ_NON_BLOCKING }) @Retention(RetentionPolicy.SOURCE) public @interface ReadMode {} /** * The read mode indicating the read operation will block until all data * requested has been read. */ public final static int READ_BLOCKING = 0; /** * The read mode indicating the read operation will return immediately after * reading as much audio data as possible without blocking. */ public final static int READ_NON_BLOCKING = 1; //--------------------------------------------------------- // Used exclusively by native code //-------------------- Loading Loading @@ -144,6 +167,7 @@ public class AudioRecord * The encoding of the audio samples. * @see AudioFormat#ENCODING_PCM_8BIT * @see AudioFormat#ENCODING_PCM_16BIT * @see AudioFormat#ENCODING_PCM_FLOAT */ private int mAudioFormat; /** Loading Loading @@ -212,9 +236,9 @@ public class AudioRecord * 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 audioFormat the format in which the audio data is to be returned. * See {@link AudioFormat#ENCODING_PCM_8BIT}, {@link AudioFormat#ENCODING_PCM_16BIT}, * and {@link AudioFormat#ENCODING_PCM_FLOAT}. * @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 Loading Loading @@ -559,13 +583,14 @@ public class AudioRecord case AudioFormat.ENCODING_DEFAULT: mAudioFormat = AudioFormat.ENCODING_PCM_16BIT; break; case AudioFormat.ENCODING_PCM_FLOAT: 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."); + " Should be ENCODING_PCM_8BIT, ENCODING_PCM_16BIT, or ENCODING_PCM_FLOAT."); } } Loading @@ -573,7 +598,8 @@ public class AudioRecord // Convenience method for the contructor's audio buffer size check. // preconditions: // mChannelCount is valid // mAudioFormat is AudioFormat.ENCODING_PCM_8BIT OR AudioFormat.ENCODING_PCM_16BIT // mAudioFormat is AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT, // or AudioFormat.ENCODING_PCM_FLOAT // postcondition: // mNativeBufferSizeInBytes is valid (multiple of frame size, positive) private void audioBuffSizeCheck(int audioBufferSize) throws IllegalArgumentException { Loading Loading @@ -632,8 +658,8 @@ public class AudioRecord } /** * Returns the configured audio data format. See {@link AudioFormat#ENCODING_PCM_16BIT} * and {@link AudioFormat#ENCODING_PCM_8BIT}. * Returns the configured audio data format. See {@link AudioFormat#ENCODING_PCM_8BIT}, * {@link AudioFormat#ENCODING_PCM_16BIT}, and {@link AudioFormat#ENCODING_PCM_FLOAT}. */ public int getAudioFormat() { return mAudioFormat; Loading Loading @@ -732,12 +758,6 @@ public class AudioRecord 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; Loading Loading @@ -841,11 +861,13 @@ public class AudioRecord // Audio data supply //-------------------- /** * Reads audio data from the audio hardware for recording into a buffer. * Reads audio data from the audio hardware for recording into a byte array. * The format specified in the AudioRecord constructor should be * {@link AudioFormat#ENCODING_PCM_8BIT} to correspond to the data in the array. * @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} * @return the number of bytes that were read 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. Loading @@ -866,11 +888,13 @@ public class AudioRecord /** * Reads audio data from the audio hardware for recording into a buffer. * Reads audio data from the audio hardware for recording into a short array. * The format specified in the AudioRecord constructor should be * {@link AudioFormat#ENCODING_PCM_16BIT} to correspond to the data in the array. * @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} * @return the number of shorts that were read 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. Loading @@ -889,18 +913,55 @@ public class AudioRecord return native_read_in_short_array(audioData, offsetInShorts, sizeInShorts); } /** * Reads audio data from the audio hardware for recording into a float array. * The format specified in the AudioRecord constructor should be * {@link AudioFormat#ENCODING_PCM_FLOAT} to correspond to the data in the array. * @param audioData the array to which the recorded audio data is written. * @param offsetInFloats index in audioData from which the data is written. * @param sizeInFloats the number of requested floats. * @param readMode one of {@link #READ_BLOCKING}, {@link #READ_NON_BLOCKING}. * <BR>With {@link #READ_BLOCKING}, the read will block until all the requested data * is read. * <BR>With {@link #READ_NON_BLOCKING}, the read will return immediately after * reading as much audio data as possible without blocking. * @return the number of floats that were read 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 floats will not exceed sizeInFloats. */ public int read(float[] audioData, int offsetInFloats, int sizeInFloats, @ReadMode int readMode) { if (mState != STATE_INITIALIZED) { return ERROR_INVALID_OPERATION; } if ( (audioData == null) || (offsetInFloats < 0 ) || (sizeInFloats < 0) || (offsetInFloats + sizeInFloats < 0) // detect integer overflow || (offsetInFloats + sizeInFloats > audioData.length)) { return ERROR_BAD_VALUE; } return native_read_in_float_array(audioData, offsetInFloats, sizeInFloats, readMode == READ_BLOCKING); } /** * 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. * The representation of the data in the buffer will depend on the format specified in * the AudioRecord constructor, and will be native endian. * @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} * @param sizeInBytes the number of requested bytes. It is recommended but not enforced * that the number of bytes requested be a multiple of the frame size (sample size in * bytes multiplied by the channel count). * @return the number of bytes that were read 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. * The number of bytes read will truncated to be a multiple of the frame size. */ public int read(ByteBuffer audioBuffer, int sizeInBytes) { if (mState != STATE_INITIALIZED) { Loading Loading @@ -1101,6 +1162,9 @@ public class AudioRecord private native final int native_read_in_short_array(short[] audioData, int offsetInShorts, int sizeInShorts); private native final int native_read_in_float_array(float[] audioData, int offsetInFloats, int sizeInFloats, boolean isBlocking); private native final int native_read_in_direct_buffer(Object jBuffer, int sizeInBytes); private native final int native_set_marker_pos(int marker); Loading