From ac4c1109f86aa8c5877c276ae4eaab7a4fc68eb2 Mon Sep 17 00:00:00 2001 From: David Reid Date: Sun, 1 Apr 2018 11:13:17 +1000 Subject: [PATCH] Make channel router API consistent with format converter. --- mini_al.h | 45 +++++++++++++++------------------------- tests/mal_test_0.c | 51 +++++++++++++++++++++++++++++++--------------- 2 files changed, 51 insertions(+), 45 deletions(-) diff --git a/mini_al.h b/mini_al.h index c18ca378..817f20c2 100644 --- a/mini_al.h +++ b/mini_al.h @@ -730,13 +730,13 @@ typedef struct mal_channel channelMapIn[MAL_MAX_CHANNELS]; mal_channel channelMapOut[MAL_MAX_CHANNELS]; mal_channel_mix_mode mixingMode; + mal_channel_router_read_deinterleaved_proc onReadDeinterleaved; + void* pUserData; } mal_channel_router_config; struct mal_channel_router { mal_channel_router_config config; - mal_channel_router_read_deinterleaved_proc onReadDeinterleaved; - void* pUserData; mal_bool32 isPassthrough : 1; mal_bool32 isSimpleShuffle : 1; mal_uint8 shuffleTable[MAL_MAX_CHANNELS]; @@ -1856,13 +1856,13 @@ mal_uint64 mal_format_converter_read_deinterleaved(mal_format_converter* pConver /////////////////////////////////////////////////////////////////////////////// // Initializes a channel router where it is assumed that the input data is non-interleaved. -mal_result mal_channel_router_init_deinterleaved(const mal_channel_router_config* pConfig, mal_channel_router_read_deinterleaved_proc onRead, void* pUserData, mal_channel_router* pRouter); +mal_result mal_channel_router_init_deinterleaved(const mal_channel_router_config* pConfig, mal_channel_router* pRouter); // Reads data from the channel router as deinterleaved channels. mal_uint64 mal_channel_router_read_deinterleaved(mal_channel_router* pRouter, mal_uint64 frameCount, void** ppSamplesOut, void* pUserData); // Helper for initializing a channel router config. -mal_channel_router_config mal_channel_router_config_init(mal_uint32 channelsIn, const mal_channel channelMapIn[MAL_MAX_CHANNELS], mal_uint32 channelsOut, const mal_channel channelMapOut[MAL_MAX_CHANNELS], mal_channel_mix_mode mixingMode); +mal_channel_router_config mal_channel_router_config_init(mal_uint32 channelsIn, const mal_channel channelMapIn[MAL_MAX_CHANNELS], mal_uint32 channelsOut, const mal_channel channelMapOut[MAL_MAX_CHANNELS], mal_channel_mix_mode mixingMode, mal_channel_router_read_deinterleaved_proc onRead, void* pUserData); /////////////////////////////////////////////////////////////////////////////// @@ -17421,7 +17421,7 @@ mal_bool32 mal_channel_router__is_spatial_channel_position(const mal_channel_rou return MAL_TRUE; } -mal_result mal_channel_router_init__common(const mal_channel_router_config* pConfig, void* pUserData, mal_channel_router* pRouter) +mal_result mal_channel_router_init_deinterleaved(const mal_channel_router_config* pConfig, mal_channel_router* pRouter) { if (pRouter == NULL) { return MAL_INVALID_ARGS; @@ -17432,6 +17432,9 @@ mal_result mal_channel_router_init__common(const mal_channel_router_config* pCon if (pConfig == NULL) { return MAL_INVALID_ARGS; } + if (pConfig->onReadDeinterleaved == NULL) { + return MAL_INVALID_ARGS; + } if (!mal_channel_map_valid(pConfig->channelsIn, pConfig->channelMapIn)) { return MAL_INVALID_ARGS; // Invalid input channel map. @@ -17441,7 +17444,6 @@ mal_result mal_channel_router_init__common(const mal_channel_router_config* pCon } pRouter->config = *pConfig; - pRouter->pUserData = pUserData; // If the input and output channels and channel maps are the same we should use a passthrough. if (pRouter->config.channelsIn == pRouter->config.channelsOut) { @@ -17628,23 +17630,6 @@ mal_result mal_channel_router_init__common(const mal_channel_router_config* pCon } } - - return MAL_SUCCESS; -} - -mal_result mal_channel_router_init_deinterleaved(const mal_channel_router_config* pConfig, mal_channel_router_read_deinterleaved_proc onRead, void* pUserData, mal_channel_router* pRouter) -{ - mal_result result = mal_channel_router_init__common(pConfig, pUserData, pRouter); - if (result != MAL_SUCCESS) { - return result; - } - - if (onRead == NULL) { - return MAL_INVALID_ARGS; - } - - pRouter->onReadDeinterleaved = onRead; - return MAL_SUCCESS; } @@ -17688,7 +17673,7 @@ mal_uint64 mal_channel_router_read_deinterleaved(mal_channel_router* pRouter, ma // Fast path for a passthrough. if (pRouter->isPassthrough) { if (frameCount <= 0xFFFFFFFF) { - return (mal_uint32)pRouter->onReadDeinterleaved(pRouter, (mal_uint32)frameCount, ppSamplesOut, pUserData); + return (mal_uint32)pRouter->config.onReadDeinterleaved(pRouter, (mal_uint32)frameCount, ppSamplesOut, pUserData); } else { float* ppNextSamplesOut[MAL_MAX_CHANNELS]; mal_copy_memory(ppNextSamplesOut, ppSamplesOut, sizeof(float*) * pRouter->config.channelsOut); @@ -17701,7 +17686,7 @@ mal_uint64 mal_channel_router_read_deinterleaved(mal_channel_router* pRouter, ma framesToReadRightNow = 0xFFFFFFFF; } - mal_uint32 framesJustRead = (mal_uint32)pRouter->onReadDeinterleaved(pRouter, (mal_uint32)framesToReadRightNow, (void**)ppNextSamplesOut, pUserData); + mal_uint32 framesJustRead = (mal_uint32)pRouter->config.onReadDeinterleaved(pRouter, (mal_uint32)framesToReadRightNow, (void**)ppNextSamplesOut, pUserData); if (framesJustRead == 0) { break; } @@ -17736,7 +17721,7 @@ mal_uint64 mal_channel_router_read_deinterleaved(mal_channel_router* pRouter, ma framesToReadRightNow = maxFramesToReadEachIteration; } - mal_uint32 framesJustRead = pRouter->onReadDeinterleaved(pRouter, (mal_uint32)framesToReadRightNow, (void**)ppTemp, pUserData); + mal_uint32 framesJustRead = pRouter->config.onReadDeinterleaved(pRouter, (mal_uint32)framesToReadRightNow, (void**)ppTemp, pUserData); if (framesJustRead == 0) { break; } @@ -17754,7 +17739,7 @@ mal_uint64 mal_channel_router_read_deinterleaved(mal_channel_router* pRouter, ma return totalFramesRead; } -mal_channel_router_config mal_channel_router_config_init(mal_uint32 channelsIn, const mal_channel channelMapIn[MAL_MAX_CHANNELS], mal_uint32 channelsOut, const mal_channel channelMapOut[MAL_MAX_CHANNELS], mal_channel_mix_mode mixingMode) +mal_channel_router_config mal_channel_router_config_init(mal_uint32 channelsIn, const mal_channel channelMapIn[MAL_MAX_CHANNELS], mal_uint32 channelsOut, const mal_channel channelMapOut[MAL_MAX_CHANNELS], mal_channel_mix_mode mixingMode, mal_channel_router_read_deinterleaved_proc onRead, void* pUserData) { mal_channel_router_config config; mal_zero_object(&config); @@ -17770,6 +17755,8 @@ mal_channel_router_config mal_channel_router_config_init(mal_uint32 channelsIn, } config.mixingMode = mixingMode; + config.onReadDeinterleaved = onRead; + config.pUserData = pUserData; return config; } @@ -18905,8 +18892,8 @@ mal_result mal_dsp_init(const mal_dsp_config* pConfig, mal_dsp_read_proc onRead, // Channel conversion - mal_channel_router_config routerConfig = mal_channel_router_config_init(pConfig->channelsIn, pConfig->channelMapIn, pConfig->channelsOut, pConfig->channelMapOut, pConfig->channelMixMode); - result = mal_channel_router_init_deinterleaved(&routerConfig, mal_dsp__channel_router_on_read, pDSP, &pDSP->channelRouter); + mal_channel_router_config routerConfig = mal_channel_router_config_init(pConfig->channelsIn, pConfig->channelMapIn, pConfig->channelsOut, pConfig->channelMapOut, pConfig->channelMixMode, mal_dsp__channel_router_on_read, pDSP); + result = mal_channel_router_init_deinterleaved(&routerConfig, &pDSP->channelRouter); if (result != MAL_SUCCESS) { return result; } diff --git a/tests/mal_test_0.c b/tests/mal_test_0.c index 36fba5b2..c532d777 100644 --- a/tests/mal_test_0.c +++ b/tests/mal_test_0.c @@ -1295,6 +1295,8 @@ int do_channel_routing_tests() { mal_channel_router_config routerConfig; mal_zero_object(&routerConfig); + routerConfig.onReadDeinterleaved = channel_router_callback__passthrough_test; + routerConfig.pUserData = NULL; routerConfig.mixingMode = mal_channel_mix_mode_planar_blend; routerConfig.channelsIn = 6; routerConfig.channelsOut = routerConfig.channelsIn; @@ -1302,7 +1304,7 @@ int do_channel_routing_tests() mal_get_standard_channel_map(mal_standard_channel_map_microsoft, routerConfig.channelsOut, routerConfig.channelMapOut); mal_channel_router router; - mal_result result = mal_channel_router_init_deinterleaved(&routerConfig, channel_router_callback__passthrough_test, NULL, &router); + mal_result result = mal_channel_router_init_deinterleaved(&routerConfig, &router); if (result == MAL_SUCCESS) { if (!router.isPassthrough) { printf("Failed to init router as passthrough.\n"); @@ -1341,7 +1343,8 @@ int do_channel_routing_tests() } } - mal_channel_router_init_deinterleaved(&routerConfig, channel_router_callback__passthrough_test, ppTestData, &router); + routerConfig.pUserData = ppTestData; + mal_channel_router_init_deinterleaved(&routerConfig, &router); float outputA[MAL_MAX_CHANNELS][100]; float outputB[MAL_MAX_CHANNELS][100]; @@ -1353,7 +1356,7 @@ int do_channel_routing_tests() } // With optimizations. - mal_uint64 framesRead = mal_channel_router_read_deinterleaved(&router, 100, (void**)ppOutputA, router.pUserData); + mal_uint64 framesRead = mal_channel_router_read_deinterleaved(&router, 100, (void**)ppOutputA, router.config.pUserData); if (framesRead != 100) { printf("Returned frame count for optimized incorrect."); hasError = MAL_TRUE; @@ -1362,7 +1365,7 @@ int do_channel_routing_tests() // Without optimizations. router.isPassthrough = MAL_FALSE; router.isSimpleShuffle = MAL_FALSE; - framesRead = mal_channel_router_read_deinterleaved(&router, 100, (void**)ppOutputB, router.pUserData); + framesRead = mal_channel_router_read_deinterleaved(&router, 100, (void**)ppOutputB, router.config.pUserData); if (framesRead != 100) { printf("Returned frame count for unoptimized path incorrect."); hasError = MAL_TRUE; @@ -1391,6 +1394,8 @@ int do_channel_routing_tests() mal_channel_router_config routerConfig; mal_zero_object(&routerConfig); + routerConfig.onReadDeinterleaved = channel_router_callback__passthrough_test; + routerConfig.pUserData = NULL; routerConfig.mixingMode = mal_channel_mix_mode_planar_blend; routerConfig.channelsIn = 6; routerConfig.channelsOut = routerConfig.channelsIn; @@ -1400,7 +1405,7 @@ int do_channel_routing_tests() } mal_channel_router router; - mal_result result = mal_channel_router_init_deinterleaved(&routerConfig, channel_router_callback__passthrough_test, NULL, &router); + mal_result result = mal_channel_router_init_deinterleaved(&routerConfig, &router); if (result == MAL_SUCCESS) { if (router.isPassthrough) { printf("Router incorrectly configured as a passthrough.\n"); @@ -1443,7 +1448,8 @@ int do_channel_routing_tests() } } - mal_channel_router_init_deinterleaved(&routerConfig, channel_router_callback__passthrough_test, ppTestData, &router); + routerConfig.pUserData = ppTestData; + mal_channel_router_init_deinterleaved(&routerConfig, &router); float outputA[MAL_MAX_CHANNELS][100]; float outputB[MAL_MAX_CHANNELS][100]; @@ -1455,7 +1461,7 @@ int do_channel_routing_tests() } // With optimizations. - mal_uint64 framesRead = mal_channel_router_read_deinterleaved(&router, 100, (void**)ppOutputA, router.pUserData); + mal_uint64 framesRead = mal_channel_router_read_deinterleaved(&router, 100, (void**)ppOutputA, router.config.pUserData); if (framesRead != 100) { printf("Returned frame count for optimized incorrect."); hasError = MAL_TRUE; @@ -1464,7 +1470,7 @@ int do_channel_routing_tests() // Without optimizations. router.isPassthrough = MAL_FALSE; router.isSimpleShuffle = MAL_FALSE; - framesRead = mal_channel_router_read_deinterleaved(&router, 100, (void**)ppOutputB, router.pUserData); + framesRead = mal_channel_router_read_deinterleaved(&router, 100, (void**)ppOutputB, router.config.pUserData); if (framesRead != 100) { printf("Returned frame count for unoptimized path incorrect."); hasError = MAL_TRUE; @@ -1493,6 +1499,8 @@ int do_channel_routing_tests() mal_channel_router_config routerConfig; mal_zero_object(&routerConfig); + routerConfig.onReadDeinterleaved = channel_router_callback__passthrough_test; + routerConfig.pUserData = NULL; routerConfig.mixingMode = mal_channel_mix_mode_simple; routerConfig.channelsIn = 2; routerConfig.channelsOut = 6; @@ -1500,7 +1508,7 @@ int do_channel_routing_tests() mal_get_standard_channel_map(mal_standard_channel_map_microsoft, routerConfig.channelsOut, routerConfig.channelMapOut); mal_channel_router router; - mal_result result = mal_channel_router_init_deinterleaved(&routerConfig, channel_router_callback__passthrough_test, NULL, &router); + mal_result result = mal_channel_router_init_deinterleaved(&routerConfig, &router); if (result == MAL_SUCCESS) { if (router.isPassthrough) { printf("Router incorrectly configured as a passthrough.\n"); @@ -1539,6 +1547,8 @@ int do_channel_routing_tests() { mal_channel_router_config routerConfig; mal_zero_object(&routerConfig); + routerConfig.onReadDeinterleaved = channel_router_callback__passthrough_test; + routerConfig.pUserData = NULL; routerConfig.mixingMode = mal_channel_mix_mode_simple; routerConfig.channelsIn = 6; routerConfig.channelsOut = 2; @@ -1546,7 +1556,7 @@ int do_channel_routing_tests() mal_get_standard_channel_map(mal_standard_channel_map_microsoft, routerConfig.channelsOut, routerConfig.channelMapOut); mal_channel_router router; - mal_result result = mal_channel_router_init_deinterleaved(&routerConfig, channel_router_callback__passthrough_test, NULL, &router); + mal_result result = mal_channel_router_init_deinterleaved(&routerConfig, &router); if (result == MAL_SUCCESS) { if (router.isPassthrough) { printf("Router incorrectly configured as a passthrough.\n"); @@ -1585,6 +1595,8 @@ int do_channel_routing_tests() { mal_channel_router_config routerConfig; mal_zero_object(&routerConfig); + routerConfig.onReadDeinterleaved = channel_router_callback__passthrough_test; + routerConfig.pUserData = NULL; routerConfig.mixingMode = mal_channel_mix_mode_planar_blend; // Use very specific mappings for this test. @@ -1603,7 +1615,7 @@ int do_channel_routing_tests() routerConfig.channelMapOut[7] = MAL_CHANNEL_SIDE_RIGHT; mal_channel_router router; - mal_result result = mal_channel_router_init_deinterleaved(&routerConfig, channel_router_callback__passthrough_test, NULL, &router); + mal_result result = mal_channel_router_init_deinterleaved(&routerConfig, &router); if (result == MAL_SUCCESS) { if (router.isPassthrough) { printf("Router incorrectly configured as a passthrough.\n"); @@ -1659,7 +1671,8 @@ int do_channel_routing_tests() ppTestData[1][iFrame] = +1; } - mal_channel_router_init_deinterleaved(&routerConfig, channel_router_callback__passthrough_test, ppTestData, &router); + routerConfig.pUserData = ppTestData; + mal_channel_router_init_deinterleaved(&routerConfig, &router); float output[MAL_MAX_CHANNELS][100]; float* ppOutput[MAL_MAX_CHANNELS]; @@ -1667,7 +1680,7 @@ int do_channel_routing_tests() ppOutput[iChannel] = output[iChannel]; } - mal_uint64 framesRead = mal_channel_router_read_deinterleaved(&router, 100, (void**)ppOutput, router.pUserData); + mal_uint64 framesRead = mal_channel_router_read_deinterleaved(&router, 100, (void**)ppOutput, router.config.pUserData); if (framesRead != 100) { printf("Returned frame count for optimized incorrect.\n"); hasError = MAL_TRUE; @@ -1700,6 +1713,8 @@ int do_channel_routing_tests() { mal_channel_router_config routerConfig; mal_zero_object(&routerConfig); + routerConfig.onReadDeinterleaved = channel_router_callback__passthrough_test; + routerConfig.pUserData = NULL; routerConfig.mixingMode = mal_channel_mix_mode_planar_blend; // Use very specific mappings for this test. @@ -1718,7 +1733,7 @@ int do_channel_routing_tests() routerConfig.channelMapOut[1] = MAL_CHANNEL_FRONT_RIGHT; mal_channel_router router; - mal_result result = mal_channel_router_init_deinterleaved(&routerConfig, channel_router_callback__passthrough_test, NULL, &router); + mal_result result = mal_channel_router_init_deinterleaved(&routerConfig, &router); if (result == MAL_SUCCESS) { if (router.isPassthrough) { printf("Router incorrectly configured as a passthrough.\n"); @@ -1770,6 +1785,8 @@ int do_channel_routing_tests() { mal_channel_router_config routerConfig; mal_zero_object(&routerConfig); + routerConfig.onReadDeinterleaved = channel_router_callback__passthrough_test; + routerConfig.pUserData = NULL; routerConfig.mixingMode = mal_channel_mix_mode_planar_blend; // Use very specific mappings for this test. @@ -1783,7 +1800,7 @@ int do_channel_routing_tests() routerConfig.channelMapOut[3] = MAL_CHANNEL_LFE; mal_channel_router router; - mal_result result = mal_channel_router_init_deinterleaved(&routerConfig, channel_router_callback__passthrough_test, NULL, &router); + mal_result result = mal_channel_router_init_deinterleaved(&routerConfig, &router); if (result == MAL_SUCCESS) { if (router.isPassthrough) { printf("Router incorrectly configured as a passthrough.\n"); @@ -1823,6 +1840,8 @@ int do_channel_routing_tests() { mal_channel_router_config routerConfig; mal_zero_object(&routerConfig); + routerConfig.onReadDeinterleaved = channel_router_callback__passthrough_test; + routerConfig.pUserData = NULL; routerConfig.mixingMode = mal_channel_mix_mode_planar_blend; // Use very specific mappings for this test. @@ -1836,7 +1855,7 @@ int do_channel_routing_tests() routerConfig.channelMapOut[0] = MAL_CHANNEL_MONO; mal_channel_router router; - mal_result result = mal_channel_router_init_deinterleaved(&routerConfig, channel_router_callback__passthrough_test, NULL, &router); + mal_result result = mal_channel_router_init_deinterleaved(&routerConfig, &router); if (result == MAL_SUCCESS) { if (router.isPassthrough) { printf("Router incorrectly configured as a passthrough.\n");