AudioRecord 录制ENCODING_PCM_FLOAT 格式音频
ENCODING_PCM_FLOAT 需要Android 23以上版本才支持。
- 构造AudioRecord。构造方法跟其他格式数据一致,只是audioFormat更改为AudioFormat.ENCODING_PCM_FLOAT。我这里传的数据格式为audioSource:MediaRecorder.AudioSource.MIC;sample:16000;channel:AudioFormat.CHANNEL_IN_MONO
- 录制对应音频。这里需要注意的是:录制ENCODING_PCM_FLOAT 格式的音频必须使用AudioRecord中对应的read方法:
/**
* 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.
* Must not be negative, or cause the data access to go out of bounds of the array.
* @param sizeInFloats the number of requested floats.
* Must not be negative, or cause the data access to go out of bounds of the array.
* @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 zero or the positive number of floats that were read, or one of the following
* error codes. The number of floats will be a multiple of the channel count not to exceed
* sizeInFloats.
* <ul>
* <li>{@link #ERROR_INVALID_OPERATION} if the object isn't properly initialized</li>
* <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
* <li>{@link #ERROR_DEAD_OBJECT} if the object is not valid anymore and
* needs to be recreated. The dead object error code is not returned if some data was
* successfully transferred. In this case, the error is returned at the next read()</li>
* <li>{@link #ERROR} in case of other error</li>
* </ul>
*/
public int read(@NonNull float[] audioData, int offsetInFloats, int sizeInFloats,
@ReadMode int readMode) {
- audioData即为录制到的音频。
转换成ENCODING_PCM_16BIT
ENCODING_PCM_FLOAT 格式数据为32位IEEE浮点型数据。该如何转换成ENCODING_PCM_16BIT数据呢?16bit数据pcm的范围是-32768~32767.而PCM_FLOAT的数值范围为[-1,1)。对应关系一目了然即float[i]*32768就等于16bit数据中short值。
对应解析代码如下:
private byte[] convertTo16Bit(float[] data) {
short[] shortValue = new short[data.length];
byte[] byte16bit = new byte[shortValue.length * 2];
for (int i = 0; i < data.length; i++) {
shortValue[i] = (short) (32768 * data[i]);
}
byte16bit = toByteArray(shortValue);
return byte16bit;
}
private byte[] toByteArray(short[] src) {
int count = src.length;
byte[] dest = new byte[count << 1];
for (int i = 0; i < count; i++) {
dest[i * 2] = (byte) (src[i]);
dest[i * 2 + 1] = (byte) (src[i] >> 8);
}
return dest;
}