From 34d88af6524ba781473511d409ccae677ce7e7ce Mon Sep 17 00:00:00 2001 From: David Reid Date: Sun, 25 Nov 2018 09:52:05 +1000 Subject: [PATCH] Remove the passthrough algorithm from the resampler. The rationale for this is that it's just useless - just not do resampling at all if you don't need to! --- research/mal_resampler.h | 140 +-------------------------------------- 1 file changed, 2 insertions(+), 138 deletions(-) diff --git a/research/mal_resampler.h b/research/mal_resampler.h index a176cff9..a6f8b882 100644 --- a/research/mal_resampler.h +++ b/research/mal_resampler.h @@ -5,7 +5,6 @@ This is research into a new resampler for mini_al. Not yet complete. Requirements: - Selection of different algorithms. The following at a minimum: - - Passthrough - Linear with optional filtering - Sinc - Floating point pipeline for f32 and fixed point integer pipeline for s16 @@ -60,9 +59,8 @@ typedef mal_uint64 (* mal_resampler_seek_proc)(mal_resampler* pResampler, mal_ui typedef enum { - mal_resampler_algorithm_sinc = 0, /* Default. */ - mal_resampler_algorithm_linear, /* Fastest. */ - mal_resampler_algorithm_passthrough /* No resampling. */ + mal_resampler_algorithm_sinc = 0, /* Default. */ + mal_resampler_algorithm_linear, /* Fastest. */ } mal_resampler_algorithm; typedef enum @@ -200,9 +198,6 @@ mal_uint64 mal_resampler_get_expected_output_frame_count(mal_resampler* pResampl #endif #ifdef MINI_AL_IMPLEMENTATION -mal_uint64 mal_resampler_read__passthrough(mal_resampler* pResampler, mal_uint64 frameCount, void** ppFrames); -mal_uint64 mal_resampler_seek__passthrough(mal_resampler* pResampler, mal_uint64 frameCount, mal_uint32 options); - mal_uint64 mal_resampler_read__linear(mal_resampler* pResampler, mal_uint64 frameCount, void** ppFrames); mal_uint64 mal_resampler_seek__linear(mal_resampler* pResampler, mal_uint64 frameCount, mal_uint32 options); @@ -263,13 +258,6 @@ mal_result mal_resampler_init(const mal_resampler_config* pConfig, mal_resampler } switch (pResampler->config.algorithm) { - case mal_resampler_algorithm_passthrough: - { - pResampler->init = NULL; - pResampler->read = mal_resampler_read__passthrough; - pResampler->seek = mal_resampler_seek__passthrough; - } break; - case mal_resampler_algorithm_linear: { pResampler->init = NULL; @@ -347,12 +335,6 @@ mal_uint64 mal_resampler_read(mal_resampler* pResampler, mal_uint64 frameCount, return mal_resampler_seek(pResampler, frameCount, 0); } - /* Special case for passthrough. That has a specialized function for reading for efficiency. */ - if (pResampler->config.algorithm == mal_resampler_algorithm_passthrough) { - return pResampler->read(pResampler, frameCount, ppFrames); - } - - return pResampler->read(pResampler, frameCount, ppFrames); } @@ -367,12 +349,6 @@ mal_uint64 mal_resampler_seek(mal_resampler* pResampler, mal_uint64 frameCount, return 0; /* Nothing to do, so return early. */ } - /* Special case for passthrough. That has a specialized function for reading for efficiency. */ - if (pResampler->config.algorithm == mal_resampler_algorithm_passthrough) { - return pResampler->seek(pResampler, frameCount, options); - } - - return pResampler->seek(pResampler, frameCount, options); } @@ -411,11 +387,6 @@ double mal_resampler_get_cached_input_time(mal_resampler* pResampler) return 0; /* Invalid args. */ } - /* Special case for passthrough. Nothing is ever cached. */ - if (pResampler->config.algorithm == mal_resampler_algorithm_passthrough) { - return 0; - } - return mal_resampler__calculate_cached_input_time(pResampler); } @@ -430,11 +401,6 @@ double mal_resampler_get_cached_output_time(mal_resampler* pResampler) return 0; /* Invalid args. */ } - /* Special case for passthrough. Nothing is ever cached. */ - if (pResampler->config.algorithm == mal_resampler_algorithm_passthrough) { - return 0; - } - return mal_resampler__calculate_cached_output_time(pResampler); } @@ -449,11 +415,6 @@ mal_uint64 mal_resampler_get_required_input_frame_count(mal_resampler* pResample return 0; } - /* Special case for passthrough. */ - if (pResampler->config.algorithm == mal_resampler_algorithm_passthrough) { - return outputFrameCount; - } - /* First grab the amount of output time sitting in the cache. */ double cachedOutputTime = mal_resampler__calculate_cached_output_time(pResampler); if (cachedOutputTime >= outputFrameCount) { @@ -488,108 +449,11 @@ mal_uint64 mal_resampler_get_expected_output_frame_count(mal_resampler* pResampl return 0; } - /* Special case for passthrough. */ - if (pResampler->config.algorithm == mal_resampler_algorithm_passthrough) { - return inputFrameCount; - } - /* What we're actually calculating here is how many whole output frames will be calculated after consuming inputFrameCount + mal_resampler_get_cached_input_time(). */ return (mal_uint64)floor((mal_resampler__calculate_cached_input_time(pResampler) + inputFrameCount) / pResampler->config.ratio); } -/* -Passthrough -*/ -mal_uint64 mal_resampler_read__passthrough(mal_resampler* pResampler, mal_uint64 frameCount, void** ppFrames) -{ - mal_assert(pResampler != NULL); - mal_assert(pResampler->config.onRead != NULL); - mal_assert(frameCount > 0); - mal_assert(ppFrames != NULL); - - /* - It's tempting to to just call pResampler->config.onRead() and pass in ppFrames directly, however this violates - our requirement that all buffers passed into onRead() are aligned to MAL_SIMD_ALIGNMENT. If any of the ppFrames - buffers are misaligned we need to read into a temporary buffer. - */ - mal_bool32 isOutputBufferAligned = MAL_TRUE; - for (mal_uint32 iChannel = 0; iChannel < pResampler->config.channels; ++iChannel) { - if (((mal_uintptr)ppFrames[iChannel] & (MAL_SIMD_ALIGNMENT-1)) != 0) { - isOutputBufferAligned = MAL_FALSE; - break; - } - } - - if (frameCount <= 0xFFFFFFFF && isOutputBufferAligned) { - return pResampler->config.onRead(pResampler, (mal_uint32)frameCount, ppFrames); /* Fast path. */ - } else { - MAL_DECLARE_ALIGNED_STACK_BUFFER(float, ppRunningFrames, 4096, pResampler->config.channels); - - mal_uint64 totalFramesRead = 0; - while (frameCount > 0) { - mal_uint64 framesToReadNow = (pResampler->config.format == mal_format_f32) ? ppRunningFramesFrameCount : ppRunningFramesFrameCount*2; /* x2 for the s16 frame count because ppRunningFramesFrameCount is based on f32. */ - if (framesToReadNow > frameCount) { - framesToReadNow = frameCount; - } - - mal_uint32 framesJustRead = pResampler->config.onRead(pResampler, (mal_uint32)framesToReadNow, (void**)ppRunningFrames); - if (framesJustRead == 0) { - break; - } - - totalFramesRead += framesJustRead; - frameCount -= framesJustRead; - - mal_uint32 bytesJustRead = framesJustRead * mal_get_bytes_per_sample(pResampler->config.format); - for (mal_uint32 iChannel = 0; iChannel < pResampler->config.channels; ++iChannel) { - mal_copy_memory(ppFrames[iChannel], ppRunningFrames[iChannel], bytesJustRead); - ppFrames[iChannel] = mal_offset_ptr(ppFrames[iChannel], bytesJustRead); - } - - if (framesJustRead < framesToReadNow) { - break; - } - } - - return totalFramesRead; - } -} - -mal_uint64 mal_resampler_seek__passthrough(mal_resampler* pResampler, mal_uint64 frameCount, mal_uint32 options) -{ - mal_assert(pResampler != NULL); - mal_assert(pResampler->config.onRead != NULL); - mal_assert(frameCount > 0); - - if ((options & MAL_RESAMPLER_SEEK_NO_CLIENT_READ) != 0) { - return frameCount; /* No input from onRead(), so just return immediately. */ - } - - /* Getting here means we need to read from onRead(). In this case we just read into a trash buffer. */ - MAL_DECLARE_ALIGNED_STACK_BUFFER(float, trash, 4096, pResampler->config.channels); - - mal_uint64 totalFramesRead = 0; - while (frameCount > 0) { - mal_uint64 framesToRead = trashFrameCount; - if (framesToRead > frameCount) { - framesToRead = frameCount; - } - - mal_uint64 framesRead = pResampler->config.onRead(pResampler, (mal_uint32)framesToRead, (void**)trash); - totalFramesRead += framesRead; - frameCount -= framesRead; - - /* Don't get stuck in a loop if the client returns no samples. */ - if (framesRead < framesToRead) { - break; - } - } - - return totalFramesRead; -} - - /* Linear */