mirror of
https://github.com/samsonjs/media.git
synced 2026-03-31 10:25:48 +00:00
Scale AudioTrack buffer size for AudioTrack speed adjustment
PiperOrigin-RevId: 326642908
This commit is contained in:
parent
eabc486b58
commit
977f0d1ed0
2 changed files with 31 additions and 30 deletions
|
|
@ -191,6 +191,16 @@ public final class DefaultAudioSink implements AudioSink {
|
|||
}
|
||||
}
|
||||
|
||||
/** The default playback speed. */
|
||||
public static final float DEFAULT_PLAYBACK_SPEED = 1f;
|
||||
/** The minimum allowed playback speed. Lower values will be constrained to fall in range. */
|
||||
public static final float MIN_PLAYBACK_SPEED = 0.1f;
|
||||
/** The maximum allowed playback speed. Higher values will be constrained to fall in range. */
|
||||
public static final float MAX_PLAYBACK_SPEED = 8f;
|
||||
|
||||
/** The default skip silence flag. */
|
||||
private static final boolean DEFAULT_SKIP_SILENCE = false;
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({OUTPUT_MODE_PCM, OUTPUT_MODE_OFFLOAD, OUTPUT_MODE_PASSTHROUGH})
|
||||
|
|
@ -210,11 +220,10 @@ public final class DefaultAudioSink implements AudioSink {
|
|||
private static final long OFFLOAD_BUFFER_DURATION_US = 50_000_000;
|
||||
|
||||
/**
|
||||
* A multiplication factor to apply to the minimum buffer size requested by the underlying
|
||||
* {@link AudioTrack}.
|
||||
* A multiplication factor to apply to the minimum buffer size requested by the underlying {@link
|
||||
* AudioTrack}.
|
||||
*/
|
||||
private static final int BUFFER_MULTIPLICATION_FACTOR = 4;
|
||||
|
||||
/** To avoid underruns on some devices (e.g., Broadcom 7271), scale up the AC3 buffer duration. */
|
||||
private static final int AC3_BUFFER_MULTIPLICATION_FACTOR = 2;
|
||||
|
||||
|
|
@ -239,10 +248,6 @@ public final class DefaultAudioSink implements AudioSink {
|
|||
*/
|
||||
@SuppressLint("InlinedApi")
|
||||
private static final int WRITE_NON_BLOCKING = AudioTrack.WRITE_NON_BLOCKING;
|
||||
/** The default playback speed. */
|
||||
private static final float DEFAULT_PLAYBACK_SPEED = 1f;
|
||||
/** The default skip silence flag. */
|
||||
private static final boolean DEFAULT_SKIP_SILENCE = false;
|
||||
|
||||
private static final String TAG = "AudioTrack";
|
||||
|
||||
|
|
@ -582,6 +587,7 @@ public final class DefaultAudioSink implements AudioSink {
|
|||
outputChannelConfig,
|
||||
outputEncoding,
|
||||
specifiedBufferSize,
|
||||
enableAudioTrackPlaybackParams,
|
||||
canApplyPlaybackParameters,
|
||||
availableAudioProcessors);
|
||||
if (isAudioTrackInitialized()) {
|
||||
|
|
@ -1007,6 +1013,7 @@ public final class DefaultAudioSink implements AudioSink {
|
|||
|
||||
@Override
|
||||
public void setPlaybackSpeed(float playbackSpeed) {
|
||||
playbackSpeed = Util.constrainValue(playbackSpeed, MIN_PLAYBACK_SPEED, MAX_PLAYBACK_SPEED);
|
||||
if (enableAudioTrackPlaybackParams && Util.SDK_INT >= 23) {
|
||||
setAudioTrackPlaybackSpeedV23(playbackSpeed);
|
||||
} else {
|
||||
|
|
@ -1802,6 +1809,7 @@ public final class DefaultAudioSink implements AudioSink {
|
|||
int outputChannelConfig,
|
||||
int outputEncoding,
|
||||
int specifiedBufferSize,
|
||||
boolean enableAudioTrackPlaybackParams,
|
||||
boolean canApplyPlaybackParameters,
|
||||
AudioProcessor[] availableAudioProcessors) {
|
||||
this.inputFormat = inputFormat;
|
||||
|
|
@ -1815,7 +1823,7 @@ public final class DefaultAudioSink implements AudioSink {
|
|||
this.availableAudioProcessors = availableAudioProcessors;
|
||||
|
||||
// Call computeBufferSize() last as it depends on the other configuration values.
|
||||
this.bufferSize = computeBufferSize(specifiedBufferSize);
|
||||
this.bufferSize = computeBufferSize(specifiedBufferSize, enableAudioTrackPlaybackParams);
|
||||
}
|
||||
|
||||
/** Returns if the configurations are sufficiently compatible to reuse the audio track. */
|
||||
|
|
@ -1925,13 +1933,15 @@ public final class DefaultAudioSink implements AudioSink {
|
|||
}
|
||||
}
|
||||
|
||||
private int computeBufferSize(int specifiedBufferSize) {
|
||||
private int computeBufferSize(
|
||||
int specifiedBufferSize, boolean enableAudioTrackPlaybackParameters) {
|
||||
if (specifiedBufferSize != 0) {
|
||||
return specifiedBufferSize;
|
||||
}
|
||||
switch (outputMode) {
|
||||
case OUTPUT_MODE_PCM:
|
||||
return getPcmDefaultBufferSize();
|
||||
return getPcmDefaultBufferSize(
|
||||
enableAudioTrackPlaybackParameters ? MAX_PLAYBACK_SPEED : DEFAULT_PLAYBACK_SPEED);
|
||||
case OUTPUT_MODE_OFFLOAD:
|
||||
return getEncodedDefaultBufferSize(OFFLOAD_BUFFER_DURATION_US);
|
||||
case OUTPUT_MODE_PASSTHROUGH:
|
||||
|
|
@ -1949,7 +1959,7 @@ public final class DefaultAudioSink implements AudioSink {
|
|||
return (int) (bufferDurationUs * rate / C.MICROS_PER_SECOND);
|
||||
}
|
||||
|
||||
private int getPcmDefaultBufferSize() {
|
||||
private int getPcmDefaultBufferSize(float maxAudioTrackPlaybackSpeed) {
|
||||
int minBufferSize =
|
||||
AudioTrack.getMinBufferSize(outputSampleRate, outputChannelConfig, outputEncoding);
|
||||
Assertions.checkState(minBufferSize != ERROR_BAD_VALUE);
|
||||
|
|
@ -1957,7 +1967,13 @@ public final class DefaultAudioSink implements AudioSink {
|
|||
int minAppBufferSize = (int) durationUsToFrames(MIN_BUFFER_DURATION_US) * outputPcmFrameSize;
|
||||
int maxAppBufferSize =
|
||||
max(minBufferSize, (int) durationUsToFrames(MAX_BUFFER_DURATION_US) * outputPcmFrameSize);
|
||||
return Util.constrainValue(multipliedBufferSize, minAppBufferSize, maxAppBufferSize);
|
||||
int bufferSize =
|
||||
Util.constrainValue(multipliedBufferSize, minAppBufferSize, maxAppBufferSize);
|
||||
if (maxAudioTrackPlaybackSpeed != 1f) {
|
||||
// Maintain the buffer duration by scaling the size accordingly.
|
||||
bufferSize = Math.round(bufferSize * maxAudioTrackPlaybackSpeed);
|
||||
}
|
||||
return bufferSize;
|
||||
}
|
||||
|
||||
@RequiresApi(21)
|
||||
|
|
|
|||
|
|
@ -29,22 +29,10 @@ import java.nio.ShortBuffer;
|
|||
*/
|
||||
public final class SonicAudioProcessor implements AudioProcessor {
|
||||
|
||||
/**
|
||||
* The maximum allowed playback speed in {@link #setSpeed(float)}.
|
||||
*/
|
||||
public static final float MAXIMUM_SPEED = 8.0f;
|
||||
/**
|
||||
* The minimum allowed playback speed in {@link #setSpeed(float)}.
|
||||
*/
|
||||
public static final float MINIMUM_SPEED = 0.1f;
|
||||
/**
|
||||
* Indicates that the output sample rate should be the same as the input.
|
||||
*/
|
||||
/** 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.
|
||||
*/
|
||||
/** The threshold below which the difference between two pitch/speed factors is negligible. */
|
||||
private static final float CLOSE_THRESHOLD = 0.01f;
|
||||
|
||||
/**
|
||||
|
|
@ -70,9 +58,7 @@ public final class SonicAudioProcessor implements AudioProcessor {
|
|||
private long outputBytes;
|
||||
private boolean inputEnded;
|
||||
|
||||
/**
|
||||
* Creates a new Sonic audio processor.
|
||||
*/
|
||||
/** Creates a new Sonic audio processor. */
|
||||
public SonicAudioProcessor() {
|
||||
speed = 1f;
|
||||
pendingInputAudioFormat = AudioFormat.NOT_SET;
|
||||
|
|
@ -94,7 +80,6 @@ public final class SonicAudioProcessor implements AudioProcessor {
|
|||
* @return The actual new playback speed.
|
||||
*/
|
||||
public float setSpeed(float speed) {
|
||||
speed = Util.constrainValue(speed, MINIMUM_SPEED, MAXIMUM_SPEED);
|
||||
if (this.speed != speed) {
|
||||
this.speed = speed;
|
||||
pendingSonicRecreation = true;
|
||||
|
|
|
|||
Loading…
Reference in a new issue