Skip to content

Commit 2e539c8

Browse files
committed
MiniSteno works: Par and Ser OK
1 parent aa5bc6f commit 2e539c8

6 files changed

Lines changed: 206 additions & 32 deletions

File tree

Classes/BusLinking/BusLink.sc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ BusLink {
3939
}
4040

4141
free { // may do more stuff later
42+
if (this === BusLink.nullBus) { ^this };
4243
bus.free;
4344
}
4445

Classes/Chuck/Chuck.sc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ Chuck {
77
var <name, <argsTemplate, <source, <args, <>output, <maps;
88
classvar >parentArgs;
99
classvar inactive;
10-
10+
var <>level; // checking how to sort graph; for MiniSteno
11+
1112
inactive { ^this.class.inactive }
1213
*inactive {
1314
inactive ?? { inactive = List() };
@@ -58,6 +59,10 @@ Chuck {
5859
output = source.play(output, args, this);
5960
this.changed(\play, task);
6061
}
62+
63+
isPlaying {
64+
^output.isPlaying;
65+
}
6166

6267
source_ { | argSource |
6368
source = argSource.asChuckSource(this);
@@ -351,11 +356,12 @@ Chuck {
351356
this.objectClosed;
352357
}
353358

354-
setBussesAndGroups { | inBus, outBus, group | // used by MiniStereo
359+
setBussesAndGroups { | inBus, outBus, group, argLevel | // used by MiniStereo
355360
this setInBus: inBus;
356361
this setOutBus: outBus;
357362
this setTarget: group;
358363
this.inactive remove: this;
364+
// level = argLevel;
359365
}
360366

361367
setInBus { | bus, param = \in |
@@ -376,4 +382,5 @@ Chuck {
376382

377383
inBus { ^args[\in] }
378384
outBus { ^args[\out] }
385+
insertSerInPar {}
379386
}

Classes/GroupLinking/GroupLink.sc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
GroupLink {
22
classvar default, <nullGroup;
33
var <>group, /* <>members, */ <readerGroup, <writerGroup;
4+
var <>level = 0;
45

56
*initClass {
67
ServerBootCheck addStartup: { this.init; };
@@ -76,6 +77,7 @@ GroupLink {
7677

7778
getReaderGroup {
7879
readerGroup ?? { readerGroup = GroupLink(Group.after(group).register) };
80+
readerGroup.level = level + 1;
7981
^readerGroup;
8082
}
8183

@@ -89,9 +91,9 @@ GroupLink {
8991
server { ^group.server }
9092

9193
printOn { arg stream;
92-
stream << "GroupLink(" << group.nodeID << ")";
94+
stream << "GroupLink *" << level << "* (" << group.nodeID << ")";
9395
}
9496
storeOn { arg stream;
95-
stream << "GroupLink(" << group.nodeID << ")";
97+
stream << "GroupLink *" << level << "* (" << group.nodeID << ")";
9698
}
9799
}

Classes/MiniSteno/MiniSteno.sc

Lines changed: 73 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ A much simpler draft that only creates chucks and puts them in Groups and links
1010

1111
MiniSteno {
1212
var <tree; // , <>parent;
13+
var <>level; // for sorting of group levels - checking the algorithm under development
14+
classvar <numLinkChucks; // for naming system-created link Chucks
1315
*fromString { | string |
16+
numLinkChucks = 0;
1417
string = string.inject(" ", { | a, x |
1518
a ++ (if ("[]()".includes(x)) { x } { format("'%', ", x) })
1619
});
@@ -23,19 +26,39 @@ MiniSteno {
2326
}
2427

2528
*new { | ... specs |
29+
var linkChuck;
2630
^this.newCopyArgs(specs collect: { | s |
27-
if (s isKindOf: Symbol) { Chuck(s) } { s }
31+
if (s isKindOf: Symbol) {
32+
if (s === '%') {
33+
linkChuck = Chuck(numLinkChucks.asSymbol);
34+
linkChuck.source = { Inp.ar };
35+
linkChuck.permanent;
36+
numLinkChucks = numLinkChucks + 1;
37+
// linkChuck.play;
38+
linkChuck;
39+
} {
40+
Chuck(s)
41+
}
42+
} { s }
2843
});
29-
}
44+
}
45+
46+
init {}
3047

3148
push {
3249
var nullGroup;
3350
nullGroup = GroupLink.nullGroup;
3451
Library.put(MiniSteno, \current, this);
3552
Chuck.initInactive;
36-
this.setBussesAndGroups(ArBusLink.nullBus, ArBusLink.nullBus, GroupLink.default);
53+
this.tree do: _.insertSerInPar;
54+
this.setBussesAndGroups(ArBusLink.nullBus, ArBusLink.nullBus, GroupLink.default, 0);
55+
numLinkChucks do: { | i |
56+
Chuck(i.asSymbol).play;
57+
};
3758
Chuck.inactive do: _.setTarget(nullGroup);
38-
59+
"================================================================".postln;
60+
MiniSteno.current.pp;
61+
"================================================================".postln;
3962
}
4063

4164
*current { ^Library.at(MiniSteno, \current) }
@@ -44,7 +67,8 @@ MiniSteno {
4467
postf ("% ( // % % %\n", levels, levels, this.class, levels);
4568
tree do: { | x |
4669
if (x isKindOf: Chuck) {
47-
postf(" % % % % %\n", levels, x, x.target, x.inBus, x.outBus);
70+
postf("*%* % % % % %\n", x.target.level,
71+
levels, x, x.target, x.inBus, x.outBus);
4872
}{
4973
x.pp(levels ++ "-");
5074
};
@@ -82,7 +106,7 @@ MiniSteno {
82106
}
83107

84108
traverseDoing { | func |
85-
this.postln;
109+
// this.postln;
86110
func.(this);
87111
tree do: { | x |
88112
if (x isKindOf: MiniSteno) { x.traverseDoing(func) }
@@ -91,29 +115,62 @@ MiniSteno {
91115
}
92116

93117
Par : MiniSteno {
94-
setBussesAndGroups { | inBus, outBus, group |
95-
tree do: { | branch | branch.setBussesAndGroups(inBus, outBus, group) }
118+
insertSerInPar {
119+
tree = tree collect: { | el |
120+
Ser(this.makeLinkChuck, el, this.makeLinkChuck)
121+
}
122+
}
123+
124+
makeLinkChuck {
125+
var linkChuck;
126+
linkChuck = Chuck(numLinkChucks.asSymbol);
127+
linkChuck.source = { Inp.ar };
128+
linkChuck.permanent;
129+
numLinkChucks = numLinkChucks + 1;
130+
linkChuck;
131+
}
132+
133+
setBussesAndGroups { | inBus, outBus, group, argLevel |
134+
tree do: { | branch, i |
135+
branch.setBussesAndGroups(inBus, outBus, group, level);
136+
};
96137
}
97138
}
98139

99140
Ser : MiniSteno {
100-
setBussesAndGroups { | inBus, outBus, group |
101-
var busArray, groupArray;
141+
insertSerInPar { }
142+
setBussesAndGroups { | inBus, outBus, group, argLevel |
143+
var busArray;
144+
this.flatten; // remove Ser in Ser nestings because they mess up Group+Bus link order
102145
busArray = [inBus];
103-
groupArray = [group];
146+
104147
tree.size - 1 do: {
105148
busArray = busArray add: ArBusLink();
106-
groupArray = groupArray add: (group = group.getReaderGroup);
107149
};
108-
busArray = busArray add: outBus;
150+
busArray = busArray add: outBus;
109151
tree do: { | branch, i |
110-
branch.setBussesAndGroups(busArray[i], busArray[i + 1], groupArray[i])
152+
branch.setBussesAndGroups(busArray[i], busArray[i + 1], group, argLevel
153+
);
154+
group = group.getReaderGroup;
155+
};
156+
}
157+
158+
flatten {
159+
var newTree;
160+
tree do: { | el |
161+
if (el isKindOf: Ser) {
162+
el.flatten;
163+
el.tree do: { | el2 | newTree = newTree add: el2 };
164+
}{
165+
newTree = newTree add: el;
166+
}
111167
};
112-
}
168+
tree = newTree;
169+
}
170+
113171
}
114172

115173
+ String {
116174
miniSteno { ^MiniSteno.fromString(this) }
117175
arlink { ^this.miniSteno.push }
118-
119176
}

Classes/MiniSteno/MiniStenoTries.scd

Lines changed: 90 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,91 @@
1+
//:
2+
"(ab)".arlink;
3+
{ Blip.arp(140, 5) * 4 } ++> \a;
4+
{ Ringz.ar(Inp.ar, LFNoise0.kr(5).range(30, 1000)) * 0.1 } ++> \b;
5+
//:
6+
"a".arlink
7+
//:
8+
"(abc)".arlink;
9+
{ Inp.ar.abs * LFNoise0.kr(20) * 0.1 } ++> \c;
10+
//:
11+
"(a[bc])".arlink;
12+
{ Inp.ar.abs * LFNoise0.kr([10, 20]) * 2 } ++> \c;
13+
//:
14+
{ Ringz.ar(Inp.ar, LFNoise0.kr(50).range(300, 400)) * 0.4 } ++> \b;
15+
{ Inp.ar.sqrt.abs * SinOsc.ar(800) * 2 * LFNoise0.kr([5, 10]) * 2 } ++> \c;
16+
//:
17+
"(a[cb])".arlink;
18+
{ Inp.ar.abs * LFNoise0.kr(10) * 30 } ++> \c;
19+
20+
//:
21+
"(a[(1c2)(3b4)])".arlink;
22+
{ Inp.ar.abs * LFNoise0.kr(10) * 30 } ++> \c;
23+
{ Inp.ar } ++> '1';
24+
{ Inp.ar } ++> '2';
25+
{ Inp.ar } ++> '3';
26+
{ Inp.ar } ++> '4';
27+
//: ================================================================
28+
//: Trying how to do this with compilation:
29+
"%".arlink;
30+
//:
31+
Chuck.all.first.isPlaying;
32+
//:
33+
"%%".arlink;
34+
//:
35+
"%a%".arlink;
36+
{ PinkNoise.arp } ++> \a;
37+
//:
38+
"(%a%)".arlink;
39+
{ PinkNoise.arp } ++> \a;
40+
//:
41+
"(%ab%)".arlink;
42+
{ PinkNoise.arp } ++> \a;
43+
{ Ringz.ar(Inp.ar, LFNoise2.kr(30).range(100, 1000)) * 0.1 } ++> \b;
44+
//:
45+
"(a[bc])".arlink;
46+
{ PinkNoise.arp } ++> \a;
47+
{ Ringz.ar(Inp.ar, LFNoise2.kr(30).range(100, 1000)) * 0.1 } ++> \b;
48+
{ Ringz.ar(Inp.ar, LFNoise0.kr([1, 1]).range(100, 1000)) * 0.1 } ++> \c;
49+
//:
50+
51+
//: ================================================================
52+
//:
53+
{ Ringz.ar(Inp.ar, LFNoise2.kr(1).range(30, 1000), 0.1) * 0 } ++> \b;
54+
//:
55+
{ LFNoise1.arp(140) } ++> \a;
56+
//:
57+
{ Inp.ar.abs * LFNoise0.kr(10) * 5.00001 } ++> \c;
58+
//:
59+
"(ac)".arlink;
60+
{ Inp.ar.abs * LFNoise0.kr(10) * 1 } ++> \c;
61+
//:
62+
"(acb)".arlink;
63+
{ Inp.ar * LFNoise0.kr(10) } ++> \c;
64+
//:
65+
66+
67+
68+
//: ================================================================
69+
70+
//: mainly test level sorting for groups!
71+
72+
"b[(abc)[ax]]".arlink;
73+
MiniSteno.current.pp;
74+
75+
"(a[bcd]e)".arlink;
76+
MiniSteno.current.pp;
77+
78+
//:
179

2-
a = "b[(abc)[ax]]".miniSteno;
3-
a.pp;
480
a.inspect;
81+
//:
82+
"(abc)[x]de(fghzxqw[ij])".arlink;
83+
MiniSteno.current.pp;
84+
//:
85+
"(a(bcd)e)".arlink;
86+
MiniSteno.current.pp;
87+
//:
588

6-
b = "(abc)[x]de(fgh[ij])".miniSteno;
789
b.findContainerOf(\a.chuck);
890

991
b.pp;
@@ -17,5 +99,9 @@ b.pp;
1799
Chuck.initInactive;
18100
Chuck.inactive;
19101

102+
//:
103+
Server.default.queryAllNodes;
20104

21-
105+
//:
106+
.replace("[", "Par(Ser('%', ")
107+
.replace("]", " '%')), ")

README.org

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ As explained above, the task-filters are stored under names generated automatica
356356
** Linking audio inputs and outputs between synths
357357
:PROPERTIES:
358358
:ID: EA903FD5-9FE9-4B0A-BEE0-B38C8807810E
359-
:eval-id: 647
359+
:eval-id: 810
360360
:END:
361361

362362
A mechanism for linking inputs and outputs and of audio and control-rate Chucks based on /Steno/ by Julian Rohrhuber is under development. (See https://github.com/telephon/Steno)
@@ -371,30 +371,51 @@ Add 2 chucks =a= and =b= linked together in series:
371371

372372
#+BEGIN_SRC sclang
373373
"(ab)".arlink;
374-
{ WhiteNoise.arps(0.01) } ++> \a;
375-
{ Ringz.ar(In.ar(\in.kr(0)), LFNoise2.kr(10).range(30, 1000), 1) } ++> \b;
374+
{ WhiteNoise.arps(0.1) } ++> \a;
375+
{ Ringz.ar(Inp.ar, LFNoise2.kr(1).range(30, 1000), 1) } ++> \b;
376+
// \a.chuck.permanent;
377+
// \b.chuck.permanent;
376378
#+END_SRC
377379

378380
Remove the effect from the audible tree:
379381

380382
#+BEGIN_SRC sclang
381383
"a".arlink
382-
#+END_SRC
384+
#+End_src
383385

384386
Bring back the effect and add a second effect to it, serially:
385387

386388
#+BEGIN_SRC sclang
387389
"(abc)".arlink;
388-
{ In.ar(\in.ar(0)).abs * 3 * Decay.kr(Dust.kr([2, 2])) } ++> \c;
390+
{ Inp.ar * LFNoise0.kr(10) } ++> \c;
389391
#+END_SRC
390392

391-
Change the arrangement to send a both to b and to c in parallel:
393+
Linking effects in parallel:
394+
395+
First listen to a single effect in series
392396
#+BEGIN_SRC sclang
393-
"a[bc]".arlink;
397+
"(ab)".arlink;
398+
{ Blip.arp(140, 5) * 4 } ++> \a;
399+
{ Ringz.ar(Inp.ar, LFNoise1.kr(25).range(30, 1000)) * 0.1 } ++> \b;
394400
#+END_SRC
395401

396-
Note: This is not yet correct. The parallel mechanism is wrong because all parallel synths read from and write to the same bus, thereby processing each other's output according to they order that they were created. Next it's needed to copy the signals to separate busses and reunite them at the end. This can be done by inserting a Ser for each element of the tree of a Par, which encloses the element in a head and a tail Chuck with automatically generated id, which copy the signal from the input to the elements in the Ser, so that they have their own bus, and then copy it back to the output of the Par.
402+
Add a second effect in series
403+
#+BEGIN_SRC sclang
404+
"(abc)".arlink;
405+
{ Inp.ar.abs * LFNoise0.kr([10, 20]) * 2 } ++> \c;
406+
#+END_SRC
397407

408+
Now in parallel
409+
#+BEGIN_SRC sclang
410+
"(a[bc])".arlink;
411+
{ Inp.ar.abs.sqrt * LFNoise0.kr([10, 20]) * 5 } ++> \c;
412+
#+END_SRC
413+
414+
Vary the effects:
415+
#+BEGIN_SRC sclang
416+
{ Ringz.ar(Inp.ar, LFNoise0.kr(50).range(300, 400)) * 0.4 } ++> \b;
417+
{ Inp.ar.sqrt.abs * SinOsc.ar(1200) * 2 * LFNoise0.kr([5, 10]) * 2 } ++> \c;
418+
#+END_SRC
398419

399420
** Multiple voice example
400421
:PROPERTIES:

0 commit comments

Comments
 (0)