mirror of
https://github.com/Pinball3D/Rabbit-R1.git
synced 2024-12-27 09:32:27 -06:00
227 lines
8.5 KiB
Java
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;
|
|
}
|
|
}
|