Mercurial > hg > c4dm-chord-transcriptions
view chordtools/parsechord.m @ 1:8973548174c1 tip
adding tools to repo
author | christopherh |
---|---|
date | Mon, 06 May 2013 14:43:47 +0100 |
parents | |
children |
line wrap: on
line source
% %PARSECHORD parse chord symbol to its constituent string elements % % [rootnote, shorthand, intervals, bass, success, errormessage] % = parsechord(chord, {verbose}) % % Parses the chord symbol string "chord" into its separate string elements. % % NOTE: This function does not check validity of the chord elements, it % merely separates them according to the chord syntax. % To obtain chord elements with included validity check use GETCHORDINFO. % % Success = 1 if symbols parsed correctly, 0 otherwise. % % If optional argument 'verbose' is 1, function prints any errormessage to % the screen. % % returns: rootnote (note string) % shorthand (shorthand string) % intervals (interval-list string) % bass (interval string) % success (boolean) % errormessage (string) % % See also: getchordinfo % % Author: Christopher Harte, March 2009 % % Copyright: Centre for Digital Music, Queen Mary University of London 2005 % % This file is part of the C4DM Chord Toolkit V2.0 % % The C4DM Chord Toolkit is free software; you can redistribute it and/or % modify it under the terms of the GNU General Public License as published % by the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % The C4DM Chord Toolkit is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with the C4DM Toolkit; if not, write to the Free Software % Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA % function [rootnote, shorthand, intervals, bass, success, errormessage] = parsechord(chord, verbose) % set verbose default to 0 if nargin <2 verbose = 0; end ilength = length(chord); % initialise variables errormessage = ''; rootnote = ''; shorthand = ''; intervals = ''; bass = ''; success = 1; index = 1; % check for 'no chord' symbol if chord(index) == 'N' rootnote = chord(index); index = index +1; % check to see there are no further characters if(index<=ilength) errormessage = sprintf(['Error in parsechord: \nExtra characters after "no chord" symbol "' chord '"\n']); success = 0; end else % parse thechord symbol % the first part of the symbol before a switch character should be the root note while ((index <=ilength )) if (chord(index) == ':') || (chord(index) == '/') || ... (chord(index) == '(') || (chord(index) == ')') break end rootnote(index) = chord(index); index = index+1; if(index > ilength) || (chord(index) == '/') % if chord is a rootnote on its own or with just a bass note % then it is a major chord therefore set shorthand to 'maj' shorthand = 'maj'; end end % initialise booleans to record which switch characters we have found colon = 0; openbracket = 0; closebracket = 0; slash = 0; % parse the rest of the chord symbol while(index <= ilength) % reset temporary index tempindex = 1; switch(chord(index)) case ':' % if we find a colon after any switch characters have % already occured then the symbol is incorrect if (colon || openbracket || closebracket || slash) errormessage = sprintf(['Error in parsechord: \nIncorrect character sequence in chord "' chord '"\n']); success = 0; index = ilength+1; else % found the first instance of a colon character colon = 1; index = index +1; if(index > ilength) errormessage = sprintf(['Error in parsechord: \nFound ":" at end of chord string "' chord '"\n']); success = 0; end % colon should be followed by a shorthand string or % an interval list contained in brackets while (index <= ilength) if (chord(index) == ':') || (chord(index) == '/') || ... (chord(index) == '(') || (chord(index) == ')') break end % copy character into shorthand shorthand(tempindex) = chord(index); index = index +1; tempindex = tempindex +1; end end case '(' % if we have had a colon but no other switch charaters then % an open bracket signifies the start of the interval list if (colon && ~slash && ~closebracket && ~openbracket) openbracket = 1; index = index +1; while (index <= ilength) if (chord(index) == ':') || (chord(index) == '/') || ... (chord(index) == '(') || (chord(index) == ')') break end % copy character into intervals intervals(tempindex) = chord(index); index = index +1; tempindex = tempindex +1; end if(index > ilength) errormessage = sprintf(['Error in parsechord: \nInterval list brackets not closed in chord "' chord '"\n']); success = 0; end else errormessage = sprintf(['Error in parsechord: \nIncorrect character sequence in chord "' chord '"\n']); success = 0; index = ilength +1; end case ')' % if we find a closing bracket then we should either be at % the end of the symbol or there should be a slash to follow if (colon && openbracket && ~slash && ~closebracket) closebracket = 1; index = index +1; else errormessage = sprintf(['Error in parsechord: \nIncorrect character sequence in chord "' chord '"\n']); success = 0; index = ilength +1; end % check to see that the brackets contained something if isempty(intervals) errormessage = sprintf(['Error in parsechord: \nBrackets contain no intervals in chord "' chord '"\n']); success = 0; index = ilength +1; end case '/' % forward slash should be followed by an interval string slash = 1; % move on to next character to process the expected bass interval index = index +1; % check that we haven't overun the end of the symbol string if(index > ilength) errormessage = sprintf(['Error in parsechord: \nNo bass interval "/" at end of chord "' chord '"\n']); success = 0; end % check that if we have had an open bracket that it also % had a closed bracket if(xor(openbracket,closebracket)) errormessage = sprintf(['Error in parsechord: \nFound "/" before closing bracket in chord "' chord '"\n']); success = 0; index = ilength +1; end % check that the previous character was not a ':' if(chord(index-2) == ':') errormessage = sprintf(['Error in parsechord: \nFound "/" directly after ":" in chord "' chord '"\n']); success = 0; index = ilength +1; end while( index <= ilength ) % if we find a switch character after a slash then % the symbol is incorrect if (chord(index) == ':') || (chord(index) == '/') || ... (chord(index) == '(') || (chord(index) == ')') errormessage = sprintf(['Error in parsechord: \nIncorrect character sequence in chord "' chord '"\n']); success = 0; index = ilength +1; else % copy remaining characters into bass bass(tempindex) = chord(index); index = index +1; tempindex = tempindex +1; end end otherwise errormessage = sprintf(['Error in parsechord: \nUnrecognised chord "' chord '"\n']); success = 0; index = ilength + 1; end end end if (verbose == 1) && (success == 0) fprintf(1,errormessage); end