Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The filters #30

Closed
23 of 25 tasks
jpcima opened this issue Jan 28, 2020 · 9 comments
Closed
23 of 25 tasks

The filters #30

jpcima opened this issue Jan 28, 2020 · 9 comments
Assignees

Comments

@jpcima
Copy link
Collaborator

jpcima commented Jan 28, 2020

I attach an implementation of filters which matches ARIA near perfectly. (when implemented there)

It uses some very generic resonant filters, it showed to be quite easy to reproduce them.

Current:
sfz-filters
sfzfilters.dsp.gz

Reference:
https://sfzformat.com/opcodes/fil_type
https://sfzformat.com/opcodes/fil2_type

Status:

  • lpf_1p
  • hpf_1p (buggy in current Plogue ARIA, reported and fixed)
  • lpf_2p
  • hpf_2p
  • bpf_2p
  • bpf_1p
  • brf_1p (equivalent of brf_2p in Plogue ARIA)
  • brf_2p
  • lpf_4p
  • hpf_4p
  • lpf_6p
  • hpf_6p

New ARIA extensions:

  • lsh
  • hsh
  • peq

Not implemented by ARIA:

  • apf_1p
  • lpf_2p_sv
  • hpf_2p_sv
  • bpf_2p_sv
  • brf_2p_sv
  • pkf_2p
  • comb
  • pink

Implemented by us, not in specification:

  • bpf_4p
  • bpf_6p
@redtide
Copy link
Member

redtide commented Jan 29, 2020

brf_2p is listed in SFZ1 fil_type, I kept them separated.

@jpcima
Copy link
Collaborator Author

jpcima commented Jan 29, 2020

@redtide edited.
Also, added the All-pass and Notch.

@jpcima
Copy link
Collaborator Author

jpcima commented Jan 29, 2020

Here, I implemented the Hal Chamberlin state-variable filter.
This one fits requirements to implement the *_sv opcodes, but needs way more precaution.
chamberlin.dsp.gz

Reference: https://www.earlevel.com/main/2003/03/02/the-digital-state-variable-filter/

As noted from the article:

The main drawback of the digital state variable is that it becomes unstable at higher frequencies. It depends on the Q setting, but basically the upper bound of stability is about where f reaches 1, which is at one-sixth of the sample rate (8 kHz at 48 kHz). The only way around this is to oversample. A simple way to double the filter’s sample rate (and thereby double the filter’s frequency range) is to run the filter twice with the same input sample, and discard one output sample.

It means if we want to permit range up to 22 kHz, oversample by 3 and call the filter with 1/3 effective cutoff.
(Assuming 44.1 kHz as FsMin)

@jpcima
Copy link
Collaborator Author

jpcima commented Jan 29, 2020

More general notes:

The cutoff is modulable, it means to recompute the filter coeffs, potentially at the audio rate.

  • as it is, the operation will be expensive, considering it makes 1 or 2 mathcalls each audio frame (sin, cos, or "sincos" if known to compiler)
  • a way to reduce computation, it's to update filter coeffs less frequently. for example, only update every Nth frame (typical N=16).
  • in effect, this creates a staircase effect; while probably not perceptible, it needs to check if strong modulation affects the filter stability
  • when LFO exists, it should be tested at extreme conditions that the filter stability holds well. one can generate the faust code with internal double precision to improve numerical robustness. (flag -double)

@jpcima
Copy link
Collaborator Author

jpcima commented Jan 29, 2020

I made a multimode-filter wrapper class. It is a very simple API.
https://github.com/jpcima/sfz-filters-experimental

It's probable that sfizz can use it like it is, however, it will be better if I make also a dedicated stereo wrapper, because then it can optimize filter computations further.

It permits modulation of Cutoff and Q. It works like this:

  • Filter coeffs will recompute at some particular time intervals, such that it's less computation than updating it every frame. Computing the filter involves trigonometric functions.
  • The coeffs are also going to be smoothed (an advice of David), such that it will be more robust in case of strong modulation. Also note than in this configuration, vectorizing is not possible.
  • The smoothing is not really calibrated at this point, it was set to a default thing, which means a LFO may possibly lag. I left a TODO comment at smoothCoefs.

@jpcima
Copy link
Collaborator Author

jpcima commented Jan 30, 2020

Implemented most of filters in the sfz-filters-experimental repo above.
I think code as ready to be copied into sfizz at this point.

  • added an optimized specialization for stereo
  • added state-variable filters, based on Eric Tarr's Sallen-Key digital model
  • had to upgrade the precision to double, as some models were instable (eg. the 6-poles)

From observation, state-variable variants don't have a lot of difference with ordinary biquads.

In the repo, you can find also a JACK Qt client if you'd like to test these filters.

@jpcima
Copy link
Collaborator Author

jpcima commented Jan 30, 2020

Added the Peaking EQ and shelves.

@paulfd
Copy link
Member

paulfd commented Jan 30, 2020

Hi @jpcima and thank for all this work. I may not have time until this WE but I will prepare integration then and we can discuss more on a pull request if that's OK with you?

@jpcima jpcima mentioned this issue Jan 30, 2020
@paulfd paulfd self-assigned this Feb 9, 2020
@paulfd paulfd added this to the 0.3.0 milestone Feb 14, 2020
@paulfd
Copy link
Member

paulfd commented Feb 18, 2020

Let's move this into the release, thanks alot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants