To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Revision:

root / _writetools / chordroot_spelling.m

History | View | Annotate | Download (1.7 KB)

1
function rootspelling = chordroot_spelling(key, root, degrees)
2

    
3
temp = strsplit(':', key);
4
keyroot = temp{1};
5
if length(temp) > 1
6
    keymode = temp{2};
7
else
8
    keymode = 'major';
9
end
10

    
11

    
12

    
13
% major scale
14
scale{1} = [0 2 4 5 7 9 11];
15
% harmonic minor scale
16
scale{2} = [0 2 3 5 7 8 11];
17

    
18
diatonic = {'C','D','E','F','G','A','B'};
19
keymode_number = find(strcmp({'major','minor'},keymode));
20

    
21
if ischar(root)
22
    rootdegree = find(strcmp(diatonic,root(1)));
23
    rootpc = scale{1}(strcmp(diatonic,root(1))) + length(strfind(root,'#')) - length(strfind(root,'b'));
24
else
25
    [rootdegree, rootdegree]= min(abs(scale{1}-root));
26
    rootpc = root;
27
end
28

    
29

    
30
deg = [];
31
pcs = [];
32
for ii = 1:length(degrees)
33
    deg = [deg mod(rootdegree + str2num(degrees{ii}(end)) - 2,7)+1];
34
    pcs = [pcs mod(rootpc + degree2semitone(degrees{ii}),12)];
35
end
36

    
37
keyrootpc = scale{1}(strcmp(diatonic,keyroot(1))) + length(strfind(keyroot,'#')) - length(strfind(keyroot,'b'));
38
keydegree = find(strcmp(diatonic,keyroot(1)));
39

    
40
scalesemitone = circshift(mod(scale{keymode_number} + keyrootpc,12),[0 keydegree-1]);
41

    
42
fit = [0 0 0];
43

    
44
for deviation = -1:1 % test if the best degree is lower, just right or higher
45
    currdeg = mod(deg+deviation-1,7) + 1;
46
    chordaccidentals = mod(scalesemitone(currdeg) - pcs + 12 + 6,12) - 6;
47
    fit(deviation+2) = sum(abs(chordaccidentals));
48
end
49
[bestfitval, bestfit] = min(fit);
50
bestrootdegree = mod(rootdegree + bestfit - 2 - 1,7) + 1;
51
bestrootaccidentals = mod(rootpc - scale{1}(bestrootdegree)+6,12)-6;
52
switch bestrootaccidentals
53
    case -2 
54
        suff = 'bb';
55
    case -1
56
        suff = 'b';
57
    case 0
58
        suff = '';
59
    case 2 
60
        suff = '##';
61
    case 1
62
        suff = '#';
63
end
64
rootspelling = [diatonic{bestrootdegree}, suff];