Browse Source

cmXScore.h/c : Added colors to color map. Allow for double whole (breve) as rvalue. Changed note.rvalue from unsigned to double. Recognize 'heel' mark.

master
kevin 8 years ago
parent
commit
d7a7b3a895
2 changed files with 89 additions and 49 deletions
  1. 83
    45
      app/cmXScore.c
  2. 6
    4
      app/cmXScore.h

+ 83
- 45
app/cmXScore.c View File

@@ -28,10 +28,11 @@ enum
28 28
   kDynXsFl       = 0x0040,
29 29
   kEvenXsFl      = 0x0080,
30 30
   kTempoXsFl     = 0x0100,
31
-  kPedalDnXsFl   = 0x0200,
32
-  kPedalUpXsFl   = 0x0400,
33
-  kPedalUpDnXsFl = 0x0800,
34
-  kMetronomeXsFl = 0x1000  // duration holds BPM 
31
+  kHeelXsFl      = 0x0200,
32
+  kPedalDnXsFl   = 0x0400,
33
+  kPedalUpXsFl   = 0x0800,
34
+  kPedalUpDnXsFl = 0x1000,
35
+  kMetronomeXsFl = 0x2000  // duration holds BPM 
35 36
 };
36 37
 
37 38
 
@@ -41,7 +42,7 @@ typedef struct cmXsNote_str
41 42
   unsigned             pitch;    // midi pitch
42 43
   unsigned             tick;     // 
43 44
   unsigned             duration; // duration in ticks
44
-  unsigned             rvalue;   // 1/type = rythmic value (1/4=quarter note, 1/8=eighth note, ...)
45
+  double               rvalue;   // 1/rvalue = rythmic value (1/0.5 double whole 1/1 whole 1/2 half 1/4=quarter note, 1/8=eighth note, ...)
45 46
   const cmChar_t*      tvalue;   // text value
46 47
   struct cmXsNote_str* mlink;    // measure note list 
47 48
   struct cmXsNote_str* slink;    // time sorted event list
@@ -233,46 +234,57 @@ cmXsRC_t  _cmXScoreParsePitch( cmXScore_t* p, const cmXmlNode_t* nnp, unsigned*
233 234
   return rc;  
234 235
 }
235 236
 
236
-unsigned _cmXScoreParseNoteRValue( cmXScore_t* p, const cmXmlNode_t* nnp, const cmChar_t* label )
237
+cmXsRC_t  _cmXScoreParseNoteRValue( cmXScore_t* p, const cmXmlNode_t* nnp, const cmChar_t* label, double* rvalueRef )
237 238
 {
238 239
   typedef struct map_str
239 240
   {
240
-    unsigned        rvalue;
241
+    double         rvalue;
241 242
     const cmChar_t* label;
242 243
   } map_t;
243 244
 
244 245
   map_t mapV[] =
245 246
   {
246
-    {  -1, "measure" },  // whole measure rest
247
-    {   1, "whole"   },
248
-    {   2, "half"    },
249
-    {   4, "quarter" },
250
-    {   8, "eighth"  },
251
-    {  16, "16th"    },
252
-    {  32, "32nd"    },
253
-    {  64, "64th"    },
254
-    { 128, "128th"   },
255
-    {   0, ""        }
247
+    {-1.0, "measure" },  // whole measure rest
248
+    { 0.5, "breve"   },  // double whole
249
+    { 1.0, "whole"   },
250
+    { 2.0, "half"    },
251
+    { 4.0, "quarter" },
252
+    { 8.0, "eighth"  },
253
+    {16.0, "16th"    },
254
+    {32.0, "32nd"    },
255
+   { 64.0, "64th"    },
256
+   {128.0, "128th"   },
257
+   {  0.0, ""        }
256 258
   };
257 259
 
258 260
   const cmChar_t* str;
261
+  // get the XML rvalue label
259 262
   if((str = cmXmlNodeValue(nnp,label,NULL)) == NULL)
260 263
   {
261 264
     if((nnp = cmXmlSearch(nnp,"rest",NULL,0)) != NULL )
262 265
     {
263 266
       const cmXmlAttr_t* a;
264 267
       if((a = cmXmlFindAttrib(nnp,"measure")) != NULL && cmTextCmp(a->value,"yes")==0)
265
-        return -1;
268
+      {
269
+        *rvalueRef = -1;
270
+        return kOkXsRC;
271
+      }
266 272
     }
267
-    return 0;
273
+
274
+    return cmErrMsg(&p->err,kSyntaxErrorXsRC,"The 'beat-unit' metronome value is missing on line %i.",nnp->line);
268 275
   }
269 276
   
270 277
   unsigned i;
278
+  // lookup the rvalue numeric value from the mapV[] table
271 279
   for(i=0; mapV[i].rvalue!=0; ++i)
272 280
     if( cmTextCmp(mapV[i].label,str) == 0 )
273
-      return mapV[i].rvalue;
281
+    {
282
+      *rvalueRef = mapV[i].rvalue;
283
+      return kOkXsRC;
284
+    }
274 285
   
275
-  return 0;
286
+  // the rvalue label was not found
287
+  return cmErrMsg(&p->err,kSyntaxErrorXsRC,"Unknown rvalue type='%s'.",str);
276 288
 }
277 289
 
278 290
 cmXsRC_t  _cmXScoreParseColor( cmXScore_t* p, const cmXmlNode_t* nnp, cmXsNote_t* note )
@@ -288,28 +300,51 @@ cmXsRC_t  _cmXScoreParseColor( cmXScore_t* p, const cmXmlNode_t* nnp, cmXsNote_t
288 300
 
289 301
   map_t mapV[] =
290 302
   {
291
-    { kEvenXsFl,                         "#0000FF" },
292
-    { kTempoXsFl,                        "#00FF00" },
293
-    { kDynXsFl,                          "#FF0000" },
294
-    { kTempoXsFl | kEvenXsFl,            "#00FFFF" },
295
-    { kDynXsFl   | kEvenXsFl,            "#FF00FF" },    
296
-    { kDynXsFl   | kTempoXsFl,           "#FF7F00" },
297
-    { kTempoXsFl | kEvenXsFl | kDynXsFl, "#996633" },
298
-    { 0, "" }
303
+    { kEvenXsFl,                         "#0000FF" },  // blue (even)
304
+    { kTempoXsFl,                        "#00FF00" },  // green (tempo)
305
+    { kDynXsFl,                          "#FF0000" },  // red   (dynamics)
306
+    { kTempoXsFl | kEvenXsFl,            "#00FFFF" },  // green + blue (turquoise)
307
+    { kDynXsFl   | kEvenXsFl,            "#FF00FF" },  // red   + blue  
308
+    { kDynXsFl   | kEvenXsFl,            "#FF0CF7" },  // magenta (even+dyn)
309
+    { kDynXsFl   | kTempoXsFl,           "#FF7F00" },  // red   + green (brown)
310
+    { kTempoXsFl | kEvenXsFl | kDynXsFl, "#996633" },  // (purple)
311
+    { kDynXsFl,                          "#FF6A03" },  //   176 orange  (dynamics)
312
+    { kEvenXsFl,                         "#2F00E8" },  //  1001 blue (even)    
313
+    { kTempoXsFl,                        "#01CD1F" },  //  1196 green   (tempo)
314
+    { kEvenXsFl,                         "#3600E8" },  //  1627 blue (even)
315
+    { kDynXsFl | kTempoXsFl,             "#9E8F15" },  //  8827 brown (dyn + tempo)
316
+    { kEvenXsFl,                         "#2E00E6" },  //  5393 blue (even)
317
+    { kEvenXsFl,                         "#2C00DD" },  //  5895 blue (even)
318
+    { kDynXsFl,                          "#FF5B03" },  //  6498 orange (dyn)
319
+    { kDynXsFl,                          "#FF6104" },  //  6896 orange
320
+    { kEvenXsFl,                         "#2A00E6" },  //  7781 blue
321
+    { kEvenXsFl,                         "#2300DD" },  //  8300 blue (even)    
322
+    { kTempoXsFl,                        "#03CD22" },  // 10820 green (tempo)
323
+    { kEvenXsFl,                         "#3400DB" },  // 11627 blue (dyn)
324
+    { -1, "" }
299 325
   };
326
+
327
+  /*
328
+    orange  #FF6A03
329
+    magenta #FF0CF7
330
+    blue    #2F00E8
331
+    green   #01CD1F
332
+    gold    #9E8F15
333
+    green   #03CD22
334
+   */
300 335
   
301 336
   if((a = cmXmlFindAttrib(nnp, "color" )) != NULL )
302 337
   {
303 338
     unsigned i;
304
-    for(i=0; mapV[i].value != 0; ++i)
339
+    for(i=0; mapV[i].value != -1; ++i)
305 340
       if( cmTextCmp(a->value,mapV[i].label) == 0 )
306 341
       {
307 342
         note->flags += mapV[i].value;
308 343
         break;
309 344
       }
310 345
 
311
-    if( mapV[i].value == 0 )
312
-      rc = cmErrMsg(&p->err,kSyntaxErrorXsRC,"The note color '%s' was not found.",a->value);
346
+    if( mapV[i].value == -1 )
347
+      cmErrMsg(&p->err,kSyntaxErrorXsRC,"The note color '%s' was not found on line %i.",a->value,nnp->line);
313 348
   }
314 349
 
315 350
   return rc;
@@ -349,13 +384,17 @@ cmXsRC_t _cmXScoreParseNote(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNode_t*
349 384
   if( cmXmlNodeHasChild(nnp,"chord",NULL) )
350 385
     note->flags |= kChordXsFl;
351 386
 
387
+  // has 'heel' mark
388
+  if( cmXmlNodeHasChild(nnp,"notations","technical","heel",NULL) )
389
+    note->flags |= kHeelXsFl;
390
+  
352 391
   // set color coded flags
353 392
   if((rc = _cmXScoreParseColor(p, nnp, note )) != kOkXsRC )
354 393
     return rc;
355 394
   
356 395
   // get the note's rythmic value
357
-  if((note->rvalue =  _cmXScoreParseNoteRValue(p,nnp,"type")) == 0 )
358
-    return _cmXScoreMissingNode(p,nnp,"type");
396
+  if((rc =  _cmXScoreParseNoteRValue(p,nnp,"type",&note->rvalue)) != kOkXsRC )
397
+    return rc;
359 398
 
360 399
   note->tick = *tickRef;
361 400
 
@@ -365,7 +404,7 @@ cmXsRC_t _cmXScoreParseNote(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNode_t*
365 404
   return _cmXScorePushNote(p, meas, voiceId, note );
366 405
 }
367 406
 
368
-cmXsRC_t _cmXScorePushNonNote( cmXScore_t* p, cmXsMeas_t* meas, unsigned tick, unsigned duration, unsigned rvalue, const cmChar_t* tvalue, unsigned flags )
407
+cmXsRC_t _cmXScorePushNonNote( cmXScore_t* p, cmXsMeas_t* meas, unsigned tick, unsigned duration, double rvalue, const cmChar_t* tvalue, unsigned flags )
369 408
 {
370 409
   cmXsNote_t* note    = cmLhAllocZ(p->lhH,cmXsNote_t,1);
371 410
   unsigned    voiceId = 0;    // non-note's are always assigned to voiceId=0;
@@ -381,18 +420,17 @@ cmXsRC_t _cmXScorePushNonNote( cmXScore_t* p, cmXsMeas_t* meas, unsigned tick, u
381 420
 
382 421
 cmXsRC_t  _cmXScoreParseDirection(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNode_t* dnp, unsigned tick)
383 422
 {
384
-  const cmXmlNode_t* np = NULL;
385
-  const cmXmlAttr_t* a = NULL;
423
+  cmXsRC_t           rc       = kOkXsRC;
424
+  const cmXmlNode_t* np       = NULL;
425
+  const cmXmlAttr_t* a        = NULL;
386 426
   unsigned           flags    = 0;
387 427
   int                offset   = 0;
388
-  unsigned           rvalue   = 0;
428
+  double             rvalue   = 0;
389 429
   const cmChar_t*    tvalue   = NULL;
390 430
   unsigned           duration = 0;
391 431
 
392
-  
393 432
   cmXmlNodeInt(dnp, &offset, "offset", NULL );
394 433
    
395
- 
396 434
   // if this is a metronome direction
397 435
   if((np = cmXmlSearch( dnp, "metronome", NULL, 0)) != NULL )
398 436
   {
@@ -400,9 +438,9 @@ cmXsRC_t  _cmXScoreParseDirection(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNo
400 438
     if( cmXmlNodeUInt(np,&duration,"per-minute",NULL) != kOkXmlRC )
401 439
       return cmErrMsg(&p->err,kSyntaxErrorXsRC,"The 'per-minute' metronome value is missing on line %i.",np->line);
402 440
 
403
-    if((rvalue = _cmXScoreParseNoteRValue(p,np,"beat-unit")) == 0 )
404
-      return cmErrMsg(&p->err,kSyntaxErrorXsRC,"The 'beat-unit' metronome value is missing on line %i.",np->line);
405
-
441
+    if((rc = _cmXScoreParseNoteRValue(p,np,"beat-unit",&rvalue)) != kOkXsRC )
442
+      return rc;
443
+    
406 444
     flags = kMetronomeXsFl;
407 445
   }
408 446
   else
@@ -668,7 +706,7 @@ void _cmXScoreReportNote( cmRpt_t* rpt, const cmXsNote_t* note )
668 706
   P = cmIsFlag(note->flags,kPedalUpXsFl)   ? "^" : P;
669 707
   P = cmIsFlag(note->flags,kPedalUpDnXsFl) ? "X" : P;
670 708
   const cmChar_t* N = note->pitch==0 ? " " : cmMidiToSciPitch( note->pitch, NULL, 0 );
671
-  cmRptPrintf(rpt,"      %5i %5i %2i %3s %s%s%s%s%s%s%s%s%s",note->tick,note->duration,note->rvalue,N,B,R,G,D,C,e,d,t,P);
709
+  cmRptPrintf(rpt,"      %5i %5i %4.1f %3s %s%s%s%s%s%s%s%s%s",note->tick,note->duration,note->rvalue,N,B,R,G,D,C,e,d,t,P);
672 710
 
673 711
   if( cmIsFlag(note->flags,kSectionXsFl) )
674 712
     cmRptPrintf(rpt," %i",cmStringNullGuard(note->tvalue));
@@ -1033,7 +1071,7 @@ cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* fn )
1033 1071
   if((rc = cmXScoreInitialize( ctx, &h, fn)) != kOkXsRC )
1034 1072
     return cmErrMsg(&ctx->err,rc,"XScore alloc failed.");
1035 1073
 
1036
-  cmXScoreWriteCsv(h,"/home/kevin/temp/a0.csv");
1074
+  cmXScoreWriteCsv(h,"/Users/kevin/temp/a0.csv");
1037 1075
   cmXScoreReport(h,&ctx->rpt,true);
1038 1076
   
1039 1077
   return cmXScoreFinalize(&h);

+ 6
- 4
app/cmXScore.h View File

@@ -27,13 +27,15 @@ extern "C" {
27 27
   //
28 28
   // 2) Replace "DoletSibelius Unknown Symbol Index" with "DoletSibelius unknownSymIdx"
29 29
   //
30
-  // 3) How to assigned dynamic markings.
31
-  // 4) Tempo syntax is inconsistent.
32
-  // 5) Heel is not being recognized
33
-  // 6) Sostenuto pedal events are not being parsed.
30
+  // 3) How to assigned dynamic markings (they are not attached to notes). (from MIDI file?)
31
+  // 4) Tempo syntax is inconsistent (only a problem in full part2 score)     
32
+  // 5) Heel is being parsed but not used. 
33
+  // 6) Sostenuto pedal events are not being parsed because they are not pedal events.
34 34
   // 7) What is a 'pedal-change' event vs. a 'pedal-stop' event.
35 35
   // 8) Verify the colors.
36 36
   // 9) Remove blank bars at end.
37
+  //10) Need to assign section targets (always default to next section)
38
+  //11) Mark tied notes for skip.
37 39
  
38 40
   cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn );
39 41
   cmXsRC_t cmXScoreFinalize( cmXsH_t* hp );

Loading…
Cancel
Save