浏览代码

cmScore.h/c Changes to added new 'grace note' score column and srate to init. signature.

master
kevin 12 年前
父节点
当前提交
268f2a20c1
共有 2 个文件被更改,包括 133 次插入20 次删除
  1. 128
    17
      app/cmScore.c
  2. 5
    3
      app/cmScore.h

+ 128
- 17
app/cmScore.c 查看文件

@@ -35,10 +35,12 @@ enum
35 35
   kBarColScIdx       = 13,
36 36
   kSkipColScIdx      = 14,
37 37
   kEvenColScIdx      = 15,
38
-  kTempoColScIdx     = 16,
39
-  kDynColScIdx       = 17,
40
-  kSectionColScIdx   = 18,
41
-  kRemarkColScIdx    = 19
38
+  kGraceColScIdx     = 16,
39
+  kTempoColScIdx     = 17,
40
+  kFracColScIdx      = 18,
41
+  kDynColScIdx       = 19,
42
+  kSectionColScIdx   = 20,
43
+  kRemarkColScIdx    = 21
42 44
 };
43 45
 
44 46
 
@@ -79,6 +81,7 @@ typedef struct
79 81
   cmScCb_t          cbFunc;
80 82
   void*             cbArg;
81 83
   cmChar_t*         fn;
84
+  double            srate;
82 85
 
83 86
   cmScoreEvt_t*     array;
84 87
   unsigned          cnt;
@@ -104,6 +107,7 @@ typedef struct
104 107
   unsigned          nxtLocIdx;
105 108
   unsigned          minSetLocIdx;
106 109
   unsigned          maxSetLocIdx;
110
+  
107 111
 } cmSc_t;
108 112
 
109 113
 cmScEvtRef_t _cmScEvtRefArray[] = 
@@ -130,12 +134,10 @@ cmScEvtRef_t _cmScDynRefArray[] =
130 134
   { 3, 0, "pp"  },
131 135
   { 4, 0, "p"   },
132 136
   { 5, 0, "mp"  },
133
-  { 6, 0, "m"   },
134
-  { 7, 0, "mf"  },
135
-  { 8, 0, "f"   },
136
-  { 9, 0, "ff"  },
137
-  { 10,0, "fff" },
138
-  { 11,0, "ffff"},
137
+  { 6, 0, "mf"  },
138
+  { 7, 0, "f"   },
139
+  { 8, 0, "ff"  },
140
+  { 9,0, "fff" },
139 141
   { kInvalidDynScId,0, "***" },
140 142
 };
141 143
 
@@ -608,6 +610,14 @@ cmScRC_t _cmScParseNoteOn( cmSc_t* p, unsigned rowIdx, cmScoreEvt_t* s, unsigned
608 610
     _cmScParseAttr(p,scoreIdx,attr,kEvenScFl);
609 611
   }
610 612
 
613
+  // grace attribute
614
+  if((attr = cmCsvCellText(p->cH,rowIdx,kGraceColScIdx)) != NULL && *attr == 'g' )
615
+  {
616
+    flags += kGraceScFl;
617
+    if( cmIsNotFlag(flags,kEvenScFl) )
618
+      return cmErrMsg(&p->err,kSyntaxErrScRC,"All 'grace' notes should also be 'even' notes.");
619
+  }
620
+
611 621
   // tempo attribute
612 622
   if((attr = cmCsvCellText(p->cH,rowIdx,kTempoColScIdx)) != NULL && *attr == 't' )
613 623
   {
@@ -627,6 +637,17 @@ cmScRC_t _cmScParseNoteOn( cmSc_t* p, unsigned rowIdx, cmScoreEvt_t* s, unsigned
627 637
 
628 638
   }
629 639
 
640
+  // tempo/non-grace rythmic value
641
+  if( cmIsFlag(flags,kTempoScFl) || (cmIsFlag(flags,kEvenScFl) && cmIsNotFlag(flags,kGraceScFl)) )
642
+  {
643
+    double frac = cmCsvCellDouble(p->cH,rowIdx,kFracColScIdx);
644
+
645
+    // no 'frac' value is given for the last note of the set we must accept error
646
+    // values here and validate the actual values later
647
+    if( frac>0 && frac!=DBL_MAX )
648
+      s->frac = frac;
649
+  }
650
+
630 651
   // Returns DBL_MAX on error.
631 652
   if((durSecs =  cmCsvCellDouble(p->cH, rowIdx, kDSecsColScIdx )) == DBL_MAX) 
632 653
     durSecs = 0.25;
@@ -729,12 +750,24 @@ cmScRC_t _cmScProcSets( cmSc_t* p )
729 750
 
730 751
       // fill in the element array
731 752
       ep = sp->eles;
753
+      unsigned graceCnt = 0;
732 754
       for(j=0; ep!=NULL; ep=ep->link,++j)
733 755
       {
734 756
         assert(ep->eleIdx != cmInvalidIdx && ep->eleIdx<p->cnt);
735 757
         p->sets[i].eleArray[j] = p->array + ep->eleIdx;
736 758
         assert( cmIsFlag( p->sets[i].eleArray[j]->flags, sp->typeFl) );
737 759
         rowNumb = p->array[ep->eleIdx].csvRowNumb;
760
+
761
+        unsigned flags = p->array[ep->eleIdx].flags;
762
+
763
+        // count grace notes
764
+        if( cmIsFlag(flags,kGraceScFl) )
765
+          ++graceCnt;
766
+
767
+        // validate the 'frac' field - all but the last note in 
768
+        // tempo and non-grace evenness sets must have a non-zero 'frac' value.
769
+        if( en>0 && j<en-1 && (sp->typeFl==kTempoScFl || (sp->typeFl==kEvenScFl && graceCnt==0)) && p->array[ep->eleIdx].frac==0)
770
+          rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The note on row number %i must have a non-zero 'frac' value.",p->array[ep->eleIdx].csvRowNumb);          
738 771
       }    
739 772
 
740 773
       // get the count of sections assoc'd with this set
@@ -1073,7 +1106,7 @@ cmScRC_t _cmScInitLocArray( cmSc_t* p )
1073 1106
 }
1074 1107
 
1075 1108
 
1076
-cmScRC_t cmScoreInitialize( cmCtx_t* ctx, cmScH_t* hp, const cmChar_t* fn, const unsigned* dynRefArray, unsigned dynRefCnt, cmScCb_t cbFunc, void* cbArg )
1109
+cmScRC_t cmScoreInitialize( cmCtx_t* ctx, cmScH_t* hp, const cmChar_t* fn, double srate, const unsigned* dynRefArray, unsigned dynRefCnt, cmScCb_t cbFunc, void* cbArg )
1077 1110
 {
1078 1111
   cmScRC_t rc = kOkScRC;
1079 1112
   if((rc = cmScoreFinalize(hp)) != kOkScRC )
@@ -1107,6 +1140,7 @@ cmScRC_t cmScoreInitialize( cmCtx_t* ctx, cmScH_t* hp, const cmChar_t* fn, const
1107 1140
     p->dynRefCnt   = dynRefCnt;
1108 1141
   }
1109 1142
 
1143
+  p->srate        = srate;
1110 1144
   p->cbFunc       = cbFunc;
1111 1145
   p->cbArg        = cbArg;
1112 1146
   p->fn           = cmMemAllocStr(fn);
@@ -1526,11 +1560,87 @@ bool _cmScPerfDyn( cmSc_t* p, cmScoreSet_t* stp, bool printMissFl)
1526 1560
   return true;
1527 1561
 }
1528 1562
 
1529
-bool _cmScPerfTempo(cmSc_t* p, cmScoreSet_t* stp, bool printFl)
1563
+bool _cmScPerfTempo1(cmSc_t* p, cmScoreSet_t* stp, bool printMissFl)
1564
+{
1565
+  bool     printFl = true;
1566
+  unsigned durSmpCnt = 0;
1567
+  double   durBeats  = 0;
1568
+  int      i;
1569
+
1570
+  for(i=0; i<stp->eleCnt; ++i)
1571
+  {
1572
+    // if this event was not received - then the set is not valid
1573
+    if( stp->eleArray[i]->perfSmpIdx == cmInvalidIdx )
1574
+    {
1575
+      if( printFl && printMissFl )
1576
+        printf("TEMPO: missing loc:%i %s\n",stp->eleArray[i]->locIdx,cmMidiToSciPitch(stp->eleArray[i]->pitch,NULL,0));
1577
+      return false;
1578
+    }
1579
+
1580
+    if( i > 0 )
1581
+      durSmpCnt += stp->eleArray[i]->perfSmpIdx - stp->eleArray[i-1]->perfSmpIdx;
1582
+
1583
+    durBeats += stp->eleArray[i]->frac;
1584
+  }
1585
+
1586
+  stp->value = durBeats / (durSmpCnt / p->srate*60.0 );
1587
+  stp->doneFl = true;
1588
+
1589
+  if( printFl )
1590
+    printf("TEMPO:%f\n",stp->value);
1591
+
1592
+  return true;
1593
+}
1594
+
1595
+bool _cmScPerfTempo(cmSc_t* p, cmScoreSet_t* stp, bool printMissFl)
1530 1596
 {
1531
-  return false;
1597
+  bool     printFl = true;
1598
+  unsigned durSmpCnt = 0;
1599
+  double   durBeats  = 0;
1600
+  int      i;
1601
+
1602
+  unsigned bi = cmInvalidIdx;
1603
+  unsigned ei = cmInvalidIdx;
1604
+  unsigned missCnt = 0;
1605
+
1606
+  for(i=0; i<stp->eleCnt; ++i)
1607
+  {
1608
+    // if this event was not received - then the set is not valid
1609
+    if( stp->eleArray[i]->perfSmpIdx == cmInvalidIdx )
1610
+    {
1611
+      ++missCnt;
1612
+      if( printFl && printMissFl )
1613
+        printf("TEMPO: missing loc:%i %s\n",stp->eleArray[i]->locIdx,cmMidiToSciPitch(stp->eleArray[i]->pitch,NULL,0));
1614
+    }
1615
+    else
1616
+    {
1617
+      if( bi == cmInvalidIdx )
1618
+        bi = i;
1619
+      
1620
+      ei = i;
1621
+    }
1622
+  }
1623
+
1624
+  if( ei > bi )
1625
+  {
1626
+    for(i=bi; i<=ei; ++i)
1627
+      durBeats += stp->eleArray[i]->frac;
1628
+
1629
+    durSmpCnt = stp->eleArray[ei]->perfSmpIdx - stp->eleArray[bi]->perfSmpIdx;
1630
+
1631
+    stp->value = durBeats / (durSmpCnt / (p->srate*60.0) );
1632
+
1633
+    stp->doneFl = true;
1634
+
1635
+  }
1636
+
1637
+  if( printFl )
1638
+    printf("TEMPO:%f bi:%i ei:%i secs:%f bts:%f\n",stp->value,bi,ei,durSmpCnt/p->srate,durBeats);
1639
+
1640
+  return true;
1532 1641
 }
1533 1642
 
1643
+
1534 1644
 void _cmScPerfExec( cmSc_t* p, cmScoreSet_t* sp, bool printMissFl )
1535 1645
 {
1536 1646
   if( sp->doneFl == false )
@@ -1566,7 +1676,7 @@ void _cmScPerfExecRange( cmSc_t* p )
1566 1676
   {
1567 1677
     cmScoreSet_t* sp = p->loc[i].setList;
1568 1678
     for(; sp!=NULL; sp=sp->llink)      
1569
-      _cmScPerfExec(p,sp,false);
1679
+      _cmScPerfExec(p,sp,true);
1570 1680
     
1571 1681
   }
1572 1682
 }
@@ -1668,8 +1778,9 @@ void  cmScoreExecPerfEvent( cmScH_t h, unsigned locIdx, unsigned smpIdx, unsigne
1668 1778
       {
1669 1779
         cmScoreSet_t* stp = lp->begSectPtr->setArray[i];
1670 1780
 
1671
-        if( stp->doneFl == false )
1672
-          _cmScPerfExec(p, stp, printLvl>0 );
1781
+        // temporarily commented out for testing purposes
1782
+        // if( stp->doneFl == false )
1783
+        //  _cmScPerfExec(p, stp, printLvl>0 );
1673 1784
         
1674 1785
         if( stp->doneFl )
1675 1786
         {
@@ -1756,7 +1867,7 @@ void cmScorePrint( cmScH_t h, cmRpt_t* rpt )
1756 1867
 void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn )
1757 1868
 {
1758 1869
   cmScH_t h = cmScNullHandle;
1759
-  if( cmScoreInitialize(ctx,&h,fn,NULL,0,NULL,NULL) != kOkScRC )
1870
+  if( cmScoreInitialize(ctx,&h,fn,0,NULL,0,NULL,NULL) != kOkScRC )
1760 1871
     return;
1761 1872
 
1762 1873
   cmScorePrint(h,&ctx->rpt);

+ 5
- 3
app/cmScore.h 查看文件

@@ -40,7 +40,8 @@ extern "C" {
40 40
     kDynScFl     = 0x02,        // This note is marked for dynamics measurement
41 41
     kTempoScFl   = 0x04,        // This note is marked for tempo measurement
42 42
     kSkipScFl    = 0x08,        // This isn't a real event (e.g. tied note) skip over it
43
-    kInvalidScFl = 0x10         // This note has a calculated time
43
+    kGraceScFl   = 0x10,        // This is a grace note
44
+    kInvalidScFl = 0x20         // This note has a calculated time
44 45
   };
45 46
 
46 47
 
@@ -54,7 +55,6 @@ extern "C" {
54 55
     kScVarCnt
55 56
   };
56 57
 
57
-
58 58
   struct cmScoreLoc_str;
59 59
   struct cmScoreSet_str;
60 60
 
@@ -80,6 +80,7 @@ extern "C" {
80 80
     cmMidiByte_t pitch;        // MIDI pitch of this note
81 81
     unsigned     flags;        // Attribute flags for this event
82 82
     unsigned     dynVal;       // Dynamcis value pppp to ffff (1 to 11) for this note.
83
+    double       frac;         // Note's time value for tempo and non-grace evenness notes.
83 84
     unsigned     barNumb;      // Bar id of the measure containing this event.
84 85
     unsigned     barNoteIdx;   // Index of this note in this bar
85 86
     unsigned     csvRowNumb;   // File row number (not index) from which this record originated
@@ -130,7 +131,8 @@ extern "C" {
130 131
   // features are not used.
131 132
   // If provided the dynRefArray[] is copied into an internal array.
132 133
   // The physical array passed here therefore does not need to remain valid.
133
-  cmScRC_t      cmScoreInitialize( cmCtx_t* ctx, cmScH_t* hp, const cmChar_t* fn, const unsigned* dynRefArray, unsigned dynRefCnt, cmScCb_t cbFunc, void* cbArg );
134
+  // Set 'srate' to zero if the score will not be used to perform measurement calculations.
135
+  cmScRC_t      cmScoreInitialize( cmCtx_t* ctx, cmScH_t* hp, const cmChar_t* fn, double srate, const unsigned* dynRefArray, unsigned dynRefCnt, cmScCb_t cbFunc, void* cbArg );
134 136
   cmScRC_t      cmScoreFinalize(   cmScH_t* hp );
135 137
 
136 138
   // Filename of last successfuly loaded score file.

正在加载...
取消
保存