Browse Source

cmScore.h/c : Pedal events are now handled similarly to Note-on events and given

their own type: kPedalEvtScId and pedal down messages are assigned the
pedal event duration in cmScEvent_t.durSecs.
master
Kevin Larke 9 years ago
parent
commit
a7cecdd678
2 changed files with 124 additions and 63 deletions
  1. 122
    61
      app/cmScore.c
  2. 2
    2
      app/cmScore.h

+ 122
- 61
app/cmScore.c View File

@@ -723,7 +723,7 @@ cmScRC_t _cmScParseNoteOn( cmSc_t* p, unsigned rowIdx, cmScoreEvt_t* s, unsigned
723 723
   if((midiPitch = cmSciPitchToMidi(sciPitch)) == kInvalidMidiPitch)
724 724
     return cmErrMsg(&p->err,kSyntaxErrScRC,"Unable to convert the scientific pitch '%s' to a MIDI value. ");
725 725
 
726
-  // it is possible that note delta-secs field is empty - so default to 0
726
+  // get the sec's field - or DBL_MAX if it is not set
727 727
   if((secs =  cmCsvCellDouble(p->cH, rowIdx, kSecsColScIdx )) == DBL_MAX) // Returns DBL_MAX on error.
728 728
     flags += kInvalidScFl;
729 729
 
@@ -801,6 +801,96 @@ cmScRC_t _cmScParseNoteOn( cmSc_t* p, unsigned rowIdx, cmScoreEvt_t* s, unsigned
801 801
   return rc;
802 802
 }
803 803
 
804
+cmScRC_t _cmScParseMidiCtlMsg( cmSc_t* p, unsigned rowIdx, cmScoreEvt_t* s, unsigned scoreIdx, int barNumb, unsigned barNoteIdx, cmScoreEvt_t** pedalV, unsigned pedalN )
805
+{
806
+  cmScRC_t           rc              = kOkScRC;
807
+  unsigned           flags           = 0;
808
+  const cmChar_t*    attr;
809
+  double             secs            = DBL_MAX;
810
+  double             durSecs         = 0;
811
+  const unsigned     pedalBaseMidiId = 64;
812
+
813
+  s += scoreIdx;
814
+
815
+  // get the sec's field - or DBL_MAX if it is not set
816
+  if((secs =  cmCsvCellDouble(p->cH, rowIdx, kSecsColScIdx )) == DBL_MAX) // Returns DBL_MAX on error.
817
+    flags += kInvalidScFl;
818
+
819
+  // skip attribute
820
+  if((attr = cmCsvCellText(p->cH,rowIdx,kSkipColScIdx)) != NULL && *attr == 's' )
821
+    flags += kSkipScFl;
822
+
823
+  // get MIDI ctl msg data byte 1
824
+  unsigned d0 = cmCsvCellUInt( p->cH,rowIdx,kD0ColScIdx);
825
+
826
+  // get MIDI ctl msg data byte 2
827
+  unsigned d1 = cmCsvCellUInt( p->cH,rowIdx,kD1ColScIdx);
828
+
829
+  // if this is a pedal event
830
+  if( pedalBaseMidiId <= d0 && d0 < pedalBaseMidiId + pedalN )
831
+  {
832
+    bool     pedalDnFl = d1 >= 64;
833
+    unsigned pedalIdx  = d0 - pedalBaseMidiId;
834
+
835
+    // if this is a pedal-down message ...
836
+    if( pedalDnFl )
837
+    {
838
+      flags += kPedalDnScFl;
839
+
840
+      if( pedalV[pedalIdx] != NULL )
841
+        cmErrWarnMsg(&p->err,kPedalInvalidScRC,"The score contains multiple pedal down messages withouth an intervening pedal up message in or near bar %i.",barNumb );
842
+      else
843
+      {
844
+        // Don't store a pointer to a skipped pedal down msg because it will not
845
+        // not exist in p->array[] when the associated 'pedal-up' message is
846
+        // encountered. Note the the 'postProcFl' controlled section of
847
+        // _cmScParseFile() effectively eliminates cmScoreEvt_t records from
848
+        // p->array[] that are marked with kSkipScFl.
849
+        if( cmIsFlag(flags,kSkipScFl)  )
850
+          cmErrWarnMsg(&p->err,kPedalInvalidScRC,"A 'pedal-down' msg is marked to skip in or near bar %i this will probably produce a 'missing pedal-down' warning.",barNumb );
851
+        else
852
+          pedalV[pedalIdx] = s;  // ... store a pointer to the scEvt recd in pedalV[]
853
+      }
854
+      
855
+    }
856
+    else  // ... else this is a pedal-up msg ...
857
+    {
858
+      flags +=  kPedalUpScFl;
859
+      
860
+      if( pedalV[pedalIdx] == NULL )
861
+        cmErrWarnMsg(&p->err,kPedalInvalidScRC,"The score contains multiple pedal up messages withouth an intervening pedal down message in or near bar %i.",barNumb );
862
+      else // ... update the pedal down duration in the pedal-down message assoc'd w/ this pedal-up msg.
863
+      {
864
+        if( secs == DBL_MAX )
865
+          cmErrWarnMsg(&p->err,kPedalInvalidScRC,"A pedal-up message was encountered with an invalid time-stamp in or near bar %i the pedal down duration could therefore not be calculated.",barNumb);
866
+        else
867
+        {
868
+          // update the pedal down event record with the pedal down duration
869
+          pedalV[pedalIdx]->durSecs = secs - pedalV[pedalIdx]->secs;
870
+        }
871
+        
872
+
873
+        pedalV[pedalIdx] = NULL;
874
+      }
875
+      
876
+    }
877
+              
878
+  }
879
+
880
+  s->type       = kPedalEvtScId;
881
+  s->secs       = secs;
882
+  s->pitch      = d0;       // store the pedal type identifer in the pitch field
883
+  s->flags      = flags;
884
+  s->dynVal     = 0; 
885
+  s->barNumb    = barNumb;
886
+  s->barNoteIdx = barNoteIdx;
887
+  s->durSecs    = durSecs;
888
+  s->csvRowNumb = rowIdx+1;
889
+
890
+  return rc;
891
+}
892
+
893
+
804 894
 cmScRC_t _cmScParseSectionColumn( cmSc_t* p, unsigned rowIdx, unsigned evtIdx, cmScSect_t* sectList )
805 895
 {
806 896
   const cmCsvCell_t* cell;
@@ -1224,7 +1314,6 @@ cmScRC_t _cmScParseFile( cmSc_t* p, cmCtx_t* ctx, const cmChar_t* fn )
1224 1314
   double      secs;
1225 1315
   double      cur_secs   = 0;
1226 1316
 
1227
-  const unsigned pedalBaseMidiId = 64;
1228 1317
   const unsigned pedalN = 3;
1229 1318
   cmScoreEvt_t*  pedalV[] = { NULL,NULL,NULL };
1230 1319
 
@@ -1263,6 +1352,8 @@ cmScRC_t _cmScParseFile( cmSc_t* p, cmCtx_t* ctx, const cmChar_t* fn )
1263 1352
   // skip labels line - start on line 1
1264 1353
   for(i=1,j=0; i<p->cnt && rc==kOkScRC; ++i)
1265 1354
   {
1355
+    bool postProcFl = false;
1356
+
1266 1357
     // get the row 'type' label
1267 1358
     const char* typeLabel;
1268 1359
     if((typeLabel = cmCsvCellText(p->cH,i,kTypeLabelColScIdx)) == NULL )
@@ -1299,78 +1390,48 @@ cmScRC_t _cmScParseFile( cmSc_t* p, cmCtx_t* ctx, const cmChar_t* fn )
1299 1390
       case kNonEvtScId:  // parse note-on events
1300 1391
         if((rc =  _cmScParseNoteOn(p, i, p->array, j, barNumb, barNoteIdx )) == kOkScRC )
1301 1392
         {
1302
-          // this note was successfully parsed so time has advanced
1303
-          secs =  p->array[j].secs;
1304
-
1305
-          // if this note was not assigned time a time then set it
1306
-          if( p->array[j].secs == DBL_MAX )
1307
-          {
1308
-            p->array[j].secs = cur_secs;
1309
-            // note that 'secs' is now set to DBL_MAX so cur_secs will not be updated on this row iteration
1310
-          }
1311
-
1312
-          // if this note was marked to skip then don't advance j (and thereby
1313
-          // write over this scEvt with the next note). ...
1314
-          if( cmIsFlag(p->array[j].flags,kSkipScFl) == false )
1315
-          {
1316
-            p->array[j].index = j;   // ... otherwise advance j
1317
-            ++j;
1318
-          }
1319
-
1393
+          postProcFl = true;
1320 1394
           ++barNoteIdx;
1321 1395
         }
1322 1396
         break;
1323 1397
         
1324 1398
       case kCtlEvtScId:
1399
+        if((rc = _cmScParseMidiCtlMsg(p, i, p->array, j, barNumb, barNoteIdx, pedalV, pedalN )) == kOkScRC )
1325 1400
         {
1326
-          unsigned d0 = cmCsvCellUInt( p->cH,i,kD0ColScIdx);
1327
-          unsigned d1 = cmCsvCellUInt( p->cH,i,kD1ColScIdx);
1328
-
1329
-          // if this is a pedal event
1330
-          if( pedalBaseMidiId <= d0 && d0 < pedalBaseMidiId + pedalN )
1331
-          {
1332
-            bool     pedalDnFl = d1 >= 64;
1333
-            unsigned pedalIdx  = d0 - pedalBaseMidiId;
1334
-
1335
-            assert( pedalBaseMidiId <= d0 && pedalIdx < pedalN );
1336
-
1337
-            // store the pedal type identifer in the pitch field
1338
-            p->array[j].pitch = d0;
1339
-
1340
-            // if this is a pedal-down message ...
1341
-            if( pedalDnFl )
1342
-            {
1343
-              if( pedalV[pedalIdx] != NULL )
1344
-                cmErrWarnMsg(&p->err,kPedalInvalidScRC,"The score contains multiple pedal down messages withouth an intervening pedal up message in or near bar %i.",barNumb );
1345
-              else
1346
-                pedalV[pedalIdx] = p->array + j;  // ... store a pointer to the scEvt recd in pedalV[]
1347
-
1348
-              p->array[j].flags |= kPedalDnFl;
1349
-            }
1350
-            else  // ... else this is a pedal-up msg ...
1351
-            {
1352
-              p->array[j].flags |= kPedalUpFl;
1353
-
1354
-              if( pedalV[pedalIdx] == NULL )
1355
-                cmErrWarnMsg(&p->err,kPedalInvalidScRC,"The score contains multiple pedal up messages withouth an intervening pedal down message in or near bar %i.",barNumb );
1356
-              else // ... update the pedal down duration in the pedal-down message assoc'd w/ this pedal-up msg.
1357
-              {
1358
-                pedalV[pedalIdx]->durSecs = p->array[j].secs - pedalV[pedalIdx]->secs;
1359
-                pedalV[pedalIdx] = NULL;
1360
-              }
1361
-              
1362
-            }
1363
-
1364
-              
1365
-          }
1401
+          postProcFl = true;
1366 1402
         }
1367
-        // fall through
1403
+        break;
1368 1404
 
1369 1405
       default:
1370 1406
         // Returns DBL_MAX on error.
1371 1407
         secs =  cmCsvCellDouble(p->cH, i, kSecsColScIdx );
1372 1408
         break;
1373 1409
     }
1410
+
1411
+    if( postProcFl )
1412
+    {
1413
+      // update the 'secs' according to the parsed time
1414
+      secs =  p->array[j].secs;
1415
+
1416
+      // it is possible that the parsed time field was blank ...
1417
+      if( p->array[j].secs == DBL_MAX )
1418
+      {
1419
+        // ... so set the msg time to the last valid time
1420
+        p->array[j].secs = cur_secs;
1421
+        // note that 'secs' is now set to DBL_MAX so cur_secs will 
1422
+        // not be updated on this row iteration
1423
+      }
1424
+
1425
+      // if this msg was marked to skip then don't advance j (and thereby
1426
+      // write over this scEvt with the next note). ...
1427
+      if( cmIsFlag(p->array[j].flags,kSkipScFl) == false )
1428
+      {
1429
+        p->array[j].index = j;   // ... otherwise advance j
1430
+        ++j;
1431
+      }
1432
+
1433
+
1434
+    }
1374 1435
     
1375 1436
     if( rc == kOkScRC )
1376 1437
     {

+ 2
- 2
app/cmScore.h View File

@@ -45,8 +45,8 @@ extern "C" {
45 45
     kSkipScFl    = 0x008,        // This isn't a real event (e.g. tied note) skip over it
46 46
     kGraceScFl   = 0x010,        // This is a grace note
47 47
     kInvalidScFl = 0x020,        // This note has a calculated time
48
-    kPedalDnFl   = 0x040,        // This is a pedal down event (pitch holds the pedal id and durSecs holds the time the pedal will remain down.)
49
-    kPedalUpFl   = 0x080         // This is a pedal up event (pitch holds the pedal id)
48
+    kPedalDnScFl   = 0x040,        // This is a pedal down event (pitch holds the pedal id and durSecs holds the time the pedal will remain down.)
49
+    kPedalUpScFl   = 0x080         // This is a pedal up event (pitch holds the pedal id)
50 50
   };
51 51
 
52 52
 

Loading…
Cancel
Save