|
@@ -1335,6 +1335,132 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
|
1335
|
1335
|
}
|
1336
|
1336
|
}
|
1337
|
1337
|
|
|
1338
|
+void cmMidiFileCalcNoteDurations2( cmMidiFileH_t h )
|
|
1339
|
+{
|
|
1340
|
+ _cmMidiFile_t* p;
|
|
1341
|
+
|
|
1342
|
+ if((p = _cmMidiFileHandleToPtr(h)) == NULL )
|
|
1343
|
+ return;
|
|
1344
|
+
|
|
1345
|
+ if( p->msgN == 0 )
|
|
1346
|
+ return;
|
|
1347
|
+
|
|
1348
|
+ unsigned mi = cmInvalidId;
|
|
1349
|
+ cmMidiTrackMsg_t* noteM[ kMidiNoteCnt * kMidiChCnt ]; // ptr to note-on or NULL if the note is not sounding
|
|
1350
|
+ bool noteGateM[ kMidiNoteCnt * kMidiChCnt ]; // true if the associated note key is depressed
|
|
1351
|
+ bool sustV[kMidiChCnt]; //
|
|
1352
|
+ bool sostV[kMidiChCnt]; //
|
|
1353
|
+ unsigned i,j;
|
|
1354
|
+
|
|
1355
|
+ for(i=0; i<kMidiChCnt; ++i)
|
|
1356
|
+ {
|
|
1357
|
+ sustV[i] = false;
|
|
1358
|
+ sostV[i] = false;
|
|
1359
|
+ for(j=0; j<kMidiNoteCnt; ++j)
|
|
1360
|
+ {
|
|
1361
|
+ noteM[ i*kMidiNoteCnt + j ] = NULL;
|
|
1362
|
+ noteGateM[ i*kMidiNoteCnt + j ] = false;
|
|
1363
|
+ }
|
|
1364
|
+ }
|
|
1365
|
+
|
|
1366
|
+ for(mi=0; mi<p->msgN; ++mi)
|
|
1367
|
+ {
|
|
1368
|
+ cmMidiTrackMsg_t* m = p->msgV[mi];
|
|
1369
|
+
|
|
1370
|
+ assert( mi==0 || (mi>0 && m->amicro >= p->msgV[mi-1]->amicro) );
|
|
1371
|
+
|
|
1372
|
+ // ignore all non-channel messages
|
|
1373
|
+ if( !cmMidiIsChStatus( m->status ) )
|
|
1374
|
+ continue;
|
|
1375
|
+
|
|
1376
|
+ cmMidiByte_t ch = m->u.chMsgPtr->ch;
|
|
1377
|
+ cmMidiByte_t d0 = m->u.chMsgPtr->d0;
|
|
1378
|
+ cmMidiByte_t d1 = m->u.chMsgPtr->d1;
|
|
1379
|
+
|
|
1380
|
+ if( cmMidiFileIsNoteOn(m) )
|
|
1381
|
+ {
|
|
1382
|
+ unsigned k = ch*kMidiNoteCnt + d0;
|
|
1383
|
+ cmMidiTrackMsg_t* m0 = noteM[k];
|
|
1384
|
+
|
|
1385
|
+ // a key was pressed - so it should not be currently down
|
|
1386
|
+ if( noteGateM[k] )
|
|
1387
|
+ {
|
|
1388
|
+ assert( m0 != NULL );
|
|
1389
|
+ cmErrWarnMsg(&p->err,kMissingNoteOffMfRC,"Missing note-off for note-on:%s",cmMidiToSciPitch(d0,NULL,0));
|
|
1390
|
+ }
|
|
1391
|
+
|
|
1392
|
+ noteM[k] = m;
|
|
1393
|
+ noteGateM[k] = true;
|
|
1394
|
+ }
|
|
1395
|
+ else
|
|
1396
|
+ if( cmMidiFileIsNoteOff(m) )
|
|
1397
|
+ {
|
|
1398
|
+ unsigned k = ch*kMidiNoteCnt + d0;
|
|
1399
|
+ cmMidiTrackMsg_t* m0 = noteM[k];
|
|
1400
|
+
|
|
1401
|
+ // a key was released - so it should not be currently up
|
|
1402
|
+ if( noteGateM[k]==false )
|
|
1403
|
+ {
|
|
1404
|
+ assert( m0 != NULL );
|
|
1405
|
+ cmErrWarnMsg(&p->err,kMissingNoteOffMfRC,"Missing note-on for note-off:%s",cmMidiToSciPitch(d0,NULL,0));
|
|
1406
|
+ }
|
|
1407
|
+
|
|
1408
|
+ // FIX: release note here - if pedal is not down
|
|
1409
|
+
|
|
1410
|
+ noteM[k] = NULL;
|
|
1411
|
+ noteGateM[k] = false;
|
|
1412
|
+ }
|
|
1413
|
+ else
|
|
1414
|
+ if( cmMidiFileIsSustainPedalDown(m) )
|
|
1415
|
+ {
|
|
1416
|
+ // if the sustain channel is already down
|
|
1417
|
+ if( sustV[ch] )
|
|
1418
|
+ {
|
|
1419
|
+ cmErrWarnMsg(&p->err,kSustainPedalMfRC,"The sustain pedal went down twice with no intervening release.");
|
|
1420
|
+ }
|
|
1421
|
+
|
|
1422
|
+ sustV[ch] = true;
|
|
1423
|
+ }
|
|
1424
|
+ else
|
|
1425
|
+ if( cmMidiFileIsSutainPedalUp(m) )
|
|
1426
|
+ {
|
|
1427
|
+ // if the sustain channel is already up
|
|
1428
|
+ if( sustV[ch]==false )
|
|
1429
|
+ {
|
|
1430
|
+ cmErrWarnMsg(&p->err,kSustainPedalMfRC,"The sustain pedal release message was received with no previous pedal down.");
|
|
1431
|
+ }
|
|
1432
|
+
|
|
1433
|
+ // FIX: release sustaining notes here
|
|
1434
|
+ sustV[ch] = false;
|
|
1435
|
+ }
|
|
1436
|
+ else
|
|
1437
|
+ if( cmMidiFileIsSostenutoPedalDown(m) )
|
|
1438
|
+ {
|
|
1439
|
+ // if the sustain channel is already down
|
|
1440
|
+ if( sostV[ch] )
|
|
1441
|
+ {
|
|
1442
|
+ cmErrWarnMsg(&p->err,kSostenutoPedalMfRC,"The sostenuto pedal went down twice with no intervening release.");
|
|
1443
|
+ }
|
|
1444
|
+
|
|
1445
|
+ sostV[ch] = true;
|
|
1446
|
+ }
|
|
1447
|
+ else
|
|
1448
|
+ if( cmMidiFileIsSostenutoPedalUp(m) )
|
|
1449
|
+ {
|
|
1450
|
+ // if the sustain channel is already up
|
|
1451
|
+ if( sostV[ch]==false )
|
|
1452
|
+ {
|
|
1453
|
+ cmErrWarnMsg(&p->err,kSostenutoPedalMfRC,"The sostenuto pedal release message was received with no previous pedal down.");
|
|
1454
|
+ }
|
|
1455
|
+
|
|
1456
|
+ // FIX: release sostenuto notes here
|
|
1457
|
+ sostV[ch] = false;
|
|
1458
|
+
|
|
1459
|
+ }
|
|
1460
|
+
|
|
1461
|
+
|
|
1462
|
+ }
|
|
1463
|
+}
|
1338
|
1464
|
|
1339
|
1465
|
void cmMidiFileSetDelay( cmMidiFileH_t h, unsigned ticks )
|
1340
|
1466
|
{
|