Syntactic Confectionery Delight PerlMonks

### comment on

 Need Help??

Good point. You are right that the code above is only for major keys.

Minor keys are a bit more complex though than "reverse the use of sharps and flats". For the minor scales, only D,G switch from flats to sharps. F and all flat keys (Ab,Bb, etc) uses flats in both major and minor modes. B,E and all sharp keys (A#,B#,etc) use sharps for both major and minor modes. A goes from sharps to all naturals, and C goes from all naturals to flats. See Key signature.

So here is the script revised to take into account minor keys as well as major keys (changes marked with <== ):

```use strict;
use warnings;

my %Tone =( A => 0, B => 2, C => 3, D => 5, E => 7, F => 8, G=>10);
my @Notes;
foreach my \$natural ('A'..'G') {
my \$i = \$Tone{\$natural};
my \$iFlat = \$i ? \$i-1 : 11;

\$Tone{\$natural.'#'} = \$i+1;
\$Tone{\$natural.'b'} = \$iFlat;

\$Notes[\$iFlat][0]=\$natural.'b';
\$Notes[\$i][0] = \$natural;
\$Notes[\$i][1] = \$natural;
\$Notes[\$i+1][1]=\$natural.'#';
}

#print "Tone: ". Dumper(\%Tone);
#print "Notes: ". Dumper(\@Notes);

sub transpose {
my (\$key, \$aChord, \$toKey) = @_;
my @aTransposed;

my \$bMinor = \$key =~ /m\$/ ? 1 : 0;           # <==
\$key= \$key =~ /^(.*)m\$/ ? \$1 : \$key;         # <==
\$toKey= \$toKey =~ /^(.*)m\$/ ? \$1 : \$toKey;   # <==

my \$iShift = \$Tone{\$toKey} - \$Tone{\$key};

my \$iIndex = \$bMinor                         # <==
? (\$toKey =~ /^(?:C|D|F|G|.b)\$/ ? 0 : 1) # minor key
: (\$toKey =~ /^(?:F|.b)\$/ ? 0 : 1); # F uses flats in major

push @aTransposed, \$Notes[(\$Tone{\$_}+\$iShift) % 12][\$iIndex]
for @\$aChord;
return \@aTransposed;
}

# demo
local \$"='-';
print "Major modes\n";
for ('A'..'G','Eb','Bb', 'D', 'E') {
print "C-E-G => \$_ : @{transpose('C',[qw(C E G)],\$_)}\n";
}

print "Minor modes\n";
for ('A'..'G','Eb','Bb', 'D', 'E') {
print "C-Eb-G => \$_ : @{transpose('Cm',[qw(C Eb G)],qq{\${_}m})}\n";
}

# outputs
Major modes
C-E-G => A : A-C#-E
C-E-G => B : B-D#-F#
C-E-G => C : C-E-G
C-E-G => D : D-F#-A
C-E-G => E : E-G#-B
C-E-G => F : F-A-C
C-E-G => G : G-B-D
C-E-G => Eb : Eb-G-Bb
C-E-G => Bb : Bb-D-F
C-E-G => D : D-F#-A
C-E-G => E : E-G#-B
Minor modes
C-Eb-G => A : A-C-E
C-Eb-G => B : B-D-F#
C-Eb-G => C : C-Eb-G
C-Eb-G => D : D-F-A
C-Eb-G => E : E-G-B
C-Eb-G => F : F-Ab-C
C-Eb-G => G : G-Bb-D
C-Eb-G => Eb : Eb-Gb-Bb
C-Eb-G => Bb : Bb-Db-F
C-Eb-G => D : D-F-A
C-Eb-G => E : E-G-B

And should anyone else see room for improvement, please post!

In reply to Re^3: Transpose guitar chords by ELISHEVA
in thread Transpose guitar chords by Cody Fendant

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

• Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
• Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
• Read Where should I post X? if you're not absolutely sure you're posting in the right place.
• Posts may use any of the Perl Monks Approved HTML tags:
a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
• You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
 For: Use: & & < < > > [ [ ] ]
• Link using PerlMonks shortcuts! What shortcuts can I use for linking?

Create A New User
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2021-04-21 08:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?

No recent polls found

Notices?