Resampler: For LPF orders to be a multiple of 2.

This is in preparation for an implementation simplification for the
purpose of some upcoming optimizations.
This commit is contained in:
David Reid
2026-02-08 19:21:10 +10:00
parent a04f300821
commit 20180b0ae5
+19 -5
View File
@@ -3017,7 +3017,9 @@ The linear resampler performs low-pass filtering before or after downsampling or
depending on the sample rates you're converting between. When decreasing the sample rate, the
low-pass filter will be applied before downsampling. When increasing the rate it will be performed
after upsampling. By default a fourth order low-pass filter will be applied. This can be configured
via the `lpfOrder` configuration variable. Setting this to 0 will disable filtering.
via the `lpfOrder` configuration variable. Setting this to 0 will disable filtering. It should be
set to a multiple of 2, such as 2, 4, 6, 8, etc. There are diminishing returns the higher you go.
The maximum is `MA_MAX_FILTER_ORDER` which is 8 by default (it can be configured at compile time).
The low-pass filter has a cutoff frequency which defaults to half the sample rate of the lowest of
the input and output sample rates (Nyquist Frequency).
@@ -5580,7 +5582,7 @@ typedef struct
ma_uint32 channels;
ma_uint32 sampleRateIn;
ma_uint32 sampleRateOut;
ma_uint32 lpfOrder; /* The low-pass filter order. Setting this to 0 will disable low-pass filtering. */
ma_uint32 lpfOrder; /* The low-pass filter order. Setting this to 0 will disable low-pass filtering. Must be a multiple of 2. */
float lpfNyquistFactor; /* 0..1. Defaults to 1. 1 = Half the sampling frequency (Nyquist Frequency), 0.5 = Quarter the sampling frequency (half Nyquest Frequency), etc. */
} ma_linear_resampler_config;
@@ -5667,7 +5669,7 @@ struct ma_resampler_config
void* pBackendUserData;
struct
{
ma_uint32 lpfOrder;
ma_uint32 lpfOrder; /* Must be a multiple of 2. */
} linear;
};
@@ -8718,7 +8720,7 @@ then be set directly on the structure. Below are the members of the `ma_device_c
resampling.linear.lpfOrder
The linear resampler applies a low-pass filter as part of its processing for anti-aliasing. This setting controls the order of the filter. The higher
the value, the better the quality, in general. Setting this to 0 will disable low-pass filtering altogether. The maximum value is
`MA_MAX_FILTER_ORDER`. The default value is `min(4, MA_MAX_FILTER_ORDER)`.
`MA_MAX_FILTER_ORDER`. The default value is `min(4, MA_MAX_FILTER_ORDER)`. It must be a multiple of 2.
playback.pDeviceID
A pointer to a `ma_device_id` structure containing the ID of the playback device to initialize. Setting this NULL (default) will use the system's
@@ -58986,6 +58988,8 @@ static ma_result ma_linear_resampler_set_rate_internal(ma_linear_resampler* pRes
static ma_result ma_linear_resampler_get_heap_layout(const ma_linear_resampler_config* pConfig, ma_linear_resampler_heap_layout* pHeapLayout)
{
ma_uint32 lpfOrder;
MA_ASSERT(pHeapLayout != NULL);
MA_ZERO_OBJECT(pHeapLayout);
@@ -59002,6 +59006,11 @@ static ma_result ma_linear_resampler_get_heap_layout(const ma_linear_resampler_c
return MA_INVALID_ARGS;
}
lpfOrder = pConfig->lpfOrder;
if ((lpfOrder & 0x1) != 0) {
lpfOrder += 1; /* Round up to even. */
}
pHeapLayout->sizeInBytes = 0;
/* x0 */
@@ -59025,7 +59034,7 @@ static ma_result ma_linear_resampler_get_heap_layout(const ma_linear_resampler_c
{
ma_result result;
size_t lpfHeapSizeInBytes;
ma_lpf_config lpfConfig = ma_lpf_config_init(pConfig->format, pConfig->channels, 1, 1, pConfig->lpfOrder); /* Sample rate and cutoff frequency do not matter. */
ma_lpf_config lpfConfig = ma_lpf_config_init(pConfig->format, pConfig->channels, 1, 1, lpfOrder); /* Sample rate and cutoff frequency do not matter. */
result = ma_lpf_get_heap_size(&lpfConfig, &lpfHeapSizeInBytes);
if (result != MA_SUCCESS) {
@@ -59085,6 +59094,11 @@ MA_API ma_result ma_linear_resampler_init_preallocated(const ma_linear_resampler
pResampler->lpfOrder = pConfig->lpfOrder;
pResampler->lpfNyquistFactor = pConfig->lpfNyquistFactor;
/* The order needs to be even. */
if ((pResampler->lpfOrder & 0x1) != 0) {
pResampler->lpfOrder += 1; /* Round up to even. */
}
pResampler->_pHeap = pHeap;
MA_ZERO_MEMORY(pHeap, heapLayout.sizeInBytes);