diff options
author | Chris Robinson <[email protected]> | 2021-02-24 21:44:55 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2021-02-24 22:21:18 -0800 |
commit | 6e676b81d588f9bfd2b0b69af48cdf9a701ca24a (patch) | |
tree | 24904c3230cc5c62f95aace4a766cd874914022f /core/bsinc_tables.cpp | |
parent | 5511bffdeb3dedd9e73f41cd873dbd448b3b153a (diff) |
Avoiding cutting all bsinc resampler output at scale 0
This is mostly for the SampleConverter, used by some capture backends. When
recording at really low rates, like 5512hz, with a device capturing at a higher
rate like 44100hz or 48000hz, it hits the filter's downscaling limit and
produces pure silence.
In such cases, it's better to just accept some aliasing noise so that the app
will still get some recognizable audio. The alternative would be to scale the
desired rate by 2x, 3x, etc until it's above the bsinc limit, then take every
2nd, 3rd, etc sample of the result as if by an extra simpler resampler pass.
Diffstat (limited to 'core/bsinc_tables.cpp')
-rw-r--r-- | core/bsinc_tables.cpp | 13 |
1 files changed, 6 insertions, 7 deletions
diff --git a/core/bsinc_tables.cpp b/core/bsinc_tables.cpp index cfd9a046..8f375ac2 100644 --- a/core/bsinc_tables.cpp +++ b/core/bsinc_tables.cpp @@ -123,7 +123,7 @@ struct BSincHeader { uint num_points{Order+1}; for(uint si{0};si < BSincScaleCount;++si) { - const double scale{scaleBase + (scaleRange * si / (BSincScaleCount-1))}; + const double scale{scaleBase + (scaleRange * (si+1) / BSincScaleCount)}; const uint a_{std::min(static_cast<uint>(num_points / 2.0 / scale), num_points)}; const uint m{2 * a_}; @@ -162,14 +162,13 @@ struct BSincFilterArray { auto filter = std::make_unique<filter_type>(BSincScaleCount); /* Calculate the Kaiser-windowed Sinc filter coefficients for each - * scale and phase index. The output of scale index 0 is all 0s, so - * start at 1. + * scale and phase index. */ - for(uint si{1};si < BSincScaleCount;++si) + for(uint si{0};si < BSincScaleCount;++si) { const uint m{hdr.a[si] * 2}; const size_t o{(BSincPointsMax-m) / 2}; - const double scale{hdr.scaleBase + (hdr.scaleRange * si / (BSincScaleCount-1))}; + const double scale{hdr.scaleBase + (hdr.scaleRange * (si+1) / BSincScaleCount)}; const double cutoff{scale - (hdr.scaleBase * std::max(0.5, scale) * 2.0)}; const auto a = static_cast<double>(hdr.a[si]); const double l{a - 1.0}; @@ -236,8 +235,8 @@ struct BSincFilterArray { } /* This last simplification is done to complete the bilinear - * equation for the combination of phase and scale. - */ + * equation for the combination of phase and scale. + */ for(size_t i{0};i < m;++i) { const double spDelta{(filter[si+1][pi+1][o+i] - filter[si+1][pi][o+i]) - |