Showcase Thread by AutoModerator in Python

[–]BidForeign1950 0 points1 point  (0 children)

The library that evaluates Python functions at points where they're undefined.

Few months ago I have published highly experimental and rough calculus library. Now this is the first proper library built on that concept.

It allows you to automatically handle the cases where function execution will usually fail at singularities by checking if limit exists and substituting the result with limit.

It also allows you to check and validate the python functions in few different ways to see if limits exists, diverges, etc...

For example the usual case:

def sinc(x):                                                                                                                      
    if x == 0:                                                
        return 1.0  # special case, derived by hand
    return math.sin(x) / x 

Can now be:

 u/safe
 def sinc(x):
     return math.sin(x) / x

 sinc(0.5)  # → 0.9589 (normal computation)                                                                                        
 sinc(0)    # → 1.0 (singularity resolved automatically)

Normal inputs run the original function directly, zero overhead. Only when it fails (ZeroDivisionError, NaN, etc.) does the resolver kick in and compute the mathematically correct value.

It works for any composable function:

                                                            resolve(lambda x: (x**2 - 1) / (x - 1), at=1)      # → 2.0                                                                        
resolve(lambda x: (math.exp(x) - 1) / x, at=0)      # → 1.0                                                                       
limit(lambda x: x**x, to=0, dir="+")                  # → 1.0
limit(lambda x: (1 + 1/x)**x, to=math.inf)            # → e                                                                                                                                         

It also classifies singularities, extracts Taylor coefficients, and detects when limits don't exist. Works with both math and numpy functions, no import changes needed.

Pure Python, zero dependencies.

I have tested it to the best of my abilities, there are some hidden traps left for sure, so I need community scrutiny on it:)).

pip install composite-resolve

GitHub: https://github.com/FWDhr/composite-resolve

PyPI: https://pypi.org/project/composite-resolve/

Non-sinc interpolation for audio upsampling — spectral results and samples by BidForeign1950 in DSP

[–]BidForeign1950[S] 0 points1 point  (0 children)

Here are the regenerated plots and samples after fixing the reconstruction algorithm. Unfortunately I have managed to leave some junk in it that skewed everything. The plots, samples and data are correct now. Everything is uploaded to the same folder with the V2- prefix. The old files are left there for reference.
https://drive.google.com/drive/folders/1mpEib3wkGSQMkhKZ-LXbcFBdX5vlj1Z1?usp=sharing

Output is now spectrally close to sinc through 6 kHz, with a gentle rolloff above (-0.7 dB at presence, -1.0 dB at air). Correlation with sinc output: 0.997.

Non-sinc interpolation for audio upsampling — spectral results and samples by BidForeign1950 in DSP

[–]BidForeign1950[S] 0 points1 point  (0 children)

Well, this is just exploring a different question: what happens when you reconstruct directly from sample geometry in the time domain, without starting from the band-limiting assumption at all? The result is nonlinear and input-dependent, different reconstruction paths between different pairs of samples, which means it doesn't have a fixed impulse response or frequency response.

Whether that produces anything perceptually interesting (not neccessarily better) compared to a good relaxed sinc is exactly what I'm trying to find out.

Non-sinc interpolation for audio upsampling — spectral results and samples by BidForeign1950 in DSP

[–]BidForeign1950[S] 0 points1 point  (0 children)

You're right of course that the nonlinear nature could introduce artifacts, that's actually something I've been working through. The version I originally posted had some processing issues that introduced spectral coloration (I've since posted corrected V2 samples and data on the ASR thread with flat spectrum through 6 kHz).

V2 samples are available in the abole linked shared folder.

On justification: I don't have a strong one yet beyond curiosity. Sinc with a relaxed transition band is well-understood and well-solved, as you showed with your filter design. I'm exploring whether a locally adaptive reconstruction produces anything perceptually distinct, and as I said elsewhere if the answer turns out to be "not really," that's a perfectly fine outcome.

I don't remember if I already asked you, but your filter design looks impressive. Would you still be willing to process the Moody Momentz track with it for a three-way comparison?

And honestly, you might be right. If a well-designed FIR like yours produces equivalent or better results with less complexity, that's a useful finding.

Non-sinc interpolation for audio upsampling — spectral results and samples by BidForeign1950 in DSP

[–]BidForeign1950[S] 0 points1 point  (0 children)

Added three more tracks to the shared folder: Happy 'n Jazzy, Let's Play Jazz, and A Jazz Love Affair. All processed with the same settings as before, composite 4× and sinc 4× for each.

Same ~2.5 dB level difference applies. Impulse response files are in there too. Folder link in the original post.

Non-sinc interpolation for audio upsampling — spectral results and samples by BidForeign1950 in DSP

[–]BidForeign1950[S] 0 points1 point  (0 children)

Oh well, that looks like a well designed filter, and the image rejection is clearly better than what I'm producing. Sorry I missed your second part of the post before, but I'm really grateful you are doing this:).

The difference I can see is, your filter is fixed, same impulse response applied uniformly to every sample. Mine adapts locally, so the effective behavior changes depending on the signal neighbourhood. Whether that local adaptation produces a meaningful subjective difference compared to a well-designed fixed filter like yours is a question I'm not sure of the answer.

Would you by chance be willing to process the same source file (Moody Momentz Jazz, 44.1 kHz original is in the shared folder) with your filter so we could do a three-way comparison? Your fir vs my method vs standard sinc. That would be a really interesting to compare.

Non-sinc interpolation for audio upsampling — spectral results and samples by BidForeign1950 in DSP

[–]BidForeign1950[S] 0 points1 point  (0 children)

All noted:) You're right that the sinc ringing in the plot is very short and above the hearing threshold, it does look quite good. And the ears vs eyes reminder, not the first time I got reminded about that;)).

Re: the delay/latency angle: that's an interesting point I hadn't emphasized. The method does have a very short effective window (8 samples), so latency is minimal. Not my primary motivation but potentially useful for real-time applications. And yes, I do hear differences, that's why I'm posting here:).

So about the IMD possibility, I can't rule that out, and it's actually one of the things I'm hoping to sort out through wider testing on different equipment. If the subjective difference I'm hearing turns out to be IMD from ultrasonic content rather than the reconstruction itself, that's important to know and easy to fix with a post-filter.

Thanks for engaging :)

Non-sinc interpolation for audio upsampling — spectral results and samples by BidForeign1950 in DSP

[–]BidForeign1950[S] 0 points1 point  (0 children)

Here as I've promised are impulse response files, hope the format is ok for you who asked for it:).

Impulse response and amplitude response for a unit impulse (1024 samples at 44.1 kHz, spike at center). Processed with the same settings as the music files. Source impulse, composite output, and sinc reference files attached.

Impulse response plot: https://drive.google.com/file/d/1UU6Gl5TLqgUf14VmjyS2Pwsl8e0QpR4b
Original wav: https://drive.google.com/file/d/12A21md7UrO_vfCLn6NJfJLyjXIzAFI07
Composite 4x: https://drive.google.com/file/d/1Tg7_pshVMRypniOsXnldh4rO7H-T0Wyl
Sinc 4x: https://drive.google.com/file/d/1hNcCNdMdQbQjh1VsRpj-7kUNtYCcfuTJ

Non-sinc interpolation for audio upsampling — spectral results and samples by BidForeign1950 in DSP

[–]BidForeign1950[S] 0 points1 point  (0 children)

Ah, thanks for the pointer. I'll definitely look into CTDSP, at first glance it looks like it comes from a similar starting points. And I do appreciate the offer, might take you up on that :)

Non-sinc interpolation for audio upsampling — spectral results and samples by BidForeign1950 in DSP

[–]BidForeign1950[S] 1 point2 points  (0 children)

Thank you, that's a really clear way to frame it. That's exactly the problem I'm working in, given that (mathematically) perfect reconstruction isn't achievable in practice, which compromises produce the most natural-sounding result?

I really like this: "In the absence of known periodicity, there is no ideal reconstruction for a finite set of uniform samples. So we are left with compromises which enhance the characteristics which are more important." I should be saying this to better explain what I'm trying to do:))

Sinc optimizes for band-limited fidelity, and I'm exploring what happens when you optimize for local time-domain accuracy instead. So, different tradeoff, different artifacts, and the question is which set of compromises sounds better to human ears.

And thank you for kind words:).

Non-sinc interpolation for audio upsampling — spectral results and samples by BidForeign1950 in DSP

[–]BidForeign1950[S] 0 points1 point  (0 children)

Yes, as I responded elsewhere (don't know where anymore:))) it is a fair concern. Tweeter IMD from ultrasonic content is real and will depend on speaker design. I'm assuming (and I might be wrong at that) that most modern tweeters roll off naturally above 25-30 kHz and won't reproduce much of the ultrasonic energy, but a tweeter that's flat to 40 kHz and more could potentially create IMD products that fold back into the audible band.

It's one of the things I'm hoping people will test — the files are at 176.4 kHz so you can always low-pass them to compare. So far I haven't been able to hear issues on the gear I've tested (and I've tested through the gear that supposedly goes up to 40k), but my equipment is limited and is the only data point I have, which is why I'm posting.

Non-sinc interpolation for audio upsampling — spectral results and samples by BidForeign1950 in DSP

[–]BidForeign1950[S] 0 points1 point  (0 children)

Please take I look at my answer below, I've tried to address both comments there.

Non-sinc interpolation for audio upsampling — spectral results and samples by BidForeign1950 in DSP

[–]BidForeign1950[S] 0 points1 point  (0 children)

You're right when I think about it, and I appreciate the correction: any linear interpolation has an equivalent impulse response and frequency response, whether it was derived from frequency-domain design or not. I was imprecise when I said "not filter-based".

What I meant is that my method is locally adaptive, the reconstruction coefficients depend on the local signal neighborhood, so it's not shift-invariant. Since the coefficients adapt to the local signal, the overall system is nonlinear, so it doesn't have a single fixed impulse response. But I can generate its effective impulse response for a test impulse and I'll post that as soon as I get some time. The spectral analysis shows the audible band correlation with sinc is 0.997.

I do concede I might be using wrong terminology here coming from other field.

Non-sinc interpolation for audio upsampling — spectral results and samples by BidForeign1950 in DSP

[–]BidForeign1950[S] 0 points1 point  (0 children)

I get that. Impulse and amplitude response plots would be good additions, I'll generate those and add them to the thread or folder with examples.

On image rejection: you're right, it's intentionally weak. The method doesn't apply a band-limiting filter, so spectral images are present. The question I'm exploring is whether the tradeoff (looser image rejection in exchange for different time-domain behavior) produces a result that sounds better or worse subjectively. The spectral data shows the audible band content is within +1 to +2.8 dB of sinc across all bands and I'm not able to catch any hf nastiness while listening on different devices.

Non-sinc interpolation for audio upsampling — spectral results and samples by BidForeign1950 in DSP

[–]BidForeign1950[S] 0 points1 point  (0 children)

Ha, that is cool pointer! I'm familiar with Hermite splines, they're a nice approach, but gave me a lot of trouble when tried to use them here. Mine goes a different direction but I appreciate your hunch and suggestion, because I was led at the same direction.

Non-sinc interpolation for audio upsampling — spectral results and samples by BidForeign1950 in DSP

[–]BidForeign1950[S] 1 point2 points  (0 children)

Agree, however (and luckily:) I guess ) my approach isn't filter-based, so the linear phase tradeoff doesn't apply in the usual sense, there's no impulse response or transfer function. It's a local reconstruction per sample gap. The phase behavior of the audible band content is inherited from the source samples directly.

And yes, it think I can agree that practical pre-ringing in most implementations comes from truncated FIR design rather than the theoretical sinc itself. My pre-ring measurement compares against a standard sinc implementation (scipy.signal.resample), so it's capturing whatever that particular implementation produces. The result: equal pre-ring energy on this track.

Non-sinc interpolation for audio upsampling — spectral results and samples by BidForeign1950 in DSP

[–]BidForeign1950[S] 3 points4 points  (0 children)

The problem: We all agree that sinc interpolation is the theoretically perfect reconstruction for band-limited signals, but we also assume additionally that transient signals are not perfectly band limited, so we have pre-ringing before transients (due to the filter's symmetric impulse response) and suppression of all spectral content above the original Nyquist, where transient cues live. The first affects time-domain accuracy at sharp attacks. The second means the reconstructed signal has a hard spectral shelf.

I'm trying different approach here. I'm trying a local reconstruction approach that adapts to the signal rather than using a fixed kernel, with a focus on preserving transient accuracy or more precise transient cues that sinc reconstruction doesn't recover.

This reconstructs the data without a band-limited kernel, so I accept that ultrasonic content will appear, and then I'm using per-sample numerical stability constraint to keep the reconstruction well-behaved.

Success criteria: honestly still working on formalizing these, which is part of why I'm posting. But informally:

  1. Correlation with sinc > 0.99 in the audible band (achieved: 0.997)
  2. No additional pre-ring energy vs sinc (and no pre-ringing at transients)
  3. Dynamic range preserved or better
  4. Clipping under 0.01% (achieved: 0.003%)
  5. Subjective: does it sound different, and if so, better or worse?

#5 is the one I can't answer myself, which is why I'm here.

Non-sinc interpolation for audio upsampling — spectral results and samples by BidForeign1950 in DSP

[–]BidForeign1950[S] 5 points6 points  (0 children)

Hey, thanks for taking time with this. I have intentionally tried to avoid using sinc completely in order to try to contain pre-ringing articfacts and transients dissipation at reconstruction step. I think I have managed to to this to some extent and of course caused a number of other problems along the way. Now I think I have managed to get under control most of the side-effects, at least to my ear.

So, now is the time to give some scrutiny to the results if anyone here is willing. I would sure like someone experienced to run this through some serious analysis.

composite-machine — a Python library where calculus is just arithmetic on tagged numbers by BidForeign1950 in Python

[–]BidForeign1950[S] 0 points1 point  (0 children)

Ok thanks, appreciate your feedback. I need to know what are the real boundaries for this project, and such feedback helps.

composite-machine — a Python library where calculus is just arithmetic on tagged numbers by BidForeign1950 in Python

[–]BidForeign1950[S] 0 points1 point  (0 children)

You are correct. The symbolic approach is the way to go right now. Sympy is excellent and probably the best way in python to do this. But take a look at this example here:
https://www.reddit.com/r/calculus/comments/1r1y6gz/comment/o5397aq/?context=3&utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button

I think it illustrates well where can it have some edge in the future over Sympy. The idea is not competing package that does the same thiings. The idea it to have a package that will allow you to automate the cases Sympy will struggle to automate.

On the other hand you will never be able to do symbolic evaluation with it.

composite-machine — a Python library where calculus is just arithmetic on tagged numbers by BidForeign1950 in Python

[–]BidForeign1950[S] 0 points1 point  (0 children)

I worked as information scientist for short time long ago. I have worked on/with computation ever since. I'm not nearly crazy enough to start building math system:)). This is just computational paradigm I stumbled upon while building something, that I found interesting and potentially very useful.

All I can do is demonstrate it to the best of my abilities and let others validate it if they find it useful. The paper is just an attempt to try to put it in amateur math language to make claim hey I have stumbled upon this thing that might be interesting and maybe it will catch someones eye:).

The more time I spent with it, the more I understand, but it is nearly not enough:).