1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
class:: VOsc
summary:: Variable wavetable oscillator.
related:: Classes/COsc, Classes/Osc, Classes/OscN, Classes/VOsc3
categories:: UGens>Generators>Deterministic
Description::
A wavetable lookup oscillator which can be swept smoothly across
wavetables. Fractional values of table will interpolate between two adjacent tables.
This oscillator requires at least two buffers to be filled with a wavetable format
signal. This preprocesses the signal into a form which can be used efficiently by
the oscillator. All the wavetables must be allocated to the same size, and the size
must be a power of two.
subsection:: Setting your tables with Buffers
The wavetable can be generated by filling a buffer via the
link::Classes/Buffer#Buffer Fill Commands:: (e.g. link::Classes/Buffer#-sine1::).
Set code::wavetable: true:: to ensure the proper data formatting.
Identically, you can create a link::Classes/Buffer:: object by sending one of the
code::\b_gen:: messages code::\sine1::, code::\sine2::,
code::\sine3:: (see
link::Reference/Server-Command-Reference#Wave Fill Commands:: and examples below),
again remembering to enable the wavetable format.
You can use link::Classes/Buffer#*allocConsecutive:: to ensure a contiguous buffers
numbers to be interpolated.
subsection:: Setting your tables with Signals
This can also be achieved by creating a link::Classes/Signal:: object and sending
it the link::Classes/Signal#-asWavetable:: message, saving it to disk, and having
the server load it from there.
classmethods::
method::ar, kr
argument::bufpos
Buffer index. Can be swept continuously among adjacent wavetable
buffers of the same size.
argument::freq
Frequency in Hertz. (non-interpolated control-rate)
argument::phase
Phase offset or modulator in radians.
argument::mul
Output will be multiplied by this value.
argument::add
This value will be added to the output.
Examples::
code::
// allocate and fill the buffers to be used by VOsc
(
s.waitForBoot({
var numBufs = 8;
// allocate table of consecutive buffers
~bufs = Buffer.allocConsecutive(numBufs, s, 1024, 1);
s.sync;
~bufs.do({ arg buf, i;
var n, a;
// generate array of harmonic amplitudes
n = (i+1)**2;
a = Array.fill(n, { arg j; ((n-j)/n).squared.round(0.001) });
// fill table
// argument '7': flag for the \sine1 wave fill method
// see "Wave Fill Commands" in the Server Command Reference
s.performList(\sendMsg, \b_gen, buf.bufnum, \sine1, 7, a);
s.sync;
});
"Buffers prepared.".postln;
})
)
// play the synth, indexing into the buffers with MouseX
(
x = SynthDef("help-VOsc",{ arg out = 0, bufoffset = 0;
// mouse x controls the wavetable position
var bufindex = MouseX.kr(0, ~bufs.size - 1) + bufoffset;
Out.ar(out,
VOsc.ar(bufindex, [120, 121], 0, 0.3)
)
}).play(s,[\out, 0, \bufoffset, ~bufs.first.bufnum]);
)
// fill the buffers with new harmonics on-the-fly
(
~bufs.do({ arg buf, i;
var a;
a = Array.fill(i, 0) ++ [0.5, 1, 0.5];
s.performList(\sendMsg, \b_gen, buf.bufnum, \sine1, 7, a);
});
)
// new harmonics...
(
~bufs.do({ arg buf, i;
var a = Array.fill(32,0);
12.do({ arg i; a.put(32.rand, 1) });
s.performList(\sendMsg, \b_gen, buf.bufnum, \sine1, 7, a);
});
)
// new harmonics...
(
~bufs.do({ arg buf, i;
var a = Array.fill((i+1)**2, { arg j; 1.0.rand2 });
s.performList(\sendMsg, \b_gen, buf.bufnum, \sine1, 7, a);
});
)
// cleanup
(
x.free;
~bufs.do(_.free);
)
::
|