On Sun, May 30, 2021 at 7:14 AM <chanof@xxxxxxxxxxx> wrote:
> Hi there,
> May ask to you how to archive an hardsynced sware wave and the best practice to antialiasing,
First, the bad news -- anti-aliasing is not well supported in
SuperCollider. AFAIK would have to write it in C++ (or FAUST) as a
binary UGen. (The most common way to handle antialiasing is
oversampling -- compute the geometric waveform, with aliasing, but at
4x or 8x the sampling rate, and then use a filter to band-limit the
signal *before* downsampling to the final rate. SC server doesn't have
oversampling between UGens. A single UGen can oversample internally,
but that needs C++ or FAUST. The other way might be related to BLEP
but we don't have a way to apply that to an arbitrary signal.)
But, a hard-synced pulse wave is not too difficult, if you take it apart.
Many types of oscillators can be viewed in terms of the relationship
between an increasing phase and the final output, e.g. a sinewave:
```
p = {
var phase = Phasor.ar(0, 220 * SampleDur.ir, 0, 1);
[phase, (phase * 2pi).sin]
}.plot;
p.superpose_(true).refresh;
p.plotColor_([Color.red, Color.green]).refresh;
```
(It will look the same if you use `SinOsc.ar(220)` instead of the
`sin` operator.)
OK, now a square wave.
```
p = {
var phase = Phasor.ar(0, 220 * SampleDur.ir, 0, 1);
[phase, LFPulse.ar(220, 0.5)]
}.plot;
p.superpose_(true).refresh;
p.plotColor_([Color.red, Color.green]).refresh;
```
In the relationship that emerges is: When the phasor is above a
threshold, push it to +1; when below, -1. The threshold determines the
pulse width.
```
(
a = {
var freq = MouseY.kr(200, 600, 1);
var width = MouseX.kr(0.01, 0.99, 0);
var ph = Phasor.ar(0, freq * SampleDur.ir, 0, 1);
// (ph > width) is 0 to 1
// we need -1 to 1
var pulse = (ph > width) * 2 - 1;
// width != 0.5 will have some DC offset
pulse = LeakDC.ar(pulse);
(pulse * 0.1).dup
}.play;
)
a.release; // when done
```
You can't hard sync Pulse or LFPulse, but... you can do it to Phasor.
And we know how to turn a Phasor into a (non-bandlimited ;'-/ ) pulse
wave.
```
(
a = {
var freq = MouseX.kr(200, 1200, 1);
var width = LFDNoise3.kr(0.2).range(0.15, 0.5);
var syncfreq = MouseY.kr(50, 200, 1);
var syncOsc = SinOsc.ar(syncfreq);
// 'trigger' when syncOsc has an upward zero crossing
var ph = Phasor.ar(syncOsc, freq * SampleDur.ir, 0, 1, 0);
var pulse = (ph > width) * 2 - 1;
pulse = LeakDC.ar(pulse);
(pulse * 0.1).dup
}.play;
)
a.release; // when done
```
(Move the mouse left/right for the classic sync sweep effect. At
moderate frequencies it's not too bad.)
hjh
_______________________________________________
sc-users mailing list
info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: https://listarc.bham.ac.uk/marchives/sc-users/
search: https://listarc.bham.ac.uk/lists/sc-users/search/