Tips on how to avoid audio clipping

kmll's icon

I have created a simple patch that gives an gate effect by multiplying by 1 and 0. However this results in nasty clips since the audio is cut directly. Any tips on how to solve this. (I tested with the [Line] object and this worked if the metro setting was slow but not if the metro bangs quickly )

Max Patch
Copy patch and select New From Clipboard in Max.

Peter McCulloch's icon

What's happening is not technically clipping (that's when you run out of headroom by exceeding the output range [-1,1] of your dac~), but is a discontinuity in audio.You need to do some interpolation as you change the gain in order to prevent this. Here's an example using line~.
(you don't want to use line because it won't change on a sample-by-sample basis and this will cause "zipper
noise" when it changes in stages rather than continuously). In general, any changes in gain should be interpolated if the gain will be changed while the sound is being heard. HTH!

Max Patch
Copy patch and select New From Clipboard in Max.

kmll's icon

Hi Peter. Thanks for the advise this is just what I was after.

Sorry for calling it clipping but in Norway where I live clipping means cut so thats why I used the wrong phrase. However with regards to the output range do you know anywhere I can read up on this being from [-1,1]

Also the patch you provided is just what I was after but I do not quite understand what it does. Can I please ask you to elaborate the [pack f 100.] part?

Thanks

Peter McCulloch's icon

No worries on the terminology; just wanted to clarify so it would be easier when looking for help.
The output range of dac~ is [-1,1] and samples outside this range will be clipped to that range. You can certainly have values larger than this range in MSP, but when they go to the dac~, they have to be within this range. You can read more about this in the beginning MSP tutorials.

Line~ interprets lists as pairs of target and time. Toggle with pack f 100 will make lists of 0. 100. and 1. 100., and line~ will go to 0/1 over 100 ms. The f in pack is short for "float". Toggle outputs ints, but it's helpful for pack to go ahead and treat it as a float in case you wanted to use a flonum with pack to change the volume in the future.

It's not the only way you can do it; you could use join or a message box with $1 100, but I use pack because it allows me to alter either value (target or time) and the "f" serves as a reminder of the type that's going to go in, and that it will be replaced. You could write pack 0. 100. as well, but I prefer not to because I could easily forget a decimal place and then pack would treat the incoming value as an integer; this is fine when I'm just sending toggles, but often I want to get the in between values, too, so converting to an int is undesirable.

That's a lengthy explanation for something that is perhaps my own idiosyncrasy, but hopefully it helps.

kmll's icon

Thank you so much for the good explanation. I understand now and I believe this is a very useful tecnique that I will use in the future. Thanks for sharing and explaining this.