Skip to content

Instantly share code, notes, and snippets.

@creaktive
Last active November 21, 2019 19:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save creaktive/1e2c42264a8f6a2799cd726b2e237607 to your computer and use it in GitHub Desktop.
Save creaktive/1e2c42264a8f6a2799cd726b2e237607 to your computer and use it in GitHub Desktop.
heptatonic scale generator
#!/usr/bin/env perl
# inspired by https://randscullard.com/CircleOfFifths/
# and http://pages.mtu.edu/~suits/notefreqs.html
use 5.010;
use strict;
use warnings;
use charnames ();
use open OUT => ':locale';
use utf8;
my $tones = 12;
my @mode = qw( 2 2 1 2 2 2 1 ); # Ionian
# my @mode = qw( 2 1 2 2 1 2 2 ); # Aeolian
my %natural = qw( 0 C 2 D 4 E 5 F 7 G 9 A 11 B );
my @note;
my $c = 0;
for my $i ( @mode ) {
push @note => $c;
$c += $i;
}
my ( %sharp, %flat );
for my $i ( keys %natural ) {
$sharp { ( $i + 1 ) % $tones } = $natural{ $i } . "\N{MUSIC SHARP SIGN}";
$flat { ( $i - 1 ) % $tones } = $natural{ $i } . "\N{MUSIC FLAT SIGN}";
}
sub print_scale (@) { sprintf join( ' ', ( '%-2s' ) x 7 ) => @_ }
sub notes ($) { map { ( 7 * $_[ 0 ] + $note[ $_ ] ) % $tones } 0 .. $#mode }
for my $i ( 0 .. 6 ) {
say print_scale map {
$i == 6
? $sharp{ $_ } || $natural{ $_ }
: $natural{ $_ } || $sharp{ $_ }
} notes $i
}
for my $i ( 6 .. 11 ) {
say print_scale map {
$i == 6
? $flat{ $_ } || $natural{ $_ }
: $natural{ $_ } || $flat{ $_ }
} notes $i
}
__DATA__
C D E F G A B
G A B C D E F♯
D E F♯ G A B C♯
A B C♯ D E F♯ G♯
E F♯ G♯ A B C♯ D♯
B C♯ D♯ E F♯ G♯ A♯
F♯ G♯ A♯ B C♯ D♯ E♯
G♭ A♭ B♭ C♭ D♭ E♭ F
D♭ E♭ F G♭ A♭ B♭ C
A♭ B♭ C D♭ E♭ F G
E♭ F G A♭ B♭ C D
B♭ C D E♭ F G A
F G A B♭ C D E
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Major & Minor Scales</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:200" rel="stylesheet">
<style>
body { background-color: #000 }
table {
border: 0;
-webkit-border-horizontal-spacing: 0;
-webkit-border-vertical-spacing: 0;
}
td {
width: 10em;
height: 10em;
color: #fff;
font-family: 'Source Code Pro', monospace;
font-size: 10pt;
text-align: center;
vertical-align: middle;
}
td span { opacity: 0.75 }
td span big { font-size: 3em }
</style>
</head>
<body><table>
<tr>
<td style="background-color:#9A0000"><span><big>C♯</big><br/>277.2 Hz<br/>124.5 cm</span></td>
<td style="background-color:#FF0000"><span><big>D♯</big><br/>311.1 Hz<br/>110.9 cm</span></td>
<td style="background-color:#FF5300"><span><big>F</big><br/>349.2 Hz<br/>98.8 cm</span></td>
<td style="background-color:#FFD400"><span><big>F♯</big><br/>370.0 Hz<br/>93.2 cm</span></td>
<td style="background-color:#20FF00"><span><big>G♯</big><br/>415.3 Hz<br/>83.1 cm</span></td>
<td style="background-color:#4800FF"><span><big>A♯</big><br/>466.2 Hz<br/>74.0 cm</span></td>
<td style="background-color:#610000"><span><big>C</big><br/>523.3 Hz<br/>65.9 cm</span></td>
</tr>
<tr>
<td style="background-color:#FFD400"><span><big>F♯</big><br/>370.0 Hz<br/>93.2 cm</span></td>
<td style="background-color:#20FF00"><span><big>G♯</big><br/>415.3 Hz<br/>83.1 cm</span></td>
<td style="background-color:#4800FF"><span><big>A♯</big><br/>466.2 Hz<br/>74.0 cm</span></td>
<td style="background-color:#610061"><span><big>B</big><br/>493.9 Hz<br/>69.9 cm</span></td>
<td style="background-color:#9A0000"><span><big>C♯</big><br/>554.4 Hz<br/>62.2 cm</span></td>
<td style="background-color:#FF0000"><span><big>D♯</big><br/>622.3 Hz<br/>55.4 cm</span></td>
<td style="background-color:#FF5300"><span><big>F</big><br/>698.5 Hz<br/>49.4 cm</span></td>
</tr>
<tr>
<td style="background-color:#610061"><span><big>B</big><br/>493.9 Hz<br/>69.9 cm</span></td>
<td style="background-color:#9A0000"><span><big>C♯</big><br/>554.4 Hz<br/>62.2 cm</span></td>
<td style="background-color:#FF0000"><span><big>D♯</big><br/>622.3 Hz<br/>55.4 cm</span></td>
<td style="background-color:#FF0000"><span><big>E</big><br/>659.3 Hz<br/>52.3 cm</span></td>
<td style="background-color:#FFD400"><span><big>F♯</big><br/>740.0 Hz<br/>46.6 cm</span></td>
<td style="background-color:#20FF00"><span><big>G♯</big><br/>830.6 Hz<br/>41.5 cm</span></td>
<td style="background-color:#4800FF"><span><big>A♯</big><br/>932.3 Hz<br/>37.0 cm</span></td>
</tr>
<tr>
<td style="background-color:#FF0000"><span><big>E</big><br/>329.6 Hz<br/>104.7 cm</span></td>
<td style="background-color:#FFD400"><span><big>F♯</big><br/>370.0 Hz<br/>93.2 cm</span></td>
<td style="background-color:#20FF00"><span><big>G♯</big><br/>415.3 Hz<br/>83.1 cm</span></td>
<td style="background-color:#00B6FF"><span><big>A</big><br/>440.0 Hz<br/>78.4 cm</span></td>
<td style="background-color:#610061"><span><big>B</big><br/>493.9 Hz<br/>69.9 cm</span></td>
<td style="background-color:#9A0000"><span><big>C♯</big><br/>554.4 Hz<br/>62.2 cm</span></td>
<td style="background-color:#FF0000"><span><big>D♯</big><br/>622.3 Hz<br/>55.4 cm</span></td>
</tr>
<tr>
<td style="background-color:#00B6FF"><span><big>A</big><br/>440.0 Hz<br/>78.4 cm</span></td>
<td style="background-color:#610061"><span><big>B</big><br/>493.9 Hz<br/>69.9 cm</span></td>
<td style="background-color:#9A0000"><span><big>C♯</big><br/>554.4 Hz<br/>62.2 cm</span></td>
<td style="background-color:#D20000"><span><big>D</big><br/>587.3 Hz<br/>58.7 cm</span></td>
<td style="background-color:#FF0000"><span><big>E</big><br/>659.3 Hz<br/>52.3 cm</span></td>
<td style="background-color:#FFD400"><span><big>F♯</big><br/>740.0 Hz<br/>46.6 cm</span></td>
<td style="background-color:#20FF00"><span><big>G♯</big><br/>830.6 Hz<br/>41.5 cm</span></td>
</tr>
<tr>
<td style="background-color:#D20000"><span><big>D</big><br/>293.7 Hz<br/>117.5 cm</span></td>
<td style="background-color:#FF0000"><span><big>E</big><br/>329.6 Hz<br/>104.7 cm</span></td>
<td style="background-color:#FFD400"><span><big>F♯</big><br/>370.0 Hz<br/>93.2 cm</span></td>
<td style="background-color:#B5FF00"><span><big>G</big><br/>392.0 Hz<br/>88.0 cm</span></td>
<td style="background-color:#00B6FF"><span><big>A</big><br/>440.0 Hz<br/>78.4 cm</span></td>
<td style="background-color:#610061"><span><big>B</big><br/>493.9 Hz<br/>69.9 cm</span></td>
<td style="background-color:#9A0000"><span><big>C♯</big><br/>554.4 Hz<br/>62.2 cm</span></td>
</tr>
<tr>
<td style="background-color:#B5FF00"><span><big>G</big><br/>392.0 Hz<br/>88.0 cm</span></td>
<td style="background-color:#00B6FF"><span><big>A</big><br/>440.0 Hz<br/>78.4 cm</span></td>
<td style="background-color:#610061"><span><big>B</big><br/>493.9 Hz<br/>69.9 cm</span></td>
<td style="background-color:#610000"><span><big>C</big><br/>523.3 Hz<br/>65.9 cm</span></td>
<td style="background-color:#D20000"><span><big>D</big><br/>587.3 Hz<br/>58.7 cm</span></td>
<td style="background-color:#FF0000"><span><big>E</big><br/>659.3 Hz<br/>52.3 cm</span></td>
<td style="background-color:#FFD400"><span><big>F♯</big><br/>740.0 Hz<br/>46.6 cm</span></td>
</tr>
<tr>
<td style="background-color:#610000"><span><big>C</big><br/>261.6 Hz<br/>131.9 cm</span></td>
<td style="background-color:#D20000"><span><big>D</big><br/>293.7 Hz<br/>117.5 cm</span></td>
<td style="background-color:#FF0000"><span><big>E</big><br/>329.6 Hz<br/>104.7 cm</span></td>
<td style="background-color:#FF5300"><span><big>F</big><br/>349.2 Hz<br/>98.8 cm</span></td>
<td style="background-color:#B5FF00"><span><big>G</big><br/>392.0 Hz<br/>88.0 cm</span></td>
<td style="background-color:#00B6FF"><span><big>A</big><br/>440.0 Hz<br/>78.4 cm</span></td>
<td style="background-color:#610061"><span><big>B</big><br/>493.9 Hz<br/>69.9 cm</span></td>
</tr>
<tr>
<td style="background-color:#FF5300"><span><big>F</big><br/>349.2 Hz<br/>98.8 cm</span></td>
<td style="background-color:#B5FF00"><span><big>G</big><br/>392.0 Hz<br/>88.0 cm</span></td>
<td style="background-color:#00B6FF"><span><big>A</big><br/>440.0 Hz<br/>78.4 cm</span></td>
<td style="background-color:#4800FF"><span><big>B♭</big><br/>466.2 Hz<br/>74.0 cm</span></td>
<td style="background-color:#610000"><span><big>C</big><br/>523.3 Hz<br/>65.9 cm</span></td>
<td style="background-color:#D20000"><span><big>D</big><br/>587.3 Hz<br/>58.7 cm</span></td>
<td style="background-color:#FF0000"><span><big>E</big><br/>659.3 Hz<br/>52.3 cm</span></td>
</tr>
<tr>
<td style="background-color:#4800FF"><span><big>B♭</big><br/>466.2 Hz<br/>74.0 cm</span></td>
<td style="background-color:#610000"><span><big>C</big><br/>523.3 Hz<br/>65.9 cm</span></td>
<td style="background-color:#D20000"><span><big>D</big><br/>587.3 Hz<br/>58.7 cm</span></td>
<td style="background-color:#FF0000"><span><big>E♭</big><br/>622.3 Hz<br/>55.4 cm</span></td>
<td style="background-color:#FF5300"><span><big>F</big><br/>698.5 Hz<br/>49.4 cm</span></td>
<td style="background-color:#B5FF00"><span><big>G</big><br/>784.0 Hz<br/>44.0 cm</span></td>
<td style="background-color:#00B6FF"><span><big>A</big><br/>880.0 Hz<br/>39.2 cm</span></td>
</tr>
<tr>
<td style="background-color:#FF0000"><span><big>E♭</big><br/>311.1 Hz<br/>110.9 cm</span></td>
<td style="background-color:#FF5300"><span><big>F</big><br/>349.2 Hz<br/>98.8 cm</span></td>
<td style="background-color:#B5FF00"><span><big>G</big><br/>392.0 Hz<br/>88.0 cm</span></td>
<td style="background-color:#20FF00"><span><big>A♭</big><br/>415.3 Hz<br/>83.1 cm</span></td>
<td style="background-color:#4800FF"><span><big>B♭</big><br/>466.2 Hz<br/>74.0 cm</span></td>
<td style="background-color:#610000"><span><big>C</big><br/>523.3 Hz<br/>65.9 cm</span></td>
<td style="background-color:#D20000"><span><big>D</big><br/>587.3 Hz<br/>58.7 cm</span></td>
</tr>
<tr>
<td style="background-color:#20FF00"><span><big>A♭</big><br/>415.3 Hz<br/>83.1 cm</span></td>
<td style="background-color:#4800FF"><span><big>B♭</big><br/>466.2 Hz<br/>74.0 cm</span></td>
<td style="background-color:#610000"><span><big>C</big><br/>523.3 Hz<br/>65.9 cm</span></td>
<td style="background-color:#9A0000"><span><big>D♭</big><br/>554.4 Hz<br/>62.2 cm</span></td>
<td style="background-color:#FF0000"><span><big>E♭</big><br/>622.3 Hz<br/>55.4 cm</span></td>
<td style="background-color:#FF5300"><span><big>F</big><br/>698.5 Hz<br/>49.4 cm</span></td>
<td style="background-color:#B5FF00"><span><big>G</big><br/>784.0 Hz<br/>44.0 cm</span></td>
</tr>
<tr>
<td style="background-color:#9A0000"><span><big>D♭</big><br/>277.2 Hz<br/>124.5 cm</span></td>
<td style="background-color:#FF0000"><span><big>E♭</big><br/>311.1 Hz<br/>110.9 cm</span></td>
<td style="background-color:#FF5300"><span><big>F</big><br/>349.2 Hz<br/>98.8 cm</span></td>
<td style="background-color:#FFD400"><span><big>G♭</big><br/>370.0 Hz<br/>93.2 cm</span></td>
<td style="background-color:#20FF00"><span><big>A♭</big><br/>415.3 Hz<br/>83.1 cm</span></td>
<td style="background-color:#4800FF"><span><big>B♭</big><br/>466.2 Hz<br/>74.0 cm</span></td>
<td style="background-color:#610000"><span><big>C</big><br/>523.3 Hz<br/>65.9 cm</span></td>
</tr>
<tr>
<td style="background-color:#FFD400"><span><big>G♭</big><br/>370.0 Hz<br/>93.2 cm</span></td>
<td style="background-color:#20FF00"><span><big>A♭</big><br/>415.3 Hz<br/>83.1 cm</span></td>
<td style="background-color:#4800FF"><span><big>B♭</big><br/>466.2 Hz<br/>74.0 cm</span></td>
<td style="background-color:#610061"><span><big>B</big><br/>493.9 Hz<br/>69.9 cm</span></td>
<td style="background-color:#9A0000"><span><big>D♭</big><br/>554.4 Hz<br/>62.2 cm</span></td>
<td style="background-color:#FF0000"><span><big>E♭</big><br/>622.3 Hz<br/>55.4 cm</span></td>
<td style="background-color:#FF5300"><span><big>F</big><br/>698.5 Hz<br/>49.4 cm</span></td>
</tr>
<tr>
<td style="background-color:#610061"><span><big>B</big><br/>493.9 Hz<br/>69.9 cm</span></td>
<td style="background-color:#9A0000"><span><big>D♭</big><br/>554.4 Hz<br/>62.2 cm</span></td>
<td style="background-color:#FF0000"><span><big>E♭</big><br/>622.3 Hz<br/>55.4 cm</span></td>
<td style="background-color:#FF0000"><span><big>E</big><br/>659.3 Hz<br/>52.3 cm</span></td>
<td style="background-color:#FFD400"><span><big>G♭</big><br/>740.0 Hz<br/>46.6 cm</span></td>
<td style="background-color:#20FF00"><span><big>A♭</big><br/>830.6 Hz<br/>41.5 cm</span></td>
<td style="background-color:#4800FF"><span><big>B♭</big><br/>932.3 Hz<br/>37.0 cm</span></td>
</tr>
<tr>
<td style="background-color:#9A0000"><span><big>c♯</big><br/>277.2 Hz<br/>124.5 cm</span></td>
<td style="background-color:#FF0000"><span><big>d♯</big><br/>311.1 Hz<br/>110.9 cm</span></td>
<td style="background-color:#FF0000"><span><big>e</big><br/>329.6 Hz<br/>104.7 cm</span></td>
<td style="background-color:#FFD400"><span><big>f♯</big><br/>370.0 Hz<br/>93.2 cm</span></td>
<td style="background-color:#20FF00"><span><big>g♯</big><br/>415.3 Hz<br/>83.1 cm</span></td>
<td style="background-color:#00B6FF"><span><big>a</big><br/>440.0 Hz<br/>78.4 cm</span></td>
<td style="background-color:#610061"><span><big>b</big><br/>493.9 Hz<br/>69.9 cm</span></td>
</tr>
<tr>
<td style="background-color:#FFD400"><span><big>f♯</big><br/>370.0 Hz<br/>93.2 cm</span></td>
<td style="background-color:#20FF00"><span><big>g♯</big><br/>415.3 Hz<br/>83.1 cm</span></td>
<td style="background-color:#00B6FF"><span><big>a</big><br/>440.0 Hz<br/>78.4 cm</span></td>
<td style="background-color:#610061"><span><big>b</big><br/>493.9 Hz<br/>69.9 cm</span></td>
<td style="background-color:#9A0000"><span><big>c♯</big><br/>554.4 Hz<br/>62.2 cm</span></td>
<td style="background-color:#D20000"><span><big>d</big><br/>587.3 Hz<br/>58.7 cm</span></td>
<td style="background-color:#FF0000"><span><big>e</big><br/>659.3 Hz<br/>52.3 cm</span></td>
</tr>
<tr>
<td style="background-color:#610061"><span><big>b</big><br/>493.9 Hz<br/>69.9 cm</span></td>
<td style="background-color:#9A0000"><span><big>c♯</big><br/>554.4 Hz<br/>62.2 cm</span></td>
<td style="background-color:#D20000"><span><big>d</big><br/>587.3 Hz<br/>58.7 cm</span></td>
<td style="background-color:#FF0000"><span><big>e</big><br/>659.3 Hz<br/>52.3 cm</span></td>
<td style="background-color:#FFD400"><span><big>f♯</big><br/>740.0 Hz<br/>46.6 cm</span></td>
<td style="background-color:#B5FF00"><span><big>g</big><br/>784.0 Hz<br/>44.0 cm</span></td>
<td style="background-color:#00B6FF"><span><big>a</big><br/>880.0 Hz<br/>39.2 cm</span></td>
</tr>
<tr>
<td style="background-color:#FF0000"><span><big>e</big><br/>329.6 Hz<br/>104.7 cm</span></td>
<td style="background-color:#FFD400"><span><big>f♯</big><br/>370.0 Hz<br/>93.2 cm</span></td>
<td style="background-color:#B5FF00"><span><big>g</big><br/>392.0 Hz<br/>88.0 cm</span></td>
<td style="background-color:#00B6FF"><span><big>a</big><br/>440.0 Hz<br/>78.4 cm</span></td>
<td style="background-color:#610061"><span><big>b</big><br/>493.9 Hz<br/>69.9 cm</span></td>
<td style="background-color:#610000"><span><big>c</big><br/>523.3 Hz<br/>65.9 cm</span></td>
<td style="background-color:#D20000"><span><big>d</big><br/>587.3 Hz<br/>58.7 cm</span></td>
</tr>
<tr>
<td style="background-color:#00B6FF"><span><big>a</big><br/>440.0 Hz<br/>78.4 cm</span></td>
<td style="background-color:#610061"><span><big>b</big><br/>493.9 Hz<br/>69.9 cm</span></td>
<td style="background-color:#610000"><span><big>c</big><br/>523.3 Hz<br/>65.9 cm</span></td>
<td style="background-color:#D20000"><span><big>d</big><br/>587.3 Hz<br/>58.7 cm</span></td>
<td style="background-color:#FF0000"><span><big>e</big><br/>659.3 Hz<br/>52.3 cm</span></td>
<td style="background-color:#FF5300"><span><big>f</big><br/>698.5 Hz<br/>49.4 cm</span></td>
<td style="background-color:#B5FF00"><span><big>g</big><br/>784.0 Hz<br/>44.0 cm</span></td>
</tr>
<tr>
<td style="background-color:#D20000"><span><big>d</big><br/>293.7 Hz<br/>117.5 cm</span></td>
<td style="background-color:#FF0000"><span><big>e</big><br/>329.6 Hz<br/>104.7 cm</span></td>
<td style="background-color:#FF5300"><span><big>f</big><br/>349.2 Hz<br/>98.8 cm</span></td>
<td style="background-color:#B5FF00"><span><big>g</big><br/>392.0 Hz<br/>88.0 cm</span></td>
<td style="background-color:#00B6FF"><span><big>a</big><br/>440.0 Hz<br/>78.4 cm</span></td>
<td style="background-color:#4800FF"><span><big>b♭</big><br/>466.2 Hz<br/>74.0 cm</span></td>
<td style="background-color:#610000"><span><big>c</big><br/>523.3 Hz<br/>65.9 cm</span></td>
</tr>
<tr>
<td style="background-color:#B5FF00"><span><big>g</big><br/>392.0 Hz<br/>88.0 cm</span></td>
<td style="background-color:#00B6FF"><span><big>a</big><br/>440.0 Hz<br/>78.4 cm</span></td>
<td style="background-color:#4800FF"><span><big>b♭</big><br/>466.2 Hz<br/>74.0 cm</span></td>
<td style="background-color:#610000"><span><big>c</big><br/>523.3 Hz<br/>65.9 cm</span></td>
<td style="background-color:#D20000"><span><big>d</big><br/>587.3 Hz<br/>58.7 cm</span></td>
<td style="background-color:#FF0000"><span><big>e♭</big><br/>622.3 Hz<br/>55.4 cm</span></td>
<td style="background-color:#FF5300"><span><big>f</big><br/>698.5 Hz<br/>49.4 cm</span></td>
</tr>
<tr>
<td style="background-color:#610000"><span><big>c</big><br/>261.6 Hz<br/>131.9 cm</span></td>
<td style="background-color:#D20000"><span><big>d</big><br/>293.7 Hz<br/>117.5 cm</span></td>
<td style="background-color:#FF0000"><span><big>e♭</big><br/>311.1 Hz<br/>110.9 cm</span></td>
<td style="background-color:#FF5300"><span><big>f</big><br/>349.2 Hz<br/>98.8 cm</span></td>
<td style="background-color:#B5FF00"><span><big>g</big><br/>392.0 Hz<br/>88.0 cm</span></td>
<td style="background-color:#20FF00"><span><big>a♭</big><br/>415.3 Hz<br/>83.1 cm</span></td>
<td style="background-color:#4800FF"><span><big>b♭</big><br/>466.2 Hz<br/>74.0 cm</span></td>
</tr>
<tr>
<td style="background-color:#FF5300"><span><big>f</big><br/>349.2 Hz<br/>98.8 cm</span></td>
<td style="background-color:#B5FF00"><span><big>g</big><br/>392.0 Hz<br/>88.0 cm</span></td>
<td style="background-color:#20FF00"><span><big>a♭</big><br/>415.3 Hz<br/>83.1 cm</span></td>
<td style="background-color:#4800FF"><span><big>b♭</big><br/>466.2 Hz<br/>74.0 cm</span></td>
<td style="background-color:#610000"><span><big>c</big><br/>523.3 Hz<br/>65.9 cm</span></td>
<td style="background-color:#9A0000"><span><big>d♭</big><br/>554.4 Hz<br/>62.2 cm</span></td>
<td style="background-color:#FF0000"><span><big>e♭</big><br/>622.3 Hz<br/>55.4 cm</span></td>
</tr>
<tr>
<td style="background-color:#4800FF"><span><big>b♭</big><br/>466.2 Hz<br/>74.0 cm</span></td>
<td style="background-color:#610000"><span><big>c</big><br/>523.3 Hz<br/>65.9 cm</span></td>
<td style="background-color:#9A0000"><span><big>d♭</big><br/>554.4 Hz<br/>62.2 cm</span></td>
<td style="background-color:#FF0000"><span><big>e♭</big><br/>622.3 Hz<br/>55.4 cm</span></td>
<td style="background-color:#FF5300"><span><big>f</big><br/>698.5 Hz<br/>49.4 cm</span></td>
<td style="background-color:#FFD400"><span><big>g♭</big><br/>740.0 Hz<br/>46.6 cm</span></td>
<td style="background-color:#20FF00"><span><big>a♭</big><br/>830.6 Hz<br/>41.5 cm</span></td>
</tr>
<tr>
<td style="background-color:#FF0000"><span><big>e♭</big><br/>311.1 Hz<br/>110.9 cm</span></td>
<td style="background-color:#FF5300"><span><big>f</big><br/>349.2 Hz<br/>98.8 cm</span></td>
<td style="background-color:#FFD400"><span><big>g♭</big><br/>370.0 Hz<br/>93.2 cm</span></td>
<td style="background-color:#20FF00"><span><big>a♭</big><br/>415.3 Hz<br/>83.1 cm</span></td>
<td style="background-color:#4800FF"><span><big>b♭</big><br/>466.2 Hz<br/>74.0 cm</span></td>
<td style="background-color:#610061"><span><big>b</big><br/>493.9 Hz<br/>69.9 cm</span></td>
<td style="background-color:#9A0000"><span><big>d♭</big><br/>554.4 Hz<br/>62.2 cm</span></td>
</tr>
<tr>
<td style="background-color:#20FF00"><span><big>a♭</big><br/>415.3 Hz<br/>83.1 cm</span></td>
<td style="background-color:#4800FF"><span><big>b♭</big><br/>466.2 Hz<br/>74.0 cm</span></td>
<td style="background-color:#610061"><span><big>b</big><br/>493.9 Hz<br/>69.9 cm</span></td>
<td style="background-color:#9A0000"><span><big>d♭</big><br/>554.4 Hz<br/>62.2 cm</span></td>
<td style="background-color:#FF0000"><span><big>e♭</big><br/>622.3 Hz<br/>55.4 cm</span></td>
<td style="background-color:#FF0000"><span><big>e</big><br/>659.3 Hz<br/>52.3 cm</span></td>
<td style="background-color:#FFD400"><span><big>g♭</big><br/>740.0 Hz<br/>46.6 cm</span></td>
</tr>
<tr>
<td style="background-color:#9A0000"><span><big>d♭</big><br/>277.2 Hz<br/>124.5 cm</span></td>
<td style="background-color:#FF0000"><span><big>e♭</big><br/>311.1 Hz<br/>110.9 cm</span></td>
<td style="background-color:#FF0000"><span><big>e</big><br/>329.6 Hz<br/>104.7 cm</span></td>
<td style="background-color:#FFD400"><span><big>g♭</big><br/>370.0 Hz<br/>93.2 cm</span></td>
<td style="background-color:#20FF00"><span><big>a♭</big><br/>415.3 Hz<br/>83.1 cm</span></td>
<td style="background-color:#00B6FF"><span><big>a</big><br/>440.0 Hz<br/>78.4 cm</span></td>
<td style="background-color:#610061"><span><big>b</big><br/>493.9 Hz<br/>69.9 cm</span></td>
</tr>
<tr>
<td style="background-color:#FFD400"><span><big>g♭</big><br/>370.0 Hz<br/>93.2 cm</span></td>
<td style="background-color:#20FF00"><span><big>a♭</big><br/>415.3 Hz<br/>83.1 cm</span></td>
<td style="background-color:#00B6FF"><span><big>a</big><br/>440.0 Hz<br/>78.4 cm</span></td>
<td style="background-color:#610061"><span><big>b</big><br/>493.9 Hz<br/>69.9 cm</span></td>
<td style="background-color:#9A0000"><span><big>d♭</big><br/>554.4 Hz<br/>62.2 cm</span></td>
<td style="background-color:#D20000"><span><big>d</big><br/>587.3 Hz<br/>58.7 cm</span></td>
<td style="background-color:#FF0000"><span><big>e</big><br/>659.3 Hz<br/>52.3 cm</span></td>
</tr>
<tr>
<td style="background-color:#610061"><span><big>b</big><br/>493.9 Hz<br/>69.9 cm</span></td>
<td style="background-color:#9A0000"><span><big>d♭</big><br/>554.4 Hz<br/>62.2 cm</span></td>
<td style="background-color:#D20000"><span><big>d</big><br/>587.3 Hz<br/>58.7 cm</span></td>
<td style="background-color:#FF0000"><span><big>e</big><br/>659.3 Hz<br/>52.3 cm</span></td>
<td style="background-color:#FFD400"><span><big>g♭</big><br/>740.0 Hz<br/>46.6 cm</span></td>
<td style="background-color:#B5FF00"><span><big>g</big><br/>784.0 Hz<br/>44.0 cm</span></td>
<td style="background-color:#00B6FF"><span><big>a</big><br/>880.0 Hz<br/>39.2 cm</span></td>
</tr>
</table></body>
</html>
#!/usr/bin/env perl
# inspired by https://randscullard.com/CircleOfFifths/
# and http://pages.mtu.edu/~suits/notefreqs.html
use 5.010;
use strict;
use warnings;
use charnames ();
use open OUT => ':locale';
use utf8;
use Carp;
use POSIX;
use Scalar::Util qw(dualvar);
my $tones = 12;
my %notes = qw(0 C 2 D 4 E 5 F 7 G 9 A 11 B);
my @freqs =
map { 2 ** (($_ - 9) / $tones) * 440 }
0 .. $tones - 1;
my @wavelengths = map { 345 / $_ } @freqs;
my @rgb = reverse map {
sprintf '#' . ('%02X' x 3),
map { POSIX::round(255 * $_) }
convert_wave_length_nm_to_rgb($_)
} map {
380 + 400 * $_ # in nanometers
} map {
($_ - $wavelengths[0]) / ($wavelengths[-1] - $wavelengths[0])
} @wavelengths;
my $last_note;
my @sharps;
for my $i (0 .. $tones - 1) {
push @sharps, dualvar $i, $notes{$i} // $last_note . "\N{MUSIC SHARP SIGN}";
$last_note = $notes{$i};
}
my @flats;
for my $i (reverse 0 .. $tones - 1) {
unshift @flats, dualvar $i, => $notes{$i} // $last_note . "\N{MUSIC FLAT SIGN}";
$last_note = $notes{$i};
}
my @major = reverse ( # fifths steps
(map { $flats[$_ * 7 % $tones] } 3 .. 10),
(map { $sharps[$_ * 7 % $tones] } 11 .. 29),
);
my @major_order = reverse ( # 5,3,1,6,4,2,0
(grep { not $_ % 2 } 0 .. 6),
(grep { $_ % 2 } 1 .. 5),
);
my @minor = ( # fourths steps
(map { $sharps[$_ * 5 % $tones] } -2 .. 11),
(map { $flats[$_ * 5 % $tones] } 12 .. 24),
);
my @minor_order = @major_order[5, 6, 0 .. 4];
say <<'HEADER';
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Major & Minor Scales</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:200" rel="stylesheet">
<style>
body { background-color: #000 }
table {
border: 0;
-webkit-border-horizontal-spacing: 0;
-webkit-border-vertical-spacing: 0;
}
td {
width: 10em;
height: 10em;
color: #fff;
font-family: 'Source Code Pro', monospace;
font-size: 10pt;
text-align: center;
vertical-align: middle;
}
td span { opacity: 0.75 }
td span big { font-size: 3em }
</style>
</head>
<body><table>
HEADER
print_scale(0, (@major[$_ .. $_ + 6]) [@major_order]) for 5 .. 19;
print_scale(1, (@minor[$_ .. $_ + 6]) [@minor_order]) for 5 .. 19;
say <<'FOOTER';
</table></body>
</html>
FOOTER
sub print_scale {
my ($is_minor, @scale) = @_;
my $row = qq(\t\t<td style="background-color:%s"><span><big>%s</big><br/>%0.1f Hz<br/>%0.1f cm</span></td>\n);
say "\t<tr>";
my $o = 1;
my $prev_note;
for my $note (@scale) {
++$o if defined $prev_note && $freqs[$note] < $freqs[$prev_note];
printf $row,
$rgb[$note],
$is_minor ? lc $note : uc $note,
$o * $freqs[$note],
($wavelengths[$note] * 100) / $o;
$prev_note = $note;
}
say "\t</tr>";
}
# Ported to Perl from: https://github.com/ArashPartow/bitmap/blob/master/bitmap_image.hpp
# Credits: Dan Bruton http://www.physics.sfasu.edu/astro/color.html
sub convert_wave_length_nm_to_rgb {
my ($wave_length_nm, $gamma) = @_;
$gamma ||= 0.8;
my ($red, $green, $blue);
if ((380 <= $wave_length_nm) && ($wave_length_nm < 440)) {
$red = -($wave_length_nm - 440) / (440 - 380);
$green = 0;
$blue = 1;
} elsif ((440 <= $wave_length_nm) && ($wave_length_nm < 490)) {
$red = 0;
$green = ($wave_length_nm - 440) / (490 - 440);
$blue = 1;
} elsif ((490 <= $wave_length_nm) && ($wave_length_nm < 510)) {
$red = 0;
$green = 1;
$blue = -($wave_length_nm - 510) / (510 - 490);
} elsif ((510 <= $wave_length_nm) && ($wave_length_nm < 580)) {
$red = ($wave_length_nm - 510) / (580 - 510);
$green = 1;
$blue = 0;
} elsif ((580 <= $wave_length_nm) && ($wave_length_nm < 645)) {
$red = 1;
$green = -($wave_length_nm - 645) / (645 - 580);
$blue = 0;
} elsif ((645 <= $wave_length_nm) && ($wave_length_nm <= 780)) {
$red = 1;
$green = 0;
$blue = 0;
} else {
carp "Wave length of $wave_length_nm nm is outside of the visible range (380-780 nm)";
$red = $green = $blue = 0;
}
my $factor;
if ((380 <= $wave_length_nm) && ($wave_length_nm < 420)) {
$factor = 0.3 + 0.7 * ($wave_length_nm - 380) / (420 - 380);
} elsif ((420 <= $wave_length_nm) && ($wave_length_nm < 700)) {
$factor = 1;
} elsif ((700 <= $wave_length_nm) && ($wave_length_nm <= 780)) {
$factor = 0.3 + 0.7 * (780 - $wave_length_nm) / (780 - 700);
} else {
$factor = 0;
}
return map {
($_ * $factor) ** $gamma
} ($red, $green, $blue);
}
__DATA__
C D E F G A B
F G A A♯ C D E
A♯ C D D♯ F G A
D♯ F G G♯ A♯ C D
G♯ A♯ C C♯ D♯ F G
C♯ D♯ F F♯ G♯ A♯ C
F♯ G♯ A♯ B C♯ D♯ F
B C♯ D♯ E F♯ G♯ A♯
E F♯ G♯ A B C♯ D♯
A B C♯ D E F♯ G♯
D E F♯ G A B C♯
G A B C D E F♯
C D E F G A B
F G A B♭ C D E
B♭ C D E♭ F G A
E♭ F G A♭ B♭ C D
A♭ B♭ C D♭ E♭ F G
D♭ E♭ F G♭ A♭ B♭ C
G♭ A♭ B♭ B D♭ E♭ F
B D♭ E♭ E G♭ A♭ B♭
E G♭ A♭ A B D♭ E♭
c d d♯ f g g♯ a♯
f g g♯ a♯ c c♯ d♯
a♯ c c♯ d♯ f f♯ g♯
d♯ f f♯ g♯ a♯ b c♯
g♯ a♯ b c♯ d♯ e f♯
c♯ d♯ e f♯ g♯ a b
f♯ g♯ a b c♯ d e
b c♯ d e f♯ g a
e f♯ g a b c d
a b c d e f g
d e f g a b♭ c
g a b♭ c d e♭ f
c d e♭ f g a♭ b♭
f g a♭ b♭ c d♭ e♭
b♭ c d♭ e♭ f g♭ a♭
e♭ f g♭ a♭ b♭ b d♭
a♭ b♭ b d♭ e♭ e g♭
d♭ e♭ e g♭ a♭ a b
g♭ a♭ a b d♭ d e
b d♭ d e g♭ g a
e g♭ g a b c d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment