sfilip / firpm

A scalable C++ implementation of the Parks-McClellan algorithm for designing FIR filters
BSD 3-Clause "New" or "Revised" License
29 stars 9 forks source link

Wishlist: allow arbitrary amplitude specification via lambdas, rather than piecewise constants #15

Open gsmecher opened 2 years ago

gsmecher commented 2 years ago

Currently, pass/stopbands are specified using std::vectors for frequency, amplitude, and weight. In principle, this allows arbitrary FIRs to be constructed using a very high number of subbands. However, it doesn't work in practice (I can substantiate "doesn't work" with a little effort: from memory, however, it's numerically unstable at subband boundaries.)

Specifying pass/stopbands as a lambda function accepting frequency and returning an (amplitude, weight) tuple would allow an arbitrary amplitude specifier and may actually reduce the number of special cases in the algorithm.

Question for @sfilip: is this an interesting refactor? If it were submitted as a pull request, what would your gut reaction be?

sfilip commented 2 years ago

Hi @gsmecher! I'm open to changes and would happily accept any PR that makes the library easier to use and/or offers more flexibility to the end user.

Regarding the construction of FIRs with a very high number of subbands, that's tricky numerically, since you would generally want the number of filter taps in such a case to be (much) larger than the number of subbands.

gsmecher commented 2 years ago

Regarding the construction of FIRs with a very high number of subbands, that's tricky numerically, since you would generally want the number of filter taps in such a case to be (much) larger than the number of subbands.

I think I understand your concern here. I'm trying to create lowpass filters with scaled inverse-sinc^n passbands - so the filter I'm producing is conceptually still only a (non-flat) passband, a transition region, and a stopband. The amplitude variation in the passband is smooth relative to the ripples in the FIR.

The trouble was, approximating a curve with piecewise linear passbands didn't work.

Thanks again - and stay tuned.