# Alias Suppression Non Linear Waveshaping

hey, ive found this code somewhere in the web for avoiding aliasing when dealing with non linear wave shaping and thought it would be capable of suppressing the alias for extreme `horizontal` values (near 0 or 1) for my attempt to write the vector phase shaping synthesis algorithm Phaseshaping Osc Algorithms - #42 by dietcv.
its working really nice on a linear ramp signal which is basically more or less we are dealing with in vector phase shaping (altered version of phase distortion).
is there someone who could help me adjusting the code for avoiding alias to use it for my VPS attempt? I already formatted the code and tried to write it in a more condensed way. Im not so sure about `BufRd` and `BufWr` because in the VPS attempt im not using any external buffers. any help would be very much appreciated.

Code for avoiding alias:

``````(
a = Array.interpolation(1000, 0.0, 1.0);
b = Buffer.sendCollection(s, a, 1);
a.plot;
)

//use an envelope with shifting points in order to dynamically change the transfer function

(
{
var bufFrames = BufFrames.ir(b.bufnum);
var sampleDur = SampleDur.ir;
var bufInputFreq = sampleDur * bufFrames;

/*
1.) use these points (modPoints) for the env levels – one extra last one (release node) so that the env loops properly
2.) make an envelope which will result in a warped transfer function
*/

var modPoints = [-1.0, -0.2, -0.5, 0.9, 1.0, 1.0];
// uncomment to replace the points with modulating values
//5.do { |i| modPoints = SinOsc.kr(ExpRand(0.1, 0.8), Rand(0.0, 6.28)).range(-0.9, 0.9)};
var env = Env(modPoints, [0.25, 0.25, 0.25, 0.25, 0.0], [2, -4, 7, -5, 0], 4, 0);
var bufInput = EnvGen.ar(env, timeScale: bufInputFreq);

var freq, sig, thisIndex, pos, playHead, output;

freq = MouseX.kr(20, 1000, 1).poll;
sig = SinOsc.ar(freq, 0, 0.8);
thisIndex = LinLin.ar(sig, -1.0, 1.0, 0.0, bufFrames);

// 3.) write the envelope (bufInput) into the buffer that is being used as the transfer function
pos = Phasor.ar(0, BufRateScale.kr(b.bufnum), 0, bufFrames);
BufWr.ar(bufInput, b.bufnum, pos);

playHead = BufRd.ar(1, b.bufnum, thisIndex, 0, 4);

output ! 2;
}.scope;
)
``````

VPS attempt (note with this example the value for `vertical` can only between two whole numbers like 2.001 and 2.999. im working on that.

``````(
{
arg freq = 300;
var horizontal = MouseX.kr(0.01,0.99);
var vertical = \vertical.kr(2.5);
var cos, phasor;

phasor = LFSaw.ar(freq/2,1).range(horizontal.neg, 1-horizontal);

phasor = phasor.bilin(0, horizontal.neg, 1-horizontal, vertical, 0, 1);
cos = Select.ar(phasor > vertical.floor,
[
(phasor * 2pi).cos.neg,
((phasor.abs.wrap(0,1)/(vertical-vertical.floor)*pi).cos*(vertical-vertical.floor)).neg-(vertical.ceil-vertical)
]
);

cos!2 * 0.1;
}.scope;
)
``````

ive tried to merge the code and came up with something like that and not sure how to continue:

``````(
{
arg freq = 150;

var bufFrames = BufFrames.ir(b.bufnum);
var sampleDur = SampleDur.ir;

var modPoints = [-1.0, -0.2, -0.5, 0.9, 1.0, 1.0];
var env = EnvGen.ar(Env(modPoints, [0.25, 0.25, 0.25, 0.25, 0.0], [2, -4, 7, -5, 0], 4, 0), timeScale: sampleDur * bufFrames);

var horizontal = MouseX.kr(0.01,0.99);
var vertical = \vertical.ar(2.5);
var cos, phasor;

phasor = Phasor.ar(0, freq/2 * sampleDur, horizontal.neg, 1-horizontal, horizontal.neg);
phasor = phasor.bilin(0, horizontal.neg, 1-horizontal, vertical, 0, 1);

//thisIndex = LinLin.ar(phasor, -1.0, 1.0, 0.0, bufFrames);

//pos = Phasor.ar(0, BufRateScale.kr(b.bufnum), 0, bufFrames);
//BufWr.ar(env, b.bufnum, pos);

//playHead = BufRd.ar(1, b.bufnum, thisIndex, 0, 4);

cos = Select.ar(phasor > vertical.floor,
[
(phasor * 2pi).cos.neg,
((phasor.abs.wrap(0,1)/(vertical-vertical.floor)*pi).cos*(vertical-vertical.floor)).neg-(vertical.ceil-vertical)
]
);

cos = LeakDC.ar(cos);
cos!2 * 0.1;
}.scope
)
``````

EDIT: ive also read something about B-Splines in several papers and downloaded the quark any ideas how to use them in relation to alias reduction?

ive used the envelope with the `modPoints` to trigger the `Phasor` and multiplied it with the `env` afterwards (is this kind of a windowed sync)? does this make any sense?
The signal has less aliasing i think (ive tried `freq` sweeps and extreme `horizontal` values) but the signal is far from beeing stable. sometimes it has audio drop outs and the function for modPoints is probably not the right one for the specific task. Im also not sure about the `timeScale` of the `env` because no buffer is used.

``````(
~nearest_even = {|val|
var val_floor, val_ceil, res, distance;
val_floor = val.floor;
val_ceil = val.ceil;
res = Select.ar (val % 2,
[ val_floor, val_ceil ],
);
distance = (val - res).abs;
[res, distance];
};

~nearest_odd = {|val|
var val_floor, val_ceil, res, distance;
val_floor = val.floor;
val_ceil = val.ceil;
res = Select.ar (val + 1 % 2,
[ val_floor, val_ceil ],
);
distance = (val - res).abs;
[res, distance];
};
)

(
a = Array.interpolation(1000, 0.0, 1.0);
b = Buffer.sendCollection(s, a, 1);
a.plot;
)

(
SynthDef(\vector, {
arg out=0, pan=0, amp=0.25, freq=300, sndBuf=0;

var sampleDur = SampleDur.ir;
var bufFrames = BufFrames.ir(sndBuf);
var bufRateScale = BufRateScale.kr(sndBuf);

var horizontal = MouseX.kr(0.01,0.99);
var vertical = K2A.ar(MouseY.kr(1.0,10.0));

var vertical_even = ~nearest_even.(vertical);
var vertical_odd = ~nearest_odd.(vertical);
var cos, phasor, sig;

//var modPoints = [-1.0, -0.2, -0.5, 0.9, 1.0, 1.0];
var modPoints = { SinOsc.kr(ExpRand(0.1, 0.8), Rand(0.0, 6.28)).range(-0.9, 0.9) } !5;
var env = EnvGen.ar(Env(modPoints, [0.25, 0.25, 0.25, 0.25, 0.0], [2, -4, 7, -5, 0], 4, 0), timeScale: sampleDur * bufFrames);

vertical = [vertical_even[0], vertical_odd[0]];

phasor = Phasor.ar(env, freq/2 * sampleDur, horizontal.neg, 1-horizontal, horizontal.neg);
phasor = phasor.bilin(0, horizontal.neg, 1-horizontal, vertical, 0, 1);

cos = (phasor * 2pi).cos.neg;

cos = XFade2.ar(cos[0], cos[1], vertical_even[1] * 2 - 1);

sig = cos * env;

sig = Pan2.ar(sig, pan, amp);
sig = LeakDC.ar(sig);
Out.ar(out, sig);
)

(instrument: \vector, midinote:43, sndBuf: b.bufnum).play;

s.freqscope;
``````

ive also found some threads about polyBLEP but not implementations in SC.

``````// PolyBLEP by Tale
// (slightly modified)
// http://www.kvraudio.com/forum/viewtopic.php?t=375517
double PolyBLEPOscillator::poly_blep(double t)
{
double dt = mPhaseIncrement / twoPI;
// 0 <= t < 1
if (t < dt) {
t /= dt;
return t+t - t*t - 1.0;
}
// -1 < t < 0
else if (t > 1.0 - dt) {
t = (t - 1.0) / dt;
return t*t + t+t + 1.0;
}
// 0 otherwise
else return 0.0;
}
``````