CODE TO WORK WITH MUSICAL KEYS (CHORDS)

V

V

Hello,
I'm working on a macro to transpose keys in song sheets.

Sub TransposeKeys()
Dim MusicNotesArray(11) As String
MusicNotesArray(0) = Chr(65) 'A
MusicNotesArray(1) = Chr(66) & Chr(98) 'Bb
MusicNotesArray(2) = Chr(66) 'B
MusicNotesArray(3) = Chr(67) 'C
MusicNotesArray(4) = Chr(67) & Chr(35) 'C#
MusicNotesArray(5) = Chr(68) 'D
MusicNotesArray(6) = Chr(69) & Chr(98) 'Eb
MusicNotesArray(7) = Chr(69) 'E
MusicNotesArray(8) = Chr(70) 'F
MusicNotesArray(9) = Chr(70) & Chr(35) 'F#
MusicNotesArray(10) = Chr(71) 'G
MusicNotesArray(11) = Chr(65) & Chr(98) 'Ab

'define actual page as a range
Dim MyRange As Range
Set MyRange = Selection.Range
Set MyRange = MyRange.GoTo(What:=wdGoToBookmark, Name:="\page")

'replace strings only in specified style
MyRange.Find.ClearFormatting
MyRange.Find.Style = ActiveDocument.Styles("Título 2")
MyRange.Find.Replacement.ClearFormatting
With MyRange.Find
.Text = MusicNotesArray(5) 'just an example
.Replacement.Text = MusicNotesArray(9) 'just an example
.MatchCase = True
.Forward = True
.Wrap = wdFindStop
End With
MyRange.Find.Execute Replace:=wdReplaceAll

End Sub

Now i'm working on a code to find and replace all ocuurences of the
musical scale in a song (sorry about my english).
My very hard problem is turn my code inteligent. For example, the code
must to find "C" and replace to "D"; "Am7" to "Bm7", etc. I'm not
considering de variations of the chords (m7, º, 7M, etc), only the #'s
and b's). The problem is if I have:

C Am7 F D#mº
onono onono nonon nonono ono

It will turned to

D Bm7 G Eb#m <- THIS CHORD IS INCORRECT!
onono onono nonon nonono ono

How to identify those chords with # or b and to avoid its incorrect
transposition?

Regards.
VFrari
 
J

Jonathan West

Hi V,

This requires more knowledge of music and harmony than of Word, but let us
see what we can do.

The first thing you need to understand properly is how the transposition
works.

If you consider the simplest scale, C major, the notes are C D E F G A B C.

The next simplest are G major and F major, with one sharp and one flat
respectively.

G major G A B C D E F# G
F major F G A Bb C D E F

When you are transposing, if your original key is a major key, so will the
key you are changing into. What you need to do is find which degree of the
scale a chord is based on in the original key, and then replace with the
same degree in the transposed key.

Taking the examples of G major and F major above, suppose your original key
is G major, and you have a C chord. Looking at the list above, you find that
C is the 4th note in G major. When transposing into F major, the chord must
be replaced with the 4th note of F major. This is Bb.

So what you need is a complete list of the notes of all the 12 major scales
and 12 minor scales. When transposing, you simply work out what key you are
in to start with, and what key you want to transpose into. Then for each
chord in the piece, you work out the degree of the scale it is based on in
the original key, and replace it with the same degree of the scale in the
transposed key. Because your lists of scales will have the sharps and flats
in them, adding or removing accidentals will happen automatically.

I'll leave the process of putting this into code as an exercise for the
student :)

--
Regards
Jonathan West - Word MVP and amateur french horn player....
http://www.multilinker.com
Please reply to the newsgroup
 
E

Ed

Jonathan:

As a so-so musician and less of a programmer, I'm wondering why you couldn't
just work with the chord name in a transposition, and never mind the major
or minor. If it's a Bb, and you're going up a full step, it's going to C,
whether major or minor, right?

I don't enough about how an array such as V set up works in VBA. Would
there be a way to simply find the chord name, find the array definition,
then replace with "array + 2", for example? This would find Bb as Array 1,
and replace with Array (1+2), which would take it up to a C.

Ed
 
J

Jonathan West

Ed said:
Jonathan:

As a so-so musician and less of a programmer, I'm wondering why you couldn't
just work with the chord name in a transposition, and never mind the major
or minor. If it's a Bb, and you're going up a full step, it's going to C,
whether major or minor, right?

You still need to know the keys you are going to and from. F# is the same
note on the keyboard as Gb, but for the purpose of keys and harmony, they
are very different. There are two parts to the issue. How many semitones you
are moving, and how many degrees of the scale you are moving. For
transposition to work right, both are constant for a particular key change,
but this results in oddities with regards to some notes having to be
sharpened or flattened. It is possible to calculate this from first
principles for each note without an array, but having an array takes out a
lot of the grunt work.

I don't enough about how an array such as V set up works in VBA. Would
there be a way to simply find the chord name, find the array definition,
then replace with "array + 2", for example? This would find Bb as Array 1,
and replace with Array (1+2), which would take it up to a C.

This is the general idea. In my original example, C is identified as
Gmajor(4), and as you are changing to F major, you need to identify
Fmajor(4), which is Bb.

The array could be an array in the following form

Dim MajorScales(-7 to 7, 7) as String

The reason for going from minus 7 would be that negative numbers would
represent numbers of flats, and positive numbers would be numbers of sharps.
The following would be an example of filling out that array with just the 3
simplest scales

MajorScales(-1, 1) = "F"
MajorScales(-1, 2) = "G"
MajorScales(-1, 3) = "A"
MajorScales(-1, 4) = "Bb"
MajorScales(-1, 5) = "C"
MajorScales(-1, 6) = "D"
MajorScales(-1, 7) = "E"
MajorScales(0, 1) = "C"
MajorScales(0, 2) = "D"
MajorScales(0, 3) = "E"
MajorScales(0, 4) = "F"
MajorScales(0, 5) = "G"
MajorScales(0, 6) = "A"
MajorScales(0, 7) = "B"
MajorScales(1, 1) = "G"
MajorScales(1, 2) = "A"
MajorScales(1, 3) = "B"
MajorScales(1, 4) = "C"
MajorScales(1, 5) = "D"
MajorScales(1, 6) = "E"
MajorScales(1, 7) = "F"
 
E

Ed

Okay, I'll admit I am out of my league here in both music and VBA! <G>
(I've got a 19-year-old son who;s a musical phenomenon. I thump a bass
guitar occasionally; he can take a Roland XP80 and give Yanni a run for his
money!) Since I see more hope to progress on the computer than a score, let
me ask this about an array, then I'll go some exploring. I'll stick to the
music situation for my questions.

You're talking about creating an array of all 12 note required for each of
the basic major and minor scales. That sounds like a look-up table of 288
values. I'm more used to working with Excel in table structures, so I'm
trying not to get too confused here.

The way I have it in my mind, if I have a value as a String (say F#) and I
Find that String, I would then need to do something like "ArrayValue of
String is X,Y". I could then say "Replace with ArrayValue(X+2, Y+2) to
insert my new value. Is it possible, then, to return the ArrayValue like
that? If not, since "C" would be a member of several different scales and
show up in several different array positions, would you have to have an
InputBox first to define which array you were working with? For that
matter, if you asked the user to Input both the scale in use and the scale
to be changed to, can you use those values to make this whole thing easier?

Ed
 
J

Jonathan West

Ed said:
Okay, I'll admit I am out of my league here in both music and VBA! <G>
(I've got a 19-year-old son who;s a musical phenomenon. I thump a bass
guitar occasionally; he can take a Roland XP80 and give Yanni a run for his
money!) Since I see more hope to progress on the computer than a score, let
me ask this about an array, then I'll go some exploring. I'll stick to the
music situation for my questions.

You're talking about creating an array of all 12 note required for each of
the basic major and minor scales. That sounds like a look-up table of 288
values. I'm more used to working with Excel in table structures, so I'm
trying not to get too confused here.

It is 7 notes for each scale, and although there are only 12 semitones in an
octave, the array will have 15 rows (-7 to +7) because you have F# major
which sounds the same as Gb major although it is written differently, Cb
major which sounds the same as B major, and C# major which sounds like Db
major.
The way I have it in my mind, if I have a value as a String (say F#) and I
Find that String, I would then need to do something like "ArrayValue of
String is X,Y". I could then say "Replace with ArrayValue(X+2, Y+2) to
insert my new value. Is it possible, then, to return the ArrayValue like
that? If not, since "C" would be a member of several different scales and
show up in several different array positions, would you have to have an
InputBox first to define which array you were working with? For that
matter, if you asked the user to Input both the scale in use and the scale
to be changed to, can you use those values to make this whole thing
easier?

But to do the transposition successfully, you need to know not only the
individual note & chord, but also the key you are in. There is a row for
each key, and each column within the row indicates a note of the scale. Each
not appears in a scale only once.

Therefore, armed with the following information, you can make the
transposition of each note/chord

1. Original key
2. Transposed key
3. Note to be transposed.

The process is as follows.

1. Find the name of the note to be transposed.
2. Find its position of that note in the row for the original key
3. Find the name of the note in the equivalent position in the row of the
transposed key.

As a horn player, I have to do this at sight when reading music! It is very
common to have to transpose up or down a step or a third.
 
E

Ed

Thanks for all the help, Jonathan. I'll go chew on this Array stuff for a
while. I think it'll be useful to me at work.

Ed
 
V

V

I think Ed is right. I just need transpose those chords which are in
the current document without worry about the harmony scale. I'm a
musician and I understand about it. My problem is called VBA!!!
 
S

Steve Hudson

G'day (e-mail address removed) (V),

use a 2d array

MyNotes(KeyNumber,ScaleNote)

so all of A major for example would be at

1,1
1,2
1,3
1,4
....

all of b major might then be at

2,1
2,2
2,3
2,4

you could even hold the name of the scale in n,0 so you just iterate
and compare all scale names until you get to the one you want.

If you contact me offlist, I would be willing to help you if we make
the proggy avail for free.



(e-mail address removed) (V) was spinning this yarn:
I think Ed is right. I just need transpose those chords which are in
the current document without worry about the harmony scale. I'm a
musician and I understand about it. My problem is called VBA!!!

Steve Hudson

Word Heretic, Sydney, Australia
Tricky stuff with Word or words for you.
wordheretic.com

If answers r 2 terse, ask again or hassle an MVP,
at least they get recognition for it then.
Lengthy replies offlist require payment.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top