Browse Source

cmScore.h/c : The durSecs's cmScEvt_t field of pedal down events now contains

the length of time the pedal is held down and the 'pitch' field is set
to the MIDI id of the pedal.
master
Kevin Larke 9 years ago
parent
commit
9e11eb49b8
2 changed files with 70 additions and 6 deletions
  1. 62
    2
      app/cmScore.c
  2. 8
    4
      app/cmScore.h

+ 62
- 2
app/cmScore.c View File

@@ -35,6 +35,8 @@ enum
35 35
   kTypeLabelColScIdx = 3,
36 36
   kDSecsColScIdx     = 4,
37 37
   kSecsColScIdx      = 5,
38
+  kD0ColScIdx        = 9,
39
+  kD1ColScIdx        = 10,
38 40
   kPitchColScIdx     = 11,
39 41
   kBarColScIdx       = 13,
40 42
   kSkipColScIdx      = 14,
@@ -1222,6 +1224,10 @@ cmScRC_t _cmScParseFile( cmSc_t* p, cmCtx_t* ctx, const cmChar_t* fn )
1222 1224
   double      secs;
1223 1225
   double      cur_secs   = 0;
1224 1226
 
1227
+  const unsigned pedalBaseMidiId = 64;
1228
+  const unsigned pedalN = 3;
1229
+  cmScoreEvt_t*  pedalV[] = { NULL,NULL,NULL };
1230
+
1225 1231
   p->sectList = cmMemAllocZ(cmScSect_t,1); // section zero
1226 1232
   
1227 1233
   //_cmScNewSet(p); // preallocate the first set
@@ -1293,20 +1299,72 @@ cmScRC_t _cmScParseFile( cmSc_t* p, cmCtx_t* ctx, const cmChar_t* fn )
1293 1299
       case kNonEvtScId:  // parse note-on events
1294 1300
         if((rc =  _cmScParseNoteOn(p, i, p->array, j, barNumb, barNoteIdx )) == kOkScRC )
1295 1301
         {
1302
+          // this note was successfully parsed so time has advanced
1296 1303
           secs =  p->array[j].secs;
1297 1304
 
1305
+          // if this note was not assigned time a time then set it
1298 1306
           if( p->array[j].secs == DBL_MAX )
1307
+          {
1299 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
+          }
1300 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). ...
1301 1314
           if( cmIsFlag(p->array[j].flags,kSkipScFl) == false )
1302 1315
           {
1303
-            p->array[j].index = j;
1316
+            p->array[j].index = j;   // ... otherwise advance j
1304 1317
             ++j;
1305 1318
           }
1306 1319
 
1307 1320
           ++barNoteIdx;
1308 1321
         }
1309 1322
         break;
1323
+        
1324
+      case kCtlEvtScId:
1325
+        {
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 <= pedalIdx && 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
+          }
1366
+        }
1367
+        // fall through
1310 1368
 
1311 1369
       default:
1312 1370
         // Returns DBL_MAX on error.
@@ -1316,6 +1374,7 @@ cmScRC_t _cmScParseFile( cmSc_t* p, cmCtx_t* ctx, const cmChar_t* fn )
1316 1374
     
1317 1375
     if( rc == kOkScRC )
1318 1376
     {
1377
+      // if sec's is valid then update cur_secs
1319 1378
       if( secs != DBL_MAX )
1320 1379
         cur_secs = secs;
1321 1380
 
@@ -1423,7 +1482,6 @@ cmScRC_t _cmScInitLocArray( cmSc_t* p )
1423 1482
   return rc;
1424 1483
 }
1425 1484
 
1426
-
1427 1485
 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, cmSymTblH_t stH )
1428 1486
 {
1429 1487
   cmScRC_t rc = kOkScRC;
@@ -2589,3 +2647,5 @@ void cmScoreFix( cmCtx_t* ctx )
2589 2647
   cmCsvFinalize(&csvH);
2590 2648
 
2591 2649
 }
2650
+
2651
+

+ 8
- 4
app/cmScore.h View File

@@ -13,7 +13,8 @@ extern "C" {
13 13
     kInvalidIdxScRC,
14 14
     kTimeLineFailScRC,
15 15
     kInvalidDynRefCntScRC,
16
-    kMidiFileFailScRC
16
+    kMidiFileFailScRC,
17
+    kPedalInvalidScRC
17 18
   };
18 19
 
19 20
   enum
@@ -31,7 +32,8 @@ extern "C" {
31 32
     kBarEvtScId,
32 33
     kPgmEvtScId,
33 34
     kCtlEvtScId,
34
-    kNonEvtScId
35
+    kNonEvtScId,
36
+    kPedalEvtScId
35 37
   };
36 38
 
37 39
   // Flags used by cmScoreEvt_t.flags
@@ -42,7 +44,9 @@ extern "C" {
42 44
     kTempoScFl   = 0x004,        // This note is marked for tempo measurement
43 45
     kSkipScFl    = 0x008,        // This isn't a real event (e.g. tied note) skip over it
44 46
     kGraceScFl   = 0x010,        // This is a grace note
45
-    kInvalidScFl = 0x020         // This note has a calculated time
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)
46 50
   };
47 51
 
48 52
 
@@ -79,7 +83,7 @@ extern "C" {
79 83
     double       durSecs;      // Duration in seconds
80 84
     unsigned     index;        // Index of this event in the event array.
81 85
     unsigned     locIdx;       // Index of the location containing this event
82
-    cmMidiByte_t pitch;        // MIDI pitch of this note
86
+    cmMidiByte_t pitch;        // MIDI pitch of this note or the MIDI pedal id of pedal down/up msg (64=sustain 65=sostenuto 66=soft)
83 87
     unsigned     flags;        // Attribute flags for this event
84 88
     unsigned     dynVal;       // Dynamcis value pppp to ffff (1 to 11) for this note.
85 89
     double       frac;         // Note's time value for tempo and non-grace evenness notes.

Loading…
Cancel
Save