|
@@ -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
|
{
|