Переглянути джерело

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

master
kevin 11 роки тому
джерело
коміт
268f2a20c1
2 змінених файлів з 133 додано та 20 видалено
  1. 128
    17
      app/cmScore.c
  2. 5
    3
      app/cmScore.h

+ 128
- 17
app/cmScore.c Переглянути файл

35
   kBarColScIdx       = 13,
35
   kBarColScIdx       = 13,
36
   kSkipColScIdx      = 14,
36
   kSkipColScIdx      = 14,
37
   kEvenColScIdx      = 15,
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
   cmScCb_t          cbFunc;
81
   cmScCb_t          cbFunc;
80
   void*             cbArg;
82
   void*             cbArg;
81
   cmChar_t*         fn;
83
   cmChar_t*         fn;
84
+  double            srate;
82
 
85
 
83
   cmScoreEvt_t*     array;
86
   cmScoreEvt_t*     array;
84
   unsigned          cnt;
87
   unsigned          cnt;
104
   unsigned          nxtLocIdx;
107
   unsigned          nxtLocIdx;
105
   unsigned          minSetLocIdx;
108
   unsigned          minSetLocIdx;
106
   unsigned          maxSetLocIdx;
109
   unsigned          maxSetLocIdx;
110
+  
107
 } cmSc_t;
111
 } cmSc_t;
108
 
112
 
109
 cmScEvtRef_t _cmScEvtRefArray[] = 
113
 cmScEvtRef_t _cmScEvtRefArray[] = 
130
   { 3, 0, "pp"  },
134
   { 3, 0, "pp"  },
131
   { 4, 0, "p"   },
135
   { 4, 0, "p"   },
132
   { 5, 0, "mp"  },
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
   { kInvalidDynScId,0, "***" },
141
   { kInvalidDynScId,0, "***" },
140
 };
142
 };
141
 
143
 
608
     _cmScParseAttr(p,scoreIdx,attr,kEvenScFl);
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
   // tempo attribute
621
   // tempo attribute
612
   if((attr = cmCsvCellText(p->cH,rowIdx,kTempoColScIdx)) != NULL && *attr == 't' )
622
   if((attr = cmCsvCellText(p->cH,rowIdx,kTempoColScIdx)) != NULL && *attr == 't' )
613
   {
623
   {
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
   // Returns DBL_MAX on error.
651
   // Returns DBL_MAX on error.
631
   if((durSecs =  cmCsvCellDouble(p->cH, rowIdx, kDSecsColScIdx )) == DBL_MAX) 
652
   if((durSecs =  cmCsvCellDouble(p->cH, rowIdx, kDSecsColScIdx )) == DBL_MAX) 
632
     durSecs = 0.25;
653
     durSecs = 0.25;
729
 
750
 
730
       // fill in the element array
751
       // fill in the element array
731
       ep = sp->eles;
752
       ep = sp->eles;
753
+      unsigned graceCnt = 0;
732
       for(j=0; ep!=NULL; ep=ep->link,++j)
754
       for(j=0; ep!=NULL; ep=ep->link,++j)
733
       {
755
       {
734
         assert(ep->eleIdx != cmInvalidIdx && ep->eleIdx<p->cnt);
756
         assert(ep->eleIdx != cmInvalidIdx && ep->eleIdx<p->cnt);
735
         p->sets[i].eleArray[j] = p->array + ep->eleIdx;
757
         p->sets[i].eleArray[j] = p->array + ep->eleIdx;
736
         assert( cmIsFlag( p->sets[i].eleArray[j]->flags, sp->typeFl) );
758
         assert( cmIsFlag( p->sets[i].eleArray[j]->flags, sp->typeFl) );
737
         rowNumb = p->array[ep->eleIdx].csvRowNumb;
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
       // get the count of sections assoc'd with this set
773
       // get the count of sections assoc'd with this set
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
   cmScRC_t rc = kOkScRC;
1111
   cmScRC_t rc = kOkScRC;
1079
   if((rc = cmScoreFinalize(hp)) != kOkScRC )
1112
   if((rc = cmScoreFinalize(hp)) != kOkScRC )
1107
     p->dynRefCnt   = dynRefCnt;
1140
     p->dynRefCnt   = dynRefCnt;
1108
   }
1141
   }
1109
 
1142
 
1143
+  p->srate        = srate;
1110
   p->cbFunc       = cbFunc;
1144
   p->cbFunc       = cbFunc;
1111
   p->cbArg        = cbArg;
1145
   p->cbArg        = cbArg;
1112
   p->fn           = cmMemAllocStr(fn);
1146
   p->fn           = cmMemAllocStr(fn);
1526
   return true;
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
 void _cmScPerfExec( cmSc_t* p, cmScoreSet_t* sp, bool printMissFl )
1644
 void _cmScPerfExec( cmSc_t* p, cmScoreSet_t* sp, bool printMissFl )
1535
 {
1645
 {
1536
   if( sp->doneFl == false )
1646
   if( sp->doneFl == false )
1566
   {
1676
   {
1567
     cmScoreSet_t* sp = p->loc[i].setList;
1677
     cmScoreSet_t* sp = p->loc[i].setList;
1568
     for(; sp!=NULL; sp=sp->llink)      
1678
     for(; sp!=NULL; sp=sp->llink)      
1569
-      _cmScPerfExec(p,sp,false);
1679
+      _cmScPerfExec(p,sp,true);
1570
     
1680
     
1571
   }
1681
   }
1572
 }
1682
 }
1668
       {
1778
       {
1669
         cmScoreSet_t* stp = lp->begSectPtr->setArray[i];
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
         if( stp->doneFl )
1785
         if( stp->doneFl )
1675
         {
1786
         {
1756
 void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn )
1867
 void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn )
1757
 {
1868
 {
1758
   cmScH_t h = cmScNullHandle;
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
     return;
1871
     return;
1761
 
1872
 
1762
   cmScorePrint(h,&ctx->rpt);
1873
   cmScorePrint(h,&ctx->rpt);

+ 5
- 3
app/cmScore.h Переглянути файл

40
     kDynScFl     = 0x02,        // This note is marked for dynamics measurement
40
     kDynScFl     = 0x02,        // This note is marked for dynamics measurement
41
     kTempoScFl   = 0x04,        // This note is marked for tempo measurement
41
     kTempoScFl   = 0x04,        // This note is marked for tempo measurement
42
     kSkipScFl    = 0x08,        // This isn't a real event (e.g. tied note) skip over it
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
     kScVarCnt
55
     kScVarCnt
55
   };
56
   };
56
 
57
 
57
-
58
   struct cmScoreLoc_str;
58
   struct cmScoreLoc_str;
59
   struct cmScoreSet_str;
59
   struct cmScoreSet_str;
60
 
60
 
80
     cmMidiByte_t pitch;        // MIDI pitch of this note
80
     cmMidiByte_t pitch;        // MIDI pitch of this note
81
     unsigned     flags;        // Attribute flags for this event
81
     unsigned     flags;        // Attribute flags for this event
82
     unsigned     dynVal;       // Dynamcis value pppp to ffff (1 to 11) for this note.
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
     unsigned     barNumb;      // Bar id of the measure containing this event.
84
     unsigned     barNumb;      // Bar id of the measure containing this event.
84
     unsigned     barNoteIdx;   // Index of this note in this bar
85
     unsigned     barNoteIdx;   // Index of this note in this bar
85
     unsigned     csvRowNumb;   // File row number (not index) from which this record originated
86
     unsigned     csvRowNumb;   // File row number (not index) from which this record originated
130
   // features are not used.
131
   // features are not used.
131
   // If provided the dynRefArray[] is copied into an internal array.
132
   // If provided the dynRefArray[] is copied into an internal array.
132
   // The physical array passed here therefore does not need to remain valid.
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
   cmScRC_t      cmScoreFinalize(   cmScH_t* hp );
136
   cmScRC_t      cmScoreFinalize(   cmScH_t* hp );
135
 
137
 
136
   // Filename of last successfuly loaded score file.
138
   // Filename of last successfuly loaded score file.

Завантаження…
Відмінити
Зберегти