Thursday, November 16, 2006

Creative Computing – Minor Project

For my minor project this semester I chose to do creative computing. It was always going to be stressful and without doubt it was an absolute pain. I decided to do two GUI’s, one for granulation and the other for real-time algorithmic break beat manipulation inspired by Nick Collin and his BBCut2 library. The Monday before the due date I was feeling good, I thought I just had a few bugs to iron out mainly in the BBCut GUI. Little did I know that the 24 hours later fixing those initial bugs had created more bugs and I ended up re writing the whole thing. Unfortunately there are still bugs in the code especially in BBCut GUI and when they are used at the same time there are some bussing issues which I would like to address for my own personal satisfaction.

So without further a due here is a link to the two codes

Granulation GUI
(
s = Server.local;
s.boot;
)



// SynthDef's for buffers
(
//Synth1
SynthDef('fplayer1',
{
arg rate1 = 1,
density1 = 1,
timedispersion1 = 0,
grainamp1 = 1,
grainampdisp1 = 0,
grainsize1 = 1;

var file1,
env1,
trigger1,
grainamplitude1;

~b1 = Buffer.read(s, "sounds/break2.wav");

trigger1 = LFPulse.kr(density1+(LFNoise1.kr(10, 0.5, 0.5) * timedispersion1));

grainamplitude1 = TRand.kr(grainamp1, grainampdisp1, trigger1);

env1 = EnvGen.kr(Env.new([0,1,1,0], [1,1,1]), trigger1, grainamplitude1, 0, grainsize1);

file1 = PlayBuf.ar(2, ~b1.bufnum, rate1, loop: 1.0);

Out.ar(10, file1*env1);

}).send(s);

//Synth2
SynthDef('fplayer2',
{
arg rate2 = 1,
density2 = 1,
timedispersion2 = 0,
grainamp2 = 1,
grainampdisp2 = 0,
grainsize2 = 1;

var file2,
env2,
trigger2,
grainamplitude2;

~b2 = Buffer.read(s, "sounds/break2.wav");

trigger2 = LFPulse.kr(density2+(LFNoise1.kr(10, 0.5, 0.5) * timedispersion2));

grainamplitude2 = TRand.kr(grainamp2, grainampdisp2, trigger2);

env2 = EnvGen.kr(Env.new([0,1,1,0], [1,1,1]), trigger2, grainamplitude2, 0, grainsize2);

file2 = PlayBuf.ar(2, ~b2.bufnum, rate2, loop: 1.0);

Out.ar(12, file2*env2); //bus must change for xfade

}).send(s);

//2dsynth
(
SynthDef('xfadebuf1',
{
var in1 = In.ar(10,2), //from cutmixer for fplayer1
out = 0;

Out.ar(out, in1)
}).send(s);

SynthDef('xfadebuf2',
{
arg out=0,
xFade=xFade.value;

var in2;
in2 = In.ar(12,2); //from cutmixer for fplayer2

XOut.ar(out, xFade, in2);
}).send(s);
);
)

//GUI Code
(
var w, serverbut, slid2d, openDialog1, addbut1, removebut1, ratesl, ratesl1, openDialog2, addbut2, removebut2, ratesl2, densl1, timedispsl1, grainampsl1, grainampdispsl1, grainsizesl1, densl2, timedispsl2, grainampsl2, grainampdispsl2, grainsizesl2, grainarray1, g1, grainarray2, g2, xFade, yAmp, vol, xfadeCtrl, volCtrl, label,slid2dlabel, xfadesl, spec, a;

g2 = Group.new;
grainarray2 = Array.new;
(
// Create a window. When it is closed, the buffer b will be freed
w = SCWindow("Granular Synthesis", Rect(200, 200, 410, 500));
w.view.decorator = FlowLayout(w.view.bounds);

a = Synth.new('fplayer1');
w.onClose = {a.free};
b = Synth.new('fplayer2');
w.onClose = {b.free};
c = Synth.new('xfadebuf1');
w.onClose = {c.free};
d = Synth.new('xfadebuf2');
w.onClose = {d.free};

w.front;

// A button to start and stop the server
serverbut = SCButton(w, Rect(04, 05, 100, 25));
serverbut.states = [
["Start Server", Color.black, Color.white],
["Stop Server", Color.white, Color.black],
];
serverbut.action = {
if (serverbut.value == 1, {s.boot;},{s.quit;});
};

w.view.decorator.nextLine;
);

(
//For "fplayer1"
Synth.new('fplayer1');
openDialog1 = SCButton(w, Rect(10, 40, 100, 25));
openDialog1.states = [
["Open File1", Color.black, Color.new(0.8,0.8,0.8)]
];
openDialog1.action = {
CocoaDialog.getPaths({ arg paths;
if (~b1 != nil, {~b1.free});
~b1 = Buffer.read(s, paths.at(0));
},{
"Cancelled".postln;
});
};


addbut1 = SCButton(w, Rect(115, 40, 100, 25));
addbut1.states = [
["Add grain1", Color.black, Color.new(0.8,0.8,0.8)]
];
g1 = Group.new;

grainarray1 = Array.new;
addbut1.action = {
grainarray1 = grainarray1.add(Synth('fplayer1', [
"rate1", 1*ratesl1.value,
"density1", 20*densl1.value,
"timedispersion1", 0.2*timedispsl1.value,
"grainamp1", grainampsl1.value,
"grainampdisp1", 0.5*grainampdispsl1.value,
"grainsize1", 0.5*grainsizesl1.value
], g1));
};

removebut1 = SCButton(w, Rect(220,40, 100, 25));
removebut1.states = [
["Remove grain1", Color.black, Color.new(0.8,0.8,0.8)]
];
removebut1.action = {
grainarray1.pop.free;
};

//Rate Slider
w.view.decorator.nextLine;
ratesl1 = EZSlider(w, 400 @ 24, "rate", ControlSpec(-4, 4, \lin, 0.01, default: 1),
{|ez| g1.set(\rate1, ez.value); },1);

//Density Slider
w.view.decorator.nextLine;
densl1 = EZSlider(w, 400 @ 24, "density", ControlSpec(0, 1, \lin, 0.01, default: 0.5),
{|ez| g1.set(\density1, ez.value.postln); },0.5);

//Time dispersion slider
w.view.decorator.nextLine;
timedispsl1 = EZSlider(w, 400 @ 24, "timedispersion", ControlSpec(0, 1, \lin, 0.01, default: 0.5),
{|ez| g1.set(\timedispersion1, ez.value); },0.5);

//Grain amp slider
w.view.decorator.nextLine;
grainampsl1 = EZSlider(w, 400 @ 24, "grainamp", ControlSpec(0, 1, \lin, 0.01, default: 0.5),
{|ez| g1.set(\grainamp1, ez.value); },0.5);

//grain amp dispersion slider
w.view.decorator.nextLine;
grainampdispsl1 = EZSlider(w, 400 @ 24, "grainampdisp", ControlSpec(0, 1, \lin, 0.01, default: 0.5),
{|ez| g1.set(\grainampdisp1, ez.value); },0.5);

//grain size sampler
w.view.decorator.nextLine;
grainsizesl1 = EZSlider(w, 400 @ 24, "grainsize", ControlSpec(0, 1, \lin, 0.001, default: 0.5),
{|ez| g1.set(\grainsize1, ez.value); },0.5);
);

(
//For "fplayer2"

w.view.decorator.nextLine;
w.view.decorator.nextLine;


Synth.new('fplayer2');
openDialog2 = SCButton(w, Rect(340, 40, 100, 25));
openDialog2.states = [
["Open File2", Color.black, Color.new(0.8,0.8,0.8)]
];

openDialog2.action = {
CocoaDialog.getPaths({ arg paths;
if (~b2 != nil, {~b2.free});
~b2 = Buffer.read(s, paths.at(0));
},{
"Cancelled".postln;
});
};

addbut2 = SCButton(w, Rect(445, 40, 100, 25));
addbut2.states = [
["Add grain2", Color.black, Color.new(0.8,0.8,0.8)]
];


addbut2.action = {
grainarray2 = grainarray2.add(Synth('fplayer2', [
"rate2", 3, // 1*ratesl2.value,
"density2", 20*densl2.value,
"timedispersion2", 0.2*timedispsl2.value,
"grainamp2", grainampsl2.value,
"grainampdisp2", 0.5*grainampdispsl2.value,
"grainsize2", 0.5*grainsizesl2.value
], g2));
};

removebut2 = SCButton(w, Rect(550, 40, 100, 25));
removebut2.states = [
["Remove grain2", Color.black, Color.new(0.8,0.8,0.8)]
];
removebut2.action = {
grainarray2.pop.free;
};

//Rate Slider
w.view.decorator.nextLine;
ratesl2 = EZSlider(w, 400 @ 24, "rate", ControlSpec(-4, 4, \lin, 0.001, default: 1),
{|ez| g2.set(\rate2, ez.value); },1);

//Density Slider
w.view.decorator.nextLine;
densl2 = EZSlider(w, 400 @ 24, "density", ControlSpec(0, 1, \lin, 0.001, default: 0.5),
{|ez| g2.set(\density2, ez.value);},0.5);

//Time dispersion slider
w.view.decorator.nextLine;
timedispsl2 = EZSlider(w, 400 @ 24, "timedispersion", ControlSpec(0, 1, \lin, 0.001, default: 0.5),
{|ez| g2.set(\timedispersion2, ez.value); },0.5);

//Grain amp slider
w.view.decorator.nextLine;
grainampsl2 = EZSlider(w, 400 @ 24, "grainamp", ControlSpec(0, 1, \lin, 0.001, default: 0.5),
{|ez| g2.set(\grainamp2, ez.value); },0.5);

//grain amp dispersion slider
w.view.decorator.nextLine;
grainampdispsl2 = EZSlider(w, 400 @ 24, "grainampdisp", ControlSpec(0, 1, \lin, 0.001, default: 0.5),
{|ez| g2.set(\grainampdisp2, ez.value); },0.5);

//grain size sampler
w.view.decorator.nextLine;
grainsizesl2 = EZSlider(w, 400 @ 24, "grainsize", ControlSpec(0, 1, \lin, 0.001, default: 0.5),
{|ez| g2.set(\grainsize2, ez.value); },0.5);

);

(
//crossfade
w.view.decorator.nextLine;
w.view.decorator.nextLine;
w.view.decorator.nextLine;

// Labels for 2D controllers
w.view.decorator.shift(100);
Synth.new('xfadebuf1');
a = Synth.tail(s, 'xfadebuf2');
xfadesl = SCSlider(w, Rect(12, 12, 200, 24));
xfadesl.value = 0.5;
xfadesl.action = {a.set(\xFade, (1*xfadesl.value))};
a.set(\xFade, 0.5);

w.view.decorator.nextLine;
w.view.decorator.shift(100);
slid2dlabel = SCStaticText(
parent: w,
bounds: Rect(
width: 200,
height: 20
);
);
slid2dlabel.string = "1<-------X-FADER------>2";
slid2dlabel.align = (\center);
slid2dlabel.font = Font("Arial", 12, 2);
slid2dlabel.background = Color.new255(84, 194, 234);

);
);
);
)



BBCut GUI

(
s = Server.local;
s.boot;

~thisPath = (PathName.new(Document.current.path)).pathOnly;

)
(
var sf1, sf2;
var w, chooseriff, shuffles, fillchance, stopchance;
var chooseriff2, shuffles2, fillchance2, stopchance2;
var openDialog, playbut;

w = SCWindow("Thrashing BBCut", Rect.new(700,80,620,150));

//b1 button
openDialog = SCButton(w, Rect(4, 1, 100, 25));
openDialog.states = [
["Buffer1", Color.black, Color.new(0.8,0.8,0.8)]
];
openDialog.action = {
CocoaDialog.getPaths({ arg paths;
if (sf1 != nil, {sf1.free});
sf1 = Buffer.read(s, paths.at(0)).postln;
},{
"Cancelled".postln;
});
};

//b2 button
openDialog = SCButton(w, Rect(516, 1, 100, 25));
openDialog.states = [
["Buffer2", Color.black, Color.new(0.8,0.8,0.8)]
];
openDialog.action = {
CocoaDialog.getPaths({ arg paths;
if (sf2 != nil, {sf2.free});
sf2 = Buffer.read(s, paths.at(0)).postln;
},{
"Cancelled".postln;
});
};

//playbutton
playbut = SCButton(w, Rect(260, 1, 100, 25));
playbut.states = [
["Start", Color.black, Color.white],
["Stop", Color.white, Color.black],
];
playbut.action = {
if (playbut.value == 1, {ExternalClock(TempoClock).play;},{ExternalClock(TempoClock).stop}).postln;
};

chooseriff=DDSlider( w, Rect.new(5,30,150,40), "chooseriff", 0, 3, 'linear', 1, 0);
shuffles=DDSlider( w, Rect.new(5,80,150,40), "shuffles", 0, 10, 'linear', 1, 0);
fillchance=DDSlider( w, Rect.new(156,30,150,40), "fillchance", 0.0, 1.0, 'linear', 0.01, 0.0);
stopchance=DDSlider( w, Rect.new(156,80,150,40), "stopchance", 0.0, 1.0, 'linear', 0.01, 0.0);


chooseriff2=DDSlider( w, Rect.new(314,30,150,40), "chooseriff", 0, 3, 'linear', 1, 0);
shuffles2=DDSlider( w, Rect.new(314,80,150,40), "shuffles", 0, 10, 'linear', 1, 0);
fillchance2=DDSlider( w, Rect.new(465,30,150,40), "fillchance", 0.0, 1.0, 'linear', 0.01, 0.0);
stopchance2=DDSlider( w, Rect.new(465,80,150,40), "stopchance", 0.0, 1.0, 'linear', 0.01, 0.0);

w.front;


Routine.run({
sf1= BBCutBuffer("sounds/break.wav",8);

s.sync;

BBCut2(CutBuf1(sf1),
ThrashCutProc1.new(0.0,0.125,8.0,[0.25,0.25,0.25,0.25],
{chooseriff.value.round(1.0).asInteger},
{shuffles.value.round(1.0).asInteger},
{fillchance.value.coin},
stopchance
)
).play(2.33);
});


Routine.run({
sf2= BBCutBuffer("sounds/cage2.wav",8);

s.sync;

BBCut2(CutBuf1(sf2),
ThrashCutProc1.new(0.0,0.125,8.0,[0.25,0.25,0.25,0.25],
{chooseriff2.value.round(1.0).asInteger},
{shuffles2.value.round(1.0).asInteger},
{fillchance2.value.coin},
stopchance2
)
).play(2.33);
});
)


Here is the score.


I will also be uploading a video instead of an mp3 to accompany the score so stay tuned!

Here's the embedded video which should be up soon...

0 Comments:

Post a Comment

<< Home