Hi, I thought I could stick forever with a message going to line~ with aproximately 30ms and my clicking troubles would be gone, but I found out a situation where I can still hear a click (actually it's more like a "puff"). I'm constructing a sampler with play, stop and pause buttons and that's where this situation appeared. I was trying to find out the origin of this quick "puff" sound when I click the stop and I got this minimum patch that still exhibits the behavior. Even with high values of 300ms, the click/puff is still audible. Is this an extreme example in some sense or the line~ modus operandi is far from perfect and should be replaced by something better?
Best way to avoid clicks (tabread4~)
Amplitude modulation of any sort, including envelopes, always distorts the spectrum to some extent.
Normally we don't notice because typical sounds have a complex spectrum, which masks the distortion.
But here, you are applying it to an artificially simple spectrum, containing only DC offset. DC offset is silent, and the spectral distortion is not, so there is nothing to cover it.
I generated an audio file with a 30 ms ramp up and 50 ms ramp down. For comparison, I applied this envelope to a sine wave in the right channel. Then I opened this file in Audacity and looked at the spectrogram.
I think it's pretty easy to see here why the envelope might be audible in the case of DC * envelope, but not perceptible in the case of the audible signal * envelope.
Bottom line is, just because you hear spectral distortion in an artificial scenario which you would never encounter with audible signals, doesn't mean that it will be noticeable in real world scenarios.
(Carrying it further: If there is no envelope, there's a risk of an instantaneous transition from non-zero to zero or vice versa. Instantaneous transitions require a lot of high-frequency content, which we hear as a click. A linear transition effectively lowpass-filters the instantaneous transition -- there are still artifacts, but they are relatively low amplitude, and in a frequency range normally occupied by musical tones at a much higher amplitude. A ramp-enveloped sound will never be perfect, but it's better than a rectangular envelope.)
"replaced by something better" -- A sinusoidal envelope shows a smoother spectrogram. You might try that: cos * 0.5 + 0.5 -- from pi to 2pi is your ramp up, 0 to pi is the ramp down.
Edit: You can eliminate the +0.5 by squaring the cos and halving theta, because cos^2 x = cos(2x) * 0.5 + 0.5. Actually cos~, IIRC, scales radians down to 0 .. 1, so you could do line~ --> cos~ --> [*~] (cos~ to both inlets) and drive it by "0.25, 0.5 30" for the ramp up, and "0, 0.25 50" for the ramp down. Haven't verified this at the computer but I think it's right.
@Cmaj7 If I recall correctly you had issues with your soundcard making artifacts when reproducing a biased signal a while back. --> https://forum.pdpatchrepo.info/topic/13603/buzzing-sound-with-tabread
The circuit your posted here is sending a flat bias to the dac...
@ddw_music Nice demonstration, that seems exactly what I'm facing. I'll try the sinusoidal envelope.
@seb-harmonik.ar The slider goes from 0 to 1 and apparently the size of the array doesn't matter, according to some tests. I tried some values from 500 to 100.000 samples.
@bocanegra That's true, but I made my tests here when there was no buzzing sound. The situation here is different, the click just happens when the volume changes abruptly (clicking the message or the slider).
Who hears clicks when switching at zero-crossings?
It's always been absolute nonsense that it's safe to edit at zero crossings -- as you demonstrated
I think: to avoid clicks, not only the signal itself should avoid discontinuities, but also the derivative (the slope) of the signal should avoid discontinuities. A sharp cutoff at a zero crossing will feature a break in the slope even if there isn't a large jump in the signal itself.
This is also why a sinusoidal envelope is smoother -- because the slope of the envelope is itself a sinusoid (derivative of sin = cos and vice versa).
@whale-av I put the array it in a [table array] and I still get the clicks. The array is already fully loaded with read -> soundfiler before any manipulation. I don't get the clicks in your patch with readsf~ when pause/resuming and neither pause/stopping, which are the problems in my original patch in progress.
@Cmaj7 Maybe you should zip up your whole patch (without sound files) and upload it to this thread.
I think you have a problem we will not find without the whole picture.
But try this patch first....... Microsound-granular.pd ..... as it is also reading from arrays (onscreen) and softening crossovers with a short fade down and back up again (duck)....... and maybe your problem is not the speed of the duck but when the duck occurs........ it needs to start before the crossover and be at zero already at the crossover point.
So the crossover needs to be delayed slightly...... the duck needs to know it is about to happen a few milliseconds earlier...... 5ms in the above patch....... see the "granular" part in the middle.
The delay will not affect your musical timing noticeably...... 5ms is like moving 5 feet away from your speakers..... or being 5 feet from another player in the band.
@whale-av So, while playing with your patch I don't think I get any clicks. I'm uploading my patch here, it's a one shot sampler with line~. I'll still implement L/R boundaries and speed change, but the main part is done. When I Pause and then press Stop (or Play) there is a click and the part that I thought would fix this is around "Trying to fix click" (at least just for the Stop). Also, maybe it's a bit messy, any tips on that are appreciated too
I'm uploading my patch here, it's a one shot sampler with line~. I'll still implement L/R boundaries and speed change, but the main part is done.
FWIW I was just working on sample playback: https://forum.pdpatchrepo.info/topic/13637/properly-usable-soundfile-playback-without-silly-gotchas
sf-play~ uses cyclone but I think sf-varispeed~ doesn't.
I find it a bit curious that users have to struggle with this basic use case.
@Cmaj7 Sorry....... been very busy.........
This should solve it........ sampler_1.pd
I have put a stupidly long fade time (1500ms) as a human readable demo of what is needed to stop clicks. You can delete the 1500 (and the visual aid) and use the horizontal fader to set the fade time in ms to a setting that works for your ears.
You can delete that too when you are happy and type the value into the [delay]s and the [pipe]........
Just out of curiosity -- since I've just spent almost 2 weeks creating abstractions to simplify sample playback for my students -- is there any advantage to the methodology in sampler_1.pd over my abstractions in https://github.com/jamshark70/hjh-abs ?
I've got it to the point where I can do this:
Sound file segments are addressable by milliseconds (not samples -- conversion is handled for you, and it works even if the sound file sample rate is different from the system sample rate, so your patch can be portable to other computers or sound cards). Backward play is fine. You can set an attack/release time, and loop.
I realize this is not pd-vanilla's native dialect, but I kinda like it.
@ddw_music Your abstractions look great......
The changes I made to the OP sampler were just to demonstrate how he can avoid clicks when stopping and starting his reading of the array........ and hopefully help explain why his solution was not working.
In my case, it's just because it looks like a project that every pd student should do. The way I made the patch is just the way I solved the problems with my limited knowledge and tried to stay as vanilla as possible. Also, it's nice to have a whole work just of your own I'll check the abstraction and the corrections as soon as I have some time.
@whale-av Hi, finally I got some time So, first of all I deleted this dumb line, which was breaking my code, making the pipe useless.
I thought this would fix everything, but since a fast transition to 0 is necessary, I still get the puff mentioned in the original problem of my first post. This is the mechanism I used to solve the clicks:
The idea is: whenever I press my custom Stop button, immediately pause the [line~] reading the array (with the [stop( message) and send a [0 fade_time( message to the [line~] responsible for the volume, but don't go to the beginning of the array immediately, wait fade_time (which is what the [pipe] is doing, in this example with fade_time = 500). Also, I just added a delay object to make the volume come back to where it was before.
Except for the send/receive design (and the state of the overall volume), I could only spot one difference comparing your patch and mine: when the Stop button is pressed, you don't [stop( it immediately like me, but you wait fade_time and only then you pause the [line~] and go to the beginning of the array. However, the [stop( message doesn't introduce a click, so I still don't know why your patch works flawlessly and not mine, am I missing something?