1 class:: SubsampleOffset
2 summary:: Offset from synth start within one sample.
3 related:: Classes/ControlRate, Classes/RadiansPerSample, Classes/SampleDur, Classes/SampleRate, Classes/OffsetOut
4 categories:: UGens>Info
9 When a synth is created from a time stamped osc-bundle, it starts
10 calculation at the next possible block (normally 64 samples). Using an
11 OffsetOut UGen, one can delay the audio so that it matches sample
15 For some synthesis methods, one needs subsample accuracy. SubsampleOffset
16 provides the information where, within the current sample, the synth was
17 scheduled. It can be used to offset envelopes or resample the audio
29 // example: demonstrate cubic subsample interpolation
32 Server.default = s = Server.internal; // switch servers for scope
35 // impulse train that can be moved between samples
37 SynthDef(\Help_SubsampleOffset, { |out, addOffset|
38 var in, dt, sampDur, extraSamples, sampleOffset, resampledSignal;
39 in = Impulse.ar(2000, 0, 0.3); // some input.
40 sampDur = SampleDur.ir; // duration of one sample
41 extraSamples = 4; // DelayC needs at least 4 samples buffer
42 sampleOffset = 1 - SubsampleOffset.ir; // balance out subsample offset
43 sampleOffset = sampleOffset + MouseX.kr(0, addOffset); // add a mouse dependent offset
45 resampledSignal = DelayC.ar(in,
46 maxdelaytime: sampDur * (1 + extraSamples),
47 delaytime: sampDur * (sampleOffset + extraSamples)
49 OffsetOut.ar(out, resampledSignal)
53 // create 2 pulse trains 1 sample apart, move one relatively to the other.
54 // when cursor is at the left, the impulses are adjacent, on the right, they are
55 // exactly 1 sample apart.
58 var dt = s.sampleRate.reciprocal; // 1 sample delay
59 s.sendBundle(0.2, [9, \Help_SubsampleOffset, s.nextNodeID, 1, 1, \out, 40, \addOffset, 3]);
60 s.sendBundle(0.2 + dt, [9, \Help_SubsampleOffset, s.nextNodeID, 1, 1, \out, 40, \addOffset, 0]);
63 s.scope(1, 40, zoom: 0.2);
69 // example of a subsample accurate sine grain:
70 // (I don't hear a difference to normal sample accurate grains, but maybe
71 // someone could add an example that shows the effect)
74 SynthDef("Help_Subsample_Grain",
75 { arg out=0, freq=440, sustain=0.005, attack=0.001;
76 var env, offset, sig, sd;
79 offset = (1 - SubsampleOffset.ir) * sd;
80 // free synth after delay:
81 Line.ar(1,0, attack + sustain + offset, doneAction:2); env = EnvGen.kr(Env.perc(attack, sustain, 0.2));
82 sig = SinOsc.ar(freq, 0, env);
84 sig = DelayC.ar(sig, sd * 4, offset);
85 OffsetOut.ar(out, sig);
86 }, [\ir, \ir, \ir, \ir]).send(s);
92 s.sendBundle(0.2, [9, \Help_Subsample_Grain, -1, 1, 1, \freq, 1000]);
93 rrand(0.001, 0.002).wait;