how to make razor distortion (from scratch)?

genfu's icon

I know that you can use the overdrive~ object to create distortion, but i'm trying to create a few different distortions without using this.

The first which I want to create is a basic razor type distortion; so for example:
if the incoming signal is less than x, and more than -x it remains the same.
if the signal is more than x it outputs as x, and if it is less than -x it outputs as -x.
so x is basically the variable threshold and anything outside of that value will be chopped off/clipped.

I would then also want to have some other selectable types, this image shows how a sinewave would be affected by the various types:
http://img509.imageshack.us/img509/5328/renoisedistortion.png

The trouble is I cannot work out how to actually do this; not even the first 'razor' one i've described above which is theoretically straight forward. Do I need to use lookup~ for this? I've been through the waveshaping tutorial, but from that I don't understand how I would use a buffer~ signal to alter an existing signal. although the lookup~ documentation implies this is possible - it shows an example of a signal being processed through lookup~ with a compression buffer to modify the signal?

I've also tried converting the signal to an integer and using 'if', then converting it back to a signal again but I must be doing something wrong there because it doesn't work.

Any pointers on this would be appreciated.

Mike S's icon

clip~ is what you need

genfu's icon

okay thanks, yes that'd do the razor.

how about the 'Shape' distortion though (in the image link I posted)? The distortion curve is softer there, so it cannot be created with a basic clipping mode. instead I probably need to apply an equation to the signal to manipulate it. someone suggested something along these lines:

k = 2 * threshold / (1 - threshold)
output = (1 + k) * input / (1 + k * abs(input))

how would i most effectively/simply do that in max/msp?

Roman Thilenius's icon

you _can do that with waveshaping using [buffir~] but you might also consider splitting the signal at a treshold (like -0.8 and 0.8) and perform functions on them; inverse, cos, tanh, things like that.