DbufTag demand rate tag system on a buffer
superclass: UGen
*new(bufnum, v, axiom, rules, recycle, mode)
bufnum a 1-channel buffer - when its size is reached, the process ends (dependent on mode).
Theoretically, tag systems have an infinite tape size - practically, one may want to try different finite sizes.
Any number of tag processes may run concurrently on a single buffer,
overwriting each other's output. While not very expressive, this may have interesting results.
other arguments and more explanations, see [Dtag]
Examples
// for all the following examples: allocate a buffer.
// deallocate later with : b.free
b = Buffer.alloc(s, 11125, 1);
// One of the examples by Emil Post
// directly listen to the tag system output (audification)
// when the tape is empty, the synth is freed (doneAction: 2)
(
{
var tag, index, axiom, rules, dt;
dt = SampleDur.ir; // play with audio rate
axiom = [1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1];
rules = [[1, 0], [1, 1, 0, 1]];
// axiom = axiom.scramble.keep(rrand(4, 16)).postln; // vary the axiom
v = 3;
tag = DbufTag(b.bufnum, v, axiom, rules);
Duty.ar(dt, 0, tag, doneAction: 2).dup * 0.1
}.play;
)
// the above as a frequency input for a sine oscillator
// repeating it after it ended, with varying deletion number
// a little pause is inserted at each repetition.
(
{
var tag, axiom, rules, index;
var freq = 15000;
var deletionNumber = MouseX.kr(1, 6);
axiom = [1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1];
rules = [[0, 1], [1, 1, 0, 1, 0]];
tag = DbufTag(b.bufnum, deletionNumber, axiom, rules);
tag = Dseq([tag, Dseq([0], freq * 0.3)], inf); // a 0.1 sec pause each overrun.
index = Duty.ar(1 / freq, Dseq([2], inf), tag, doneAction:2);
SinOsc.ar(index * 1200 + 400).dup * 0.1
}.play;
)
// recycling tag system.
(
{
var tag, axiom, rules, index;
var freq = 15000;
var recycle = MouseY.kr(1, 34);
var deletionNumber = MouseX.kr(1, 6);
axiom = [1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1];
rules = [[0, 1], [1, 1, 0, 1, 0]];
tag = DbufTag(b.bufnum, deletionNumber, axiom, rules, recycle, 4); // mode 4: post info
index = Duty.ar(1 / freq, 0, tag);
SinOsc.ar(index * 1200 + 400 * Rand(1, 1.6)).dup * 0.1
}.play;
)
// read some bit of the buffer
b.getn(0, 50, {|x| x.join.postln })
// Emil Post Big Beats
// many processes with different write speeds on one string.
(
SynthDef(\post, { |bufnum, out|
var tag, axiom, rules, index;
var freq = Rand(10000, 15000);
var deletionNumber = MouseX.kr(1, 6); // modulate deletion number
axiom = [1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1];
rules = [[0, 1], [1, 1, 0, 1, 0]];
tag = DbufTag(bufnum, deletionNumber, axiom, rules);
index = Duty.ar(1 / freq, 0, tag, doneAction:2);
Out.ar(
out,
Pan2.ar(index * 0.1, LFNoise1.kr(1))
)
}).send(s);
)
(
fork {
loop {
Synth(\post, [\bufnum, b.bufnum]);
rrand(0.3, 0.6).wait;
}
}
)
// slowly play the classic example system by Emil Post
(
b.zero; // empty the buffer.
{
var tag, trig;
var deletionNumber = 2;
var axiom = [1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1];
var rules = [[0, 0], [1, 1, 0, 1]];
tag = DbufTag(b.bufnum, deletionNumber, axiom, rules);
trig = Impulse.kr(1, 0.5);
SinOsc.ar(
Demand.kr(trig, 0, tag).poll(trig, "rule index")
* 100 + 300 + SinOsc.kr([4, 4.1], 0, 5)
)
* 0.1 ! 2
}.play;
fork {
var deletionNumber = 2, tag = 0;
0.1.wait;
loop {
b.getn(0, 70, {|x|
x = x.copy.insert(tag, "|");
x.join.postln;
tag = tag + deletionNumber;
}); // post the first 70 symbols every second.
1.wait;
}
}
);
/*
1 0 1 0 1 0 0 1 1 1 0 1 0 1 1 1 1 0 0 1
1 0 1 0 0 1 1 1 0 1 0 1 1 1 1 0 0 1 1 1 0 1
1 0 0 1 1 1 0 1 0 1 1 1 1 0 0 1 1 1 0 1 1 1 0 1
0 1 1 1 0 1 0 1 1 1 1 0 0 1 1 1 0 1 1 1 0 1 1 1 0 1
1 1 0 1 0 1 1 1 1 0 0 1 1 1 0 1 1 1 0 1 1 1 0 1 0 0
0 1 0 1 1 1 1 0 0 1 1 1 0 1 1 1 0 1 1 1 0 1 0 0 1 1 0 1
0 1 1 1 1 0 0 1 1 1 0 1 1 1 0 1 1 1 0 1 0 0 1 1 0 1 0 0
1 1 1 0 0 1 1 1 0 1 1 1 0 1 1 1 0 1 0 0 1 1 0 1 0 0 0 0 0
1 0 0 1 1 1 0 1 1 1 0 1 1 1 0 1 0 0 1 1 0 1 0 0 0 0 0 1 1 0 1
...
creating the series: 1 1 1 0 1 0 0 1 1 ...
*/