mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-24 01:04:02 +02:00
Add some channel routing tests.
This commit is contained in:
+151
-4
@@ -1261,12 +1261,13 @@ int do_format_converter_tests()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mal_uint32 channel_router_callback__passthrough_test(mal_channel_router* pRouter, mal_uint32 frameCount, void** ppSamplesOut, void* pUserData)
|
mal_uint32 channel_router_callback__passthrough_test(mal_channel_router* pRouter, mal_uint32 frameCount, void** ppSamplesOut, void* pUserData)
|
||||||
{
|
{
|
||||||
(void)pUserData;
|
float** ppSamplesIn = (float**)pUserData;
|
||||||
|
|
||||||
for (mal_uint32 iChannel = 0; iChannel < pRouter->config.channelsIn; ++iChannel) {
|
for (mal_uint32 iChannel = 0; iChannel < pRouter->config.channelsIn; ++iChannel) {
|
||||||
mal_zero_memory(ppSamplesOut[iChannel], sizeof(float)*frameCount);
|
mal_copy_memory(ppSamplesOut[iChannel], ppSamplesIn[iChannel], frameCount*sizeof(float));
|
||||||
}
|
}
|
||||||
|
|
||||||
return frameCount;
|
return frameCount;
|
||||||
@@ -1282,11 +1283,10 @@ int do_channel_routing_tests()
|
|||||||
mal_zero_object(&routerConfig);
|
mal_zero_object(&routerConfig);
|
||||||
routerConfig.mixingMode = mal_channel_mix_mode_planar_blend;
|
routerConfig.mixingMode = mal_channel_mix_mode_planar_blend;
|
||||||
routerConfig.channelsIn = 6;
|
routerConfig.channelsIn = 6;
|
||||||
routerConfig.channelsOut = 6;
|
routerConfig.channelsOut = routerConfig.channelsIn;
|
||||||
mal_get_standard_channel_map(mal_standard_channel_map_microsoft, routerConfig.channelsIn, routerConfig.channelMapIn);
|
mal_get_standard_channel_map(mal_standard_channel_map_microsoft, routerConfig.channelsIn, routerConfig.channelMapIn);
|
||||||
mal_get_standard_channel_map(mal_standard_channel_map_microsoft, routerConfig.channelsOut, routerConfig.channelMapOut);
|
mal_get_standard_channel_map(mal_standard_channel_map_microsoft, routerConfig.channelsOut, routerConfig.channelMapOut);
|
||||||
|
|
||||||
|
|
||||||
mal_channel_router router;
|
mal_channel_router router;
|
||||||
mal_result result = mal_channel_router_init_separated(&routerConfig, channel_router_callback__passthrough_test, NULL, &router);
|
mal_result result = mal_channel_router_init_separated(&routerConfig, channel_router_callback__passthrough_test, NULL, &router);
|
||||||
if (result == MAL_SUCCESS) {
|
if (result == MAL_SUCCESS) {
|
||||||
@@ -1314,6 +1314,57 @@ int do_channel_routing_tests()
|
|||||||
hasError = MAL_TRUE;
|
hasError = MAL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Here is where we check that the passthrough optimization works correctly. What we do is compare the output of the passthrough
|
||||||
|
// optimization with the non-passthrough output. We don't use a real sound here, but instead use values that makes it easier for
|
||||||
|
// us to check results. Each channel is given a value equal to it's index, plus 1.
|
||||||
|
float testData[MAL_MAX_CHANNELS][100];
|
||||||
|
float* ppTestData[MAL_MAX_CHANNELS];
|
||||||
|
for (mal_uint32 iChannel = 0; iChannel < routerConfig.channelsIn; ++iChannel) {
|
||||||
|
ppTestData[iChannel] = testData[iChannel];
|
||||||
|
for (mal_uint32 iFrame = 0; iFrame < 100; ++iFrame) {
|
||||||
|
ppTestData[iChannel][iFrame] = (float)(iChannel + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mal_channel_router_init_separated(&routerConfig, channel_router_callback__passthrough_test, ppTestData, &router);
|
||||||
|
|
||||||
|
float outputA[MAL_MAX_CHANNELS][100];
|
||||||
|
float outputB[MAL_MAX_CHANNELS][100];
|
||||||
|
float* ppOutputA[MAL_MAX_CHANNELS];
|
||||||
|
float* ppOutputB[MAL_MAX_CHANNELS];
|
||||||
|
for (mal_uint32 iChannel = 0; iChannel < routerConfig.channelsOut; ++iChannel) {
|
||||||
|
ppOutputA[iChannel] = outputA[iChannel];
|
||||||
|
ppOutputB[iChannel] = outputB[iChannel];
|
||||||
|
}
|
||||||
|
|
||||||
|
// With optimizations.
|
||||||
|
mal_uint64 framesRead = mal_channel_router_read_frames_separated(&router, 100, ppOutputA);
|
||||||
|
if (framesRead != 100) {
|
||||||
|
printf("Returned frame count for optimized incorrect.");
|
||||||
|
hasError = MAL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Without optimizations.
|
||||||
|
router.isPassthrough = MAL_FALSE;
|
||||||
|
router.isSimpleShuffle = MAL_FALSE;
|
||||||
|
framesRead = mal_channel_router_read_frames_separated(&router, 100, ppOutputB);
|
||||||
|
if (framesRead != 100) {
|
||||||
|
printf("Returned frame count for unoptimized path incorrect.");
|
||||||
|
hasError = MAL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare.
|
||||||
|
for (mal_uint32 iChannel = 0; iChannel < routerConfig.channelsOut; ++iChannel) {
|
||||||
|
for (mal_uint32 iFrame = 0; iFrame < 100; ++iFrame) {
|
||||||
|
if (ppOutputA[iChannel][iFrame] != ppOutputB[iChannel][iFrame]) {
|
||||||
|
printf("Sample incorrect [%d][%d]\n", iChannel, iFrame);
|
||||||
|
hasError = MAL_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!hasError) {
|
if (!hasError) {
|
||||||
printf("PASSED\n");
|
printf("PASSED\n");
|
||||||
}
|
}
|
||||||
@@ -1365,6 +1416,57 @@ int do_channel_routing_tests()
|
|||||||
hasError = MAL_TRUE;
|
hasError = MAL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Here is where we check that the shuffle optimization works correctly. What we do is compare the output of the shuffle
|
||||||
|
// optimization with the non-shuffle output. We don't use a real sound here, but instead use values that makes it easier
|
||||||
|
// for us to check results. Each channel is given a value equal to it's index, plus 1.
|
||||||
|
float testData[MAL_MAX_CHANNELS][100];
|
||||||
|
float* ppTestData[MAL_MAX_CHANNELS];
|
||||||
|
for (mal_uint32 iChannel = 0; iChannel < routerConfig.channelsIn; ++iChannel) {
|
||||||
|
ppTestData[iChannel] = testData[iChannel];
|
||||||
|
for (mal_uint32 iFrame = 0; iFrame < 100; ++iFrame) {
|
||||||
|
ppTestData[iChannel][iFrame] = (float)(iChannel + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mal_channel_router_init_separated(&routerConfig, channel_router_callback__passthrough_test, ppTestData, &router);
|
||||||
|
|
||||||
|
float outputA[MAL_MAX_CHANNELS][100];
|
||||||
|
float outputB[MAL_MAX_CHANNELS][100];
|
||||||
|
float* ppOutputA[MAL_MAX_CHANNELS];
|
||||||
|
float* ppOutputB[MAL_MAX_CHANNELS];
|
||||||
|
for (mal_uint32 iChannel = 0; iChannel < routerConfig.channelsOut; ++iChannel) {
|
||||||
|
ppOutputA[iChannel] = outputA[iChannel];
|
||||||
|
ppOutputB[iChannel] = outputB[iChannel];
|
||||||
|
}
|
||||||
|
|
||||||
|
// With optimizations.
|
||||||
|
mal_uint64 framesRead = mal_channel_router_read_frames_separated(&router, 100, ppOutputA);
|
||||||
|
if (framesRead != 100) {
|
||||||
|
printf("Returned frame count for optimized incorrect.");
|
||||||
|
hasError = MAL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Without optimizations.
|
||||||
|
router.isPassthrough = MAL_FALSE;
|
||||||
|
router.isSimpleShuffle = MAL_FALSE;
|
||||||
|
framesRead = mal_channel_router_read_frames_separated(&router, 100, ppOutputB);
|
||||||
|
if (framesRead != 100) {
|
||||||
|
printf("Returned frame count for unoptimized path incorrect.");
|
||||||
|
hasError = MAL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare.
|
||||||
|
for (mal_uint32 iChannel = 0; iChannel < routerConfig.channelsOut; ++iChannel) {
|
||||||
|
for (mal_uint32 iFrame = 0; iFrame < 100; ++iFrame) {
|
||||||
|
if (ppOutputA[iChannel][iFrame] != ppOutputB[iChannel][iFrame]) {
|
||||||
|
printf("Sample incorrect [%d][%d]\n", iChannel, iFrame);
|
||||||
|
hasError = MAL_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!hasError) {
|
if (!hasError) {
|
||||||
printf("PASSED\n");
|
printf("PASSED\n");
|
||||||
}
|
}
|
||||||
@@ -1530,6 +1632,51 @@ int do_channel_routing_tests()
|
|||||||
hasError = MAL_TRUE;
|
hasError = MAL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Test the actual conversion. The test data is set to +1 for the left channel, and -1 for the right channel.
|
||||||
|
float testData[MAL_MAX_CHANNELS][100];
|
||||||
|
float* ppTestData[MAL_MAX_CHANNELS];
|
||||||
|
for (mal_uint32 iChannel = 0; iChannel < routerConfig.channelsIn; ++iChannel) {
|
||||||
|
ppTestData[iChannel] = testData[iChannel];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (mal_uint32 iFrame = 0; iFrame < 100; ++iFrame) {
|
||||||
|
ppTestData[0][iFrame] = -1;
|
||||||
|
ppTestData[1][iFrame] = +1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mal_channel_router_init_separated(&routerConfig, channel_router_callback__passthrough_test, ppTestData, &router);
|
||||||
|
|
||||||
|
float output[MAL_MAX_CHANNELS][100];
|
||||||
|
float* ppOutput[MAL_MAX_CHANNELS];
|
||||||
|
for (mal_uint32 iChannel = 0; iChannel < routerConfig.channelsOut; ++iChannel) {
|
||||||
|
ppOutput[iChannel] = output[iChannel];
|
||||||
|
}
|
||||||
|
|
||||||
|
mal_uint64 framesRead = mal_channel_router_read_frames_separated(&router, 100, ppOutput);
|
||||||
|
if (framesRead != 100) {
|
||||||
|
printf("Returned frame count for optimized incorrect.\n");
|
||||||
|
hasError = MAL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
float expectedOutput[MAL_MAX_CHANNELS];
|
||||||
|
expectedOutput[0] = -1.0f; // FRONT_LEFT
|
||||||
|
expectedOutput[1] = +1.0f; // FRONT_RIGHT
|
||||||
|
expectedOutput[2] = 0.0f; // FRONT_CENTER (left and right should cancel out, totalling 0).
|
||||||
|
expectedOutput[3] = 0.0f; // LFE
|
||||||
|
expectedOutput[4] = -0.25f; // BACK_LEFT
|
||||||
|
expectedOutput[5] = +0.25f; // BACK_RIGHT
|
||||||
|
expectedOutput[6] = -0.5f; // SIDE_LEFT
|
||||||
|
expectedOutput[7] = +0.5f; // SIDE_RIGHT
|
||||||
|
for (mal_uint32 iChannel = 0; iChannel < routerConfig.channelsOut; ++iChannel) {
|
||||||
|
for (mal_uint32 iFrame = 0; iFrame < framesRead; ++iFrame) {
|
||||||
|
if (output[iChannel][iFrame] != expectedOutput[iChannel]) {
|
||||||
|
printf("Incorrect sample [%d][%d]. Expecting %f, got %f\n", iChannel, iFrame, expectedOutput[iChannel], output[iChannel][iFrame]);
|
||||||
|
hasError = MAL_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!hasError) {
|
if (!hasError) {
|
||||||
printf("PASSED\n");
|
printf("PASSED\n");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user