maximecb / noisecraft

Browser-based visual programming language and platform for sound synthesis.

Home Page:https://noisecraft.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Better, anti-aliased saw and pulse oscillators with PolyBLEP

maximecb opened this issue · comments

It's been brought to my attention that there's an issue with aliasing in the naive saw and pulse (square) oscillators that NoiseCraft currently implements.

These blog posts explain the issue and how to implement PolyBLEP oscillators that address the issye:
https://www.metafunction.co.uk/post/all-about-digital-oscillators-part-2-blits-bleps
http://www.martin-finke.de/blog/articles/audio-plugins-018-polyblep-oscillator/

This project demonstrates the issue in NoiseCraft:
https://noisecraft.app/103

This repo has source code we can base our implementation on:
https://github.com/martinfinke/PolyBLEP

This thread warns that it might sound duller, which might be worth investigating, because we don't want to cut the high-end harmonics too too much:
https://www.kvraudio.com/forum/viewtopic.php?t=375517

Hey!
This was an interesting problem so I wanted to spend some time understanding it.

I created a python script here that generates saw waves using various methods, including the pure time-based method that is currently used in NoiseCraft:
https://gist.github.com/greg7gkb/545f4e5f97af53f62fee0235288383eb

I recommend using a spectrum analyzer (spectrogram) to analyze the resulting waveforms.

Here is the spectrogram for the original, time-based approach:
Screen Shot 2022-05-01 at 11 27 29 PM
And here is the saw wave generated with PolyBLEP:
Screen Shot 2022-05-01 at 11 28 06 PM
You can see nearly all of the aliasing noise is gone using this method, and the computation cost is quite small (only two samples are adjusted near the saw wave discontinuity).

In contrast, the other method I tried, additively using sin waves to construct the saw wave, is computationally expensive and takes more work to normalize the output range.

So I'm not sure how important cpu cycles per sample generated are for the app, but PolyBlep seems like a great compromise all around (I'm not perceiving the 'dulling' discussed in the KVR forum).

Let me know what you think or if you want any more info.

Oh btw, the above screenshots were from Audacity which is available for free and includes the above spectrogram capability by default:
https://manual.audacityteam.org/man/spectrogram_view.html

Hey Greg. Thanks for taking the time to look at this. Would you feel comfortable trying to implement PolyBLEP in JS?

The NoiseCraft sawtooth oscillator is implemented here: https://github.com/maximecb/noisecraft/blob/main/public/audiograph.js#L342

My main concern would be how much this changes the "character" of the sound of existing NoiseCraft projects. If you open a pull request, I'll compare the sound of various projects using sawtooth waves. If it's too different, we could implement a new type of oscillator instead of replacing the current sawtooth.

Would you feel comfortable trying to implement PolyBLEP in JS?

For sure! Give me a day or two.

Wonderful! :)

I have a change proposal ready - would you prefer me to upload into this repo or fork and make a PR from that repo?

Oh wonderful :)

Can you fork and create a pull request?

Regarding above PR, here are the new spectrogram outputs captured from noisecraft:

Saw wave update:
Screen Shot 2022-05-04 at 8 52 40 PM
Square wave update:
Screen Shot 2022-05-04 at 8 52 27 PM
Note that the spectrums are much cleaner than before but they are not perfectly clean as you would see in an additive sine implementation.

Also note the increased computation required for PolyBlep. It's not insane but definitely more cycles than before. Suggest testing on the most complicated patch you have available to ensure that performance is still decent. I'm not sure what kind of margins you have in general for the update(freq) calls.

Greg has put together an implementation in #80 which is now pushed in the polyblep branch for reference. The conclusion is that the difference in audio output is very subtle in all the patches we've tried, at the cost of a bit more CPU cycles. Since only one person ever complained, we'll close this for now, but maybe we can add a new PolySaw oscillator type later if the purists come back and complain about the harmonics.