0
$\begingroup$

I'm working on a fork of the Rust dasp library, which is intended to be a DSP toolkit that abstracts over samples/frames/signals, and contains a number of functions and tools that work with these. One such bit of functionality is a signal interpolation feature, this supposedly allows for on-the-fly lazy resampling of a signal using sinc resampling. The Rust code that does the heavy sinc work is found here: https://github.com/RustAudio/dasp/blob/master/dasp_interpolate/src/sinc/mod.rs

However, I'm a bit confused. Looking at previous asked questions on this site and other resources on sinc interpolation and resampling, I'm seeing some yellow flags:

  • I can't seem to find any other "streaming" implementations of sinc resampling: they usually require a fixed-size buffer of samples as input, produce a fixed-size buffer of interpolated samples as output, and don't yield interpolated values one at a time.
  • Other sinc implementations are significantly more complex in terms of their required parameters. For example, the r8brain resampler requires a cutoff frequency and an attenuation level in the constructor (link), both of which are nowhere to be seen in dasp's resampler/interpolator.
  • I'm not seeing how the resampled result is lowpass filtered.

I'm admittedly new to the world of DSP, so I'm not sure if this code is correct, and if not, I'd like to understand why and how to fix it as part of my fork.

$\endgroup$
5
  • $\begingroup$ i took a glance at the code and while i am only a lowly C programmer, i don't quite see where the rubber meets the road in the code. i was sorta looking for a table lookup (into a windowed $\operatorname{sinc}(\cdot)$ function) and a dot product with the most current $L$ samples. and i was looking for a fractional sample pointer. $\endgroup$ – robert bristow-johnson Apr 2 at 23:05
  • $\begingroup$ Whoa, I'm honored to have you check out my question, your Audio EQ Cookbook has been a great help to me! But you bring up a good point, the lack of a lookup table/cache was another thing that I noticed was different between this impl and others. The most recent samples are part of the frames: ring_buffer::Fixed<S>, it's a fixed-size circular queue that gets updated as the underlying signal stream produces more frames. $\endgroup$ – Mark LeMoine Apr 2 at 23:48
  • $\begingroup$ i can't decode this. it's way too outa my element. i just can't grok where there is a fractional pointer that increments with a step size that has both an integer and fractional part. the integer part of the pointer points to the adjacent samples and the fractional part points to the set of coefficients to mix those adjacent samples to get the interpolated value, $\endgroup$ – robert bristow-johnson Apr 4 at 3:56
  • $\begingroup$ Ah, that's is in a different part of the library, in the signal portion: github.com/RustAudio/dasp/blob/master/dasp_signal/src/…. The Signal interface/trait expresses a sequences of frames as an iterator like, and interpolation is provided as an adapter to these signals. The step size incrementing (and wrapping, since the interpolant is kept between [0.0, 1.0)) occurs in the next bethod at the bottom of the above link. The Interpolator object can be one of several different supported interpolation schemes, of which the sinc interpolation is one of them. $\endgroup$ – Mark LeMoine Apr 4 at 19:09
  • $\begingroup$ Be easier and cleaner to write the code myself. I generally have a low opinion of most other people's code quality. $\endgroup$ – robert bristow-johnson Apr 4 at 19:52
0
$\begingroup$

This looks partially similar to the BASIC code in my Q&D resampling cookbook here: http://www.nicholson.com/rhn/dsp.html#3 which computes both the Sinc and the window (von Hann) on the fly (per sample).

But it appears that the .rs code is not determining the lowpass cutoff frequency (phi upper and lower) correctly. It needs to know whether the resampling is up or down in frequency, so that the Sinc computation can use something below half the lesser of the two frequencies.

Computation of one new resampled sample at a time works just fine, as long as the rate change is fixed (or increases slightly), and the initial and ending transients (related to the Sinc window width (or depth?)) are ignored (or accepted as transients).

$\endgroup$
1
  • $\begingroup$ Whoa, I'm honored again, your cookbook was incredibly helpful when I was learning about biquads! This is good to know, I was concerned about the code being incorrect as a result of the streaming approach. For running the BASIC samples on your website, would you be able to provide what flavor of BASIC it is, and/or what tools you would recommend to run them? $\endgroup$ – Mark LeMoine Apr 9 at 4:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.