Browse Source

cmXScore.h/c : Finished tie processing. Fixed bug in chord onset calculation.

master
kevin 8 years ago
parent
commit
325dd311cc
2 changed files with 169 additions and 198 deletions
  1. 166
    198
      app/cmXScore.c
  2. 3
    0
      app/cmXScore.h

+ 166
- 198
app/cmXScore.c View File

19
 
19
 
20
 enum
20
 enum
21
 {
21
 {
22
-  kSectionXsFl   = 0x0001,  // rvalue holds section number
23
-  kBarXsFl       = 0x0002,
24
-  kRestXsFl      = 0x0004,
25
-  kGraceXsFl     = 0x0008,
26
-  kDotXsFl       = 0x0010,
27
-  kChordXsFl     = 0x0020,
28
-  kDynXsFl       = 0x0040,
29
-  kEvenXsFl      = 0x0080,
30
-  kTempoXsFl     = 0x0100,
31
-  kHeelXsFl      = 0x0200,
32
-  kTieBegXsFl    = 0x0400,
33
-  kTieEndXsFl    = 0x0800,
34
-  kPedalDnXsFl   = 0x1000,
35
-  kPedalUpXsFl   = 0x2000,
36
-  kPedalUpDnXsFl = 0x4000,
37
-  kMetronomeXsFl = 0x8000  // duration holds BPM
22
+  kSectionXsFl   = 0x00001,  // rvalue holds section number
23
+  kBarXsFl       = 0x00002,
24
+  kRestXsFl      = 0x00004,
25
+  kGraceXsFl     = 0x00008,
26
+  kDotXsFl       = 0x00010,
27
+  kChordXsFl     = 0x00020,
28
+  kDynXsFl       = 0x00040,
29
+  kEvenXsFl      = 0x00080,
30
+  kTempoXsFl     = 0x00100,
31
+  kHeelXsFl      = 0x00200,
32
+  kTieBegXsFl    = 0x00400,
33
+  kTieEndXsFl    = 0x00800,
34
+  kTieProcXsFl   = 0x01000,
35
+  kPedalDnXsFl   = 0x02000,
36
+  kPedalUpXsFl   = 0x04000,
37
+  kPedalUpDnXsFl = 0x08000,
38
+  kMetronomeXsFl = 0x10000  // duration holds BPM
38
 };
39
 };
39
 
40
 
40
 struct cmXsMeas_str;
41
 struct cmXsMeas_str;
42
 
43
 
43
 typedef struct cmXsNote_str
44
 typedef struct cmXsNote_str
44
 {
45
 {
45
-  unsigned             flags;    // See k???XsFl 
46
-  unsigned             pitch;    // midi pitch
47
-  unsigned             tick;     // 
48
-  unsigned             duration; // duration in ticks
49
-  unsigned             pticks;   // play ticks (0 for non-sounding notes)
50
-  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, ...)
51
-  const cmChar_t*      tvalue;   // text value
46
+  unsigned                    flags;    // See k???XsFl 
47
+  unsigned                    pitch;    // midi pitch
48
+  cmChar_t                    step;     // A-G
49
+  unsigned                    octave;   // sci pitch octave
50
+  int                         alter;    // +n=sharps,-n=flats
51
+  unsigned                    tick;     // 
52
+  unsigned                    duration; // duration in ticks
53
+  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, ...)
54
+  const cmChar_t*             tvalue;   // text value
52
 
55
 
53
   const struct cmXsVoice_str* voice;    // voice this note belongs to 
56
   const struct cmXsVoice_str* voice;    // voice this note belongs to 
54
   const struct cmXsMeas_str*  meas;     // measure this note belongs to
57
   const struct cmXsMeas_str*  meas;     // measure this note belongs to
55
-  const cmXmlNode_t*   xmlNode;  // note xml ptr
56
 
58
 
57
-  struct cmXsNote_str* mlink;    // measure note list 
58
-  struct cmXsNote_str* slink;    // time sorted event list
59
+  const cmXmlNode_t*          xmlNode;  // note xml ptr
60
+  
61
+  struct cmXsNote_str*        mlink;    // measure note list 
62
+  struct cmXsNote_str*        slink;    // time sorted event list
59
   
63
   
60
 } cmXsNote_t;
64
 } cmXsNote_t;
61
 
65
 
232
   return rc;
236
   return rc;
233
 }
237
 }
234
 
238
 
235
-cmXsRC_t  _cmXScoreParsePitch( cmXScore_t* p, const cmXmlNode_t* nnp, unsigned* midiPitchRef )
239
+cmXsRC_t  _cmXScoreParsePitch( cmXScore_t* p, const cmXmlNode_t* nnp, cmXsNote_t* np )
236
 {
240
 {
237
   cmXsRC_t        rc     = kOkXsRC;
241
   cmXsRC_t        rc     = kOkXsRC;
238
   unsigned        octave = 0;
242
   unsigned        octave = 0;
254
 
258
 
255
   midi         += alter;
259
   midi         += alter;
256
 
260
 
257
-  *midiPitchRef = midi;
261
+  np->pitch = midi;
262
+  np->step  = *step;
263
+  np->octave = octave;
264
+  np->alter  = alter;
258
 
265
 
259
   return rc;  
266
   return rc;  
260
 }
267
 }
261
 
268
 
262
-cmXsConnect_t* _cmXScoreFindTie( const cmXScore_t* p, unsigned pitch )
263
-{
264
-  cmXsConnect_t* c = p->tieL;
265
-  for(; c!=NULL; c=c->link)
266
-  {
267
-    assert( c->note != NULL );
268
-    if( c->doneFl == false && c->note->pitch == pitch )
269
-      return c;
270
-  }
271
-  return NULL;
272
-}
273
-
274
-cmXsRC_t _cmXScoreNewTie( cmXScore_t* p, const cmXsNote_t* note )
275
-{
276
-  cmXsConnect_t* c;
277
-
278
-  // check that an open tie with the same pitch does not exist
279
-  if((c = _cmXScoreFindTie(p,note->pitch)) != NULL )
280
-  {
281
-    cmErrWarnMsg(&p->err,kUnterminatedTieXsRC,"The tie begun from note on line %i was not terminated. (pitch=%i)",c->note->xmlNode->line,c->note->pitch);
282
-    c->doneFl = true; // close the unterminated tie
283
-  }
284
-  
285
-  // allocate a new connection record
286
-  c  = cmLhAllocZ(p->lhH,cmXsConnect_t,1);
287
-
288
-  // set the first note in the connection
289
-  c->note = note;
290
-
291
-  // append the new record to the end of the tie list
292
-  if(p->tieL == NULL )
293
-    p->tieL = c;
294
-  else
295
-  {
296
-    cmXsConnect_t* cp = p->tieL;
297
-    while( cp->link != NULL )
298
-      cp = cp->link;
299
-    
300
-    cp->link = c;
301
-  }
302
-  
303
-  return kOkXsRC;
304
-}
305
-
306
-cmXsRC_t _cmXScoreContinueTie( cmXScore_t* p, const cmXsNote_t* note, unsigned measNumb )
307
-{
308
-  cmXsConnect_t* c;
309
-
310
-  // find an open tie with the same pitch
311
-  if((c = _cmXScoreFindTie(p,note->pitch)) == NULL )
312
-  {
313
-    cmErrWarnMsg(&p->err,kUnterminatedTieXsRC,"The tie ending on the note on line %i does not have an associated starting note. (pitch=%i)",note->xmlNode->line,note->pitch);
314
-    return kOkXsRC;
315
-  }
316
-  
317
-  // allocate a new connection record
318
-  cmXsConnect_t* nc  = cmLhAllocZ(p->lhH,cmXsConnect_t,1);
319
-  nc->note = note;
320
-
321
-  // add the note to the end of the tie list
322
-  if( c->nlink == NULL )
323
-    c->nlink = nc;
324
-  else
325
-  {
326
-    cmXsConnect_t* cp = c->nlink;
327
-    while( cp->nlink != NULL )
328
-      cp=cp->nlink;
329
-    cp->nlink = nc;      
330
-  }
331
-    
332
-  // if this is the last note in the tie ...
333
-  if( cmIsFlag(note->flags,kTieEndXsFl) && cmIsNotFlag(note->flags,kTieBegXsFl) )
334
-  {
335
-    c->doneFl = true;  // ... mark the tie list as complete ...
336
-    c->closeFl= true;  // ... and properly closed
337
-    printf("tie done: meas=%i line=%i pitch=%i\n",measNumb,note->xmlNode->line,note->pitch);
338
-  }
339
-  return kOkXsRC;
340
-}
341
-
342
-cmXsRC_t _cmXScoreProcessTie( cmXScore_t* p, const cmXmlNode_t* np, cmXsNote_t* note, unsigned measNumb )
343
-{
344
-  cmXsRC_t rc = kOkXsRC;
345
-  
346
-  // is this is first note in a tied pair
347
-  if( cmXmlNodeHasChildWithAttrAndValue(np,"tie","type","start",NULL) )
348
-    note->flags |= kTieBegXsFl;
349
-
350
-  // is this is second note in a tied pair
351
-  if( cmXmlNodeHasChildWithAttrAndValue(np,"tie","type","stop",NULL) )
352
-    note->flags |= kTieEndXsFl;
353
-
354
-  // if this is a tie start (and not a tie continue) 
355
-  if( cmIsFlag(note->flags,kTieBegXsFl) && cmIsNotFlag(note->flags,kTieEndXsFl) )
356
-    rc = _cmXScoreNewTie(p,note);
357
-  else
358
-    // if this is a tie continue or end
359
-    if( cmIsFlag(note->flags,kTieEndXsFl) )
360
-      rc = _cmXScoreContinueTie(p,note,measNumb); // this is a tie end or continue
361
-      
362
-  return rc;
363
-}
364
-
365
-const cmXsNote_t*  _cmXScoreResolveTie( const cmXsNote_t* note )
366
-{
367
-  const cmXsMeas_t* m = note->meas;
368
-  const cmXsNote_t* n = note->slink;
369
-
370
-  while( n!=NULL )
371
-  {    
372
-    for(; n!=NULL; n=n->slink)
373
-      if( note->pitch==n->pitch && note->voice==n->voice )
374
-        return n;
375
-
376
-    if( m->link == NULL )
377
-      break;
378
-
379
-    // got to next measure
380
-    if((m = m->link) == NULL )
381
-      break;
382
-    
383
-    n = m->noteL;
384
-  }
385
-
386
-  return NULL;
387
-}
388
-
389
-cmXsRC_t  _cmXScoreResolveTies( cmXScore_t* p )
390
-{
391
-  cmXsRC_t rc = kOkXsRC;
392
-  
393
-  cmXsPart_t* pp = p->partL;
394
-  for(; pp!=NULL; pp=pp->link)
395
-  {
396
-    cmXsMeas_t* mp = pp->measL;
397
-    for(; mp!=NULL; mp=mp->link)
398
-    {
399
-      cmXsNote_t* np = mp->noteL;
400
-      for(; np!=NULL; np=np->slink)
401
-        if( cmIsFlag(np->flags,kTieBegXsFl) )
402
-        {
403
-          const cmXsNote_t* tnp;
404
-          if((tnp = _cmXScoreResolveTie(np)) == NULL)
405
-          {
406
-            
407
-          }
408
-          else
409
-          {
410
-          }
411
-        }
412
-    }
413
-  }
414
-
415
-  return rc;
416
-}
417
-
418
-
419
-
420
 cmXsRC_t  _cmXScoreParseNoteRValue( cmXScore_t* p, const cmXmlNode_t* nnp, const cmChar_t* label, double* rvalueRef )
269
 cmXsRC_t  _cmXScoreParseNoteRValue( cmXScore_t* p, const cmXmlNode_t* nnp, const cmChar_t* label, double* rvalueRef )
421
 {
270
 {
422
   typedef struct map_str
271
   typedef struct map_str
533
   return rc;
382
   return rc;
534
 }
383
 }
535
 
384
 
536
-cmXsRC_t _cmXScoreParseNote(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNode_t* nnp, unsigned* tickRef )
385
+cmXsRC_t _cmXScoreParseNote(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNode_t* nnp, unsigned* tick0Ref, unsigned* tickRef )
537
 {
386
 {
538
   cmXsRC_t    rc   = kOkXsRC;
387
   cmXsRC_t    rc   = kOkXsRC;
539
   cmXsNote_t* note = cmLhAllocZ(p->lhH,cmXsNote_t,1);
388
   cmXsNote_t* note = cmLhAllocZ(p->lhH,cmXsNote_t,1);
548
 
397
 
549
   // if this note has a pitch
398
   // if this note has a pitch
550
   if( cmXmlNodeHasChild(nnp,"pitch",NULL) )
399
   if( cmXmlNodeHasChild(nnp,"pitch",NULL) )
551
-    if((rc = _cmXScoreParsePitch(p,nnp,&note->pitch)) != kOkXsRC )
400
+    if((rc = _cmXScoreParsePitch(p,nnp,note)) != kOkXsRC )
552
       return rc;
401
       return rc;
553
 
402
 
554
   // get the note duration
403
   // get the note duration
570
   if( cmXmlNodeHasChild(nnp,"chord",NULL) )
419
   if( cmXmlNodeHasChild(nnp,"chord",NULL) )
571
     note->flags |= kChordXsFl;
420
     note->flags |= kChordXsFl;
572
 
421
 
573
-  // process ties attached to this note
574
-  if((rc = _cmXScoreProcessTie(p,nnp,note,meas->number)) != kOkXsRC )
575
-    return rc;
422
+  // is this is first note in a tied pair
423
+  if( cmXmlNodeHasChildWithAttrAndValue(nnp,"tie","type","start",NULL) )
424
+    note->flags |= kTieBegXsFl;
425
+    
426
+  // is this is second note in a tied pair
427
+  if( cmXmlNodeHasChildWithAttrAndValue(nnp,"tie","type","stop",NULL) )
428
+    note->flags |= kTieEndXsFl;
576
   
429
   
577
   // has 'heel' mark
430
   // has 'heel' mark
578
   if( cmXmlNodeHasChild(nnp,"notations","technical","heel",NULL) )
431
   if( cmXmlNodeHasChild(nnp,"notations","technical","heel",NULL) )
586
   if((rc =  _cmXScoreParseNoteRValue(p,nnp,"type",&note->rvalue)) != kOkXsRC )
439
   if((rc =  _cmXScoreParseNoteRValue(p,nnp,"type",&note->rvalue)) != kOkXsRC )
587
     return rc;
440
     return rc;
588
 
441
 
589
-  note->tick = *tickRef;
590
 
442
 
591
-  if( cmIsNotFlag(note->flags,kChordXsFl) )
443
+  // if this is a chord note 
444
+  if( cmIsFlag(note->flags,kChordXsFl) )
445
+  {
446
+    note->tick = *tick0Ref; // then use the onset time from the previous note and do not advance time
447
+  }
448
+  else
449
+  {
450
+    *tick0Ref  = *tickRef;
451
+    note->tick = *tickRef;
452
+
592
     *tickRef += note->duration;
453
     *tickRef += note->duration;
454
+  }
593
   
455
   
594
   return _cmXScorePushNote(p, meas, voiceId, note );
456
   return _cmXScorePushNote(p, meas, voiceId, note );
595
 }
457
 }
620
   double             rvalue   = 0;
482
   double             rvalue   = 0;
621
   const cmChar_t*    tvalue   = NULL;
483
   const cmChar_t*    tvalue   = NULL;
622
   unsigned           duration = 0;
484
   unsigned           duration = 0;
485
+  bool               pushFl   = true;
623
 
486
 
624
   cmXmlNodeInt(dnp, &offset, "offset", NULL );
487
   cmXmlNodeInt(dnp, &offset, "offset", NULL );
625
    
488
    
668
       flags = kSectionXsFl;
531
       flags = kSectionXsFl;
669
     }
532
     }
670
   }
533
   }
534
+  else
535
+  {
536
+    pushFl = false;
537
+  }
671
 
538
 
672
-  return _cmXScorePushNonNote(p,meas,dnp,tick+offset,duration,rvalue,tvalue,flags);            
673
-      
539
+  if( pushFl )
540
+   rc = _cmXScorePushNonNote(p,meas,dnp,tick+offset,duration,rvalue,tvalue,flags);            
541
+  
542
+  return rc;
674
 }
543
 }
675
 
544
 
676
 
545
 
679
   cmXsRC_t           rc   = kOkXsRC;
548
   cmXsRC_t           rc   = kOkXsRC;
680
   const cmXmlNode_t* np   = NULL;  
549
   const cmXmlNode_t* np   = NULL;  
681
   unsigned           tick = 0;
550
   unsigned           tick = 0;
551
+  unsigned           tick0= 0;
682
 
552
 
683
   // allocate the 'measure' record
553
   // allocate the 'measure' record
684
   cmXsMeas_t* meas = cmLhAllocZ(p->lhH,cmXsMeas_t,1);
554
   cmXsMeas_t* meas = cmLhAllocZ(p->lhH,cmXsMeas_t,1);
719
     // if this is a 'note' node
589
     // if this is a 'note' node
720
     if( cmTextCmp(np->label,"note") == 0 )
590
     if( cmTextCmp(np->label,"note") == 0 )
721
     {
591
     {
722
-      rc = _cmXScoreParseNote(p,meas,np,&tick);
592
+      rc = _cmXScoreParseNote(p,meas,np,&tick0,&tick);
723
     }
593
     }
724
     else
594
     else
725
       // if this is a 'backup' node
595
       // if this is a 'backup' node
728
         unsigned backup;
598
         unsigned backup;
729
         cmXmlNodeUInt(np,&backup,"duration",NULL);
599
         cmXmlNodeUInt(np,&backup,"duration",NULL);
730
         tick -= backup;
600
         tick -= backup;
601
+        tick0 = tick;
731
       }
602
       }
732
       else
603
       else
733
         // if this is a 'direction' node
604
         // if this is a 'direction' node
813
   }
684
   }
814
 }
685
 }
815
 
686
 
687
+bool  _cmXScoreFindTiedNote( cmXScore_t* p, cmXsMeas_t* mp, cmXsNote_t* np )
688
+{
689
+  cmXsNote_t* nnp      = np->slink;
690
+  unsigned    measNumb = mp->number;
691
+  unsigned    measNumb0= measNumb;
692
+  cmChar_t    acc      = np->alter==-1?'b' : (np->alter==1?'#':' ');
693
+
694
+  for(; mp!=NULL; mp=mp->link)
695
+  {
696
+    if( nnp == NULL )
697
+      nnp = mp->noteL;
698
+    
699
+    for(; nnp!=NULL; nnp=nnp->slink)
700
+    {
701
+      if( /*nnp->voice->id == np->voice->id &&*/ nnp->step == np->step && nnp->octave == np->octave )
702
+      {
703
+        nnp->flags |= kTieProcXsFl;
704
+
705
+        if( cmIsNotFlag(nnp->flags,kTieBegXsFl) )
706
+        {
707
+          return true;
708
+        }
709
+
710
+        measNumb0 = mp->number; 
711
+      }
712
+    }
713
+
714
+    // if a measure was completed and no end note was found ... then the tie is unterminated
715
+    // (a tie must be continued in every measure which it passes through)
716
+    if( measNumb0 < mp->number )
717
+      break;
718
+    
719
+  }
720
+
721
+  cmErrWarnMsg(&p->err,kUnterminatedTieXsRC,"The tied %c%c%i in measure %i was not terminated.",np->step,acc,np->octave,measNumb);
722
+  return false;
723
+}
724
+
725
+void  _cmXScoreProcessTies( cmXScore_t* p )
726
+{
727
+  unsigned n = 0;
728
+  unsigned m = 0;
729
+  
730
+  cmXsPart_t* pp = p->partL;
731
+  for(; pp!=NULL; pp=pp->link)
732
+  {
733
+    cmXsMeas_t* mp = pp->measL;
734
+    for(; mp!=NULL; mp=mp->link)
735
+    {
736
+      cmXsNote_t* np = mp->noteL;
737
+      
738
+      for(; np!=NULL; np=np->slink)
739
+        if( cmIsFlag(np->flags,kTieBegXsFl) && cmIsNotFlag(np->flags,kTieProcXsFl))
740
+        {
741
+          if( _cmXScoreFindTiedNote(p,mp,np) )
742
+            m += 1;
743
+          n += 1;
744
+        } 
745
+        
746
+    }
747
+  }
748
+
749
+  printf("Found:%i Not Found:%i\n",m,n-m);
750
+}
751
+
816
 cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn )
752
 cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn )
817
 {
753
 {
818
   cmXsRC_t rc = kOkXsRC;
754
   cmXsRC_t rc = kOkXsRC;
850
   // fill in the note->slink chain to link the notes in each measure in time order
786
   // fill in the note->slink chain to link the notes in each measure in time order
851
   _cmXScoreSort(p);
787
   _cmXScoreSort(p);
852
 
788
 
789
+  _cmXScoreProcessTies(p);
790
+
853
   // CSV output initialize failed.
791
   // CSV output initialize failed.
854
   if( cmCsvInitialize(&p->csvH,ctx) != kOkCsvRC )
792
   if( cmCsvInitialize(&p->csvH,ctx) != kOkCsvRC )
855
     rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV output object create failed.");
793
     rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV output object create failed.");
899
   const cmChar_t* d  = cmIsFlag(note->flags,kDynXsFl)       ? "d" : "-";
837
   const cmChar_t* d  = cmIsFlag(note->flags,kDynXsFl)       ? "d" : "-";
900
   const cmChar_t* t  = cmIsFlag(note->flags,kTempoXsFl)     ? "t" : "-";
838
   const cmChar_t* t  = cmIsFlag(note->flags,kTempoXsFl)     ? "t" : "-";
901
   const cmChar_t* P  = cmIsFlag(note->flags,kPedalDnXsFl)   ? "V" : "-";
839
   const cmChar_t* P  = cmIsFlag(note->flags,kPedalDnXsFl)   ? "V" : "-";
840
+  const cmChar_t* S  = cmIsFlag(note->flags,kSectionXsFl)   ? "S" : "-";
902
   const cmChar_t* H  = cmIsFlag(note->flags,kHeelXsFl)      ? "H" : "-";
841
   const cmChar_t* H  = cmIsFlag(note->flags,kHeelXsFl)      ? "H" : "-";
903
   const cmChar_t* T0 = cmIsFlag(note->flags,kTieBegXsFl)    ? "T" : "-";
842
   const cmChar_t* T0 = cmIsFlag(note->flags,kTieBegXsFl)    ? "T" : "-";
904
   const cmChar_t* T1 = cmIsFlag(note->flags,kTieEndXsFl)    ? "_" : "-";
843
   const cmChar_t* T1 = cmIsFlag(note->flags,kTieEndXsFl)    ? "_" : "-";
905
   P = cmIsFlag(note->flags,kPedalUpXsFl)   ? "^" : P;
844
   P = cmIsFlag(note->flags,kPedalUpXsFl)   ? "^" : P;
906
   P = cmIsFlag(note->flags,kPedalUpDnXsFl) ? "X" : P;
845
   P = cmIsFlag(note->flags,kPedalUpDnXsFl) ? "X" : P;
907
-  const cmChar_t* N = note->pitch==0 ? " " : cmMidiToSciPitch( note->pitch, NULL, 0 );
908
-  cmRptPrintf(rpt,"      %5i %5i %4.1f %3s %s%s%s%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,H,T0,T1);
846
+  //const cmChar_t* N = note->pitch==0 ? " " : cmMidiToSciPitch( note->pitch, NULL, 0 );
847
+
848
+  cmChar_t N[] = {'\0','\0','\0','\0'};
849
+  cmChar_t acc = note->alter==-1?'b':(note->alter==1?'#':' ');
850
+  snprintf(N,4,"%c%c%1i",note->step,acc,note->octave);
851
+  
852
+  
853
+  cmRptPrintf(rpt,"      %3i %5i %5i %4.1f %3s %s%s%s%s%s%s%s%s%s%s%s%s%s",note->voice->id,note->tick,note->duration,note->rvalue,N,B,R,G,D,C,e,d,t,P,S,H,T0,T1);
909
 
854
 
910
   if( cmIsFlag(note->flags,kSectionXsFl) )
855
   if( cmIsFlag(note->flags,kSectionXsFl) )
911
     cmRptPrintf(rpt," %s",cmStringNullGuard(note->tvalue));
856
     cmRptPrintf(rpt," %s",cmStringNullGuard(note->tvalue));
912
 
857
 
858
+  if( cmIsFlag(note->flags,kMetronomeXsFl) )
859
+    cmRptPrintf(rpt," %i bpm",note->duration);
860
+
913
   printf("\n");
861
   printf("\n");
914
   
862
   
915
 }
863
 }
1261
   }  
1209
   }  
1262
 }
1210
 }
1263
 
1211
 
1212
+cmXsRC_t cmXScoreWriteMidi( cmXsH_t h, const cmChar_t* fn )
1213
+{
1214
+  assert(0); // function not implemented
1215
+  cmXScore_t* p  = _cmXScoreHandleToPtr(h);
1216
+  cmXsPart_t* pp = p->partL;
1217
+  
1218
+  for(; pp!=NULL; pp=pp->link)
1219
+  {
1220
+    const cmXsMeas_t* meas = pp->measL;
1221
+    for(; meas!=NULL; meas=meas->link)
1222
+    {
1223
+
1224
+      const cmXsNote_t* note = meas->noteL;
1225
+      for(; note!=NULL; note=note->slink)
1226
+      {
1227
+        
1228
+      }
1229
+    }
1230
+  }  
1231
+}
1264
 
1232
 
1265
 cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* fn )
1233
 cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* fn )
1266
 {
1234
 {

+ 3
- 0
app/cmXScore.h View File

40
   //10) Need to assign section targets (always default to next section)
40
   //10) Need to assign section targets (always default to next section)
41
   //11) Mark tied notes for skip. (done)
41
   //11) Mark tied notes for skip. (done)
42
   //12) Determine note off locations based on ties and slurs - defer 'pedal' to player
42
   //12) Determine note off locations based on ties and slurs - defer 'pedal' to player
43
+  //13) Check that the measures are given in sorted order.
43
   
44
   
44
  
45
  
45
   cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn );
46
   cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn );
49
 
50
 
50
   cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn );
51
   cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn );
51
 
52
 
53
+  cmXsRC_t cmXScoreWriteMidi( cmXsH_t h, const cmChar_t* fn );
54
+
52
   void     cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl );
55
   void     cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl );
53
 
56
 
54
   cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* fn );
57
   cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* fn );

Loading…
Cancel
Save