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 / _chordtools / parsechord.m

History | View | Annotate | Download (9.85 KB)

1
%
2
%PARSECHORD parse chord symbol to its constituent string elements
3
% 
4
% [rootnote, shorthand, degreelist,
5
%              bass, success, errormessage] = parsechord(chord, {verbose})
6
% 	
7
% Parses the chord symbol string "chord" into its separate string elements. 
8
% 
9
% NOTE: This function does not check validity of the chord elements, it
10
% merely separates them according to the chord syntax. 
11
% To obtain chord elements with included validity check use GETCHORDINFO.
12
%
13
% Success = 1 if symbols parsed correctly, 0 otherwise.
14
%
15
% If optional argument 'verbose' is 1, function prints any errormessage to 
16
% the screen.
17
% 	
18
% returns:  rootnote        (note string)
19
%           shorthand       (shorthand string)
20
%           degreelist      (degree-list string)
21
%           bass            (degree string)
22
%           success         (boolean)
23
%           errormessage    (string)
24
%
25
% See also: getchordinfo                     
26
%
27
% Author: Christopher Harte,  August 2005
28
% 
29
% Copyright: Centre for Digital Music, Queen Mary University of London 2005 
30
%
31
% This file is part of the C4DM Chord Toolkit.  
32
%
33
% The C4DM Chord Toolkit is free software; you can redistribute it and/or 
34
% modify it under the terms of the GNU General Public License as published 
35
% by the Free Software Foundation; either version 2 of the License, or
36
% (at your option) any later version.
37
%
38
% The C4DM Chord Toolkit is distributed in the hope that it will be useful,
39
% but WITHOUT ANY WARRANTY; without even the implied warranty of
40
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
41
% GNU General Public License for more details.
42
%
43
% You should have received a copy of the GNU General Public License
44
% along with the C4DM Toolkit; if not, write to the Free Software
45
% Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
46

    
47
%		
48
function  [rootnote, shorthand, degrees, bass, success, errormessage] = parsechord(chord, verbose)
49
	
50
% set verbose default to 0
51
if nargin <2
52
    verbose = 0;
53
end
54

    
55
ilength = length(chord);
56

    
57
% initialise variables
58
errormessage = '';
59
rootnote = '';
60
shorthand = '';
61
degrees = '';
62
bass = '';
63

    
64
success = 1;
65
index = 1;
66

    
67

    
68
% check for 'no chord' symbol
69
if chord(index) == 'N'
70
    rootnote = chord(index);
71
    index = index +1;
72
    % check to see there are no further characters
73
    if(index<=ilength)
74
        errormessage = sprintf(['Error in parsechord: \nExtra characters after "no chord" symbol "' chord '"\n']); 
75
        success = 0;
76
    end
77
else
78
% parse thechord symbol
79

    
80
    % the first part of the symbol before a switch character should be the root note
81
    while ((index <=ilength ))
82
    
83
        if (chord(index) ==  ':') || (chord(index) ==  '/') || ...
84
           (chord(index) ==  '(') || (chord(index) ==  ')')
85
            
86
            break
87
        end
88

    
89
        rootnote(index) = chord(index);
90
        index = index+1;
91
    
92
        if(index > ilength) || (chord(index) == '/')
93
            % if chord is a rootnote on its own or with just a bass note 
94
            % then it is a major chord therefore set shorthand to 'maj'
95
            shorthand = 'maj';
96
        end
97
    end
98
    
99
    % initialise booleans to record which switch characters we have found
100
    colon = 0;
101
    openbracket = 0;
102
    closebracket = 0;
103
    slash = 0;
104
    
105
    % parse the rest of the chord symbol
106
    while(index <= ilength)
107
        
108
        % reset temporary index 
109
        tempindex = 1;
110
        
111
       switch(chord(index))
112
       
113
           case ':'  
114
                        
115
               % if we find a colon after any switch characters have 
116
               % already occured then the symbol is incorrect 
117
               if (colon || openbracket || closebracket || slash)
118
                    errormessage = sprintf(['Error in parsechord: \nIncorrect character sequence in chord "' chord '"\n']); 
119
                    success = 0;
120
                    index = ilength+1;
121
               else
122
                
123
                   % found the first instance of a colon character
124
                   colon = 1;
125
                   
126
                   index = index +1;
127
                   
128
                   if(index > ilength)
129
                        errormessage = sprintf(['Error in parsechord: \nFound ":" at end of chord string "' chord '"\n']); 
130
                        success = 0; 
131
                   end
132
                   % colon should be followed by a shorthand string or
133
                   % a degree list contained in brackets
134
                   while (index <= ilength)
135
                       
136
                       if (chord(index) ==  ':') || (chord(index) ==  '/') || ...
137
                          (chord(index) ==  '(') || (chord(index) ==  ')')
138

    
139
                           break
140
                       end
141

    
142
                       % copy character into shorthand
143
                       shorthand(tempindex) = chord(index);
144
                       index = index +1;
145
                       tempindex = tempindex +1;
146

    
147
                   end
148
               
149
               end
150
               
151
           case '('
152
               
153
               % if we have had a colon but no other switch charaters then
154
               % an open bracket signifies the start of the degree list
155
               if (colon && ~slash && ~closebracket && ~openbracket) 
156
                   
157
                   openbracket = 1;
158
                   
159
                   index = index +1;
160
                   
161
                   while (index <= ilength)
162

    
163
                       if (chord(index) ==  ':') || (chord(index) ==  '/') || ...
164
                          (chord(index) ==  '(') || (chord(index) ==  ')')
165

    
166
                           break
167
                       end
168
                       
169
                       % copy character into degrees
170
                       degrees(tempindex) = chord(index);
171
                       index = index +1;
172
                       tempindex = tempindex +1;
173

    
174
                   end
175
                   
176
                   if(index > ilength)
177
                        errormessage = sprintf(['Error in parsechord: \nDegree list brackets not closed in chord "' chord '"\n']); 
178
                        success = 0; 
179
                   end
180
                   
181
               else
182
                   errormessage = sprintf(['Error in parsechord: \nIncorrect character sequence in chord "' chord '"\n']); 
183
                   success = 0;
184
                   index = ilength +1;
185
               end
186
               
187
           case ')'
188
               
189
               
190
               % if we find a closing bracket then we should either be at
191
               % the end of the symbol or there should be a slash to follow
192
               if (colon && openbracket && ~slash && ~closebracket) 
193
                   
194
                   closebracket = 1;
195
                   index = index +1;
196
                   
197
               else
198
                   errormessage = sprintf(['Error in parsechord: \nIncorrect character sequence in chord "' chord '"\n']); 
199
                   success = 0;
200
                   index = ilength +1;
201
               end
202
               
203
               % check to see that the brackets contained something
204
               if isempty(degrees)
205
                   errormessage = sprintf(['Error in parsechord: \nBrackets contain no degrees in chord "' chord '"\n']); 
206
                   success = 0;
207
                   index = ilength +1;
208
               end
209
               
210
               
211
           case '/'
212
               % forward slash should be followed by a degree string
213
              
214
                   slash = 1;
215

    
216
                   % move on to next character to process the expected bass degree
217
                   index = index +1;
218
                                     
219
                   % check that we haven't overun the end of the symbol string
220
                   if(index > ilength)
221
                        errormessage = sprintf(['Error in parsechord: \nNo bass degree "/" at end of chord "' chord '"\n']); 
222
                        success = 0; 
223
                   end
224
                   
225
                   % check that if we have had an open bracket that it also
226
                   % had a closed bracket
227
                   if(xor(openbracket,closebracket))
228
                        errormessage = sprintf(['Error in parsechord: \nFound "/" before closing bracket in chord "' chord '"\n']); 
229
                        success = 0; 
230
                        index = ilength +1;
231
                   end
232

    
233
                   % check that the previous character was not a ':'
234
                   if(chord(index-2) == ':')
235
                        errormessage = sprintf(['Error in parsechord: \nFound "/" directly after ":" in chord "' chord '"\n']); 
236
                        success = 0; 
237
                        index = ilength +1;
238
                   end
239

    
240
                   
241
                   while( index <= ilength )
242
                       
243
                       % if we find a switch character after a slash then
244
                       % the symbol is incorrect
245
                       if (chord(index) ==  ':') || (chord(index) ==  '/') || ...
246
                          (chord(index) ==  '(') || (chord(index) ==  ')')
247
         
248
                           errormessage = sprintf(['Error in parsechord: \nIncorrect character sequence in chord "' chord '"\n']); 
249
                           success = 0;
250
                           index = ilength +1;
251
                       
252
                       else
253

    
254
                           % copy remaining characters into bass
255
                           bass(tempindex) = chord(index);
256
                           index = index +1;
257
                           tempindex = tempindex +1;
258
                       end
259
                   end
260
                            
261
           otherwise
262
                errormessage = sprintf(['Error in parsechord: \nUnrecognised chord "' chord '"\n']); 
263
                success = 0;
264
                index = ilength + 1;
265
       end
266
            
267
    end
268
end            
269
            
270
if (verbose == 1) && (success == 0)
271
    fprintf(1,errormessage);
272
end
273
        
274