Move SonicAudioProcessor to media3.common module.
PiperOrigin-RevId: 501881646
This commit is contained in:
parent
693600a444
commit
1eeccb6c69
@ -49,6 +49,7 @@ import androidx.media3.common.DebugViewProvider;
|
||||
import androidx.media3.common.Effect;
|
||||
import androidx.media3.common.MediaItem;
|
||||
import androidx.media3.common.audio.AudioProcessor;
|
||||
import androidx.media3.common.audio.SonicAudioProcessor;
|
||||
import androidx.media3.common.util.GlUtil;
|
||||
import androidx.media3.common.util.Log;
|
||||
import androidx.media3.common.util.Util;
|
||||
@ -68,7 +69,6 @@ import androidx.media3.effect.TextOverlay;
|
||||
import androidx.media3.effect.TextureOverlay;
|
||||
import androidx.media3.exoplayer.ExoPlayer;
|
||||
import androidx.media3.exoplayer.audio.SilenceSkippingAudioProcessor;
|
||||
import androidx.media3.exoplayer.audio.SonicAudioProcessor;
|
||||
import androidx.media3.exoplayer.util.DebugTextViewHelper;
|
||||
import androidx.media3.transformer.DefaultEncoderFactory;
|
||||
import androidx.media3.transformer.DefaultMuxer;
|
||||
|
@ -14,7 +14,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package androidx.media3.exoplayer.audio;
|
||||
package androidx.media3.common.audio;
|
||||
|
||||
import static java.lang.Math.min;
|
||||
|
@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package androidx.media3.common.audio;
|
||||
|
||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.Format;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.common.util.Util;
|
||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
/**
|
||||
* An {@link AudioProcessor} that uses the Sonic library to modify audio speed/pitch/sample rate.
|
||||
*/
|
||||
@UnstableApi
|
||||
public class SonicAudioProcessor implements AudioProcessor {
|
||||
|
||||
/** Indicates that the output sample rate should be the same as the input. */
|
||||
public static final int SAMPLE_RATE_NO_CHANGE = -1;
|
||||
|
||||
/** The threshold below which the difference between two pitch/speed factors is negligible. */
|
||||
private static final float CLOSE_THRESHOLD = 0.0001f;
|
||||
|
||||
/**
|
||||
* The minimum number of output bytes required for duration scaling to be calculated using the
|
||||
* input and output byte counts, rather than using the current playback speed.
|
||||
*/
|
||||
private static final int MIN_BYTES_FOR_DURATION_SCALING_CALCULATION = 1024;
|
||||
|
||||
private int pendingOutputSampleRate;
|
||||
private float speed;
|
||||
private float pitch;
|
||||
|
||||
private AudioFormat pendingInputAudioFormat;
|
||||
private AudioFormat pendingOutputAudioFormat;
|
||||
private AudioFormat inputAudioFormat;
|
||||
private AudioFormat outputAudioFormat;
|
||||
|
||||
private boolean pendingSonicRecreation;
|
||||
@Nullable private Sonic sonic;
|
||||
private ByteBuffer buffer;
|
||||
private ShortBuffer shortBuffer;
|
||||
private ByteBuffer outputBuffer;
|
||||
private long inputBytes;
|
||||
private long outputBytes;
|
||||
private boolean inputEnded;
|
||||
|
||||
/** Creates a new Sonic audio processor. */
|
||||
public SonicAudioProcessor() {
|
||||
speed = 1f;
|
||||
pitch = 1f;
|
||||
pendingInputAudioFormat = AudioFormat.NOT_SET;
|
||||
pendingOutputAudioFormat = AudioFormat.NOT_SET;
|
||||
inputAudioFormat = AudioFormat.NOT_SET;
|
||||
outputAudioFormat = AudioFormat.NOT_SET;
|
||||
buffer = EMPTY_BUFFER;
|
||||
shortBuffer = buffer.asShortBuffer();
|
||||
outputBuffer = EMPTY_BUFFER;
|
||||
pendingOutputSampleRate = SAMPLE_RATE_NO_CHANGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the target playback speed. This method may only be called after draining data through the
|
||||
* processor. The value returned by {@link #isActive()} may change, and the processor must be
|
||||
* {@link #flush() flushed} before queueing more data.
|
||||
*
|
||||
* @param speed The target factor by which playback should be sped up.
|
||||
*/
|
||||
public final void setSpeed(float speed) {
|
||||
if (this.speed != speed) {
|
||||
this.speed = speed;
|
||||
pendingSonicRecreation = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the target playback pitch. This method may only be called after draining data through the
|
||||
* processor. The value returned by {@link #isActive()} may change, and the processor must be
|
||||
* {@link #flush() flushed} before queueing more data.
|
||||
*
|
||||
* @param pitch The target pitch.
|
||||
*/
|
||||
public final void setPitch(float pitch) {
|
||||
if (this.pitch != pitch) {
|
||||
this.pitch = pitch;
|
||||
pendingSonicRecreation = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the sample rate for output audio, in Hertz. Pass {@link #SAMPLE_RATE_NO_CHANGE} to output
|
||||
* audio at the same sample rate as the input. After calling this method, call {@link
|
||||
* #configure(AudioFormat)} to configure the processor with the new sample rate.
|
||||
*
|
||||
* @param sampleRateHz The sample rate for output audio, in Hertz.
|
||||
* @see #configure(AudioFormat)
|
||||
*/
|
||||
public final void setOutputSampleRateHz(int sampleRateHz) {
|
||||
pendingOutputSampleRate = sampleRateHz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the media duration corresponding to the specified playout duration, taking speed
|
||||
* adjustment into account.
|
||||
*
|
||||
* <p>The scaling performed by this method will use the actual playback speed achieved by the
|
||||
* audio processor, on average, since it was last flushed. This may differ very slightly from the
|
||||
* target playback speed.
|
||||
*
|
||||
* @param playoutDuration The playout duration to scale.
|
||||
* @return The corresponding media duration, in the same units as {@code duration}.
|
||||
*/
|
||||
public final long getMediaDuration(long playoutDuration) {
|
||||
if (outputBytes >= MIN_BYTES_FOR_DURATION_SCALING_CALCULATION) {
|
||||
long processedInputBytes = inputBytes - checkNotNull(sonic).getPendingInputBytes();
|
||||
return outputAudioFormat.sampleRate == inputAudioFormat.sampleRate
|
||||
? Util.scaleLargeTimestamp(playoutDuration, processedInputBytes, outputBytes)
|
||||
: Util.scaleLargeTimestamp(
|
||||
playoutDuration,
|
||||
processedInputBytes * outputAudioFormat.sampleRate,
|
||||
outputBytes * inputAudioFormat.sampleRate);
|
||||
} else {
|
||||
return (long) ((double) speed * playoutDuration);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@CanIgnoreReturnValue
|
||||
public final AudioFormat configure(AudioFormat inputAudioFormat)
|
||||
throws UnhandledAudioFormatException {
|
||||
if (inputAudioFormat.encoding != C.ENCODING_PCM_16BIT) {
|
||||
throw new UnhandledAudioFormatException(inputAudioFormat);
|
||||
}
|
||||
int outputSampleRateHz =
|
||||
pendingOutputSampleRate == SAMPLE_RATE_NO_CHANGE
|
||||
? inputAudioFormat.sampleRate
|
||||
: pendingOutputSampleRate;
|
||||
pendingInputAudioFormat = inputAudioFormat;
|
||||
pendingOutputAudioFormat =
|
||||
new AudioFormat(outputSampleRateHz, inputAudioFormat.channelCount, C.ENCODING_PCM_16BIT);
|
||||
pendingSonicRecreation = true;
|
||||
return pendingOutputAudioFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isActive() {
|
||||
return pendingOutputAudioFormat.sampleRate != Format.NO_VALUE
|
||||
&& (Math.abs(speed - 1f) >= CLOSE_THRESHOLD
|
||||
|| Math.abs(pitch - 1f) >= CLOSE_THRESHOLD
|
||||
|| pendingOutputAudioFormat.sampleRate != pendingInputAudioFormat.sampleRate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void queueInput(ByteBuffer inputBuffer) {
|
||||
if (!inputBuffer.hasRemaining()) {
|
||||
return;
|
||||
}
|
||||
Sonic sonic = checkNotNull(this.sonic);
|
||||
ShortBuffer shortBuffer = inputBuffer.asShortBuffer();
|
||||
int inputSize = inputBuffer.remaining();
|
||||
inputBytes += inputSize;
|
||||
sonic.queueInput(shortBuffer);
|
||||
inputBuffer.position(inputBuffer.position() + inputSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void queueEndOfStream() {
|
||||
// TODO(internal b/174554082): assert sonic is non-null here and in getOutput.
|
||||
if (sonic != null) {
|
||||
sonic.queueEndOfStream();
|
||||
}
|
||||
inputEnded = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ByteBuffer getOutput() {
|
||||
@Nullable Sonic sonic = this.sonic;
|
||||
if (sonic != null) {
|
||||
int outputSize = sonic.getOutputSize();
|
||||
if (outputSize > 0) {
|
||||
if (buffer.capacity() < outputSize) {
|
||||
buffer = ByteBuffer.allocateDirect(outputSize).order(ByteOrder.nativeOrder());
|
||||
shortBuffer = buffer.asShortBuffer();
|
||||
} else {
|
||||
buffer.clear();
|
||||
shortBuffer.clear();
|
||||
}
|
||||
sonic.getOutput(shortBuffer);
|
||||
outputBytes += outputSize;
|
||||
buffer.limit(outputSize);
|
||||
outputBuffer = buffer;
|
||||
}
|
||||
}
|
||||
ByteBuffer outputBuffer = this.outputBuffer;
|
||||
this.outputBuffer = EMPTY_BUFFER;
|
||||
return outputBuffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isEnded() {
|
||||
return inputEnded && (sonic == null || sonic.getOutputSize() == 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void flush() {
|
||||
if (isActive()) {
|
||||
inputAudioFormat = pendingInputAudioFormat;
|
||||
outputAudioFormat = pendingOutputAudioFormat;
|
||||
if (pendingSonicRecreation) {
|
||||
sonic =
|
||||
new Sonic(
|
||||
inputAudioFormat.sampleRate,
|
||||
inputAudioFormat.channelCount,
|
||||
speed,
|
||||
pitch,
|
||||
outputAudioFormat.sampleRate);
|
||||
} else if (sonic != null) {
|
||||
sonic.flush();
|
||||
}
|
||||
}
|
||||
outputBuffer = EMPTY_BUFFER;
|
||||
inputBytes = 0;
|
||||
outputBytes = 0;
|
||||
inputEnded = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void reset() {
|
||||
speed = 1f;
|
||||
pitch = 1f;
|
||||
pendingInputAudioFormat = AudioFormat.NOT_SET;
|
||||
pendingOutputAudioFormat = AudioFormat.NOT_SET;
|
||||
inputAudioFormat = AudioFormat.NOT_SET;
|
||||
outputAudioFormat = AudioFormat.NOT_SET;
|
||||
buffer = EMPTY_BUFFER;
|
||||
shortBuffer = buffer.asShortBuffer();
|
||||
outputBuffer = EMPTY_BUFFER;
|
||||
pendingOutputSampleRate = SAMPLE_RATE_NO_CHANGE;
|
||||
pendingSonicRecreation = false;
|
||||
sonic = null;
|
||||
inputBytes = 0;
|
||||
outputBytes = 0;
|
||||
inputEnded = false;
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package androidx.media3.exoplayer.audio;
|
||||
package androidx.media3.common.audio;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.Assert.fail;
|
@ -48,6 +48,7 @@ import androidx.media3.common.PlaybackParameters;
|
||||
import androidx.media3.common.audio.AudioProcessingPipeline;
|
||||
import androidx.media3.common.audio.AudioProcessor;
|
||||
import androidx.media3.common.audio.AudioProcessor.UnhandledAudioFormatException;
|
||||
import androidx.media3.common.audio.SonicAudioProcessor;
|
||||
import androidx.media3.common.audio.ToInt16PcmAudioProcessor;
|
||||
import androidx.media3.common.util.Assertions;
|
||||
import androidx.media3.common.util.Clock;
|
||||
|
@ -15,249 +15,13 @@
|
||||
*/
|
||||
package androidx.media3.exoplayer.audio;
|
||||
|
||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.Format;
|
||||
import androidx.media3.common.audio.AudioProcessor;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.common.util.Util;
|
||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
/**
|
||||
* An {@link AudioProcessor} that uses the Sonic library to modify audio speed/pitch/sample rate.
|
||||
* @deprecated Use {@link androidx.media3.common.audio.SonicAudioProcessor}.
|
||||
*/
|
||||
@Deprecated
|
||||
@UnstableApi
|
||||
public final class SonicAudioProcessor implements AudioProcessor {
|
||||
|
||||
/** Indicates that the output sample rate should be the same as the input. */
|
||||
public static final int SAMPLE_RATE_NO_CHANGE = -1;
|
||||
|
||||
/** The threshold below which the difference between two pitch/speed factors is negligible. */
|
||||
private static final float CLOSE_THRESHOLD = 0.0001f;
|
||||
|
||||
/**
|
||||
* The minimum number of output bytes required for duration scaling to be calculated using the
|
||||
* input and output byte counts, rather than using the current playback speed.
|
||||
*/
|
||||
private static final int MIN_BYTES_FOR_DURATION_SCALING_CALCULATION = 1024;
|
||||
|
||||
private int pendingOutputSampleRate;
|
||||
private float speed;
|
||||
private float pitch;
|
||||
|
||||
private AudioFormat pendingInputAudioFormat;
|
||||
private AudioFormat pendingOutputAudioFormat;
|
||||
private AudioFormat inputAudioFormat;
|
||||
private AudioFormat outputAudioFormat;
|
||||
|
||||
private boolean pendingSonicRecreation;
|
||||
@Nullable private Sonic sonic;
|
||||
private ByteBuffer buffer;
|
||||
private ShortBuffer shortBuffer;
|
||||
private ByteBuffer outputBuffer;
|
||||
private long inputBytes;
|
||||
private long outputBytes;
|
||||
private boolean inputEnded;
|
||||
|
||||
/** Creates a new Sonic audio processor. */
|
||||
public SonicAudioProcessor() {
|
||||
speed = 1f;
|
||||
pitch = 1f;
|
||||
pendingInputAudioFormat = AudioFormat.NOT_SET;
|
||||
pendingOutputAudioFormat = AudioFormat.NOT_SET;
|
||||
inputAudioFormat = AudioFormat.NOT_SET;
|
||||
outputAudioFormat = AudioFormat.NOT_SET;
|
||||
buffer = EMPTY_BUFFER;
|
||||
shortBuffer = buffer.asShortBuffer();
|
||||
outputBuffer = EMPTY_BUFFER;
|
||||
pendingOutputSampleRate = SAMPLE_RATE_NO_CHANGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the target playback speed. This method may only be called after draining data through the
|
||||
* processor. The value returned by {@link #isActive()} may change, and the processor must be
|
||||
* {@link #flush() flushed} before queueing more data.
|
||||
*
|
||||
* @param speed The target factor by which playback should be sped up.
|
||||
*/
|
||||
public void setSpeed(float speed) {
|
||||
if (this.speed != speed) {
|
||||
this.speed = speed;
|
||||
pendingSonicRecreation = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the target playback pitch. This method may only be called after draining data through the
|
||||
* processor. The value returned by {@link #isActive()} may change, and the processor must be
|
||||
* {@link #flush() flushed} before queueing more data.
|
||||
*
|
||||
* @param pitch The target pitch.
|
||||
*/
|
||||
public void setPitch(float pitch) {
|
||||
if (this.pitch != pitch) {
|
||||
this.pitch = pitch;
|
||||
pendingSonicRecreation = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the sample rate for output audio, in Hertz. Pass {@link #SAMPLE_RATE_NO_CHANGE} to output
|
||||
* audio at the same sample rate as the input. After calling this method, call {@link
|
||||
* #configure(AudioFormat)} to configure the processor with the new sample rate.
|
||||
*
|
||||
* @param sampleRateHz The sample rate for output audio, in Hertz.
|
||||
* @see #configure(AudioFormat)
|
||||
*/
|
||||
public void setOutputSampleRateHz(int sampleRateHz) {
|
||||
pendingOutputSampleRate = sampleRateHz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the media duration corresponding to the specified playout duration, taking speed
|
||||
* adjustment into account.
|
||||
*
|
||||
* <p>The scaling performed by this method will use the actual playback speed achieved by the
|
||||
* audio processor, on average, since it was last flushed. This may differ very slightly from the
|
||||
* target playback speed.
|
||||
*
|
||||
* @param playoutDuration The playout duration to scale.
|
||||
* @return The corresponding media duration, in the same units as {@code duration}.
|
||||
*/
|
||||
public long getMediaDuration(long playoutDuration) {
|
||||
if (outputBytes >= MIN_BYTES_FOR_DURATION_SCALING_CALCULATION) {
|
||||
long processedInputBytes = inputBytes - checkNotNull(sonic).getPendingInputBytes();
|
||||
return outputAudioFormat.sampleRate == inputAudioFormat.sampleRate
|
||||
? Util.scaleLargeTimestamp(playoutDuration, processedInputBytes, outputBytes)
|
||||
: Util.scaleLargeTimestamp(
|
||||
playoutDuration,
|
||||
processedInputBytes * outputAudioFormat.sampleRate,
|
||||
outputBytes * inputAudioFormat.sampleRate);
|
||||
} else {
|
||||
return (long) ((double) speed * playoutDuration);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@CanIgnoreReturnValue
|
||||
public AudioFormat configure(AudioFormat inputAudioFormat) throws UnhandledAudioFormatException {
|
||||
if (inputAudioFormat.encoding != C.ENCODING_PCM_16BIT) {
|
||||
throw new UnhandledAudioFormatException(inputAudioFormat);
|
||||
}
|
||||
int outputSampleRateHz =
|
||||
pendingOutputSampleRate == SAMPLE_RATE_NO_CHANGE
|
||||
? inputAudioFormat.sampleRate
|
||||
: pendingOutputSampleRate;
|
||||
pendingInputAudioFormat = inputAudioFormat;
|
||||
pendingOutputAudioFormat =
|
||||
new AudioFormat(outputSampleRateHz, inputAudioFormat.channelCount, C.ENCODING_PCM_16BIT);
|
||||
pendingSonicRecreation = true;
|
||||
return pendingOutputAudioFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return pendingOutputAudioFormat.sampleRate != Format.NO_VALUE
|
||||
&& (Math.abs(speed - 1f) >= CLOSE_THRESHOLD
|
||||
|| Math.abs(pitch - 1f) >= CLOSE_THRESHOLD
|
||||
|| pendingOutputAudioFormat.sampleRate != pendingInputAudioFormat.sampleRate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queueInput(ByteBuffer inputBuffer) {
|
||||
if (!inputBuffer.hasRemaining()) {
|
||||
return;
|
||||
}
|
||||
Sonic sonic = checkNotNull(this.sonic);
|
||||
ShortBuffer shortBuffer = inputBuffer.asShortBuffer();
|
||||
int inputSize = inputBuffer.remaining();
|
||||
inputBytes += inputSize;
|
||||
sonic.queueInput(shortBuffer);
|
||||
inputBuffer.position(inputBuffer.position() + inputSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queueEndOfStream() {
|
||||
// TODO(internal b/174554082): assert sonic is non-null here and in getOutput.
|
||||
if (sonic != null) {
|
||||
sonic.queueEndOfStream();
|
||||
}
|
||||
inputEnded = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer getOutput() {
|
||||
@Nullable Sonic sonic = this.sonic;
|
||||
if (sonic != null) {
|
||||
int outputSize = sonic.getOutputSize();
|
||||
if (outputSize > 0) {
|
||||
if (buffer.capacity() < outputSize) {
|
||||
buffer = ByteBuffer.allocateDirect(outputSize).order(ByteOrder.nativeOrder());
|
||||
shortBuffer = buffer.asShortBuffer();
|
||||
} else {
|
||||
buffer.clear();
|
||||
shortBuffer.clear();
|
||||
}
|
||||
sonic.getOutput(shortBuffer);
|
||||
outputBytes += outputSize;
|
||||
buffer.limit(outputSize);
|
||||
outputBuffer = buffer;
|
||||
}
|
||||
}
|
||||
ByteBuffer outputBuffer = this.outputBuffer;
|
||||
this.outputBuffer = EMPTY_BUFFER;
|
||||
return outputBuffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnded() {
|
||||
return inputEnded && (sonic == null || sonic.getOutputSize() == 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
if (isActive()) {
|
||||
inputAudioFormat = pendingInputAudioFormat;
|
||||
outputAudioFormat = pendingOutputAudioFormat;
|
||||
if (pendingSonicRecreation) {
|
||||
sonic =
|
||||
new Sonic(
|
||||
inputAudioFormat.sampleRate,
|
||||
inputAudioFormat.channelCount,
|
||||
speed,
|
||||
pitch,
|
||||
outputAudioFormat.sampleRate);
|
||||
} else if (sonic != null) {
|
||||
sonic.flush();
|
||||
}
|
||||
}
|
||||
outputBuffer = EMPTY_BUFFER;
|
||||
inputBytes = 0;
|
||||
outputBytes = 0;
|
||||
inputEnded = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
speed = 1f;
|
||||
pitch = 1f;
|
||||
pendingInputAudioFormat = AudioFormat.NOT_SET;
|
||||
pendingOutputAudioFormat = AudioFormat.NOT_SET;
|
||||
inputAudioFormat = AudioFormat.NOT_SET;
|
||||
outputAudioFormat = AudioFormat.NOT_SET;
|
||||
buffer = EMPTY_BUFFER;
|
||||
shortBuffer = buffer.asShortBuffer();
|
||||
outputBuffer = EMPTY_BUFFER;
|
||||
pendingOutputSampleRate = SAMPLE_RATE_NO_CHANGE;
|
||||
pendingSonicRecreation = false;
|
||||
sonic = null;
|
||||
inputBytes = 0;
|
||||
outputBytes = 0;
|
||||
inputEnded = false;
|
||||
}
|
||||
}
|
||||
// TODO(b/261567371): Move `final` from common SonicAudioProcessor method signatures to class
|
||||
// signature when removing this file.
|
||||
public final class SonicAudioProcessor extends androidx.media3.common.audio.SonicAudioProcessor {}
|
||||
|
@ -21,8 +21,8 @@ import static java.lang.Math.min;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.audio.AudioProcessor;
|
||||
import androidx.media3.common.audio.BaseAudioProcessor;
|
||||
import androidx.media3.common.audio.SonicAudioProcessor;
|
||||
import androidx.media3.common.util.Util;
|
||||
import androidx.media3.exoplayer.audio.SonicAudioProcessor;
|
||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
|
@ -34,6 +34,7 @@ import androidx.media3.common.MediaItem;
|
||||
import androidx.media3.common.MediaLibraryInfo;
|
||||
import androidx.media3.common.MimeTypes;
|
||||
import androidx.media3.common.audio.AudioProcessor;
|
||||
import androidx.media3.common.audio.SonicAudioProcessor;
|
||||
import androidx.media3.common.util.Clock;
|
||||
import androidx.media3.common.util.HandlerWrapper;
|
||||
import androidx.media3.common.util.ListenerSet;
|
||||
@ -42,7 +43,6 @@ import androidx.media3.common.util.Util;
|
||||
import androidx.media3.effect.GlEffect;
|
||||
import androidx.media3.effect.GlEffectsFrameProcessor;
|
||||
import androidx.media3.effect.GlMatrixTransformation;
|
||||
import androidx.media3.exoplayer.audio.SonicAudioProcessor;
|
||||
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
|
||||
import androidx.media3.exoplayer.source.MediaSource;
|
||||
import androidx.media3.extractor.DefaultExtractorsFactory;
|
||||
|
@ -46,8 +46,8 @@ import androidx.media3.common.C;
|
||||
import androidx.media3.common.Format;
|
||||
import androidx.media3.common.MediaItem;
|
||||
import androidx.media3.common.MimeTypes;
|
||||
import androidx.media3.common.audio.SonicAudioProcessor;
|
||||
import androidx.media3.common.util.Util;
|
||||
import androidx.media3.exoplayer.audio.SonicAudioProcessor;
|
||||
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
|
||||
import androidx.media3.exoplayer.source.MediaSource;
|
||||
import androidx.media3.extractor.DefaultExtractorsFactory;
|
||||
|
Loading…
x
Reference in New Issue
Block a user