Use BigDecimal as speed parameter for RandomParameterizedSonicTest

This change simplifies conversions to `BigDecimal` and rounding to a set
number of decimal places.

PiperOrigin-RevId: 684890287
This commit is contained in:
ivanbuper 2024-10-11 10:57:03 -07:00 committed by Copybara-Service
parent 98dc7f2def
commit 7e023f915b
2 changed files with 18 additions and 35 deletions

View File

@ -16,7 +16,6 @@
package androidx.media3.common.audio; package androidx.media3.common.audio;
import static androidx.media3.test.utils.TestUtil.generateFloatInRange; import static androidx.media3.test.utils.TestUtil.generateFloatInRange;
import static androidx.media3.test.utils.TestUtil.roundToDecimalPlaces;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static java.lang.Math.max; import static java.lang.Math.max;
@ -96,15 +95,16 @@ public final class RandomParameterizedSonicTest {
*/ */
private static ImmutableList<Object[]> initParams() { private static ImmutableList<Object[]> initParams() {
ImmutableSet.Builder<Object[]> paramsBuilder = new ImmutableSet.Builder<>(); ImmutableSet.Builder<Object[]> paramsBuilder = new ImmutableSet.Builder<>();
ImmutableSet.Builder<Float> speedsBuilder = new ImmutableSet.Builder<>(); ImmutableSet.Builder<BigDecimal> speedsBuilder = new ImmutableSet.Builder<>();
for (int i = 0; i < PARAM_COUNT; i++) { for (int i = 0; i < PARAM_COUNT; i++) {
Range<Float> range = SPEED_RANGES.get(i % SPEED_RANGES.size()); Range<Float> range = SPEED_RANGES.get(i % SPEED_RANGES.size());
speedsBuilder.add( BigDecimal speed =
(float) BigDecimal.valueOf(generateFloatInRange(random, range))
roundToDecimalPlaces(generateFloatInRange(random, range), SPEED_DECIMAL_PRECISION)); .setScale(SPEED_DECIMAL_PRECISION, RoundingMode.HALF_EVEN);
speedsBuilder.add(speed);
} }
ImmutableSet<Float> speeds = speedsBuilder.build(); ImmutableSet<BigDecimal> speeds = speedsBuilder.build();
ImmutableSet<Long> lengths = ImmutableSet<Long> lengths =
new ImmutableSet.Builder<Long>() new ImmutableSet.Builder<Long>()
@ -116,7 +116,7 @@ public final class RandomParameterizedSonicTest {
.iterator()) .iterator())
.build(); .build();
for (long length : lengths) { for (long length : lengths) {
for (float speed : speeds) { for (BigDecimal speed : speeds) {
paramsBuilder.add(new Object[] {speed, length}); paramsBuilder.add(new Object[] {speed, length});
} }
} }
@ -124,7 +124,7 @@ public final class RandomParameterizedSonicTest {
} }
@Parameter(0) @Parameter(0)
public float speed; public BigDecimal speed;
@Parameter(1) @Parameter(1)
public long streamLength; public long streamLength;
@ -138,8 +138,8 @@ public final class RandomParameterizedSonicTest {
new Sonic( new Sonic(
/* inputSampleRateHz= */ SAMPLE_RATE, /* inputSampleRateHz= */ SAMPLE_RATE,
/* channelCount= */ 1, /* channelCount= */ 1,
/* speed= */ speed, /* speed= */ speed.floatValue(),
/* pitch= */ speed, /* pitch= */ speed.floatValue(),
/* outputSampleRateHz= */ SAMPLE_RATE); /* outputSampleRateHz= */ SAMPLE_RATE);
long readSampleCount = 0; long readSampleCount = 0;
@ -164,11 +164,10 @@ public final class RandomParameterizedSonicTest {
sonic.flush(); sonic.flush();
BigDecimal bigSampleRate = new BigDecimal(SAMPLE_RATE); BigDecimal bigSampleRate = new BigDecimal(SAMPLE_RATE);
BigDecimal bigSpeed = new BigDecimal(String.valueOf(speed));
BigDecimal bigLength = new BigDecimal(String.valueOf(streamLength)); BigDecimal bigLength = new BigDecimal(String.valueOf(streamLength));
// The scale of expectedSize will always be equal to bigLength. Thus, the result will always // The scale of expectedSize will be bigLength.scale() - speed.scale(). Thus, the result should
// yield an integer. // always yield an integer.
BigDecimal expectedSize = bigLength.divide(bigSpeed, RoundingMode.HALF_EVEN); BigDecimal expectedSize = bigLength.divide(speed, RoundingMode.HALF_EVEN);
// Calculate number of times that Sonic accumulates truncation error. Set scale to 20 decimal // Calculate number of times that Sonic accumulates truncation error. Set scale to 20 decimal
// places, so that division doesn't return an integral. // places, so that division doesn't return an integral.
@ -179,7 +178,7 @@ public final class RandomParameterizedSonicTest {
// inputSampleRate / speed - (int) inputSampleRate / speed. Set scale to 20 decimal places, so // inputSampleRate / speed - (int) inputSampleRate / speed. Set scale to 20 decimal places, so
// that division doesn't return an integral. // that division doesn't return an integral.
BigDecimal individualError = BigDecimal individualError =
bigSampleRate.divide(bigSpeed, /* scale */ 20, RoundingMode.HALF_EVEN); bigSampleRate.divide(speed, /* scale */ 20, RoundingMode.HALF_EVEN);
individualError = individualError =
individualError.subtract(individualError.setScale(/* newScale= */ 0, RoundingMode.FLOOR)); individualError.subtract(individualError.setScale(/* newScale= */ 0, RoundingMode.FLOOR));
// Calculate total accumulated error = (int) floor(errorCount * individualError). // Calculate total accumulated error = (int) floor(errorCount * individualError).
@ -199,7 +198,7 @@ public final class RandomParameterizedSonicTest {
new Sonic( new Sonic(
/* inputSampleRateHz= */ SAMPLE_RATE, /* inputSampleRateHz= */ SAMPLE_RATE,
/* channelCount= */ 1, /* channelCount= */ 1,
speed, speed.floatValue(),
/* pitch= */ 1, /* pitch= */ 1,
/* outputSampleRateHz= */ SAMPLE_RATE); /* outputSampleRateHz= */ SAMPLE_RATE);
long readSampleCount = 0; long readSampleCount = 0;
@ -221,12 +220,10 @@ public final class RandomParameterizedSonicTest {
} }
sonic.flush(); sonic.flush();
BigDecimal bigSpeed = new BigDecimal(String.valueOf(speed));
BigDecimal bigLength = new BigDecimal(String.valueOf(streamLength)); BigDecimal bigLength = new BigDecimal(String.valueOf(streamLength));
// The scale of expectedSampleCount will always be equal to bigLength. Thus, the result will // The scale of expectedSampleCount will be bigLength.scale() - speed.scale(). Thus, the result
// always // should always yield an integer.
// yield an integer. BigDecimal expectedSampleCount = bigLength.divide(speed, RoundingMode.HALF_EVEN);
BigDecimal expectedSampleCount = bigLength.divide(bigSpeed, RoundingMode.HALF_EVEN);
// Calculate allowed tolerance and round to nearest integer. // Calculate allowed tolerance and round to nearest integer.
BigDecimal allowedTolerance = BigDecimal allowedTolerance =

View File

@ -65,8 +65,6 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
@ -686,18 +684,6 @@ public class TestUtil {
return bottom + random.nextFloat() * (top - bottom); return bottom + random.nextFloat() * (top - bottom);
} }
/**
* Rounds {@code num} to {@code decimalPlaces}, using {@link RoundingMode#HALF_EVEN}.
*
* <p>The number is converted first into a {@link BigDecimal} on which the scale is set to {@code
* decimalPlaces}. Finally, the method returns the {@link BigDecimal#doubleValue()} of the scaled
* big decimal.
*/
public static double roundToDecimalPlaces(double num, int decimalPlaces) {
BigDecimal bigDecimal = new BigDecimal(Double.toString(num));
return bigDecimal.setScale(decimalPlaces, RoundingMode.HALF_EVEN).doubleValue();
}
private static final class NoUidOrShufflingTimeline extends Timeline { private static final class NoUidOrShufflingTimeline extends Timeline {
private final Timeline delegate; private final Timeline delegate;