ryukau / VSTPlugins

Uhhyou Plugins VST 3 repository.
https://ryukau.github.io/VSTPlugins/
GNU General Public License v3.0
329 stars 12 forks source link

Suggestion for GlitchSprinkler #52

Closed arseniiv closed 2 months ago

arseniiv commented 2 months ago

Hi! Do you want to try adding an additional playback mode for the synth where the pitches are more true without compromising integer sample count of individual periods. (I’m not sure if it would always sound good but it should be not too complicated to try out and decide.) The idea is using periods of N samples and periods of N−1 samples at different times, making the average frequency more precise than a period of N or N−1 samples can get by themselves.

The basic idea of which period to choose is as in Bresenham’s line drawing algorithm. I already proposed to do the same for another plugin which is also sample-perfect by design: (comment). Translating my pseudocode from there, we have:

// init either at the very start or after each note on:
phase = 0;  // can be arbitrary in range [0; 1)

// init after each note on, note frequency being `f`:
period = sampleRate / f;
smallerPeriod = floor(period);
delta = period - smallerPeriod;

// while filling in an outgoing buffer when a note is on:
while (...) {
    phase += delta;
    longerPeriodNext = (phase >= 1);
    if (longerPeriodNext) {
        phase -= 1;
    }
    addMoreSamples(longerPeriodNext);
}

I renamed a couple variables to make it clearer and applicable to this here case.

Though now I see this code might be a bit incorrect when you have the desirable period be exactly an integer amount of samples (and delta exactly zero). That’s because phase can be less than zero but I implied it won’t. Hmmm. I’ll edit the code a little bit later. When delta is not exactly zero, the code should work flawlessly because phase will be all over the place—it’s just this corner case that’s wrong.

EDIT: I think I already fixed it!

[Initially I wrote this in a Youtube comment but it got deleted again. I don’t know why I bothered when here I can link related stuff and make the code formatted...]

ryukau commented 2 months ago

I implemented your method in Python 3. Could you review that the code matches your description?

https://gist.github.com/ryukau/6c6395780bd0f58be19b7268e7f40b75

I'll make some points after confirming that the code is correct.

arseniiv commented 2 months ago

I think it’s correct! 🤝 Haven’t run the code for myself, I just read it, but if you see reasonable frequency glides on the spectrogram when trying to change frequencyHz smoothly, then that’s more evidence it’s working as intended. (Though I’d test it on a sine waveform, not just on sawtooth, for the spectrum to be clearer.)

ryukau commented 2 months ago

Thanks for confirmation. I appreciate the idea, but it's not working. Audios are attached in the zip file below. The code in previous comment is also updated to render the 4 wave files in the zip file below.

test.zip

There are some noticeable artifacts on your method. The spectrograms are shown below.

Below is before modification (constant pitch).

constantpitch

Below is after modification (Bresenham's line pitch).

bresenhampitch

It looks similar to aliasing, but they may be not. I'm not sure. Probably the main cause of the artifact is frequency modulation. It might be a bit better to slow down the FM, but then the pitch becomes vibrated.


I'll close this issue. If there's something left, feel free to add a comment or to open a discussion.

arseniiv commented 2 months ago

Yeah I see, indeed too much of other frequencies get added and are very prominent. That’s unfortunate. Thanks for testing it out!