Shaper wave shaper

Shaper.ar(bufnum, in, mul, add)

Performs waveshaping on the input signal by indexing into the table.

bufnum - the number of a buffer filled in wavetable format containing the transfer function.

in - the input signal.

Examples use the Internal Server to show the effect of waveshaping via a scope. Use .play instead if necessary.

Server.default = s = Server.internal; s.boot;

b = Buffer.alloc(s, 512, 1, {arg buf; buf.chebyMsg([1,0,1,1,0,1])});

(

{

Shaper.ar(

b,

SinOsc.ar(300, 0, Line.kr(0,1,6)),

0.5

)

}.scope;

)

For those who's like to make their own wavetables for arbitrary shapers, your buffer must be in wavetable format to have a valid transfer function. Wavetable format is a special representation which includes an extra number between each sample containing the difference between two adjacent samples, to make linear interpolation faster.

Signal: [a0, a1, a2...]

Wavetable: [a0, a1-a0, a1, a2-a1, a2, a3-a2...]

If your buffer doesn't have the deltas between adjacent samples, the calculations are wrong and you get distortion.

There are two ways to get wavetables into a server buffer. The server can generate them (see the Buffer help file for the methods sine1, sine2, sine3 and cheby).

b = Buffer.alloc(s, 1024, 1);

b.cheby([1, 0.5, 0.25, 0.125]);

(

{ var sig = Shaper.ar(b, SinOsc.ar(440, 0, 0.4));

sig ! 2

}.scope;

)

Or, you can calculate the transfer function in a client-side array (Signal class) then convert it to a wavetable and send the data over.

// or, for an arbitrary transfer function, create the data at 1/2 buffer size

t = Signal.fill(512, { |i| i.linlin(0.0, 511.0, -1.0, 1.0) });

//linear function

t.plot

//t.asWavetable will convert it to the official Wavetable format at twice the size

b.sendCollection(t.asWavetable); // may also use loadCollection here

//shaper has no effect because of the linear transfer function

(

{ var sig = Shaper.ar(b, SinOsc.ar(440, 0, 0.4));

sig ! 2

}.scope;

)

// now for a twist

a = Signal.fill(256, {arg i; var t= i/255.0; t+(0.1*(t.max(0.1)-0.1)*sin(2pi*t*80+sin(2pi*25.6*t)))});

a.plot

d= (a.copy.reverse.neg) ++ a;

d.plot

(

b = Buffer.alloc(s, 1024, 1);

b.sendCollection(d.asWavetable); // may also use loadCollection here

)

b.plot //wavetable format!

//test shaper

(

{

Shaper.ar(

b,

SinOsc.ar(440, 0.5, Line.kr(0,0.9,6))

)

}.scope

)