Re: Hardsynced squarewave and anti aliasing technics
[email protected] Sun, 30 May 2021 00:50:07 -0400
| Newsgroups | gmane.comp.audio.supercollider.user |
|---|---|
| Message-ID | <CAPjq8bT7VxcUx23CfqzhZ0MLJbbTPZNCrqEqGmr_4Rm3QS_Xrg@mail.gmail.com> |
For a couple years I've been using this approximation of a square wave that I found in some paper somewhere, can't find the paper right now, but it is basically just multiplying a sine wave by some large value, calculated to avoid extreme aliasing, and putting it through tanh distortion. Not perfect but you can go a lot higher without noticeable aliasing than with a naive approach and as a benefit supports hard sync using a phasor like James said: var phase = Phasor.ar(syncSig, freq / SampleRate.ir, 0, 1) * 2pi; var k = 12000 * (SampleRate.ir/44100) / (freq * log10(freq)); var sinSig = SinOsc.ar(0, phase); var sqSig = tanh(sinSig * k); a little more complicated to implement variable pulse width but I can share my solution to that too if anyone's interested.. On Sat, May 29, 2021 at 9:14 PM <[email protected]> wrote: > On Sun, May 30, 2021 at 7:14 AM <[email protected]> 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: http://www.listarc.bham.ac.uk/marchives/sc-users/ > search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ >