From 9ed471651efff7fe7c0b59b45057d95e37fe0689 Mon Sep 17 00:00:00 2001 From: olly Date: Tue, 24 Mar 2020 15:32:52 +0000 Subject: [PATCH] Support 32-bit FP to 16-bit Int audio resampling This is a no-op for DefaultAudioSink for now, because DefaultAudioSink currently disables processing anyway if the input uses ENCODING_PCM_FLOAT. Issue: #7134 PiperOrigin-RevId: 302670534 --- .../audio/ResamplingAudioProcessor.java | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/ResamplingAudioProcessor.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/ResamplingAudioProcessor.java index 7175b93614..883f5bcb92 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/ResamplingAudioProcessor.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/ResamplingAudioProcessor.java @@ -20,8 +20,17 @@ import com.google.android.exoplayer2.Format; import java.nio.ByteBuffer; /** - * An {@link AudioProcessor} that converts 8-bit, 24-bit and 32-bit integer PCM audio to 16-bit - * integer PCM audio. + * An {@link AudioProcessor} that converts different PCM audio encodings to 16-bit integer PCM. The + * following encodings are supported as input: + * + * */ /* package */ final class ResamplingAudioProcessor extends BaseAudioProcessor { @@ -33,7 +42,8 @@ import java.nio.ByteBuffer; && encoding != C.ENCODING_PCM_16BIT && encoding != C.ENCODING_PCM_16BIT_BIG_ENDIAN && encoding != C.ENCODING_PCM_24BIT - && encoding != C.ENCODING_PCM_32BIT) { + && encoding != C.ENCODING_PCM_32BIT + && encoding != C.ENCODING_PCM_FLOAT) { throw new UnhandledAudioFormatException(inputAudioFormat); } return encoding != C.ENCODING_PCM_16BIT @@ -60,10 +70,10 @@ import java.nio.ByteBuffer; resampledSize = (size / 3) * 2; break; case C.ENCODING_PCM_32BIT: + case C.ENCODING_PCM_FLOAT: resampledSize = size / 2; break; case C.ENCODING_PCM_16BIT: - case C.ENCODING_PCM_FLOAT: case C.ENCODING_INVALID: case Format.NO_VALUE: default: @@ -101,8 +111,16 @@ import java.nio.ByteBuffer; buffer.put(inputBuffer.get(i + 3)); } break; - case C.ENCODING_PCM_16BIT: case C.ENCODING_PCM_FLOAT: + // 32 bit floating point -> 16 bit resampling. Floating point values are in the range + // [-1.0, 1.0], so need to be scaled by Short.MAX_VALUE. + for (int i = position; i < limit; i += 4) { + short value = (short) (inputBuffer.getFloat(i) * Short.MAX_VALUE); + buffer.put((byte) (value & 0xFF)); + buffer.put((byte) ((value >> 8) & 0xFF)); + } + break; + case C.ENCODING_PCM_16BIT: case C.ENCODING_INVALID: case Format.NO_VALUE: default: