|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Music::Scales;  | 
| 
2
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
164909
 | 
 use strict;  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
247
 | 
    | 
| 
3
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
6609
 | 
 use Text::Abbrev;  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
335
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
539
 | 
    | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 BEGIN {  | 
| 
6
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
32
 | 
 	use Exporter ();  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
108
 | 
    | 
| 
7
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
106
 | 
 	use vars qw ($VERSION @ISA @EXPORT);  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
588
 | 
    | 
| 
8
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
12
 | 
 	$VERSION     = 0.07;  | 
| 
9
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
73
 | 
 	@ISA         = qw (Exporter);  | 
| 
10
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13618
 | 
 	@EXPORT      = qw (get_scale_notes get_scale_nums get_scale_offsets is_scale get_scale_PDL get_scale_MIDI);  | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Scales - supply necessary notes / offsets for musical scales  | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SYNOPSIS  | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     use Music::Scales;  | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my @maj = get_scale_notes('Eb');           # defaults to major  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     print join(" ",@maj);                      # "Eb F G Ab Bb C D"  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my @blues = get_scale_nums('bl');          # 'bl','blu','blue','blues'  | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     print join(" ",@blues);                    # "0 3 5 6 7 10"  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my %min = get_scale_offsets ('G','mm',1);  # descending melodic minor  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     print map {"$_=$min{$_} "} sort keys %min; # "A=0 B=-1 C=0 D=0 E=-1 F=0 G=0"  | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DESCRIPTION  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Given a keynote A-G(#/b) and a scale-name, will return the scale,   | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  either as an array of notenames or as a hash of semitone-offsets for each note.  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 METHODS  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 get_scale_nums($scale[,$descending])  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 returns an array of semitone offsets for the requested scale, ascending/descending the given scale for one octave.  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The descending flag determines the direction of the scale, and also affects those scales (such as melodic minor) where the notes vary depending upon the direction.  | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Scaletypes and valid values for $scale are listed below.  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 get_scale_notes($notename[,$scale,$descending,$keypref])  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 returns an array of notenames, starting from the given keynote.  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Enharmonic equivalencies (whether to use F# or Gb, for instance) are calculated based on the keynote and the scale. Basically, it attempts to do the Right Thing if the scale is an 8-note one,   | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 (the 7th in G harmonic minor being F# rather than Gb, although G minor is a 'flat' key), but for any other scales, (Chromatic, blues etc.) it picks equivalencies based upon the keynote.  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This can be overidden with $keypref, setting to be either '#' or 'b' for sharps and flats respectively. Cruftiness abounds here :)  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 get_scale_offsets($notename[,$scale,$descending,$keypref])  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 as get_scale_notes(), except it returns a hash of notenames with the values being a semitone offset (-1, 0 or 1) as shown in the synopsis.  | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 get_scale_MIDI($notename,$octave[,$scale,$descending])  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 as get_scale_notes(), but returns an array of MIDI note-numbers, given an octave number (-1..9).  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 get_scale_PDL($notename,$octave[,$scale,$descending])  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 as get_scale_MIDI(), but returns an array of PDL-format notes.  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 is_scale($scalename)  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 returns true if $scalename is a valid scale name used in this module.  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SCALES   | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Scales can be passed either by name or number.  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The default scale is 'major' if none  / invalid is given.  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Text::Abbrev is used on scalenames, so they can be as abbreviated as unambiguously possible ('dor','io' etc.).  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Other abbreviations are shown in brackets.  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   1 ionian / major / hypolydian  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   2 dorian / hypmixolydian  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   3 phrygian / hypoaeolian  | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   4 lydian  / hypolocrian  | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   5 mixolydian / hypoionian  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   6 aeolian / hypodorian / minor / m  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   7 locrian / hypophrygian  | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   8 harmonic minor / hm  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   9 melodic minor / mm  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  10 blues   | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  11 pentatonic (pmajor)  | 
| 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  12 chromatic   | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  13 diminished   | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  14 wholetone   | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  15 augmented   | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  16 hungarian minor   | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  17 3 semitone   | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  18 4 semitone   | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  19 neapolitan minor (nmin)  | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  20 neapolitan major (nmaj)  | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  21 todi   | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  22 marva   | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  23 persian   | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  24 oriental   | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  25 romanian   | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  26 pelog   | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  27 iwato   | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  28 hirajoshi   | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  29 egyptian   | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  30 pentatonic minor (pminor)  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 EXAMPLE  | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This will print every scale in every key, adjusting the enharmonic equivalents accordingly.  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	foreach my $note qw (C C# D D# E F F# G G# A A# B) {  | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         foreach my $mode (1..30) {  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             my @notes = get_scale_notes($note,$mode);  | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             push @notes, get_scale_notes($note,$mode,1); # descending  | 
| 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             print join(" ",@notes),"\n";  | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 TODO  | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Add further range of scales from http://www.cs.ruu.nl/pub/MIDI/DOC/scales.zip  | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Improve enharmonic eqivalents.  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Microtones  | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Generate ragas,gamelan etc.  - maybe needs an 'ethnic' subset of modules  | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 AUTHOR  | 
| 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Ben Daglish (bdaglish@surfnet-ds.co.uk)  | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Thanks to Steve Hay for pointing out my 'minor' mix-up and many suggestions.  | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Thanks also to Gene Boggs for the 'is_scale' suggestion / code.  | 
| 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 BUGS   | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  A few enharmonic problems still...  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  All feedback most welcome.  | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 COPYRIGHT  | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Copyright (c) 2003, Ben Daglish. All Rights Reserved.  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  This program is free software; you can redistribute  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  it and/or modify it under the same terms as Perl itself.  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  The full text of the license can be found in the  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  LICENSE file included with this module.  | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SEE ALSO  | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 PDL::Audio::Scale, perl(1).  | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %modes = qw(ionian 1 major 1 hypolydian 1 dorian 2 hypomyxolydian 2   | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	phrygian 3 hypoaeolian 3 lydian 4 hypolocrian 4 mixolydian 5 hypoionian 5  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	aeolian 6 minor 6 m 6 hypodorian 6 locrian 7 hypophrygian 7   | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	harmonicminor 8 hm 8 melodicminor 9 mm 9  | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	blues 10 pentatonic 11 pmaj 11 chromatic 12 diminished 13 wholetone 14  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	augmented 15 hungarianminor 16 3semitone 17 4semitone 18   | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	neapolitanminor 19 nmin 19 neapolitanmajor 20 nmaj 20  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	todi 21 marva 22 persian 23 oriental 24 romanian 25 pelog 26  | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	iwato 27 hirajoshi 28 egyptian 29 pminor 30 pentatonicminor 30  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %abbrevs = abbrev(keys %modes);  | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 while (my ($k,$v) = each %abbrevs) {  | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	$modes{$k} = $modes{$v};  | 
| 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my @scales=([0,2,4,5,7,9,11],	# Ionian(1)  | 
| 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,2,3,5,7,9,10],	# Dorian (2)  | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,1,3,5,7,8,10],	# Phrygian (3)  | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,2,4,6,7,9,11],	# Lydian (4)  | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,2,4,5,7,9,10],	# Mixolydian (5)  | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,2,3,5,7,8,10],	# Aeolian (6)  | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,1,3,5,6,8,10],	# Locrian (7)  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,2,3,5,7,8,11],	# Harmonic Minor (8)  | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,2,3,5,7,9,11],	# Melodic Minor (9)  | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,3,5,6,7,10],		# Blues (10)  | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,2,4,7,9],		# Pentatonic (11)  | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,1,2,3,4,5,6,7,8,9,10,11],# Chromatic (12)  | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,2,3,5,6,8,9,11],	# Diminished (13)  | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,2,4,6,8,10],		# Whole tone(14)  | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,3,4,7,8,11],		# Augmented (15)  | 
| 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,2,3,6,7,8,11],	# Hungarian minor (16)  | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,3,6,9],			# 3 semitone (dimished arpeggio) (17)  | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,4,8],			# 4 semitone (augmented arpeggio) (18)  | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,1,3,5,7,8,11],	# Neapolitan minor  (19)  | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,1,3,5,7,9,11],	# Neapolitan major (20)  | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,1,3,6,7,8,11],	# Todi (Indian) (21)  | 
| 
190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,1,4,6,7,9,11],	# Marva (Indian) (22)  | 
| 
191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,1,4,5,6,8,11],	# Persian (23)  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,1,4,5,6,9,10],	# Oriental (24)  | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,2,3,6,7,9,10],	# Romanian (25)  | 
| 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,1,3,7,10],		# Pelog (Balinese) (26)  | 
| 
195
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,1,5,6,10],		# Iwato (Japanese) (27)  | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,2,3,7,8],		# Hirajoshi (Japanese) (28)  | 
| 
197
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,2,5,7,10],		# Egyptian (29)  | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			[0,3,5,7,10],		# Pentatonic Minor (30)  | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_scale_nums {  | 
| 
202
 | 
14
 | 
 
 | 
 
 | 
  
14
  
 | 
  
1
  
 | 
19
 | 
 	my ($mode,$descending) = @_;  | 
| 
203
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
 	$mode = get_mode($mode);  | 
| 
204
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
 	my @dists = @{$scales[$mode-1]};  | 
| 
 
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
    | 
| 
205
 | 
14
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
50
 | 
 	if ($descending && $mode == 9) {  | 
| 
206
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$dists[5]-- ;$dists[6]--;  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
208
 | 
14
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
68
 | 
 	($descending) ? reverse @dists  : @dists;  | 
| 
209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_scale_offsets {  | 
| 
212
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
 	my @scale = get_scale_notes(@_);  | 
| 
213
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my %key_alts = qw(C 0 D 0 E 0 F 0 G 0 A 0 B 0);  | 
| 
214
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	foreach (@scale) {  | 
| 
215
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$key_alts{$_}++ if s/#//;  | 
| 
216
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$key_alts{$_}-- if s/b//;  | 
| 
217
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
218
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	%key_alts;  | 
| 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_mode {  | 
| 
222
 | 
23
 | 
 
 | 
  
100
  
 | 
  
23
  
 | 
  
0
  
 | 
56
 | 
 	my $mode = shift() || 1;  | 
| 
223
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
167
 | 
 	$mode =~ s/[^a-zA-Z0-9]//g;  | 
| 
224
 | 
23
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
95
 | 
 	$mode = $modes{lc($mode)} unless $mode =~/^[0-9]+$/;  | 
| 
225
 | 
23
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
125
 | 
 	($mode && ($mode <= @scales)) ? $mode : 1;  | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub note_to_num {  | 
| 
229
 | 
46
 | 
 
 | 
 
 | 
  
46
  
 | 
  
0
  
 | 
54
 | 
 	my $note = shift();  | 
| 
230
 | 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
492
 | 
 	my %note2num = ('A','0','A#','1','BB','1','B','2','C','3','C#','4','DB','4','D','5','D#','6','EB','6','E','7','F','8','F#','9','GB','9','G','10','G#','11','AB','11');  | 
| 
231
 | 
46
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
117
 | 
 	return $note if ($note =~/^[0-9]+$/);  | 
| 
232
 | 
46
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
268
 | 
 	(defined $note2num{uc($note)}) ? $note2num{uc($note)} : 0;  | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub note_to_MIDI {  | 
| 
236
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
0
  
 | 
4
 | 
 	my ($note,$octave) = @_;  | 
| 
237
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
 	((note_to_num($note)+9) % 12) + (12 * ++$octave );   | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_scale_MIDI {  | 
| 
241
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
1
  
 | 
14
 | 
 	my ($note,$octave,$mode,$descending) = @_;  | 
| 
242
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
 	my $basenum = note_to_MIDI($note,$octave);  | 
| 
243
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
 	return map {$basenum + $_} get_scale_nums($mode,$descending);  | 
| 
 
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
    | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_scale_PDL {  | 
| 
247
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
  
1
  
 | 
16
 | 
 	my ($note,$octave,$mode,$descending,$keypref) = @_;  | 
| 
248
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
 	scale_to_PDL($octave,get_scale_notes($note,$mode,$descending,$keypref));  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_scale_notes {  | 
| 
252
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
  
1
  
 | 
26
 | 
 	my ($keynote,$mode,$descending,$keypref) = @_;  | 
| 
253
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
 	my @notes = ('A'..'G');  | 
| 
254
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
 	my @nums = (2,1,2,2,1,2,2);  | 
| 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
256
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
 	$keynote =~ s/^[a-z]/\u$&/;  | 
| 
257
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
27
 | 
 	$keypref='' unless defined $keypref;  | 
| 
258
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
 	my $keynum = note_to_num(uc($keynote));  | 
| 
259
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
 	$mode = get_mode($mode);  | 
| 
260
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
 	my @dists = get_scale_nums($mode,$descending);  | 
| 
261
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
24
 | 
 	@dists = reverse @dists if $descending;  | 
| 
262
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
 	my @scale = map {($_+$keynum-$dists[0])%12} @dists;  | 
| 
 
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
121
 | 
    | 
| 
263
 | 
9
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
57
 | 
 	$keypref='b' if (!$keypref && $descending && $mode == 12); #prefer flat descending chromatic  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
265
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
97
 | 
 	my %num2note = (0,'A',1,'A#',2,'B',3,'C',4,'C#',5,'D',6,'D#',7,'E',8,'F',9,'F#',10,'G',11,'G#');  | 
| 
266
 | 
9
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
65
 | 
 	%num2note = (0,'A',1,'Bb',2,'B',3,'C',4,'Db',5,'D',6,'Eb',7,'E',8,'F',9,'Gb',10,'G',11,'Ab') if (($keypref eq 'b') || ($keynote =~ /.b/i));  | 
| 
267
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
 	my @mscale = $keynote;  | 
| 
268
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
23
 | 
 	if (@scale  > 7) {	# we're not bothered by niceties, so just convert  | 
| 
269
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
 		@mscale = map {$num2note{$_}} @scale;  | 
| 
 
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
81
 | 
    | 
| 
270
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	else {  | 
| 
272
 | 
7
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
19
 | 
 		$keynote = $num2note{$keynote} if $keynote =~/^[0-9]+$/;  | 
| 
273
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
 		my $kk = $keynote; $kk =~ s/b|\#//; $kk = ord($kk) - ord('A');  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
274
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
 		foreach(0..$kk-1) {# rotate to keynote  | 
| 
275
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
 			push @notes,shift(@notes);  | 
| 
276
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
 			push @nums,shift(@nums);  | 
| 
277
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
278
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
 		push @notes,shift(@notes);  | 
| 
279
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
 		shift(@dists);  | 
| 
280
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
 		my $cu = shift(@nums);  | 
| 
281
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
20
 | 
 		$cu++ if ($keynote =~ /b/);  | 
| 
282
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
19
 | 
 		$cu-- if ($keynote =~ /#/);  | 
| 
283
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
 		foreach (@dists) {  | 
| 
284
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
 			my $m = $_ - $cu;  | 
| 
285
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
 			my $ns = shift(@nums);  | 
| 
286
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
 			push @nums,$ns;  | 
| 
287
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
 			my $n = shift(@notes);   | 
| 
288
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
 			push @notes,$n;  | 
| 
289
 | 
36
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
198
 | 
 			while (abs($m) > 2 || (@scale < 7 && abs($m) >= $ns)) {	# step up/down notes, 'reducing' flats/sharps  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
290
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
 				$n = shift(@notes); push @notes,$n;  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
    | 
| 
291
 | 
6
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
12
 | 
 				if ($m > 0) {$m -= $ns;$cu += $ns }  | 
| 
 
 | 
6
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
    | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
292
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 				elsif ($m < 0){$m += $ns;$cu -= $ns}  | 
| 
293
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
 				$ns = shift(@nums); push @nums,$ns;  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
    | 
| 
294
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
295
 | 
36
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
78
 | 
 			$n .= '#' x $m if ($m > 0);  | 
| 
296
 | 
36
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
217
 | 
 			$n .= 'b' x abs($m) if ($m < 0);  | 
| 
297
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
 			push @mscale,$n;  | 
| 
298
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
62
 | 
 			$cu += $ns;  | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
301
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
32
 | 
 	if ($descending) {  | 
| 
302
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
 		@mscale = reverse @mscale;  | 
| 
303
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
 		unshift @mscale,pop(@mscale);  | 
| 
304
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
305
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
101
 | 
 	@mscale;  | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
308
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub is_scale {  | 
| 
310
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
  
1
  
 | 
18
 | 
 	my $name = shift();  | 
| 
311
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     $name =~ s/[^a-zA-Z0-9]//g;  | 
| 
312
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
41
 | 
     return exists $modes{lc $name} ? 1 : 0;  | 
| 
313
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub scale_to_PDL {  | 
| 
316
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
  
0
  
 | 
154
 | 
 	my ($octave,@scale)=@_;  | 
| 
317
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 	my @result;  | 
| 
318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	my $descending;  | 
| 
319
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
 	my $n1 = note_to_num($scale[0]);  | 
| 
320
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
 	my $n2 = note_to_num($scale[1]);  | 
| 
321
 | 
4
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
21
 | 
 	if ($n2 < $n1 && ($n1-$n2 < 5)) {  | 
| 
322
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
 		$descending = 1;  | 
| 
323
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
 		@scale = reverse @scale;  | 
| 
324
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
325
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
 	my $last = (note_to_num($scale[0]) + 9) % 12;  | 
| 
326
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
 	foreach (@scale) {  | 
| 
327
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
 		my $n = (note_to_num($_) + 9) % 12;  | 
| 
328
 | 
22
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
43
 | 
 		$octave++ if ($last > $n); #switched over octave at 'c'  | 
| 
329
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
 		s/\#/s/g;  | 
| 
330
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28
 | 
 		s/b/f/g;  | 
| 
331
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
 		push @result,lc($_).$octave;  | 
| 
332
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
 		$last = $n;  | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
334
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
 	@result = reverse @result if $descending;  | 
| 
335
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
 	@result;  | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
337
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
338
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;   | 
| 
339
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |