瀏覽代碼

cmMidiFile.c : Finished update to cmMidiFileCalcNoteDurations() to include sostenuto pedal state.

master
kevin 8 年之前
父節點
當前提交
74acab1539
共有 1 個文件被更改,包括 73 次插入35 次删除
  1. 73
    35
      cmMidiFile.c

+ 73
- 35
cmMidiFile.c 查看文件

@@ -1335,15 +1335,20 @@ void cmMidiFileCalcNoteDurations2( cmMidiFileH_t h )
1335 1335
   }
1336 1336
 }
1337 1337
 
1338
-bool _cmMidiFileCalcNoteDur( cmMidiTrackMsg_t* m0, cmMidiTrackMsg_t* m1, int noteGateFl, bool sustainGateFl, bool sostGateFl )
1338
+void _cmMidiFileSetDur( cmMidiTrackMsg_t* m0, cmMidiTrackMsg_t* m1 )
1339
+{
1340
+  // calculate the duration of the sounding note
1341
+  ((cmMidiChMsg_t*)m0->u.chMsgPtr)->durMicros = m1->amicro - m0->amicro;
1342
+}
1343
+
1344
+bool _cmMidiFileCalcNoteDur( cmMidiTrackMsg_t* m0, cmMidiTrackMsg_t* m1, int noteGateFl, int sustainGateFl, bool sostGateFl )
1339 1345
 {
1340 1346
   // if the note is being kept sounding because the key is still depressed,
1341 1347
   //    the sustain pedal is down or it is being held by the sostenuto pedal ....
1342
-  if( noteGateFl>0 || sustainGateFl || sostGateFl )
1348
+  if( noteGateFl>0 || sustainGateFl>0 || sostGateFl )
1343 1349
     return false;  // ... do nothing
1344 1350
 
1345
-  // calculate the duration of the sounding note
1346
-  ((cmMidiChMsg_t*)m0->u.chMsgPtr)->durMicros = m1->amicro - m0->amicro;
1351
+  _cmMidiFileSetDur(m0,m1);
1347 1352
   
1348 1353
   return true;
1349 1354
 }
@@ -1360,17 +1365,23 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
1360 1365
 
1361 1366
   unsigned          mi = cmInvalidId;
1362 1367
   cmMidiTrackMsg_t* noteM[     kMidiNoteCnt * kMidiChCnt ];  // ptr to note-on or NULL if the note is not sounding
1368
+  cmMidiTrackMsg_t* sustV[                    kMidiChCnt ];
1369
+  cmMidiTrackMsg_t* sostV[                    kMidiChCnt ];
1363 1370
   int               noteGateM[ kMidiNoteCnt * kMidiChCnt ];  // true if the associated note key is depressed
1364 1371
   bool              sostGateM[ kMidiNoteCnt * kMidiChCnt ];  // true if the associated note was active when the sost. pedal went down
1365
-  bool              sustV[kMidiChCnt];                       // true if the associated sustain pedal is down
1366
-  bool              sostV[kMidiChCnt];                       // true if the associated sostenuto pedal is down
1372
+  int               sustGateV[ kMidiChCnt];                  // true if the associated sustain pedal is down
1373
+  int               sostGateV[ kMidiChCnt];                  // true if the associated sostenuto pedal is down
1367 1374
   unsigned          i,j;
1368 1375
 
1369 1376
   // initialize the state tracking variables
1370 1377
   for(i=0; i<kMidiChCnt; ++i)
1371 1378
   {
1372
-    sustV[i] = false;
1373
-    sostV[i] = false;
1379
+    sustV[i]     = NULL;
1380
+    sustGateV[i] = 0;
1381
+    
1382
+    sostV[i]     = NULL;
1383
+    sostGateV[i] = 0;
1384
+    
1374 1385
     for(j=0; j<kMidiNoteCnt; ++j)
1375 1386
     {
1376 1387
       noteM[     i*kMidiNoteCnt + j ] = NULL;
@@ -1410,8 +1421,6 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
1410 1421
         noteM[k]     = m;
1411 1422
         noteGateM[k] = 1;
1412 1423
       }
1413
-        
1414
-      
1415 1424
     }
1416 1425
     else
1417 1426
       
@@ -1433,7 +1442,7 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
1433 1442
             noteGateM[k] -= 1; // update the note gate state
1434 1443
 
1435 1444
             // update the sounding note status
1436
-            if( _cmMidiFileCalcNoteDur(m0, m, noteGateM[k], sustV[ch], sostGateM[k]) )
1445
+            if( _cmMidiFileCalcNoteDur(m0, m, noteGateM[k], sustGateV[ch], sostGateM[k]) )
1437 1446
               noteM[k] = NULL;
1438 1447
           }
1439 1448
         }
@@ -1444,10 +1453,14 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
1444 1453
         if( cmMidiFileIsSustainPedalDown(m) )
1445 1454
         {
1446 1455
           // if the sustain channel is already down
1447
-          if( sustV[ch] )
1448
-            cmErrWarnMsg(&p->err,kSustainPedalMfRC,"%i : The sustain pedal went down twice with no intervening release.",m->uid);
1456
+          //if( sustGateV[ch] )
1457
+          //  cmErrWarnMsg(&p->err,kSustainPedalMfRC,"%i : The sustain pedal went down twice with no intervening release.",m->uid);
1449 1458
 
1450
-          sustV[ch] = true;          
1459
+          sustGateV[ch] += 1;
1460
+
1461
+          if( sustV[ch] == NULL )
1462
+            sustV[ch] = m;
1463
+          
1451 1464
         }
1452 1465
         else
1453 1466
 
@@ -1455,18 +1468,29 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
1455 1468
           if( cmMidiFileIsSustainPedalUp(m) )
1456 1469
           {
1457 1470
             // if the sustain channel is already up
1458
-            if( sustV[ch]==false )
1471
+            if( sustGateV[ch]==0 )
1459 1472
               cmErrWarnMsg(&p->err,kSustainPedalMfRC,"%i : The sustain pedal release message was received with no previous pedal down.",m->uid);
1460 1473
 
1461
-            sustV[ch] = false;
1474
+            if( sustGateV[ch] >= 1 )
1475
+            {
1476
+              sustGateV[ch] -= 1;
1462 1477
 
1463
-            unsigned k = ch*kMidiNoteCnt;
1464
-            
1465
-            // for each sounding note on this channel
1466
-            for(; k<ch*kMidiNoteCnt+kMidiNoteCnt; ++k)
1467
-              if( noteM[k]!=NULL && _cmMidiFileCalcNoteDur(noteM[k], m, noteGateM[k], sustV[ch], sostGateM[k]) )
1468
-                noteM[k] = NULL;
1478
+              if( sustGateV[ch] == 0 )
1479
+              {
1480
+                unsigned k = ch*kMidiNoteCnt;
1481
+                
1482
+                // for each sounding note on this channel
1483
+                for(; k<ch*kMidiNoteCnt+kMidiNoteCnt; ++k)
1484
+                  if( noteM[k]!=NULL && _cmMidiFileCalcNoteDur(noteM[k], m, noteGateM[k], sustGateV[ch], sostGateM[k]) )
1485
+                    noteM[k] = NULL;
1469 1486
 
1487
+                if( sustV[ch] != NULL )
1488
+                {
1489
+                  _cmMidiFileSetDur(sustV[ch],m);
1490
+                  sustV[ch] = NULL;
1491
+                }
1492
+              }
1493
+            }
1470 1494
           }
1471 1495
           else
1472 1496
 
@@ -1474,15 +1498,15 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
1474 1498
             if( cmMidiFileIsSostenutoPedalDown(m) )
1475 1499
             {
1476 1500
               // if the sustain channel is already down
1477
-              if( sostV[ch] )
1478
-                cmErrWarnMsg(&p->err,kSostenutoPedalMfRC,"%i : The sostenuto pedal went down twice with no intervening release.",m->uid);
1501
+              //if( sostGateV[ch] )
1502
+              //  cmErrWarnMsg(&p->err,kSostenutoPedalMfRC,"%i : The sostenuto pedal went down twice with no intervening release.",m->uid);
1479 1503
 
1480 1504
               // record the notes that are active when the sostenuto pedal went down
1481 1505
               unsigned k = ch * kMidiNoteCnt;
1482 1506
               for(i=0; i<kMidiNoteCnt; ++i)
1483 1507
                 sostGateM[k+i] = noteGateM[k+i] > 0;
1484 1508
               
1485
-              sostV[ch] = true;          
1509
+              sostGateV[ch] += 1;          
1486 1510
             }
1487 1511
             else
1488 1512
 
@@ -1490,19 +1514,33 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
1490 1514
               if( cmMidiFileIsSostenutoPedalUp(m) )
1491 1515
               {
1492 1516
                 // if the sustain channel is already up
1493
-                if( sostV[ch]==false )
1517
+                if( sostGateV[ch]==0 )
1494 1518
                   cmErrWarnMsg(&p->err,kSostenutoPedalMfRC,"%i : The sostenuto pedal release message was received with no previous pedal down.",m->uid);
1495 1519
 
1496
-                sostV[ch] = false;
1497
-
1498
-                // for each note on this channel
1499
-                unsigned k = ch*kMidiNoteCnt;
1500
-                
1501
-                for(; k<ch*kMidiNoteCnt+kMidiNoteCnt; ++k)
1520
+                if( sostGateV[ch] >= 1 )
1502 1521
                 {
1503
-                  sostGateM[k] = false;
1504
-                  if( noteM[k]!=NULL && _cmMidiFileCalcNoteDur(noteM[k], m, noteGateM[k], sustV[ch], sostGateM[k]) )
1505
-                    noteM[k] = NULL;
1522
+                  sostGateV[ch] -= 1;
1523
+
1524
+                  if( sostGateV[ch] == 0 )
1525
+                  {
1526
+                    unsigned k = ch*kMidiNoteCnt;
1527
+                    
1528
+                    // for each note on this channel
1529
+                    for(; k<ch*kMidiNoteCnt+kMidiNoteCnt; ++k)
1530
+                    {
1531
+                      sostGateM[k] = false;
1532
+                      
1533
+                      if( noteM[k]!=NULL && _cmMidiFileCalcNoteDur(noteM[k], m, noteGateM[k], sustGateV[ch], sostGateM[k]) )
1534
+                        noteM[k] = NULL;
1535
+                    }
1536
+                    
1537
+                    if( sostV[ch] != NULL )
1538
+                    {
1539
+                      _cmMidiFileSetDur(sostV[ch],m);
1540
+                      sostV[ch] = NULL;
1541
+                    }
1542
+
1543
+                  }
1506 1544
                 }
1507 1545
               }
1508 1546
     

Loading…
取消
儲存