class:: SubsampleOffset summary:: Offset from synth start within one sample. related:: Classes/ControlRate, Classes/RadiansPerSample, Classes/SampleDur, Classes/SampleRate, Classes/OffsetOut categories:: UGens>Info Description:: When a synth is created from a time stamped osc-bundle, it starts calculation at the next possible block (normally 64 samples). Using an OffsetOut UGen, one can delay the audio so that it matches sample accurately. For some synthesis methods, one needs subsample accuracy. SubsampleOffset provides the information where, within the current sample, the synth was scheduled. It can be used to offset envelopes or resample the audio output. classmethods:: method::ir Examples:: code:: // example: demonstrate cubic subsample interpolation // impulse train that can be moved between samples ( SynthDef(\Help_SubsampleOffset, { |out, addOffset| var in, dt, sampDur, extraSamples, sampleOffset, resampledSignal; in = Impulse.ar(2000, 0, 0.3); // some input. sampDur = SampleDur.ir; // duration of one sample extraSamples = 4; // DelayC needs at least 4 samples buffer sampleOffset = 1 - SubsampleOffset.ir; // balance out subsample offset sampleOffset = sampleOffset + MouseX.kr(0, addOffset); // add a mouse dependent offset // cubic resampling: resampledSignal = DelayC.ar(in, maxdelaytime: sampDur * (1 + extraSamples), delaytime: sampDur * (sampleOffset + extraSamples) ); OffsetOut.ar(out, resampledSignal) }).add; ) // create 2 pulse trains 1 sample apart, move one relatively to the other. // when cursor is at the left, the impulses are adjacent, on the right, they are // exactly 1 sample apart. ( var dt = s.sampleRate.reciprocal; // 1 sample delay s.sendBundle(0.2, [9, \Help_SubsampleOffset, s.nextNodeID, 1, 1, \out, 40, \addOffset, 3]); s.sendBundle(0.2 + dt, [9, \Help_SubsampleOffset, s.nextNodeID, 1, 1, \out, 40, \addOffset, 0]); ) s.scope(1, 40, zoom: 0.2); // example of a subsample accurate sine grain: // (I don't hear a difference to normal sample accurate grains, but maybe // someone could add an example that shows the effect) ( SynthDef("Help_Subsample_Grain", { arg out=0, freq=440, sustain=0.005, attack=0.001; var env, offset, sig, sd; sd = SampleDur.ir; offset = (1 - SubsampleOffset.ir) * sd; // free synth after delay: Line.ar(1,0, attack + sustain + offset, doneAction: Done.freeSelf); env = EnvGen.kr(Env.perc(attack, sustain, 0.2)); sig = SinOsc.ar(freq, 0, env); sig = DelayC.ar(sig, sd * 4, offset); OffsetOut.ar(out, sig); }, [\ir, \ir, \ir, \ir]).add; ) ( Routine { loop { s.sendBundle(0.2, [9, \Help_Subsample_Grain, -1, 1, 1, \freq, 1000]); rrand(0.001, 0.002).wait; } }.play; ) ::