mirror of
https://github.com/androidx/media.git
synced 2025-05-04 22:20:47 +08:00
Simplify buffer resizing in Sonic
This is in preparation for making it possible to flush a Sonic instance so that it's not necessary to create new ones every time the processor is flushed. There should be no behavior changes here. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=191410326
This commit is contained in:
parent
8b5a34769f
commit
53eae50c0c
@ -41,17 +41,14 @@ import java.util.Arrays;
|
|||||||
private final int maxRequiredFrameCount;
|
private final int maxRequiredFrameCount;
|
||||||
private final short[] downSampleBuffer;
|
private final short[] downSampleBuffer;
|
||||||
|
|
||||||
private int inputBufferSizeFrames;
|
|
||||||
private short[] inputBuffer;
|
private short[] inputBuffer;
|
||||||
private int outputBufferSize;
|
private int inputFrameCount;
|
||||||
private short[] outputBuffer;
|
private short[] outputBuffer;
|
||||||
private int pitchBufferSize;
|
private int outputFrameCount;
|
||||||
private short[] pitchBuffer;
|
private short[] pitchBuffer;
|
||||||
|
private int pitchFrameCount;
|
||||||
private int oldRatePosition;
|
private int oldRatePosition;
|
||||||
private int newRatePosition;
|
private int newRatePosition;
|
||||||
private int inputFrameCount;
|
|
||||||
private int outputFrameCount;
|
|
||||||
private int pitchFrameCount;
|
|
||||||
private int remainingInputToCopyFrameCount;
|
private int remainingInputToCopyFrameCount;
|
||||||
private int prevPeriod;
|
private int prevPeriod;
|
||||||
private int prevMinDiff;
|
private int prevMinDiff;
|
||||||
@ -71,22 +68,16 @@ import java.util.Arrays;
|
|||||||
int inputSampleRateHz, int channelCount, float speed, float pitch, int outputSampleRateHz) {
|
int inputSampleRateHz, int channelCount, float speed, float pitch, int outputSampleRateHz) {
|
||||||
this.inputSampleRateHz = inputSampleRateHz;
|
this.inputSampleRateHz = inputSampleRateHz;
|
||||||
this.channelCount = channelCount;
|
this.channelCount = channelCount;
|
||||||
|
this.speed = speed;
|
||||||
|
this.pitch = pitch;
|
||||||
|
rate = (float) inputSampleRateHz / outputSampleRateHz;
|
||||||
minPeriod = inputSampleRateHz / MAXIMUM_PITCH;
|
minPeriod = inputSampleRateHz / MAXIMUM_PITCH;
|
||||||
maxPeriod = inputSampleRateHz / MINIMUM_PITCH;
|
maxPeriod = inputSampleRateHz / MINIMUM_PITCH;
|
||||||
maxRequiredFrameCount = 2 * maxPeriod;
|
maxRequiredFrameCount = 2 * maxPeriod;
|
||||||
downSampleBuffer = new short[maxRequiredFrameCount];
|
downSampleBuffer = new short[maxRequiredFrameCount];
|
||||||
inputBufferSizeFrames = maxRequiredFrameCount;
|
|
||||||
inputBuffer = new short[maxRequiredFrameCount * channelCount];
|
inputBuffer = new short[maxRequiredFrameCount * channelCount];
|
||||||
outputBufferSize = maxRequiredFrameCount;
|
|
||||||
outputBuffer = new short[maxRequiredFrameCount * channelCount];
|
outputBuffer = new short[maxRequiredFrameCount * channelCount];
|
||||||
pitchBufferSize = maxRequiredFrameCount;
|
|
||||||
pitchBuffer = new short[maxRequiredFrameCount * channelCount];
|
pitchBuffer = new short[maxRequiredFrameCount * channelCount];
|
||||||
oldRatePosition = 0;
|
|
||||||
newRatePosition = 0;
|
|
||||||
prevPeriod = 0;
|
|
||||||
this.speed = speed;
|
|
||||||
this.pitch = pitch;
|
|
||||||
this.rate = (float) inputSampleRateHz / outputSampleRateHz;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,7 +89,7 @@ import java.util.Arrays;
|
|||||||
public void queueInput(ShortBuffer buffer) {
|
public void queueInput(ShortBuffer buffer) {
|
||||||
int framesToWrite = buffer.remaining() / channelCount;
|
int framesToWrite = buffer.remaining() / channelCount;
|
||||||
int bytesToWrite = framesToWrite * channelCount * 2;
|
int bytesToWrite = framesToWrite * channelCount * 2;
|
||||||
enlargeInputBufferIfNeeded(framesToWrite);
|
inputBuffer = ensureSpaceForAdditionalFrames(inputBuffer, inputFrameCount, framesToWrite);
|
||||||
buffer.get(inputBuffer, inputFrameCount * channelCount, bytesToWrite / 2);
|
buffer.get(inputBuffer, inputFrameCount * channelCount, bytesToWrite / 2);
|
||||||
inputFrameCount += framesToWrite;
|
inputFrameCount += framesToWrite;
|
||||||
processStreamInput();
|
processStreamInput();
|
||||||
@ -134,7 +125,9 @@ import java.util.Arrays;
|
|||||||
outputFrameCount + (int) ((remainingFrameCount / s + pitchFrameCount) / r + 0.5f);
|
outputFrameCount + (int) ((remainingFrameCount / s + pitchFrameCount) / r + 0.5f);
|
||||||
|
|
||||||
// Add enough silence to flush both input and pitch buffers.
|
// Add enough silence to flush both input and pitch buffers.
|
||||||
enlargeInputBufferIfNeeded(remainingFrameCount + 2 * maxRequiredFrameCount);
|
inputBuffer =
|
||||||
|
ensureSpaceForAdditionalFrames(
|
||||||
|
inputBuffer, inputFrameCount, remainingFrameCount + 2 * maxRequiredFrameCount);
|
||||||
for (int xSample = 0; xSample < 2 * maxRequiredFrameCount * channelCount; xSample++) {
|
for (int xSample = 0; xSample < 2 * maxRequiredFrameCount * channelCount; xSample++) {
|
||||||
inputBuffer[remainingFrameCount * channelCount + xSample] = 0;
|
inputBuffer[remainingFrameCount * channelCount + xSample] = 0;
|
||||||
}
|
}
|
||||||
@ -157,17 +150,24 @@ import java.util.Arrays;
|
|||||||
|
|
||||||
// Internal methods.
|
// Internal methods.
|
||||||
|
|
||||||
private void enlargeOutputBufferIfNeeded(int frameCount) {
|
/**
|
||||||
if (outputFrameCount + frameCount > outputBufferSize) {
|
* Returns {@code buffer} or a copy of it, such that there is enough space in the returned buffer
|
||||||
outputBufferSize += (outputBufferSize / 2) + frameCount;
|
* to store {@code newFrameCount} additional frames.
|
||||||
outputBuffer = Arrays.copyOf(outputBuffer, outputBufferSize * channelCount);
|
*
|
||||||
}
|
* @param buffer The buffer.
|
||||||
}
|
* @param frameCount The number of frames already in the buffer.
|
||||||
|
* @param additionalFrameCount The number of additional frames that need to be stored in the
|
||||||
private void enlargeInputBufferIfNeeded(int frameCount) {
|
* buffer.
|
||||||
if (inputFrameCount + frameCount > inputBufferSizeFrames) {
|
* @return A buffer with enough space for the additional frames.
|
||||||
inputBufferSizeFrames += (inputBufferSizeFrames / 2) + frameCount;
|
*/
|
||||||
inputBuffer = Arrays.copyOf(inputBuffer, inputBufferSizeFrames * channelCount);
|
private short[] ensureSpaceForAdditionalFrames(
|
||||||
|
short[] buffer, int frameCount, int additionalFrameCount) {
|
||||||
|
int currentCapacityFrames = buffer.length / channelCount;
|
||||||
|
if (frameCount + additionalFrameCount <= currentCapacityFrames) {
|
||||||
|
return buffer;
|
||||||
|
} else {
|
||||||
|
int newCapacityFrames = 3 * currentCapacityFrames / 2 + additionalFrameCount;
|
||||||
|
return Arrays.copyOf(buffer, newCapacityFrames * channelCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +179,7 @@ import java.util.Arrays;
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void copyToOutput(short[] samples, int positionFrames, int frameCount) {
|
private void copyToOutput(short[] samples, int positionFrames, int frameCount) {
|
||||||
enlargeOutputBufferIfNeeded(frameCount);
|
outputBuffer = ensureSpaceForAdditionalFrames(outputBuffer, outputFrameCount, frameCount);
|
||||||
System.arraycopy(
|
System.arraycopy(
|
||||||
samples,
|
samples,
|
||||||
positionFrames * channelCount,
|
positionFrames * channelCount,
|
||||||
@ -306,10 +306,7 @@ import java.util.Arrays;
|
|||||||
|
|
||||||
private void moveNewSamplesToPitchBuffer(int originalOutputFrameCount) {
|
private void moveNewSamplesToPitchBuffer(int originalOutputFrameCount) {
|
||||||
int frameCount = outputFrameCount - originalOutputFrameCount;
|
int frameCount = outputFrameCount - originalOutputFrameCount;
|
||||||
if (pitchFrameCount + frameCount > pitchBufferSize) {
|
pitchBuffer = ensureSpaceForAdditionalFrames(pitchBuffer, pitchFrameCount, frameCount);
|
||||||
pitchBufferSize += (pitchBufferSize / 2) + frameCount;
|
|
||||||
pitchBuffer = Arrays.copyOf(pitchBuffer, pitchBufferSize * channelCount);
|
|
||||||
}
|
|
||||||
System.arraycopy(
|
System.arraycopy(
|
||||||
outputBuffer,
|
outputBuffer,
|
||||||
originalOutputFrameCount * channelCount,
|
originalOutputFrameCount * channelCount,
|
||||||
@ -359,7 +356,9 @@ import java.util.Arrays;
|
|||||||
// Leave at least one pitch sample in the buffer.
|
// Leave at least one pitch sample in the buffer.
|
||||||
for (int position = 0; position < pitchFrameCount - 1; position++) {
|
for (int position = 0; position < pitchFrameCount - 1; position++) {
|
||||||
while ((oldRatePosition + 1) * newSampleRate > newRatePosition * oldSampleRate) {
|
while ((oldRatePosition + 1) * newSampleRate > newRatePosition * oldSampleRate) {
|
||||||
enlargeOutputBufferIfNeeded(1);
|
outputBuffer =
|
||||||
|
ensureSpaceForAdditionalFrames(
|
||||||
|
outputBuffer, outputFrameCount, /* additionalFrameCount= */ 1);
|
||||||
for (int i = 0; i < channelCount; i++) {
|
for (int i = 0; i < channelCount; i++) {
|
||||||
outputBuffer[outputFrameCount * channelCount + i] =
|
outputBuffer[outputFrameCount * channelCount + i] =
|
||||||
interpolate(pitchBuffer, position * channelCount + i, oldSampleRate, newSampleRate);
|
interpolate(pitchBuffer, position * channelCount + i, oldSampleRate, newSampleRate);
|
||||||
@ -386,7 +385,7 @@ import java.util.Arrays;
|
|||||||
newFrameCount = period;
|
newFrameCount = period;
|
||||||
remainingInputToCopyFrameCount = (int) (period * (2.0f - speed) / (speed - 1.0f));
|
remainingInputToCopyFrameCount = (int) (period * (2.0f - speed) / (speed - 1.0f));
|
||||||
}
|
}
|
||||||
enlargeOutputBufferIfNeeded(newFrameCount);
|
outputBuffer = ensureSpaceForAdditionalFrames(outputBuffer, outputFrameCount, newFrameCount);
|
||||||
overlapAdd(
|
overlapAdd(
|
||||||
newFrameCount,
|
newFrameCount,
|
||||||
channelCount,
|
channelCount,
|
||||||
@ -409,7 +408,8 @@ import java.util.Arrays;
|
|||||||
newFrameCount = period;
|
newFrameCount = period;
|
||||||
remainingInputToCopyFrameCount = (int) (period * (2.0f * speed - 1.0f) / (1.0f - speed));
|
remainingInputToCopyFrameCount = (int) (period * (2.0f * speed - 1.0f) / (1.0f - speed));
|
||||||
}
|
}
|
||||||
enlargeOutputBufferIfNeeded(period + newFrameCount);
|
outputBuffer =
|
||||||
|
ensureSpaceForAdditionalFrames(outputBuffer, outputFrameCount, period + newFrameCount);
|
||||||
System.arraycopy(
|
System.arraycopy(
|
||||||
samples,
|
samples,
|
||||||
position * channelCount,
|
position * channelCount,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user