xiphonics / picoTracker

BSD 3-Clause "New" or "Revised" License
202 stars 17 forks source link

Clicking Sounds When Abruptly Changing Sample Position (PLOF, Slice, RTRG) in the Sample Player #215

Open fpiesik opened 1 week ago

fpiesik commented 1 week ago

Whenever the sample player makes abrupt changes to the sample position (e.g., using PLOF, slice, or RTRG commands), an audible click sound can occur due to the instant change in amplitude.

Steps to Reproduce:

  1. Load a loop into the Sample Player.
  2. Use the PLOF command to jump to different positions within the loop.

Expected Behavior:

Position hopping should work without any audible clicking sounds, by implementing smoother transitions or a mechanism to avoid abrupt waveform changes.

Possible Solutions:

Code Hints:

In the code, I found some indications that an anti-click mechanism may have been partially implemented by the original authors:

In SampleInstrument.cpp:
Line 25: #define SHOULD_KILL_CLICKS true
Lines 291, 921, 1093: rp->couldClick_ = SHOULD_KILL_CLICKS;

However, the couldClick_ variable does not seem to be used elsewhere in the code. It appears this feature is still a work in progress.

It would be fantastic if this work could be completed, as the presence of these clicks significantly detracts from the experience of sample mangling in LGPT.

maks commented 1 week ago

Thanks for filling this issue.

I've run into clicks while using some of the fx commands too, but I'm not sure about the best way to go about addressing this, for instance using PLOF for granular playback of very short samples, it often won't make sense to do any of those 3 possible solutions you listed.

fpiesik commented 6 days ago

I have two ideas in mind:

  1. Adding an option in the instrument menu that allows the user to choose between "smoothed" or "raw" position-hopping. This way, users can select the mode that best suits their needs.
  2. Introducing slice-offset markers to fine-tune slice positions manually to find zero-crossings. This option would apply only to slices but could allow for smooth hopping between different parts of a loop without causing audio clicks while leaving granular synthesis untouched.

The second approach might be more technically straightforward to implement, as triggering a fade mechanism at the exact right time seems complicated, especially since everything else appears to be k-rate-timed, which isn't fast or precise enough. This is particularly true with fade-outs, as they need to occur before the sample position is changed. To achieve this, you'd need to introduce some kind of look-ahead mechanism to determine whether a PLOF command will be triggered in the next step.

fpiesik commented 5 days ago

The more I play with the tracker, the more I realize that it definitely needs a smoothing mechanism. For example, if I play a bass sample that is half a note long and want to trigger it every quarter note, it clicks almost every time. I think there is no way around to implement a detector that triggers the sample to fade out before its play position changes.

maks commented 5 days ago

@fpiesik thats an interesting example, but in this case, it sounds more like what you want is to be able to set a ADSR volume envelope?

fpiesik commented 5 days ago

Envelopes would definitely help in some cases. There’s already the possibility to use the VOLM command to achieve something similar to envelopes, but that requires setting the VOLM speed fast enough to ensure the envelope is completely finished before the next note is triggered. That’s not very convenient. So I think there should be something at a lower level that always ensures at least a few milliseconds of fading between sudden sample amplitude value changes.

maks commented 5 days ago

Yes I've noticed that myself too, tables aren't fast enough to implement ADSR envelopes properly so I have implementing dedicated ADSR vol envelopes on the to-do list.

fpiesik commented 5 days ago

I'm looking forward to envelopes, but I'm not convinced they will eliminate the problem of clicking sounds in many cases. For example, if you choose a long decay for sustained notes, you'd have to adjust the decay every time you want to mix shorter notes with the longer ones.