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
Confusion about how to use LPC, and the Numerical Error it gives #1277
Comments
I don't have a ton of experience with LPC, but a few things come to mind:
I suspect these issues shouldn't occur when analyzing real data, but I'd like to have a better understanding of what's going on here. Maybe @ajweiss can chime in? |
I'll take a look at the numerical problem now, I'm guessing it may have to do with scaling. Yes, LPC is what you want, it will give you the filter coefficients for an IIR filter of the given order, given the input signal and an order. |
Incidentally, it's long been on my todo list to put together an example notebook that demos source filter separation and synthesis by analysis using LPC, maybe it's time to pick that back up... |
Ah thanks for the explanation. Some examples on this would be great! |
I'm currently trying to port the algorithm to rust, with the source from here: http://www.emptyloop.com/technotes/A%20tutorial%20on%20Burg's%20method,%20algorithm%20and%20recursion.pdf |
@ajweiss Do you have any sources about LPC I can read about? I understand it can be used to get the parameters of a linear model to predict the next value of a signal, but then why do the parameters also work as a filter, that also generates roughly the same signal if you put something through it? |
Hey, sorry I haven't had much chance to look at this. To quickly answer questions:
Anyway, this is just a quick note and it's from memory on stuff I haven't looked at in a little while. Please feel free to e-mail me if you have additional questions that are not librosa related. Otherwise happy to continue to conversation here for librosa related stuff (specifically ensuring the LPC feature is usable, what a nice demo notebook may look like or any other problems suggestions for librosa). Sound good? |
I should also add (in case you're asking about general applications), LPC is also useful for "analysis by synthesis" which is often used to analyze speech. I think your original reference talks about this, where the vocal tract is modeled by a source-filter system, where the source is a model of "glottal pulses" that provides excitation to an IIR filter which models the resonance of the vocal tract. (In the compression example, you store the frequency of the glottal pulse excitations and then the parameters for the AR filter which shapes it's input to model the resonant modes of the vocal tract). An additional form of analysis is to look at the frequency response of this sequence of digital filters, where peaks in the spectrogram will show these resonant modes, or formants. This along with the vocoders seems like fun for the demo. :) |
Ah thanks again for the detailed response! As for a good demo, I think it would be nice to both give an example of a predictive model and a filter, and an explanation of how/why that works. (along with the other things you mentioned) |
Chiming in here -- I'm extending the API to support LPC on multichannel inputs over in #1351 (prototype code buried in the comment thread), and ran into the stability issue when applying LPC to a framed signal. In the current implementation, we fail if Since I'm still a relative newbie at LPC business, I thought I'd ask for opinions on modifying this line: Line 943 in d9b72af
to something like reflect_coeff = dtype(-2) * np.dot(bwd_pred_error, fwd_pred_error) / (dtype(den) + epsilon) where Thoughts? (Esp. @ajweiss ?) |
I think the concern here, at least theoretically, is that a failed
computation could produce a filter with poles outside the unit circle. In
this case, the filter becomes unstable and can cease responding to changes
in input. This is theoretical though, and I'm not sure the actual impacts
on a real digital filter.
I'm just getting my day started, I'll take a look in depth later and get
back to you!
…On Thu, Aug 5, 2021, 7:39 AM Brian McFee ***@***.***> wrote:
Chiming in here -- I'm extending the API to support LPC on multichannel
inputs over in #1351 <#1351>
(prototype code buried in the comment thread), and ran into the stability
issue when applying LPC to a framed signal. In the current implementation,
we fail if den <= 0, and in the multichannel case, this extends to if
np.any(den <= 0) (which causes the entire function to fail). This would
be bad news if we wanted to implement something like LPCC, where failure in
one frame means failure for the entire computation.
Since I'm still a relative newbie at LPC business, I thought I'd ask for
opinions on modifying this line:
https://github.com/librosa/librosa/blob/d9b72af964820fc796425c55d3dccd7f6b908bf9/librosa/core/audio.py#L943
to something like
reflect_coeff = dtype(-2) * np.dot(bwd_pred_error, fwd_pred_error) / (dtype(den) + epsilon)
where epsilon = librosa.util.tiny(dtype), and dropping the underflow
condition in the loop. (Alternatively, we could do np.max(den, epsilon).)
This way we'll avoid divide by zeros, and potentially produce some garbage
features, but not cancel the entire computation.
Thoughts? (Esp. @ajweiss <https://github.com/ajweiss> ?)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1277 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADJB232NU7WGVFNH6PCM4LT3KPDXANCNFSM4W5OWX7A>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email>
.
|
Sure. I think adding a floor to the divisor still achieves that goal, but we'd suffer a little in estimation error. I haven't thought this through deeply though, so perhaps I'm missing something. |
Just a quick heads up that I tried out this idea, and it seems to work fine. An example that previously caused a numerical underflow seems relatively well behaved; the coefficients don't blow up on us (capping out around ~200 in this case). So, not a definitive proof that things will always come out okay, but it seems like a promising start. |
Interesting. Does the spectrum of the input signal and the frequency response of the found filter look similar? (example of how to get the frequency response using |
Looking at the code now, I think it's probably fine. If we wanted to be pedantic then maybe instead of throwing the By doing this we do deviate from the paper definition some more, but it's not the first time someone just added an eps in to keep the machine running. :) |
Yes, flag for the warning is a good idea. This has the added benefit of removing a branch point from the inner loop, so it should be substantially faster as well. I'll hold off on implementing that until after merging #1351 . |
Hey everyone! PS: funnily enough, I get the |
I'm actually not sure anything needs to be done - I got impatient because the exception was breaking some test cases that really ought to have worked. I had commented out the exception in #1351, see here: Lines 944 to 947 in eb603e7
and the epsilon floor is implemented below: Line 954 in eb603e7
That would be great! Maybe as an example to add to the gallery? |
Oh, I see now! I didn't look into the source so I thought it hadn't been addressed yet.
Do you mean the examples here or here? I suppose it's the latter. I will find some time to add a PR. |
It'll be 0.9, but hopefully before end-of-year!
Correct - my plan is to deprecate the examples folder #1328 and shift entirely to notebook-based examples built in the documentation.
🎉 |
In terms of analysis, I have a branch (https://github.com/ajweiss/librosa/tree/lpcspec) that implements both a short time LPC transform (windowed LPC coeffs) and also a function that then takes those coefficients and computes their spectrum. It hasn't been touched in quite a while, but is a pretty good start (I think) on the analysis side of things. What were you thinking in terms of analysis? I've been thinking about dusting this off for quite some time. I'd also be interested in collaborating on examples. In general I was considering LPC spectral analysis and perhaps a basic compression demo... What did you have in mind? |
That sounds great! I imagine it's much easier to implement now that the core LPC function can directly operate along a target axis (eg after framing). |
THanks for the pointer, @ajweiss! I will take a look at your code. |
Okay @miccio-dk keep me posted on the LPC spectrum and STLPC stuff specifically. If there isn't overlap there with the stuff you're hoping to do (or the stuff that is done is sufficiently complete that you don't feel like it would make for an interesting project), let me know and I'll pick it back up and create a PR from it. Otherwise, I'll get out of your way. :) |
Is there anything left to do here? It seems to me that the original issue is now resolved (since 0.9.0). If we want to discuss LPCC, perhaps that should be spun into a new feature request issue. |
I'll close this one out as resolved, but I'd still be keen to discuss extending our LPC functionality in other issues. |
Describe the bug
I don't understand what the Numerical error, input ill-conditioned?" error means in the LPC function, and I also find the documentation a bit confusing, as it doesn't really specify how I can use the LPC function.
To Reproduce
Software versions*
Additional context
I'm trying to use LPC to resynthesize speech from a given audio sample, however I struggle to understand how I should do this and how I have to use LPC in general.
From what I understand from here: https://www.fon.hum.uva.nl/rob/VocalTractExamples/
It's possible to use LPC to get the filter coefficients for source-filter synthesis, which is what I'm tying to do.
The text was updated successfully, but these errors were encountered: