aboutsummaryrefslogtreecommitdiffstats
path: root/core/bsinc_tables.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2021-02-24 21:44:55 -0800
committerChris Robinson <[email protected]>2021-02-24 22:21:18 -0800
commit6e676b81d588f9bfd2b0b69af48cdf9a701ca24a (patch)
tree24904c3230cc5c62f95aace4a766cd874914022f /core/bsinc_tables.cpp
parent5511bffdeb3dedd9e73f41cd873dbd448b3b153a (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.cpp13
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]) -