Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / HelpSource / Classes / Scale.schelp
blobc0e92ed9b2a852657a5216f3b30613e4cb8edcef
1 CLASS::Scale
2 summary::represents a musical scale
3 related::Classes/Tuning
4 categories::Math, Tuning
6 DESCRIPTION::
7 Scale supports arbitrary octave divisions and ratios, and (in conjunction with link::Classes/Tuning::) can generate pitch information in various ways, including as input to Patterns.
9 code::
10 s.boot;
12 a = Scale.major;
13 a.degrees;              // [ 0, 2, 4, 5, 7, 9, 11 ]
14 a.semitones;            // [ 0, 2, 4, 5, 7, 9, 11 ]
15 a.cents;                // [ 0, 200, 300, 500, 700, 900, 1100 ]
16 a.ratios;               // [ 1, 1.1224620483089, 1.2599210498937, 1.3348398541685, etc. ]
18 Pbind(\scale, a, \degree, Pseq((0..7) ++ (6..0) ++ [\rest], 1), \dur, 0.25).play;
20 // use non-standard tuning
21 a.tuning_(\just);
22 a.degrees;              // no change; degrees are independent of tuning
23 a.semitones;            // [ 0, 2.0391000173077, 3.1564128700055, 4.9804499913461, etc. ]
24 a.ratios.collect(_.round(0.001));       // [ 1, 1.125, 1.2, 1.333, 1.5, 1.667, 1.875 ]
26 Pbind(\scale, a, \degree, Pseq((0..7) ++ (6..0) ++ [\rest], 1), \dur, 0.25).play;
29 subsection::Creation
31 strong::*major, *minor, *dorian, *chromatic, *todi, *hijaz, *partch_o1, etc.::
33 Creates a scale from the library stored in link::Classes/ScaleInfo::. Each scale comes with an appropriate default link::Classes/Tuning::, but alternate tunings can be specified at creation time:
34 code::
35 Scale.phrygian(\pythagorean)
37 If the tuning size does not match the scale's link::#-pitchesPerOctave::, a warning will be thrown, and the scale will use its default tuning.
39 For a complete list of available scales, execute
40 code::
41 Scale.directory
44 CLASSMETHODS::
46 method::choose
47 Creates a random scale from the library, constrained by size and pitchsPerOctave if desired.
48 code::
49 Scale.choose;           // could be anything
50 Scale.choose(7);        // will be a seven-note scale in its default tuning (could be any)
51 Scale.choose(7, 12);    // will be a seven-note scale in a twelve-tone tuning (usually ET!2)
53 // Random seven-note scale in random twelve-tone tuning
54 a = Scale.choose(7, 12).tuning_(Tuning.choose(12));
55 a.tuning.name;
58 method::new
59 Creates a Scale from scratch. strong::degrees:: should be an array of Integers or scale name. If strong::pitchesPerOctave:: is nil, will guess the most appropriate number based on degrees. strong::tuning:: can be an instance of link::Classes/Tuning:: or a symbol; if nil, will be equal temperament of pitchesPerOctave. Specify strong::descDegrees:: if the Scale should play differently when descending than when ascending; otherwise it should be nil.
60 code::
61 Scale.new(#[0, 1, 3, 6, 8, 10, 11], name: "My ET12");           // will be in ET12
62 Scale.new(#[0, 3, 7, 10, 15, 19, 22], name: "My Quarter-Tone"); // will be in ET24
63 Scale.new(#[0, 6, 17, 21, 30, 39], 43, \partch, "My Partch");
66 INSTANCEMETHODS::
68 private::storeOn, storedKey, storeArgs, printOn
70 method::tuning
71 Sets or gets the tuning of the Scale.
72 argument::inTuning
73 can be either an instance of link::Classes/Tuning:: or a symbol matching a library tuning.
75 method::semitones
76 Returns a tuned array of semitone values. link::#-as::(Array) is equivalent; link::#-as::(List) returns it as a list, etc.
78 method::cents
79 Returns a tuned array of cent values.
81 method::ratios
82 Returns a tuned array of ratios.
84 method::as
85 Converting. For example code::as(Array)::, code::as(List):: and code::as(LocalBuf):: which is useful for server-side work.
86 code::
88 r = {
89         var scale = Scale.choose.postln;
90         SinOsc.ar(
91                 (
92                         DegreeToKey.kr(
93                                 scale.as(LocalBuf),
94                                 MouseX.kr(0,15), // mouse indexes into scale
95                                 scale.stepsPerOctave,
96                                 1, // mul = 1
97                                 60 // offset by 72 notes
98                         )
99                         + LFNoise1.kr([3,3], 0.04) // add some low freq stereo detuning
100                 ).midicps, // convert midi notes to hertz
101                 0,
102                 0.25
103         )
104 }.play;
107 r.free;
110 method::size
111 Returns the length of the scale.
112 code::
113 Scale.ionian.size; // 7
114 Scale.minorPentatonic.size; // 5
115 Scale.ajam.size; // 7
116 Scale.partch_o1.size; // 6
119 method::pitchesPerOctave
120 Returns the size of the pitch class set from which the tuning is drawn.
121 code::
122 Scale.ionian.pitchesPerOctave; // 12
123 Scale.minorPentatonic.pitchesPerOctave; // 12
124 Scale.ajam.pitchesPerOctave; // 24--this is a quarter-tone scale
125 Scale.partch_o1.pitchesPerOctave; // 43
128 method::stepsPerOctave
129 Usually 12, but may be different if the current tuning has a stretched or compressed octave. Needed for degreeToKey.
130 code::
131 Scale.new((0..14), 15, tuning: \wcAlpha).stepsPerOctave;        // ~ 11.7
132 Scale.new(#[0, 3, 6, 9, 12], 13, tuning: \bp).stepsPerOctave;   // ~ 19.02
134 but note:
135 code::
136 Scale.ajam.stepsPerOctave;      // 12 -- quarter-tone scales have normal octaves
139 method::at, wrapAt
140 These access the array generated by semitones.
141 code::
142 a = Scale.major;
143 a.wrapAt(4);    // 7
144 a.wrapAt(5);    // 9
145 a.wrapAt(6);    // 11
146 a.wrapAt(7);    // 0
149 method::degreeToFreq
150 Returns a frequency based on current tuning and rootFreq argument.
151 code::
152 Scale.major.degreeToFreq(2, 60.midicps, 1);             // 659.25511...
153 Scale.major(\just).degreeToFreq(2, 60.midicps, 1);      // 654.06391...
156 method::degreeToRatio
157 Returns a ratio based on current tuning.
158 code::
159 Scale.major.degreeToRatio(2, 1).round(0.001);           // 2.52
160 Scale.major(\just).degreeToRatio(2, 1).round(0.001);    // 2.5
163 EXAMPLES::
165 code::
167 s.waitForBoot({
168         a = Scale.ionian;
170         p = Pbind(
171                 \degree, Pseq([0, 1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1, 0, \rest], inf),
172                 \scale, Pfunc({ a }, inf),
173                 \dur, 0.25
174         );
176         q = p.play;
180 // change scale
181 a = Scale.phrygian;
183 // change tuning
184 a.tuning_(\just);
186 // can also set tuning at creation time
187 a = Scale.ionian(\pythagorean);
189 // if you use a tuning with the wrong number of pitches per octave,
190 // you get a warning and the scale reverts to default tuning
191 a.tuning_(\partch);
193 // random scale
195 a = Scale.choose(7, 12);
196 [a.name, a.tuning.name].postln;
200 // or make up your own arbitrary scales and tunings
201 a = Scale.new(
202         #[0, 2, 4, 5, 7, 9, 10],
203         12,
204         Tuning.new([0, 0.8, 2.1, 3, 4.05, 5.2, 6, 6.75, 8.3, 9, 10.08, 11.5]),
205         "Custom"
209 // tuning has its own class
210 t = Tuning.werckmeister;
212 a = Scale.lydian(t);
214 q.stop;
216 // getting info
217 a.name;
218 a.degrees;
219 a.semitones;
220 a.ratios;
222 a.tuning.name;
223 a.tuning.semitones;
224 a.tuning.ratios;
227 code::
228 // cmd-J to see scale and tuning dictionaries in full
229 ScaleInfo
230 TuningInfo
233 code::
234 // for ascending/descending scales, use Pavaroh
236 Pbind(\note, Pavaroh(
237         Pseq([0, 1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1, 0, \rest], 2),
238                 Scale.melodicMinor,
239                 Scale.melodicMinorDesc
240         ),
241         \dur, 0.25
242 ).play;
246 code::
247 // note that the root pitch is not stored in the Scale (which should arguably be called a Mode for that reason)
248 // instead you supply it at play time:
250 // key of A
251 Pbind(
252         \degree, Pseq((0..7), inf), // your melody goes here
253         \scale, Scale.major, // your scale goes here
254         \root, -3 // semitones relative to 60.midicps, so this is A
255 ).play;