SuperCollider CLASSES (extension)

CutStream3

BBCut2 with live input
Inherits from: CutSynth : Object

Description

Playback for a stream of audio which can be cut-up, with offsetting relative to the last beat marked by the clock. The stream can be any bus on the Server, so might be a file streamed off disk, a current audio input or some synthesised data.

Each grain may have associated parameters for playback speed, enveloping and dutycycle (ratio of duration to inter-onset-interval).

Note that CutStream3 uses In.ar rather than InFeedback.ar, for reaction speed, so execution order is important. you cannot cut-up a stream created later in the execution order. Change the SynthDefs in the class file to InFeedback if you want no execution order worries, at the expense of an audio block's delay (usually 64 samples).

Class Methods

*new (aed, offset, swing, deviationmult, pretrim, posttrim, pbsfunc, dutycycle, atk, rel, curve)

Arguments:

aed

a running AnalyseEventsDatabase object, using the same ExternalClock as the cutter.

offset

value to offset from the last recorded beat of the clock. 0 keeps this reference point, 2 would be a reference start time of three beats ago (last recorded, then back another 2). The default is 1. However, the meaning of this parameter changes when setoffset is applied by certain cut procedures; here it determines the region of offsetting in beats.

swing

Number of beats of delay to apply for offbeat semiquavers, ie 0.0 is no swing, 0.08 is UK garage swing. For strict quantisation on-the-fly deviationmult must also be 0.0.

deviationmult

Multiplies the groove based time deviations of events. Set to 0.0 for rigid quantise based playback, 1.0 for full original timing properties.

pretrim

If playing back a cut, play any events within the cut even if there tming deviation puts them ahead of the cut start. Ie, play anticipatory events.

posttrim

The same for events whose deviation puts them after the end of the cut, but whose quantised position is within the cut.

pbsfunc

Manipulate playback speed, would usually be 1.0.

dutycycle

Ratio of duration to inter-onset-interval (IOI). 0.5 would mean that the duration of grains is only half the length between cut start times.

atk

Enveloping parameter for attack speed. Rated as a proportion of the overall envelope (0.0 to 1.0)

rel

Enveloping parameter for release speed. Rated as a proportion of the overall envelope (0.0 to 1.0)

curve

Envelope curve

Inherited class methods

Instance Methods

Inherited instance methods

Undocumented instance methods

-database

-database = value

-deviationmult

-deviationmult = value

-free

-initCutStream3 (aed, off, sw, dm, pt, pstt, nb, pbs, dc, ap, rp, c)

-posttrim

-posttrim = value

-pretrim

-pretrim = value

-renderBlock (block, clock)

-setup

-swing

-swing = value

Examples

s=Server.default;

c=ExternalClock(2.3).play;

e=AnalyseEventsDatabase.new;

e.analyse(clock:c);

//must be same clock    
a=BBCut2(CutStream3(e,1,0.0), ChooseCutProc(0.5,2)).play(c);

a.end;

e.stop;

c.stop;


//sing along to the beat and have the events found in the audio stream in time, auto quantised
(
var b,buf,e, clock;

clock= ExternalClock(TempoClock(2.1));  
        
clock.play;     
        
e=AnalyseEventsDatabase.new;

e.analyse(clock:clock);
                
Routine.run({
    
b=BBCutBuffer(Platform.resourceDir +/+ "sounds/break.aiff",8);    

s.sync; //this forces a wait for the Buffer to be allocated

//3 beats into the past
BBCut2(CutStream3(e,3,0.0,0.0, false, false), ChooseCutProc({[1.5,1.0].choose},2)).play(clock);

BBCut2(CutBuf1(b), BBCutProc11.new).play(clock);
});

)



//beat induction and event capture on an existing track
(
var trackbus, trackgroup;

s.latency=0.05;

//clear any existing OSCresponder
OSCresponder.all.do({arg val; if(val.cmdName=='/tr',{OSCresponder.remove(val)}); });

//run a line at a time
~clock= ServerClock.new;    
    
~clock.play(100,s); //will wait on trigID 100
    
~database=AnalyseEventsDatabase.new;    
    
Routine.run({

//choose some file you want to track off your hard drive
~source=Buffer.read(s,"/Volumes/data/stevebeattrack/samples/100.wav");
 
s.sync;
 
~trackbus=Bus.audio(s,1);

trackgroup= Group.before(Node.basicNew(s,1));

//run a beat tracker on the Server which sends the appropriate OSC message
~tracksynth= SynthDef(\help_cutstream3,{arg vol=1.0, beepvol=0.0, lock=0;
var trackb,trackh,trackq,tempo;
var source, beep;

source= PlayBuf.ar(1,~source.bufnum,1.0,1,0,1);

//see AutoTrack help file
#trackb,trackh,trackq,tempo=AutoTrack.kr(source, lock);

beep= SinOsc.ar(1000,0.0,Decay.kr(trackb,0.1));

Out.ar(~trackbus.index,source);

Out.ar(0,Pan2.ar((vol*source)+(beepvol*beep),0.0));

SendTrig.kr(trackb,100,tempo);  //sends with ID of 100 matching what clock expects

}).play(trackgroup);

//creates at tail of trackgroup
~database.analyse(~trackbus.index, 101, trackgroup, 0.34, ~clock); //trigID 101 is default

});

)

//default is add to head of group at Node 1 CutGroup
a=BBCut2(CutStream3(~database, 4, 0.0, 0.0,false,false), ChooseCutProc(1,2)).play(~clock);

b=BBCut2(CutStream3(~database, 4, 0.0, 0.0,false,false), BBCutProc11.new).play(~clock);

c=BBCut2([CutMod1.new,CutRev1.new,CutStream3(~database, 4, 0.0, 0.0,false,false)], ChooseCutProc(0.5,4)).play(~clock);

~tracksynth.set(\vol,0.0);

~tracksynth.set(\beepvol,1.0);

~database.threshold_(0.1); //make it more event trigger happy

a.end;
b.end;
c.end;

~clock.stop;
~database.stop;