I have to make a converter that accepts an int
representing the chromatic interval of a current tone (i.e. root = 1, minor second = 2, minor seventh = 11, major ninth = 15, major thirteen = 22 etc.), and convert it to the diatonic scale interval and vice versa.
So considering the above example, here are some mappings:
Diat. | Chrom.
---------------------
1 (C) | 1
b2 (Db) | 2
2 (D) | 3
4 (F) | 6
b7 (Bb) | 11
9 (D) | 15
#11 (F#) | 19
b13 (Ab) | 21
Obviously I can do two functions with a simple 1 to 1 switch
statement, or, as suggested, use a bi-directional dictionary, but before doing so I was wondering if I can find more an efficient way to do that.
The diatonic output doesn't have to be a precise tone, enharmonic tones are good too, so D#
and Eb
are the same.
The parse method however, has to know how to parse both sharps and flats, but this can simply be achieved by setting all sharps to a higher tone flat.
For the chrom. to diat. function, I was thinking more of an algorithm that calculates that. I'm trying to figure it out now, still didn't manage to tho. It has to divide the chromatic steps according to the visual ordering of the piano keyboard, meaning divide the amount in half excluding the half steps between E-F and B-C that are considered whole diatonic steps.
I prefer it to be a calculation rather than a static mapping, so I can later work with transposed scales etc.
You'd need a special bidirectional Dictionary for this. Here's one: Getting key of value of a generic Dictionary?
Transpositions could be easily handled by modulo arithmetic and by calculating the relative distances between notes.
You could also define class holding pairs of desired elements and put them in a circular linked list or on a binary search tree if You're looking for speed. But I don't think it does really matter when You are dealing with only 12 simple elements.