Add check for isIdentity in ChannelMappingMatrix.
Make clearer the intermediate matrix property names. PiperOrigin-RevId: 505732563
This commit is contained in:
parent
4a9cf7d069
commit
ff56b7d294
@ -49,6 +49,7 @@ import static androidx.media3.common.util.Assertions.checkArgument;
|
|||||||
private final float[] coefficients;
|
private final float[] coefficients;
|
||||||
private final boolean isZero;
|
private final boolean isZero;
|
||||||
private final boolean isDiagonal;
|
private final boolean isDiagonal;
|
||||||
|
private final boolean isIdentity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a standard channel mixing matrix that converts from {@code inputChannelCount} channels
|
* Creates a standard channel mixing matrix that converts from {@code inputChannelCount} channels
|
||||||
@ -71,31 +72,6 @@ import static androidx.media3.common.util.Assertions.checkArgument;
|
|||||||
createMixingCoefficients(inputChannelCount, outputChannelCount));
|
createMixingCoefficients(inputChannelCount, outputChannelCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float[] createMixingCoefficients(int inputChannelCount, int outputChannelCount) {
|
|
||||||
if (inputChannelCount == outputChannelCount) {
|
|
||||||
int channelCount = inputChannelCount;
|
|
||||||
float[] coefficients = new float[channelCount * channelCount];
|
|
||||||
for (int c = 0; c < channelCount; c++) {
|
|
||||||
coefficients[channelCount * c + c] = 1f;
|
|
||||||
}
|
|
||||||
return coefficients;
|
|
||||||
}
|
|
||||||
if (inputChannelCount == 1 && outputChannelCount == 2) {
|
|
||||||
// Mono -> stereo.
|
|
||||||
return new float[] {1f, 1f};
|
|
||||||
}
|
|
||||||
if (inputChannelCount == 2 && outputChannelCount == 1) {
|
|
||||||
// Stereo -> mono.
|
|
||||||
return new float[] {0.5f, 0.5f};
|
|
||||||
}
|
|
||||||
throw new UnsupportedOperationException(
|
|
||||||
"Default channel mixing coefficients for "
|
|
||||||
+ inputChannelCount
|
|
||||||
+ "->"
|
|
||||||
+ outputChannelCount
|
|
||||||
+ " are not yet implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a matrix with the given coefficients in row-major order.
|
* Creates a matrix with the given coefficients in row-major order.
|
||||||
*
|
*
|
||||||
@ -114,20 +90,28 @@ import static androidx.media3.common.util.Assertions.checkArgument;
|
|||||||
this.coefficients = checkCoefficientsValid(coefficients);
|
this.coefficients = checkCoefficientsValid(coefficients);
|
||||||
|
|
||||||
// Calculate matrix properties.
|
// Calculate matrix properties.
|
||||||
boolean hasNonZero = false;
|
boolean allDiagonalCoefficientsAreOne = true;
|
||||||
boolean hasNonZeroOutOfDiagonal = false;
|
boolean allCoefficientsAreZero = true;
|
||||||
for (int i = 0; i < inputChannelCount; i++) {
|
boolean allNonDiagonalCoefficientsAreZero = true;
|
||||||
for (int o = 0; o < outputChannelCount; o++) {
|
for (int row = 0; row < inputChannelCount; row++) {
|
||||||
if (getMixingCoefficient(i, o) != 0f) {
|
for (int col = 0; col < outputChannelCount; col++) {
|
||||||
hasNonZero = true;
|
float coefficient = getMixingCoefficient(row, col);
|
||||||
if (i != o) {
|
boolean onDiagonal = row == col;
|
||||||
hasNonZeroOutOfDiagonal = true;
|
|
||||||
|
if (coefficient != 1f && onDiagonal) {
|
||||||
|
allDiagonalCoefficientsAreOne = false;
|
||||||
|
}
|
||||||
|
if (coefficient != 0f) {
|
||||||
|
allCoefficientsAreZero = false;
|
||||||
|
if (!onDiagonal) {
|
||||||
|
allNonDiagonalCoefficientsAreZero = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isZero = !hasNonZero;
|
isZero = allCoefficientsAreZero;
|
||||||
isDiagonal = isSquare() && !hasNonZeroOutOfDiagonal;
|
isDiagonal = isSquare() && allNonDiagonalCoefficientsAreZero;
|
||||||
|
isIdentity = isDiagonal && allDiagonalCoefficientsAreOne;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInputChannelCount() {
|
public int getInputChannelCount() {
|
||||||
@ -158,6 +142,11 @@ import static androidx.media3.common.util.Assertions.checkArgument;
|
|||||||
return isDiagonal;
|
return isDiagonal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns whether this is an identity matrix. */
|
||||||
|
public boolean isIdentity() {
|
||||||
|
return isIdentity;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns a new matrix with the given scaling factor applied to all coefficients. */
|
/** Returns a new matrix with the given scaling factor applied to all coefficients. */
|
||||||
public ChannelMixingMatrix scaleBy(float scale) {
|
public ChannelMixingMatrix scaleBy(float scale) {
|
||||||
float[] scaledCoefficients = new float[coefficients.length];
|
float[] scaledCoefficients = new float[coefficients.length];
|
||||||
@ -167,6 +156,34 @@ import static androidx.media3.common.util.Assertions.checkArgument;
|
|||||||
return new ChannelMixingMatrix(inputChannelCount, outputChannelCount, scaledCoefficients);
|
return new ChannelMixingMatrix(inputChannelCount, outputChannelCount, scaledCoefficients);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static float[] createMixingCoefficients(int inputChannelCount, int outputChannelCount) {
|
||||||
|
if (inputChannelCount == outputChannelCount) {
|
||||||
|
return initializeIdentityMatrix(outputChannelCount);
|
||||||
|
}
|
||||||
|
if (inputChannelCount == 1 && outputChannelCount == 2) {
|
||||||
|
// Mono -> stereo.
|
||||||
|
return new float[] {1f, 1f};
|
||||||
|
}
|
||||||
|
if (inputChannelCount == 2 && outputChannelCount == 1) {
|
||||||
|
// Stereo -> mono.
|
||||||
|
return new float[] {0.5f, 0.5f};
|
||||||
|
}
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"Default channel mixing coefficients for "
|
||||||
|
+ inputChannelCount
|
||||||
|
+ "->"
|
||||||
|
+ outputChannelCount
|
||||||
|
+ " are not yet implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float[] initializeIdentityMatrix(int channelCount) {
|
||||||
|
float[] coefficients = new float[channelCount * channelCount];
|
||||||
|
for (int c = 0; c < channelCount; c++) {
|
||||||
|
coefficients[channelCount * c + c] = 1f;
|
||||||
|
}
|
||||||
|
return coefficients;
|
||||||
|
}
|
||||||
|
|
||||||
private static float[] checkCoefficientsValid(float[] coefficients) {
|
private static float[] checkCoefficientsValid(float[] coefficients) {
|
||||||
for (int i = 0; i < coefficients.length; i++) {
|
for (int i = 0; i < coefficients.length; i++) {
|
||||||
if (coefficients[i] < 0f) {
|
if (coefficients[i] < 0f) {
|
||||||
|
@ -25,6 +25,51 @@ import org.junit.runner.RunWith;
|
|||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
public class ChannelMixingMatrixTest {
|
public class ChannelMixingMatrixTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onesOnDiagonal_1To1_hasCorrectProperties() {
|
||||||
|
int inputCount = 1;
|
||||||
|
int outputCount = 1;
|
||||||
|
float[] coefficients = new float[] {1f};
|
||||||
|
ChannelMixingMatrix matrix = new ChannelMixingMatrix(inputCount, outputCount, coefficients);
|
||||||
|
assertThat(matrix.isZero()).isFalse();
|
||||||
|
assertThat(matrix.isSquare()).isTrue();
|
||||||
|
assertThat(matrix.isDiagonal()).isTrue();
|
||||||
|
assertThat(matrix.isIdentity()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onesOnDiagonal_2To3_hasCorrectProperties() {
|
||||||
|
int inputCount = 2;
|
||||||
|
int outputCount = 3;
|
||||||
|
float[] coefficients =
|
||||||
|
new float[] {
|
||||||
|
1f, 0f, 0f,
|
||||||
|
0f, 1f, 0f,
|
||||||
|
};
|
||||||
|
ChannelMixingMatrix matrix = new ChannelMixingMatrix(inputCount, outputCount, coefficients);
|
||||||
|
assertThat(matrix.isZero()).isFalse();
|
||||||
|
assertThat(matrix.isSquare()).isFalse();
|
||||||
|
assertThat(matrix.isDiagonal()).isFalse();
|
||||||
|
assertThat(matrix.isIdentity()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onesOnDiagonal_3To3_hasCorrectProperties() {
|
||||||
|
int inputCount = 3;
|
||||||
|
int outputCount = 3;
|
||||||
|
float[] coefficients =
|
||||||
|
new float[] {
|
||||||
|
1f, 0f, 0f,
|
||||||
|
0f, 1f, 0f,
|
||||||
|
0f, 0f, 1f
|
||||||
|
};
|
||||||
|
ChannelMixingMatrix matrix = new ChannelMixingMatrix(inputCount, outputCount, coefficients);
|
||||||
|
assertThat(matrix.isZero()).isFalse();
|
||||||
|
assertThat(matrix.isSquare()).isTrue();
|
||||||
|
assertThat(matrix.isDiagonal()).isTrue();
|
||||||
|
assertThat(matrix.isIdentity()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void allZeroValues_3To2_hasCorrectProperties() {
|
public void allZeroValues_3To2_hasCorrectProperties() {
|
||||||
int inputCount = 3;
|
int inputCount = 3;
|
||||||
@ -40,6 +85,7 @@ public class ChannelMixingMatrixTest {
|
|||||||
assertThat(matrix.isZero()).isTrue();
|
assertThat(matrix.isZero()).isTrue();
|
||||||
assertThat(matrix.isSquare()).isFalse();
|
assertThat(matrix.isSquare()).isFalse();
|
||||||
assertThat(matrix.isDiagonal()).isFalse();
|
assertThat(matrix.isDiagonal()).isFalse();
|
||||||
|
assertThat(matrix.isIdentity()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -57,6 +103,7 @@ public class ChannelMixingMatrixTest {
|
|||||||
assertThat(matrix.isZero()).isTrue();
|
assertThat(matrix.isZero()).isTrue();
|
||||||
assertThat(matrix.isSquare()).isTrue();
|
assertThat(matrix.isSquare()).isTrue();
|
||||||
assertThat(matrix.isDiagonal()).isTrue();
|
assertThat(matrix.isDiagonal()).isTrue();
|
||||||
|
assertThat(matrix.isIdentity()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -74,6 +121,7 @@ public class ChannelMixingMatrixTest {
|
|||||||
assertThat(matrix.isZero()).isTrue();
|
assertThat(matrix.isZero()).isTrue();
|
||||||
assertThat(matrix.isSquare()).isFalse();
|
assertThat(matrix.isSquare()).isFalse();
|
||||||
assertThat(matrix.isDiagonal()).isFalse();
|
assertThat(matrix.isDiagonal()).isFalse();
|
||||||
|
assertThat(matrix.isIdentity()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -91,6 +139,7 @@ public class ChannelMixingMatrixTest {
|
|||||||
assertThat(matrix.isZero()).isFalse();
|
assertThat(matrix.isZero()).isFalse();
|
||||||
assertThat(matrix.isSquare()).isFalse();
|
assertThat(matrix.isSquare()).isFalse();
|
||||||
assertThat(matrix.isDiagonal()).isFalse();
|
assertThat(matrix.isDiagonal()).isFalse();
|
||||||
|
assertThat(matrix.isIdentity()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -107,6 +156,7 @@ public class ChannelMixingMatrixTest {
|
|||||||
assertThat(matrix.isZero()).isFalse();
|
assertThat(matrix.isZero()).isFalse();
|
||||||
assertThat(matrix.isSquare()).isTrue();
|
assertThat(matrix.isSquare()).isTrue();
|
||||||
assertThat(matrix.isDiagonal()).isFalse();
|
assertThat(matrix.isDiagonal()).isFalse();
|
||||||
|
assertThat(matrix.isIdentity()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -125,6 +175,7 @@ public class ChannelMixingMatrixTest {
|
|||||||
assertThat(matrix.isZero()).isFalse();
|
assertThat(matrix.isZero()).isFalse();
|
||||||
assertThat(matrix.isSquare()).isTrue();
|
assertThat(matrix.isSquare()).isTrue();
|
||||||
assertThat(matrix.isDiagonal()).isTrue();
|
assertThat(matrix.isDiagonal()).isTrue();
|
||||||
|
assertThat(matrix.isIdentity()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -141,5 +192,6 @@ public class ChannelMixingMatrixTest {
|
|||||||
assertThat(matrix.isZero()).isFalse();
|
assertThat(matrix.isZero()).isFalse();
|
||||||
assertThat(matrix.isSquare()).isFalse();
|
assertThat(matrix.isSquare()).isFalse();
|
||||||
assertThat(matrix.isDiagonal()).isFalse();
|
assertThat(matrix.isDiagonal()).isFalse();
|
||||||
|
assertThat(matrix.isIdentity()).isFalse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user