Saurabh Pandey
Saurabh Pandey

Reputation: 549

float [] to bytes array conversion for AudioTrack

I am using AudioTrack for playing through some float values.

code:

float[] audio_payload = getFloatValues();
final int length = audio_payload.length;

int PLAYER_MODE = AudioTrack.MODE_STREAM;
int PLAYER_STREAM_TYPE = AudioManager.STREAM_MUSIC;
int PLAYER_FORMAT = AudioFormat.ENCODING_PCM_FLOAT;
int PLAYER_CONF = AudioFormat.CHANNEL_OUT_MONO;

int PLAYER_SR = 44100;
AudioTrack track = new AudioTrack(PLAYER_STREAM_TYPE, PLAYER_SR, PLAYER_CONF, PLAYER_FORMAT, audio_payload.length*4, PLAYER_MODE);
track.write(audio_payload, 0, length, AudioTrack.WRITE_NON_BLOCKING);
track.play();

My problem is in android version 20 or below the function, track.write(float[], offset, lenghtInBytes, writeMode); isnt supported. Android Developer Docs

How can I convert my float values to short or bytes array for playing as they are supported on Android API level 3 or above?

I tried converting my float array to short array but it didnt worked, After conversion my original audio was changed. Same happend when I tried converting float to byte array.

The project I am working on has native-lib, so any conversion between flooat to short or float to byte in C or Java would be helpful.

Shorts to Float code i used:

public static short floatToShort(float x) {
    if (x < Short.MIN_VALUE) {
        return Short.MIN_VALUE;
    }
    if (x > Short.MAX_VALUE) {
        return Short.MAX_VALUE;
    }
    return (short) Math.round(x);
}

float to bytes:

public static byte[] convertToByteArray(float value) {
      byte[] bytes = new byte[4];
      ByteBuffer buffer = ByteBuffer.allocate(bytes.length);
      buffer.putFloat(value);
      return buffer.array();

  }

After conversion audio recorder wasn't playing audio, nor I could see any error

Update Also Tried

private short [] floatArrayToShortArray(float [] array) {
    short [] payload = new short[array.length];
    for (int i=0; i<array.length; i++) {
        payload[i] = (short) ((short) array[i] * 32767);
    }
    return payload;

}

But the audioTrack is not able to play.

Upvotes: 3

Views: 1415

Answers (1)

rude
rude

Reputation: 2340

I was able to convert the Float to PCM16 short within such method:

/**
 * Used to convert Float to PCM16 short byte array.
 */
private val convertBuffer = ByteBuffer.allocate(2).apply {
    order(ByteOrder.LITTLE_ENDIAN)
}

/**
 * Converts Float to PCM16 short byte buffer.
 * @param value Float value to convert
 * @return PCM16 short byte array from Float value
 */
private fun floatToPcm16(value: Float): ByteArray {
    convertBuffer.clear()
    convertBuffer.putShort((value * 32768F).toShort())
    return convertBuffer.array()
}

Upvotes: 1

Related Questions