Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re^3: Transpose guitar chords

by ELISHEVA (Prior)
on Feb 27, 2011 at 18:58 UTC ( #890443=note: print w/ replies, xml ) Need Help??


in reply to Re^2: Transpose guitar chords
in thread Transpose guitar chords

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!


Comment on Re^3: Transpose guitar chords
Select or Download Code
Replies are listed 'Best First'.
Re^4: Transpose guitar chords
by Anonymous Monk on Feb 28, 2011 at 01:22 UTC
    Right, sorry, I should have said, sometimes reverse the use of sharps and flats. Another nice improvement would be to handle chord names in full generality, including minor chords, augmented, diminished, etc . This is mostly a matter of allowing suffixes after the sharp or flat notation, in the typical form, e.g. G sharp minor half diminished seventh is G#m7(b5). I think you'd just have to take everything after the A-G(#|b)? and just carry it through the transposition.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://890443]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (11)
As of 2015-07-28 22:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (260 votes), past polls