Browse Source

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

master
kevin 8 years ago
parent
commit
74acab1539
1 changed files with 73 additions and 35 deletions
  1. 73
    35
      cmMidiFile.c

+ 73
- 35
cmMidiFile.c View File

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
   // if the note is being kept sounding because the key is still depressed,
1346
   // if the note is being kept sounding because the key is still depressed,
1341
   //    the sustain pedal is down or it is being held by the sostenuto pedal ....
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
     return false;  // ... do nothing
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
   return true;
1353
   return true;
1349
 }
1354
 }
1360
 
1365
 
1361
   unsigned          mi = cmInvalidId;
1366
   unsigned          mi = cmInvalidId;
1362
   cmMidiTrackMsg_t* noteM[     kMidiNoteCnt * kMidiChCnt ];  // ptr to note-on or NULL if the note is not sounding
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
   int               noteGateM[ kMidiNoteCnt * kMidiChCnt ];  // true if the associated note key is depressed
1370
   int               noteGateM[ kMidiNoteCnt * kMidiChCnt ];  // true if the associated note key is depressed
1364
   bool              sostGateM[ kMidiNoteCnt * kMidiChCnt ];  // true if the associated note was active when the sost. pedal went down
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
   unsigned          i,j;
1374
   unsigned          i,j;
1368
 
1375
 
1369
   // initialize the state tracking variables
1376
   // initialize the state tracking variables
1370
   for(i=0; i<kMidiChCnt; ++i)
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
     for(j=0; j<kMidiNoteCnt; ++j)
1385
     for(j=0; j<kMidiNoteCnt; ++j)
1375
     {
1386
     {
1376
       noteM[     i*kMidiNoteCnt + j ] = NULL;
1387
       noteM[     i*kMidiNoteCnt + j ] = NULL;
1410
         noteM[k]     = m;
1421
         noteM[k]     = m;
1411
         noteGateM[k] = 1;
1422
         noteGateM[k] = 1;
1412
       }
1423
       }
1413
-        
1414
-      
1415
     }
1424
     }
1416
     else
1425
     else
1417
       
1426
       
1433
             noteGateM[k] -= 1; // update the note gate state
1442
             noteGateM[k] -= 1; // update the note gate state
1434
 
1443
 
1435
             // update the sounding note status
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
               noteM[k] = NULL;
1446
               noteM[k] = NULL;
1438
           }
1447
           }
1439
         }
1448
         }
1444
         if( cmMidiFileIsSustainPedalDown(m) )
1453
         if( cmMidiFileIsSustainPedalDown(m) )
1445
         {
1454
         {
1446
           // if the sustain channel is already down
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
         else
1465
         else
1453
 
1466
 
1455
           if( cmMidiFileIsSustainPedalUp(m) )
1468
           if( cmMidiFileIsSustainPedalUp(m) )
1456
           {
1469
           {
1457
             // if the sustain channel is already up
1470
             // if the sustain channel is already up
1458
-            if( sustV[ch]==false )
1471
+            if( sustGateV[ch]==0 )
1459
               cmErrWarnMsg(&p->err,kSustainPedalMfRC,"%i : The sustain pedal release message was received with no previous pedal down.",m->uid);
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
           else
1495
           else
1472
 
1496
 
1474
             if( cmMidiFileIsSostenutoPedalDown(m) )
1498
             if( cmMidiFileIsSostenutoPedalDown(m) )
1475
             {
1499
             {
1476
               // if the sustain channel is already down
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
               // record the notes that are active when the sostenuto pedal went down
1504
               // record the notes that are active when the sostenuto pedal went down
1481
               unsigned k = ch * kMidiNoteCnt;
1505
               unsigned k = ch * kMidiNoteCnt;
1482
               for(i=0; i<kMidiNoteCnt; ++i)
1506
               for(i=0; i<kMidiNoteCnt; ++i)
1483
                 sostGateM[k+i] = noteGateM[k+i] > 0;
1507
                 sostGateM[k+i] = noteGateM[k+i] > 0;
1484
               
1508
               
1485
-              sostV[ch] = true;          
1509
+              sostGateV[ch] += 1;          
1486
             }
1510
             }
1487
             else
1511
             else
1488
 
1512
 
1490
               if( cmMidiFileIsSostenutoPedalUp(m) )
1514
               if( cmMidiFileIsSostenutoPedalUp(m) )
1491
               {
1515
               {
1492
                 // if the sustain channel is already up
1516
                 // if the sustain channel is already up
1493
-                if( sostV[ch]==false )
1517
+                if( sostGateV[ch]==0 )
1494
                   cmErrWarnMsg(&p->err,kSostenutoPedalMfRC,"%i : The sostenuto pedal release message was received with no previous pedal down.",m->uid);
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…
Cancel
Save