christopherh@1: % christopherh@1: %INTERVAL2NOTE convert an interval to correctly spelled note w.r.t. a root christopherh@1: % christopherh@1: % [note,success,errormessage] = interval2note(interval, root {verbose}) christopherh@1: % christopherh@1: % Converts an interval to a note (string) with root as reference note christopherh@1: % for interval degree. christopherh@1: % christopherh@1: % Success = 1 if interval is converted correctly, 0 otherwise. christopherh@1: % christopherh@1: % If optional argument 'verbose' is 1, function prints any errormessage to christopherh@1: % the screen. christopherh@1: % christopherh@1: % returns: note (string) christopherh@1: % success (boolean) christopherh@1: % errormessage (string) christopherh@1: % christopherh@1: % See also intervals2notes, parsenote. christopherh@1: % christopherh@1: % christopherh@1: % Author: Christopher Harte, March 2009 christopherh@1: % christopherh@1: % Copyright: Centre for Digital Music, Queen Mary University of London 2005 christopherh@1: % christopherh@1: % This file is part of the C4DM Chord Toolkit V2.0 christopherh@1: % christopherh@1: % The C4DM Chord Toolkit is free software; you can redistribute it and/or christopherh@1: % modify it under the terms of the GNU General Public License as published christopherh@1: % by the Free Software Foundation; either version 2 of the License, or christopherh@1: % (at your option) any later version. christopherh@1: % christopherh@1: % The C4DM Chord Toolkit is distributed in the hope that it will be useful, christopherh@1: % but WITHOUT ANY WARRANTY; without even the implied warranty of christopherh@1: % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the christopherh@1: % GNU General Public License for more details. christopherh@1: % christopherh@1: % You should have received a copy of the GNU General Public License christopherh@1: % along with the C4DM Toolkit; if not, write to the Free Software christopherh@1: % Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA christopherh@1: christopherh@1: % christopherh@1: function [note,success,errormessage] = interval2note(interval, root,verbose) christopherh@1: christopherh@1: if nargin < 3 christopherh@1: verbose = 0; christopherh@1: end christopherh@1: errormessage = ''; christopherh@1: christopherh@1: error1 = ''; christopherh@1: error2 = ''; christopherh@1: christopherh@1: note = []; christopherh@1: christopherh@1: degreetranslation = [5,0,2,4,-1,1,3,5]; % scale interval translations on line of fifths christopherh@1: christopherh@1: fifthpositions = {'F','C','G','D','A','E','B'}; %order of naturals on line of fifths christopherh@1: christopherh@1: success = 1; christopherh@1: christopherh@1: % parse the root note christopherh@1: [rootnatural,rootaccs, rsuccess, error1] = parsenote(root); christopherh@1: christopherh@1: %parse the interval christopherh@1: [degree, intervalaccs, present, dsuccess, error2] = parseinterval(interval); christopherh@1: christopherh@1: % if parsing symbols was successful christopherh@1: if(rsuccess && dsuccess); christopherh@1: christopherh@1: switch(rootnatural) % find root natural position on line of fifths christopherh@1: christopherh@1: case 'F' christopherh@1: fifthindex = 0; christopherh@1: case 'C' christopherh@1: fifthindex = 1; christopherh@1: case 'G' christopherh@1: fifthindex = 2; christopherh@1: case 'D' christopherh@1: fifthindex = 3; christopherh@1: case 'A' christopherh@1: fifthindex = 4; christopherh@1: case 'E' christopherh@1: fifthindex = 5; christopherh@1: case 'B' christopherh@1: fifthindex = 6; christopherh@1: christopherh@1: end christopherh@1: christopherh@1: %locate enharmonic root on line of fifths (modulo 6 arithmetic) christopherh@1: christopherh@1: fifthoffset = rootaccs*7; christopherh@1: christopherh@1: fifthindex = fifthindex + fifthoffset; christopherh@1: christopherh@1: christopherh@1: % calculate degree translation on line of fifths (add 1 to account christopherh@1: % for matlab referencing of array elements... christopherh@1: degreeoffset = degreetranslation(mod(degree,7)+1); christopherh@1: finalposition = fifthindex + degreeoffset; christopherh@1: christopherh@1: christopherh@1: naturalvalue = mod(finalposition,7); christopherh@1: christopherh@1: christopherh@1: % calculate number of accidentals christopherh@1: if finalposition <0 christopherh@1: %if final position is negative then calculate number of flats christopherh@1: % remembering to include the extra first flat (-1) christopherh@1: accidentals = fix((finalposition+1)/7) + intervalaccs -1; christopherh@1: christopherh@1: else christopherh@1: % note is a natural or has a number of sharps christopherh@1: accidentals = fix(finalposition/7) + intervalaccs; christopherh@1: end christopherh@1: christopherh@1: note = fifthpositions(naturalvalue+1); christopherh@1: christopherh@1: if accidentals > 0 christopherh@1: christopherh@1: for i=1:accidentals christopherh@1: christopherh@1: note = strcat(note, '#'); christopherh@1: christopherh@1: end christopherh@1: christopherh@1: elseif accidentals <=0 christopherh@1: christopherh@1: for i=1:abs(accidentals) christopherh@1: christopherh@1: note = strcat(note, 'b'); christopherh@1: christopherh@1: end christopherh@1: end christopherh@1: christopherh@1: else christopherh@1: christopherh@1: success=0; christopherh@1: christopherh@1: end christopherh@1: christopherh@1: if(success==0) % correct interval therefore return success = 1 christopherh@1: % if not an integer then the interval string is incorrect christopherh@1: errormessage = [error1 error2 sprintf(['Error in interval2note: Unrecognised interval "' interval '" or root "' root '"\n'])]; christopherh@1: christopherh@1: if verbose == 1 christopherh@1: fprintf(1,errormessage); christopherh@1: end christopherh@1: christopherh@1: end christopherh@1: christopherh@1: christopherh@1: christopherh@1: christopherh@1: christopherh@1: christopherh@1: christopherh@1: christopherh@1: