NAME

Music::Scales - Generate musical scales

VERSION

version 0.11

SYNOPSIS

use Music::Scales;
my @maj = get_scale_notes('Eb');           # defaults to major
print join(" ",@maj);                      # "Eb F G Ab Bb C D"
@maj = get_scale_MIDI('C', 4);             # 60, 62, 64, 65, 67, 69, 71
@maj = get_scale_PDL('Eb', 4);             # ef4, f4, g4, af4, bf4, c5, d5
my @blues = get_scale_nums('bl');          # 'bl','blu','blue','blues'
print join(" ",@blues);                    # "0 3 5 6 7 10"
my %min = get_scale_offsets ('G','mm',1);  # descending melodic minor
print join " ", map {"$_=$min{$_} "} sort keys %min; # "A=0 B=-1 C=0 D=0 E=-1 F=0 G=0"
print is_scale('foo') ? 1 : 0;

DESCRIPTION

Given a keynote A-G(#/b) and a scale-name, will return the scale, either as an array of notenames or as a hash of semitone-offsets for each note.

All functions are exported by default. Also the essential variables, %modes, %abbrevs, and @scales are exported. Please see the source for their definitions.

METHODS

get_scale_nums($scale[,$descending])

returns an array of semitone offsets for the requested scale, ascending/descending the given scale for one octave.

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.

Scaletypes and valid values for $scale are listed below.

get_scale_notes($notename[,$scale,$descending,$keypref])

returns an array of notenames, starting from the given keynote.

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, (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.

This can be overidden with $keypref, setting to be either '#' or 'b' for sharps and flats respectively. Cruftiness abounds here :)

get_scale_offsets($notename[,$scale,$descending,$keypref])

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.

get_scale_MIDI($notename,$octave[,$scale,$descending])

as get_scale_notes(), but returns an array of MIDI note-numbers, given an octave number (-1..9).

get_scale_PDL($notename,$octave[,$scale,$descending])

as get_scale_MIDI(), but returns an array of PDL-format notes.

is_scale($scalename)

returns true if $scalename is a valid scale name used in this module.

SCALES

Scales can be passed either by name or number.

The default scale is 'major' if none / invalid is given.

Text::Abbrev is used on scalenames, so they can be as abbreviated as unambiguously possible ('dor','io' etc.). Other abbreviations are shown in brackets.

 1 ionian / major / hypolydian
 2 dorian / hypmixolydian
 3 phrygian / hypoaeolian
 4 lydian  / hypolocrian
 5 mixolydian / hypoionian
 6 aeolian / hypodorian / minor / m
 7 locrian / hypophrygian
 8 harmonic minor / hm
 9 melodic minor / mm
10 blues 
11 pentatonic (pmajor)
12 chromatic 
13 diminished 
14 wholetone 
15 augmented 
16 hungarian minor 
17 3 semitone 
18 4 semitone 
19 neapolitan minor (nmin)
20 neapolitan major (nmaj)
21 todi 
22 marva 
23 persian 
24 oriental 
25 romanian 
26 pelog 
27 iwato 
28 hirajoshi 
29 egyptian 
30 pentatonic minor (pminor)

EXAMPLE

This will print every scale in every key, adjusting the enharmonic equivalents accordingly.

foreach my $note qw (C C# D D# E F F# G G# A A# B) {
    foreach my $mode (1..30) {
        my @notes = get_scale_notes($note,$mode);
        push @notes, get_scale_notes($note,$mode,1); # descending
        print join(" ",@notes),"\n";
    }
}

TODO

Add further range of scales from http://www.cs.ruu.nl/pub/MIDI/DOC/scales.zip

Improve enharmonic equivalents.

Microtones

Generate ragas,gamelan etc. - maybe needs an 'ethnic' subset of modules

BUGS

A few enharmonic problems still...

All feedback most welcome.

SEE ALSO

PDL::Audio::Scale, perl(1).

THANK YOU

Thanks to Steve Hay for pointing out my 'minor' mix-up and many suggestions.

Thanks also to Gene Boggs for the 'is_scale' suggestion / code.

AUTHOR

Ben Daglish <bdaglish@surfnet-ds.co.uk>

COPYRIGHT AND LICENSE

This software is copyright (c) 2003-2026 by Ben Daglish.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.