SuperCollider CLASSES (extension)

DbufTag
ExtensionExtension

demand rate tag system on a buffer
Inherits from: DUGen : UGen : AbstractFunction : Object
Subclasses: Dtag

Description

Emil Post's tag system as a demand rate ugen - Buffer version.

Class Methods

*new (bufnum, v, axiom, rules, recycle: 0, mode: 0)

Full arguments description and more explanations, see Dtag

Arguments:

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.

Inherited class methods

Undocumented class methods

*convertRules (axiom, rules)

Instance Methods

Inherited instance methods

Undocumented instance methods

-allSymbols

-axiom

-axiom = value

-rules

-rules = value

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 ...
*/