File: tuningScale.sc

package info (click to toggle)
supercollider-sc3-plugins 3.7.1~repack-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 14,332 kB
  • ctags: 11,704
  • sloc: cpp: 140,180; lisp: 14,746; ansic: 2,133; xml: 86; makefile: 82; haskell: 21; sh: 8
file content (109 lines) | stat: -rw-r--r-- 2,349 bytes parent folder | download | duplicates (4)
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
//  2003 Lance Putnam

+ SequenceableCollection {

	// Makes a specified tuning scale
	// The last element of stepRatios is the octave ratio.  This is typically 2.

	*tuningScale { arg rootFreq = 440, stepRatios=#[1.5, 2], loFreqBound = 20, hiFreqBound = 20000;
		var index, octaveUp, octaveDown, divs, scaleFreqs;
		var current, octave;

		divs = stepRatios.size;
		if(stepRatios[divs-1] <= 1.001, { ^nil });

		index = -1;
		octaveUp = stepRatios[divs - 1];
		octaveDown = 1/octaveUp;
		octave = rootFreq;
		scaleFreqs = this.new;

		while({ octave > loFreqBound }, {	// below low bound?
			octave = octave * octaveDown;	// go down by "octave" from root
		});

		current = octave;

		while({ current < loFreqBound }, {	// below low bound?
			index = index + 1;
			if(index >= divs, {
				index = 0;
				octave = octave * octaveUp;
			});
			current = octave * stepRatios[index];	// go up one step
		});

		while({ current <= hiFreqBound }, {	// at or below high bound?

			scaleFreqs = scaleFreqs.add(current);
			index = index + 1;
			if(index >= divs, {
				index = 0;
				octave = octave * octaveUp;
			});
			current = octave * stepRatios[index];
		});

		^scaleFreqs
	}

	// does a binary search
	nearestTo { arg value;
		var lowerInd, upperInd, centerInd;

		lowerInd = 0;
		upperInd = this.size - 1;

		while({ (upperInd - lowerInd) > 1 },{

			centerInd = (((upperInd - lowerInd)/2.0)+lowerInd).round.asInt;

			if( value < this[centerInd], {
				upperInd = centerInd;
			},{
				lowerInd = centerInd;
			});
		});

		if( (value - this[lowerInd]) < (this[upperInd] - value), {
			^this[lowerInd]
		},{
			^this[upperInd]
		});
	}

	// same as nearestTo, but input/output is an array
	nearestToList { arg values;
		var matches;
		var lowerInd, upperInd, centerInd;

		values.do({ arg value, i;

			lowerInd = 0;
			upperInd = this.size - 1;

			while({ (upperInd - lowerInd) > 1 },{

				centerInd = (((upperInd - lowerInd)/2.0)+lowerInd).round.asInt;

				if( value < this[centerInd], {
					upperInd = centerInd;
				},{
					lowerInd = centerInd;
				});

				//("In range: [" ++ this[lowerInd] ++ ", " ++ this[upperInd] ++ "]").postln;

			});

			if( (value - this[lowerInd]) < (this[upperInd] - value), {
				matches = matches.add( this[lowerInd] );
			},{
				matches = matches.add( this[upperInd] );
			});
		});

		^matches
	}

}