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 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
class:: VOsc3
summary:: Three variable wavetable oscillators.
related:: Classes/COsc, Classes/Osc, Classes/OscN, Classes/VOsc
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.
While link::Classes/VOsc:: cycles through its wavetable at one frequency,
this unit generator contains three oscillators at different frequencies,
mixed together.
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::freq1
Frequency in Hertz of the 1st oscillator. (non-interpolated control-rate)
argument::freq2
Frequency in Hertz of the 2nd oscillator. (non-interpolated control-rate)
argument::freq3
Frequency in Hertz of the 3rd oscillator. (non-interpolated control-rate)
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 VOsc3
(
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, freq = 240;
// mouse x controls the wavetable position
var bufindex = MouseX.kr(0, ~bufs.size - 1) + bufoffset;
Out.ar(out,
VOsc3.ar(
bufindex,
freq + [0,1],
freq + [0.37, 1.1],
freq + [0.43, -0.29],
0.3
)
)
}).play(s,[\out, 0, \bufoffset, ~bufs.first.bufnum, \freq, 240]);
)
// 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, n;
n = (i+1)*8;
a = Array.fill(n,0);
(n>>1).do({ arg i; a.put(n.rand, 1) });
s.performList(\sendMsg, \b_gen, buf.bufnum, \sine1, 7, a);
});
)
// new harmonics...
(
~bufs.do({ arg buf, i;
var a, n;
n = (i+1)**2;
a = Array.fill(n, { 1.0.rand2 });
s.performList(\sendMsg, \b_gen, buf.bufnum, \sine1, 7, a);
});
)
// new harmonics...
(
var a = Array.fill(64, { 1.0.rand2 });
var n = [1, a.size].interpolate(~bufs.size-1);
~bufs.do({ arg buf, i;
n[i].postln;
s.performList(\sendMsg, \b_gen, buf.bufnum, \sine1, 7, a.keep(n[i].asInteger).postln);
});
)
// cleanup
(
x.free;
~bufs.do(_.free);
)
::
|