matthiasm@8: function rootspelling = chordroot_spelling(key, root, degrees) matthiasm@8: matthiasm@8: temp = strsplit(':', key); matthiasm@8: keyroot = temp{1}; matthiasm@8: if length(temp) > 1 matthiasm@8: keymode = temp{2}; matthiasm@8: else matthiasm@8: keymode = 'major'; matthiasm@8: end matthiasm@8: matthiasm@8: matthiasm@8: matthiasm@8: % major scale matthiasm@8: scale{1} = [0 2 4 5 7 9 11]; matthiasm@8: % harmonic minor scale matthiasm@8: scale{2} = [0 2 3 5 7 8 11]; matthiasm@8: matthiasm@8: diatonic = {'C','D','E','F','G','A','B'}; matthiasm@8: keymode_number = find(strcmp({'major','minor'},keymode)); matthiasm@8: matthiasm@8: if ischar(root) matthiasm@8: rootdegree = find(strcmp(diatonic,root(1))); matthiasm@8: rootpc = scale{1}(strcmp(diatonic,root(1))) + length(strfind(root,'#')) - length(strfind(root,'b')); matthiasm@8: else matthiasm@8: [rootdegree, rootdegree]= min(abs(scale{1}-root)); matthiasm@8: rootpc = root; matthiasm@8: end matthiasm@8: matthiasm@8: matthiasm@8: deg = []; matthiasm@8: pcs = []; matthiasm@8: for ii = 1:length(degrees) matthiasm@8: deg = [deg mod(rootdegree + str2num(degrees{ii}(end)) - 2,7)+1]; matthiasm@8: pcs = [pcs mod(rootpc + degree2semitone(degrees{ii}),12)]; matthiasm@8: end matthiasm@8: matthiasm@8: keyrootpc = scale{1}(strcmp(diatonic,keyroot(1))) + length(strfind(keyroot,'#')) - length(strfind(keyroot,'b')); matthiasm@8: keydegree = find(strcmp(diatonic,keyroot(1))); matthiasm@8: matthiasm@8: scalesemitone = circshift(mod(scale{keymode_number} + keyrootpc,12),[0 keydegree-1]); matthiasm@8: matthiasm@8: fit = [0 0 0]; matthiasm@8: matthiasm@8: for deviation = -1:1 % test if the best degree is lower, just right or higher matthiasm@8: currdeg = mod(deg+deviation-1,7) + 1; matthiasm@8: chordaccidentals = mod(scalesemitone(currdeg) - pcs + 12 + 6,12) - 6; matthiasm@8: fit(deviation+2) = sum(abs(chordaccidentals)); matthiasm@8: end matthiasm@8: [bestfitval, bestfit] = min(fit); matthiasm@8: bestrootdegree = mod(rootdegree + bestfit - 2 - 1,7) + 1; matthiasm@8: bestrootaccidentals = mod(rootpc - scale{1}(bestrootdegree)+6,12)-6; matthiasm@8: switch bestrootaccidentals matthiasm@8: case -2 matthiasm@8: suff = 'bb'; matthiasm@8: case -1 matthiasm@8: suff = 'b'; matthiasm@8: case 0 matthiasm@8: suff = ''; matthiasm@8: case 2 matthiasm@8: suff = '##'; matthiasm@8: case 1 matthiasm@8: suff = '#'; matthiasm@8: end matthiasm@8: rootspelling = [diatonic{bestrootdegree}, suff];