Module: MusicSetTheory

Extended by:
MusUtility
Includes:
MusUtility, Temperament
Defined in:
lib/music_set_theory.rb,
lib/music_set_theory/chords.rb,
lib/music_set_theory/chords.rb,
lib/music_set_theory/chords.rb,
lib/music_set_theory/chords.rb,
lib/music_set_theory/scales.rb,
lib/music_set_theory/scales.rb,
lib/music_set_theory/scales.rb,
lib/music_set_theory/scales.rb,
lib/music_set_theory/scales.rb,
lib/music_set_theory/scales.rb,
lib/music_set_theory/scales.rb,
lib/music_set_theory/scales.rb,
lib/music_set_theory/version.rb,
lib/music_set_theory/musutility.rb,
lib/music_set_theory/musutility.rb,
lib/music_set_theory/musutility.rb,
lib/music_set_theory/temperament.rb,
lib/music_set_theory/temperament.rb,
lib/music_set_theory/temperament.rb,
lib/music_set_theory/temperament.rb,
lib/music_set_theory/temperament.rb,
lib/music_set_theory/temperament.rb,
lib/music_set_theory/temperament.rb,
lib/music_set_theory/temperament.rb,
lib/music_set_theory/temperament.rb,
lib/music_set_theory/chord_generator.rb,
lib/music_set_theory/chord_generator.rb,
lib/music_set_theory/chord_generator.rb,
lib/music_set_theory/chord_generator.rb,
lib/music_set_theory/chord_generator.rb

Defined Under Namespace

Modules: MusUtility, ScaleArray, Temperament Classes: NoteSeq, NoteSeqChord, NoteSeqScale, ScaleChordCell, ScaleChordRow, ScaleChords

Constant Summary collapse

CHORDTYPE_DICT =

Original comments: This dictionary contains a list of different nseq_nat_posns values for different types of chords in the Western tradition. Note that all arrays are stored base 0, not base 1, so a "seventh" chord is stored as [0, 2, 4, 6] - not [1, 3, 5, 7].

Attention

! in degree, but base is 0, not 1.

{
  "Triad"             => [0, 2, 4],
  "Seventh"           => [0, 2, 4, 6],
  "Ninth"             => [0, 2, 4, 6, 8],
  "Eleventh"          => [0, 2, 4, 6, 8, 10],
  "Thirteenth"        => [0, 2, 4, 6, 8, 10, 12],
  "Added Ninth"       => [0, 2, 4, 8],
  "Suspended"         => [0, 3, 4],
  "Suspended Seventh" => [0, 3, 4, 6],
  "Sixth"             => [0, 2, 4, 5],
  "Sixth/Ninth"       => [0, 2, 4, 5, 8],
  "Added Eleventh"    => [0, 2, 4, 10],
  "Fifth"             => [0, 4],
}
HEPT_NAT_POSNS =

Note: MelMinScale represents a melodic minor scale ascending. See the Aeolian mode of the Major scale for melodic minor scale descending.

(0...7).to_a
MEL_MIN_NOTE_POS =
[0, 2, 3, 5, 7, 9, 11]
HARM_MIN_NOTE_POS =
[0, 2, 3, 5, 7, 8, 11]
HARM_MAJ_NOTE_POS =
[0, 2, 4, 5, 7, 8, 11]
DISC_MIN_NOTE_POS =
[0, 2, 3, 5, 6, 9, 11]
HUNGARIAN_NOTE_POS =
[0, 3, 4, 6, 7, 9, 10]
MAJOR_MODES =

For ease of comprehension, we have the list of modes as arrays which can be browsed from outside.

[ "Ionian",
"Dorian",
"Phrygian",
"Lydian",
"Mixolydian",
"Aeolian",
"Locrian", ]
MAJORMODES =
MAJOR_MODES
MEL_MINOR_MODES =
[ "Jazz Minor",
"Dorian " + M_FLAT + "9",
"Lydian Augmented",
"Lydian Dominant",
"Mixolydian " + M_FLAT + "13",
"Semilocrian",
"Superlocrian", ]
MELMINORMODES =
MEL_MINOR_MODES
HARM_MINOR_MODES =
[ "Harmonic Minor",
"Locrian " + M_SHARP + "6",
"Ionian Augmented",
"Romanian",
"Phrygian Dominant",
"Lydian " + M_SHARP + "2",
"Ultralocrian", ]
HARMINORMODES =

for compatibility... typo?

HARM_MINOR_MODES
HARM_MAJOR_MODES =
[ "Harmonic Major",
"Dorian " + M_FLAT + "6",
"Phrygian " + M_FLAT + "4",
"Lydian " + M_FLAT + "3",
"Mixolydian " + M_FLAT + "9",
"Lydian " + M_SHARP + "2 " + M_SHARP + "5",
"Locrian " + M_FLAT + M_FLAT + "7", ]
HARMMAJORMODES =
HARM_MAJOR_MODES
DISCORD_MIN_MODES =
[ "Melodic Minor " + M_FLAT + "5",
"Dorian " + M_FLAT + "9 " + M_FLAT + "4",
"Minor Lydian Augmented",
"Lydian Dominant " + M_FLAT + "9",
"Lydian Augmented " + M_SHARP + "2 " + M_SHARP + "3",
"Semilocrian " + M_FLAT + M_FLAT + "7",
"Superlocrian " + M_FLAT + M_FLAT + "6", ]
DISCORDMINMODES =
DISCORD_MIN_MODES
HUNGARIAN_MODES =
[ "Hungarian",
"Superlocrian " + M_FLAT + M_FLAT + "6 " + M_FLAT + M_FLAT + "7",
"Harmonic Minor " + M_FLAT + "5",
"Superlocrian " + M_SHARP + "6",
"Melodic Minor " + M_SHARP + "5",
"Dorian " + M_FLAT + "9 " + M_SHARP + "11",
"Lydian Augmented " + M_SHARP + "3", ]
HUNGARIANMODES =
HUNGARIAN_MODES
MODE_ARRAY =
[
  MAJOR_MODES,
  MEL_MINOR_MODES,
  HARM_MINOR_MODES,
  HARM_MAJOR_MODES,
  DISCORD_MIN_MODES,
  HUNGARIAN_MODES,
]
Pentatonic_NAT_POSNS =
(0...5).to_a
Hexatonic_NAT_POSNS =

6音音階

(0...6).to_a
Heptatonic_NAT_POSNS =

7音音階

HEPT_NAT_POSNS
Octatonic_NAT_POSNS =

8音音階

(0...8).to_a
MAJOR_PENTA_NOTE_POS =

Pentatonic.

[ 0, 2, 4, 7,  9, ]
MINOR_PENTA_NOTE_POS =
[ 0, 3, 5, 7, 10, ]
RYUKYU_PENTA_NOTE_POS =
[ 0, 4, 5, 7, 11, ]
BLUES_HEXA_NOTE_POS =
[ 0, 3, 5, 6, 7, 10, ]
VERSION =
"0.0.5"
CHORDTYPE_ARRAY =

Used to give a full list of chord types.

[
  "Fifth", "Triad", "Seventh", "Ninth", "Eleventh", "Thirteenth",
  "Added Ninth", "Suspended", "Suspended Seventh", "Sixth", "Sixth/Ninth",
  "Added Eleventh",
]
0
1
2

Constants included from MusUtility

MusUtility::SPACECOMMA

Constants included from Temperament

Temperament::CHROM_NAT_NOTES, Temperament::CHROM_NAT_NOTE_POS, Temperament::CHROM_SIZE, Temperament::MNU_FLAT, Temperament::MNU_NATURAL, Temperament::MNU_SHARP, Temperament::M_FLAT, Temperament::M_NATURAL, Temperament::M_SHARP, Temperament::NSEQ_CHORD, Temperament::NSEQ_SCALE, Temperament::NSEQ_TYPE_HASH, Temperament::RE_NOTEPARSE, Temperament::RE_SHARP, Temperament::WestTemp, Temperament::WestTment

Class Method Summary collapse

Instance Method Summary collapse

Methods included from MusUtility

deep_freeze, deep_melt, enl_seq, multislice, norm_seq, repseq, rotate, rotate_and_zero, scalar_addition, seqtostr

Methods included from Temperament

#WestTempNew, WestTempNew, #un_unicode_accdtls

Class Method Details

.def_scale(const_name, name:, tment:, note_pos:, modes: [], scale_array: :ScaleArray) ⇒ Object



447
448
449
450
451
452
453
454
455
456
457
458
459
# File 'lib/music_set_theory/scales.rb', line 447

def self.def_scale( const_name, name: , tment: ,
                    note_pos: , modes: [],
                    scale_array: :ScaleArray )
  posns = (0...(note_pos.size)).to_a

  tmp = NoteSeqScale.new(name, tment, note_pos, posns, modes)
  self.const_set(const_name, tmp)
  ret = self.const_get(const_name)

  self.const_get(scale_array).const_set(const_name,ret)

  ret
end

.scales(scale_array: :ScaleArray) ⇒ Object



466
467
468
# File 'lib/music_set_theory/scales.rb', line 466

def self.scales( scale_array: :ScaleArray )
  self.const_get(scale_array).constants
end

.undef_scale(const_name, scale_array: :ScaleArray) ⇒ Object



461
462
463
464
# File 'lib/music_set_theory/scales.rb', line 461

def self.undef_scale( const_name, scale_array: :ScaleArray )
  self.const_get(scale_array).send(:remove_const, const_name)
  self.send(:remove_const, const_name)
end

Instance Method Details

#chordgentable(scales) ⇒ Object

(**) I dont need this. Generates a table representation of a series of scales, represented by a scale_chords instance.



333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
# File 'lib/music_set_theory/chord_generator.rb', line 333

def chordgentable( scales )
  startrow  = "<tr>\n"
  endrow    = "</tr>\n"
  thestring = ""


  for scale in scales
    thestring += "<h2>%s</h2>\n" % (scale.key + " " +scale.full_name)
    thestring += ("<table id=\"%s\" class=\"chordtable\">\n" % 
        (scale.key + ""))
    thestring += "<caption>%s</caption>\n" %
      (scale.key + " " + scale.full_name +
        ": " + seqtostr(scale.full_notes))
    thestring += "<thead>\n" + startrow + "<th>Chord Types</th>\n"
    # for q in range(7)
    for q in 0...7
      thestring += "<th>%s</th>\n" % str(int_to_roman(q+1))
    end
    thestring += endrow + "</thead>\n<tbody>\n"

    for i in scale.rows
      thestring += startrow
      thestring += "<td>%s</td>\n" % i.chord_type
      for j in i.notes
        if not j.chordname_1
          thestring += ("<td><p>%s<br />" % (str(j.chordname_1)))
          thestring += ("<i>%s</i><br />" % (str(j.chordname_2)))
        else
          thestring += ("<td><p>%s<br />" %
                        (j.notes[0]+" "+str(j.chordname_1)))
          thestring += ("<i>%s</i><br />" % (j.notes[0]+str(j.chordname_2)))
        end

        thestring += ("<b>%s</b></p></td>" % seqtostr(j.notes))
      end
      thestring += endrow
    end
    thestring += "\n</tbody>\n</table>\n"
  end

  return thestring
end

#generate_west_chords(west_temp = MusicSetTheory::Temperament. WestTempNew()) ⇒ Object

This function generates most of the chords in the Western tradition (and some that are not really chords at all).

Args

west_temp

temperament.

Returns

Chord table (Array of NoteSeqChord).

Warns

! this methods modifies west_temp. Be careful...



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
# File 'lib/music_set_theory/chords.rb', line 145

def generate_west_chords( west_temp = MusicSetTheory::Temperament.
                                        WestTempNew() )
  chordseq = []
  bases     = [[0, 3], [0, 4]]
  triads    = enl_seq(bases, [6, 7, 8])


  # PKM2014 - add two pseudo suspended chords
  suspendeds  = [[0, 5, 6], [0, 5, 7], [0, 5, 8], [0, 6, 7], [0, 6, 8]]
  sixths      = enl_seq(triads, [8, 9])
  sevenths    = enl_seq(triads, [10, 11])
  suspended_sevenths = enl_seq(suspendeds, [9, 10, 11])

  ninths      = enl_seq(sevenths, [13, 14, 15])
  elevenths   = enl_seq(ninths, [17, 18])
  thirteenths = enl_seq(elevenths, [20, 21])

  add_ninths  = enl_seq(triads, [13, 14, 15])
  six_ninths  = enl_seq(sixths, [13, 14, 15])

  sevenths_and_above = sevenths + ninths + elevenths + thirteenths +
                         suspended_sevenths

  # We add the power chords.
  chordseq.append(NoteSeqChord.new("Power Fifth", west_temp, [0, 7],
     CHORDTYPE_DICT["Fifth"], "5"))
  chordseq.append(NoteSeqChord.new("Tritone", west_temp, [0, 6],
     CHORDTYPE_DICT["Fifth"], "T"))
  chordseq.append(NoteSeqChord.new("Power Sharp Fifth", west_temp, [0, 8],
     CHORDTYPE_DICT["Fifth"], "+5"))


  # We add the diminished chords, as they take special handling.
  chordseq.append(NoteSeqChord.new("Diminish 7th", west_temp, [0, 3, 6, 9],
     CHORDTYPE_DICT["Seventh"], "dim7"))
  chordseq.append(NoteSeqChord.new("Diminish 9th", west_temp, [0, 3, 6, 9, 13],
     CHORDTYPE_DICT["Ninth"], "dim9"))
  chordseq.append(NoteSeqChord.new("Diminish 11th", west_temp,
     [0, 3, 6, 9, 13, 16], CHORDTYPE_DICT["Eleventh"], "dim11"))
  chordseq.append(NoteSeqChord.new("Diminish 13th", west_temp,
     [0, 3, 6, 9, 13, 16, 20], CHORDTYPE_DICT["Thirteenth"], "dim13"))


  # We loop over the triads and the added ninths together. For this
  # reason, we set up some maps for the ease of iteration.
  #
  triad_names = {
    3 =>{ 6 =>"Diminish 5th",   7 =>"Minor", 8 =>"Minor Sharp 5th", },
    4 =>{ 6 =>"Major Flat 5th", 7 =>"Major", 8 =>"Augment", }, }
  triad_abbrv = {
    3 =>{ 6 =>"dim5", 7 =>"min", 8 =>"min+5", },
    4 =>{ 6 =>"-5",   7 =>"maj", 8 =>"+",     }, }
  add9_names = {
    13 =>" Add Flat 9th", 14 =>" Add 9th", 15 =>" Add Sharp 9th", }
  add9_abbrv = {
    13 =>" add-9",        14 =>" add9",    15 =>" add+9", }

  add11_names = {17 =>" Add 11th", 18 =>" Add Sharp 11th", }
  add11_abbrv = {17 =>" add11",    18 =>" add+11", }

  add6_names = {20 =>" Add Flat 6th", 21 =>" Add 6th", }
  add6_abbrv = {20 =>" add-6",        21 =>" add6", }


  #
  for i in [3, 4]
    for j in [6, 7, 8]
      our_tname = triad_names[i][j]
      our_tabbr = triad_abbrv[i][j]
      chordseq.append(NoteSeqChord.new(
        our_tname, west_temp, [0, i, j],
        CHORDTYPE_DICT["Triad"], our_tabbr))

      #
      for k in [13, 14, 15]
        if i == 3 && k == 15
          # pass;
        else
          chordseq.append(NoteSeqChord.new(our_tname + add9_names[k],
            west_temp, [0, i, j, k],
            CHORDTYPE_DICT["Added Ninth"],
            our_tabbr+add9_abbrv[k]))
        end
      end

      #
      for k in [17, 18]
        if k == 18 && j == 6
          # pass;
        else
          chordseq.append(NoteSeqChord.new(our_tname + add11_names[k],
            west_temp, [0, i, j, k], CHORDTYPE_DICT["Added Eleventh"],
            our_tabbr+add11_abbrv[k]))
        end
      end

      #
      for k in [20, 21]
        if i == 3 && j == 6 && k == 21
          #  pass; # Pattern already taken by Diminished 7 chord.
        else
          chordseq.append(NoteSeqChord.new(our_tname + add6_names[k],
            west_temp, [0, i, j, k], CHORDTYPE_DICT["Sixth"],
            our_tabbr+add6_abbrv[k]))
        end

        for l in [13, 14, 15]
          if i == 3 && l == 15
            # pass
          else
            chordseq.append(NoteSeqChord.new(
              our_tname + add6_names[k] + add9_names[l],
              west_temp, [0, i, j, k, l], 
              CHORDTYPE_DICT["Sixth/Ninth"],
              our_tabbr+add6_abbrv[k]+add9_abbrv[l]))
          end
        end  # endof l

      end  # endof k

    end  # endof j
  end  # endof i

  # Then we add the suspended chords. They are treated differently
  # from other chords, as one can't put 9th, 11th or 13th on there.
  #
  chordseq.append(NoteSeqChord.new("Suspend Flat 5th",
    west_temp, [0, 5, 6], CHORDTYPE_DICT["Suspended"], "sus-5"))
  chordseq.append(NoteSeqChord.new("Suspend",
    west_temp, [0, 5, 7], CHORDTYPE_DICT["Suspended"], "sus"))
  chordseq.append(NoteSeqChord.new("Suspend Sharp 5th",
    west_temp, [0, 5, 8], CHORDTYPE_DICT["Suspended"], "sus+5"))

  # PKM2014 - add two pseudo suspended chords

  chordseq.append(NoteSeqChord.new("Suspend Sharp 4th",
    west_temp, [0, 6, 7], CHORDTYPE_DICT["Suspended"], "sus+4"))
  chordseq.append(NoteSeqChord.new("Suspend Sharp 4th Sharp 5th",
    west_temp, [0, 6, 8], CHORDTYPE_DICT["Suspended"], "sus+4+5"))


  # Afterwards, we add the 7th (including sus 7th), 9th, 11th and
  # 13th chords.


  for i in sevenths_and_above
    suspendsharpfourth = false
    abbrev  = ""
    name    = ""

    if i.include? 5
      abbrev += "sus / "
      name   += "Suspend "
    end

    # PKM2014 - add code for two pseudo suspended 7th chords
    if i.size == 4 && i.include?(6) && ((i.include? 7) || (i.include? 8))
      abbrev += "sus+4 / ";
      name   += "Suspend Sharp 4th "
      suspendsharpfourth = true
    end
    if i.include? 3
      if i.include? 11
        abbrev += "maj / min";
        name   += "Major / Minor "
      else
        abbrev += "min";
        name   += "Minor "
      end
    else
      if 11 in i:
        abbrev += "maj";
        name   += "Major "

      #PKM2014 - this is for suspended diminished chords.

      elsif i.include? 9 && i.size == 4 &&
        ((i.include? 5) || (i.include? 6 &&
                            ((i.include? 7) || (i.include? 8))))
        abbrev += "dim";
        name   += "Diminish "
      end
    end

    if i.include? 21
      abbrev += "13";
      name   += "13th "
    elsif i.include? 17
      abbrev += "11";
      name   += "11th "
    elsif i.include? 14
      abbrev += "9";
      name   += "9th "
    else
      abbrev += "7";
      name   += "7th "
    end

    if i.include? 20
      abbrev += "-13";
      name += "Flat 13th "
    end
    if i.include? 18
      abbrev += "+11";
      name += "Sharp 11th "
    end
    if i.include? 15
      abbrev += "+9";
      name += "Sharp 9th "
    end
    if i.include? 13
      abbrev += "-9";
      name += "Flat 9th "
    end
    if i.include? 8
      abbrev += "+5";
      name += "Sharp 5th "
    end
    if i.include? 6 && !(suspendsharpfourth)
      abbrev += "-5";
      name += "Flat 5th ";
    end

    # We eliminate chords that consist of the same note seperated by
    # an octave!

    if i.include?(3) && i.include?(15)
      # pass;
    elsif i.include?(5) && i.include?(17)
      # pass;
    elsif i.include?(6) && i.include?(18)
      # pass;
    elsif i.include?(8) && i.include?(20)
      # pass
    else
      name = name.rstrip

      if i.include? 5
        our_chordtype = CHORDTYPE_DICT["Suspended Seventh"]
      elsif i.include?(20) || i.include?(21)
        our_chordtype = CHORDTYPE_DICT["Thirteenth"]
      elsif i.include?(17) || i.include?(18)
        our_chordtype = CHORDTYPE_DICT["Eleventh"]
      elsif i.include?(13) || i.include?(14) || i.include?(15)
        our_chordtype = CHORDTYPE_DICT["Ninth"]
      else
        our_chordtype = CHORDTYPE_DICT["Seventh"]
        chordseq.append(NoteSeqChord.new(name,
          west_temp, i, our_chordtype, abbrev))
      end
    end

  end

  return chordseq
end

#int_to_roman(input) ⇒ Object

""" Convert an integer to Roman numerals.

Examples:
>>> int_to_roman(0)
Traceback (most recent call last):
ValueError: Argument must be between 1 and 3999

>>> int_to_roman(-1)
Traceback (most recent call last):
ValueError: Argument must be between 1 and 3999

>>> int_to_roman(1.5)
Traceback (most recent call last):
TypeError: expected integer, got <type 'float'>

>>> for i in range(1, 21): print int_to_roman(i)
...
I
II
III
IV
V
VI
VII
VIII
IX
X
XI
XII
XIII
XIV
XV
XVI
XVII
XVIII
XIX
XX
>>> print int_to_roman(2000)
MM
>>> print int_to_roman(1999)
MCMXCIX
"""

Raises:

  • (ArgumentError)


149
150
151
152
153
154
# File 'lib/music_set_theory/chord_generator.rb', line 149

def int_to_roman( input )
  raise ArgumentError, "#{input} must be greater than zero." if input <= 0
  raise TypeError, "Input must be an integer." unless input.is_a? Integer

  input.to_roman
end

#make_roman_numeral_list(num) ⇒ Object

Make a sequence of roman numerals from 1 to num.



158
159
160
161
# File 'lib/music_set_theory/chord_generator.rb', line 158

def make_roman_numeral_list( num )
  #return([int_to_roman(i) for i in range(1, num + 1)])
  (1...(num + 1)).map{|i| int_to_roman(i) }
end

#makebaserep(notex, base = 0) ⇒ Object

Used for converting "C" -> 1, "Db"-> 2b, etc.



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/music_set_theory/chord_generator.rb', line 241

def makebaserep( notex, base = 0 )
  notexparsed = WestTemp.note_parse(notex)
  #pos_rep = str(WestTemp.nat_key_lookup_order[notexparsed[0]] + base)
  pos_rep = (WestTemp.nat_key_lookup_order[notexparsed[0]] + base).to_s

  if notexparsed[1] > 0
    ret = pos_rep + (M_SHARP * notexparsed[1])
  elsif notexparsed[1] < 0
    ret = pos_rep + (M_FLAT * (-1 * notexparsed[1]))
  else
    ret = pos_rep
  end

  ret
end

#populate_scale_chords(scale_name, key, possiblechords, west_temp = WestTemp) ⇒ Object

Returns an instance of scale_chords using the following inputs:

Args

scale_name

a name of a scale like "Dorian".

key

generally a standard music key like "C".

possiblechords

a sequence of chord types like "Seventh" and "Ninth".

west_temp

Temperament object.

Returns

ScaleChords object.

def populate_scale_chords( scale_name, key, possiblechords )



269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# File 'lib/music_set_theory/chord_generator.rb', line 269

def populate_scale_chords( scale_name, key, possiblechords,
                           west_temp = WestTemp )
  our_scale = west_temp.get_nseqby_name(scale_name, NSEQ_SCALE)
  # num_elem = len(our_scale.nseq_posn)
  num_elem = our_scale.nseq_posn.size

  begin
    int_of_key    = key.to_i
    is_key_an_int = true
  rescue ValueError
    is_key_an_int = false
    int_of_key    = nil
  end

  if is_key_an_int
    #our_scale_notes = [makebaserep(x, int_of_key) for x in 
    #our_scale.get_notes_for_key("C")]
    our_scale_notes = our_scale.get_notes_for_key("C").map{|x|
                        makebaserep(x, int_of_key) }
  else
    our_scale_notes = our_scale.get_notes_for_key(key)
  end

  our_chord_data = ScaleChords.new(scale_name, key, our_scale_notes,
                     make_roman_numeral_list(num_elem))

  for i in possiblechords
    ourchordrow = ScaleChordRow.new(i)
    our_chord_data.rows.append(ourchordrow)

    # for j in range(num_elem):
    for j in 0...num_elem
      our_slice = CHORDTYPE_DICT[i]

      if is_key_an_int
        #our_chord_notes = [makebaserep(x, int_of_key) for x in
        #  our_scale.get_notes_for_key("C", j, our_slice)]
        our_chord_notes = our_scale.get_notes_for_key("C", j, our_slice).
                            map{|x| makebaserep(x, int_of_key) }
      else
        our_chord_notes = our_scale.get_notes_for_key(key, j, our_slice)
      end

      #our_posn  = our_scale.get_posn_for_offset(j, our_slice, true)
      our_posn  = our_scale.get_posn_for_offset(j, our_slice, raz: true)
      our_chord = west_temp.get_nseqby_seqpos(our_posn, NSEQ_CHORD)
      if our_chord
        ourchordrow.notes.append(ScaleChordCell.new(our_chord.nseq_name,
          our_chord.nseq_abbrev, our_chord_notes))
      else
        ourchordrow.notes.append(ScaleChordCell.new("", "", our_chord_notes))
      end

    end
  end

  return our_chord_data
end

#scale_analysis(scale_name, perm_chord_type) ⇒ Object

This is for decomposing a scale into chords. We use this as a test routine so we know what is required.



529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
# File 'lib/music_set_theory/scales.rb', line 529

def scale_analysis( scale_name, perm_chord_type )
   # 1. Lookup scale name.
   noteseq_founditem = noteseq.find_by_name(scale_name)

   # 2. Find scale pattern.
   ournoteseq = noteseq_founditem.noteseq

   #
   noteseq_founditem.noteseq.getpattern(noteseq_founditem.indices)

   #for i in range(ournoteseq.nseq_posn.len()):
   for i in 0...ournoteseq.nseq_posn.size
     ournoteslice = noteseq_for_slice(i, perm_chord_type)
     notechord_founditem = noteseq.find_by_chord(ournoteslice)

     if notechord_founditem == None
       print("None")
     else
       print(notechord_founditem.getName())
     end
   end

   return
end