-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmakeRandomEnv.scd
More file actions
113 lines (93 loc) · 2.42 KB
/
Copy pathmakeRandomEnv.scd
File metadata and controls
113 lines (93 loc) · 2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
(
(PathName(thisProcess.nowExecutingPath).pathOnly
+/+ "makeRandomEnvValidation.scd").load;
~makeRandomEnv = { |
duration,
minLevel,
maxLevel,
minSegments,
maxSegments,
minSegmentDuration = 0.05,
startLevel = nil,
endLevel = nil,
maxLevelChange = nil,
curve = \lin
|
var feasibleMaxSegments;
var numSegments;
var remainingDuration;
var times;
var changeLimit;
var actualStart;
var actualEnd;
var totalReach;
var levels;
~validateRandomEnvConstraints.(
duration,
minLevel,
maxLevel,
minSegments,
maxSegments,
minSegmentDuration,
startLevel,
endLevel,
maxLevelChange
);
feasibleMaxSegments = (duration / minSegmentDuration)
.floor
.asInteger
.min(maxSegments);
numSegments = rrand(
minSegments.asInteger,
feasibleMaxSegments
);
remainingDuration =
duration - (numSegments * minSegmentDuration);
times = if(remainingDuration > 0, {
(minSegmentDuration ! numSegments)
+ (
Array.fill(numSegments, { 1.0.rand.max(1e-9) })
.normalizeSum
* remainingDuration
)
}, {
minSegmentDuration ! numSegments
});
times[times.size - 1] =
times.last + (duration - times.sum);
changeLimit = maxLevelChange ?? {
maxLevel - minLevel
};
actualStart = startLevel ?? {
rrand(minLevel, maxLevel)
};
totalReach = numSegments * changeLimit;
actualEnd = endLevel ?? {
rrand(
(actualStart - totalReach).max(minLevel),
(actualStart + totalReach).min(maxLevel)
)
};
if((actualEnd - actualStart).abs > totalReach, {
Error("The endpoints cannot satisfy maxLevelChange").throw;
});
levels = List[actualStart];
(numSegments - 1).do { |i|
var previousLevel;
var remainingSegments;
var lo;
var hi;
previousLevel = levels.last;
remainingSegments = numSegments - i - 1;
lo = minLevel
.max(previousLevel - changeLimit)
.max(actualEnd - (remainingSegments * changeLimit));
hi = maxLevel
.min(previousLevel + changeLimit)
.min(actualEnd + (remainingSegments * changeLimit));
levels.add(~randomEnvLevelBetween.(lo, hi));
};
levels.add(actualEnd);
Env(levels.asArray, times, curve)
};
)