Rabbit-R1/android (non root)/java/sources/androidx/media3/exoplayer/audio/SilenceSkippingAudioProcessor.java
2024-05-21 17:08:36 -04:00

227 lines
8.5 KiB
Java

package androidx.media3.exoplayer.audio;
import androidx.media3.common.audio.AudioProcessor;
import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.Util;
import java.nio.ByteBuffer;
/* loaded from: classes2.dex */
public final class SilenceSkippingAudioProcessor extends androidx.media3.common.audio.BaseAudioProcessor {
public static final long DEFAULT_MINIMUM_SILENCE_DURATION_US = 150000;
public static final long DEFAULT_PADDING_SILENCE_US = 20000;
public static final short DEFAULT_SILENCE_THRESHOLD_LEVEL = 1024;
private static final int STATE_MAYBE_SILENT = 1;
private static final int STATE_NOISY = 0;
private static final int STATE_SILENT = 2;
private int bytesPerFrame;
private boolean enabled;
private boolean hasOutputNoise;
private byte[] maybeSilenceBuffer;
private int maybeSilenceBufferSize;
private final long minimumSilenceDurationUs;
private byte[] paddingBuffer;
private final long paddingSilenceUs;
private int paddingSize;
private final short silenceThresholdLevel;
private long skippedFrames;
private int state;
public long getSkippedFrames() {
return this.skippedFrames;
}
@Override // androidx.media3.common.audio.BaseAudioProcessor, androidx.media3.common.audio.AudioProcessor
public boolean isActive() {
return this.enabled;
}
public void setEnabled(boolean z) {
this.enabled = z;
}
public SilenceSkippingAudioProcessor() {
this(150000L, 20000L, (short) 1024);
}
public SilenceSkippingAudioProcessor(long j, long j2, short s) {
Assertions.checkArgument(j2 <= j);
this.minimumSilenceDurationUs = j;
this.paddingSilenceUs = j2;
this.silenceThresholdLevel = s;
this.maybeSilenceBuffer = Util.EMPTY_BYTE_ARRAY;
this.paddingBuffer = Util.EMPTY_BYTE_ARRAY;
}
@Override // androidx.media3.common.audio.BaseAudioProcessor
public AudioProcessor.AudioFormat onConfigure(AudioProcessor.AudioFormat audioFormat) throws AudioProcessor.UnhandledAudioFormatException {
if (audioFormat.encoding == 2) {
return this.enabled ? audioFormat : AudioProcessor.AudioFormat.NOT_SET;
}
throw new AudioProcessor.UnhandledAudioFormatException(audioFormat);
}
@Override // androidx.media3.common.audio.AudioProcessor
public void queueInput(ByteBuffer byteBuffer) {
while (byteBuffer.hasRemaining() && !hasPendingOutput()) {
int i = this.state;
if (i == 0) {
processNoisy(byteBuffer);
} else if (i == 1) {
processMaybeSilence(byteBuffer);
} else if (i == 2) {
processSilence(byteBuffer);
} else {
throw new IllegalStateException();
}
}
}
@Override // androidx.media3.common.audio.BaseAudioProcessor
protected void onQueueEndOfStream() {
int i = this.maybeSilenceBufferSize;
if (i > 0) {
output(this.maybeSilenceBuffer, i);
}
if (this.hasOutputNoise) {
return;
}
this.skippedFrames += this.paddingSize / this.bytesPerFrame;
}
@Override // androidx.media3.common.audio.BaseAudioProcessor
protected void onFlush() {
if (this.enabled) {
this.bytesPerFrame = this.inputAudioFormat.bytesPerFrame;
int durationUsToFrames = durationUsToFrames(this.minimumSilenceDurationUs) * this.bytesPerFrame;
if (this.maybeSilenceBuffer.length != durationUsToFrames) {
this.maybeSilenceBuffer = new byte[durationUsToFrames];
}
int durationUsToFrames2 = durationUsToFrames(this.paddingSilenceUs) * this.bytesPerFrame;
this.paddingSize = durationUsToFrames2;
if (this.paddingBuffer.length != durationUsToFrames2) {
this.paddingBuffer = new byte[durationUsToFrames2];
}
}
this.state = 0;
this.skippedFrames = 0L;
this.maybeSilenceBufferSize = 0;
this.hasOutputNoise = false;
}
@Override // androidx.media3.common.audio.BaseAudioProcessor
protected void onReset() {
this.enabled = false;
this.paddingSize = 0;
this.maybeSilenceBuffer = Util.EMPTY_BYTE_ARRAY;
this.paddingBuffer = Util.EMPTY_BYTE_ARRAY;
}
private void processNoisy(ByteBuffer byteBuffer) {
int limit = byteBuffer.limit();
byteBuffer.limit(Math.min(limit, byteBuffer.position() + this.maybeSilenceBuffer.length));
int findNoiseLimit = findNoiseLimit(byteBuffer);
if (findNoiseLimit == byteBuffer.position()) {
this.state = 1;
} else {
byteBuffer.limit(findNoiseLimit);
output(byteBuffer);
}
byteBuffer.limit(limit);
}
private void processMaybeSilence(ByteBuffer byteBuffer) {
int limit = byteBuffer.limit();
int findNoisePosition = findNoisePosition(byteBuffer);
int position = findNoisePosition - byteBuffer.position();
byte[] bArr = this.maybeSilenceBuffer;
int length = bArr.length;
int i = this.maybeSilenceBufferSize;
int i2 = length - i;
if (findNoisePosition < limit && position < i2) {
output(bArr, i);
this.maybeSilenceBufferSize = 0;
this.state = 0;
return;
}
int min = Math.min(position, i2);
byteBuffer.limit(byteBuffer.position() + min);
byteBuffer.get(this.maybeSilenceBuffer, this.maybeSilenceBufferSize, min);
int i3 = this.maybeSilenceBufferSize + min;
this.maybeSilenceBufferSize = i3;
byte[] bArr2 = this.maybeSilenceBuffer;
if (i3 == bArr2.length) {
if (this.hasOutputNoise) {
output(bArr2, this.paddingSize);
this.skippedFrames += (this.maybeSilenceBufferSize - (this.paddingSize * 2)) / this.bytesPerFrame;
} else {
this.skippedFrames += (i3 - this.paddingSize) / this.bytesPerFrame;
}
updatePaddingBuffer(byteBuffer, this.maybeSilenceBuffer, this.maybeSilenceBufferSize);
this.maybeSilenceBufferSize = 0;
this.state = 2;
}
byteBuffer.limit(limit);
}
private void processSilence(ByteBuffer byteBuffer) {
int limit = byteBuffer.limit();
int findNoisePosition = findNoisePosition(byteBuffer);
byteBuffer.limit(findNoisePosition);
this.skippedFrames += byteBuffer.remaining() / this.bytesPerFrame;
updatePaddingBuffer(byteBuffer, this.paddingBuffer, this.paddingSize);
if (findNoisePosition < limit) {
output(this.paddingBuffer, this.paddingSize);
this.state = 0;
byteBuffer.limit(limit);
}
}
private void output(byte[] bArr, int i) {
replaceOutputBuffer(i).put(bArr, 0, i).flip();
if (i > 0) {
this.hasOutputNoise = true;
}
}
private void output(ByteBuffer byteBuffer) {
int remaining = byteBuffer.remaining();
replaceOutputBuffer(remaining).put(byteBuffer).flip();
if (remaining > 0) {
this.hasOutputNoise = true;
}
}
private void updatePaddingBuffer(ByteBuffer byteBuffer, byte[] bArr, int i) {
int min = Math.min(byteBuffer.remaining(), this.paddingSize);
int i2 = this.paddingSize - min;
System.arraycopy(bArr, i - i2, this.paddingBuffer, 0, i2);
byteBuffer.position(byteBuffer.limit() - min);
byteBuffer.get(this.paddingBuffer, i2, min);
}
private int durationUsToFrames(long j) {
return (int) ((j * this.inputAudioFormat.sampleRate) / 1000000);
}
private int findNoisePosition(ByteBuffer byteBuffer) {
for (int position = byteBuffer.position(); position < byteBuffer.limit(); position += 2) {
if (Math.abs((int) byteBuffer.getShort(position)) > this.silenceThresholdLevel) {
int i = this.bytesPerFrame;
return i * (position / i);
}
}
return byteBuffer.limit();
}
private int findNoiseLimit(ByteBuffer byteBuffer) {
int limit = byteBuffer.limit();
do {
limit -= 2;
if (limit < byteBuffer.position()) {
return byteBuffer.position();
}
} while (Math.abs((int) byteBuffer.getShort(limit)) <= this.silenceThresholdLevel);
int i = this.bytesPerFrame;
return ((limit / i) * i) + i;
}
}