Explorar el Código

cmMIdiFile.c : Fixes to support re-triggering MIDI notes.

master
kevin hace 8 años
padre
commit
a5056e4cec
Se han modificado 1 ficheros con 32 adiciones y 29 borrados
  1. 32
    29
      cmMidiFile.c

+ 32
- 29
cmMidiFile.c Ver fichero

11
 #include "cmMidi.h"
11
 #include "cmMidi.h"
12
 #include "cmMidiFile.h"
12
 #include "cmMidiFile.h"
13
 
13
 
14
-#include "cmFloatTypes.h"
15
-#include "cmVectOps.h"
16
-
17
 #ifdef cmBIG_ENDIAN
14
 #ifdef cmBIG_ENDIAN
18
 #define mfSwap16(v)  (v)
15
 #define mfSwap16(v)  (v)
19
 #define mfSwap32(v)  (v)
16
 #define mfSwap32(v)  (v)
1338
   }
1335
   }
1339
 }
1336
 }
1340
 
1337
 
1341
-bool _cmMidiFileCalcNoteDur( cmMidiTrackMsg_t* m0, cmMidiTrackMsg_t* m1, bool noteGateFl, bool sustainGateFl, bool sostGateFl )
1338
+bool _cmMidiFileCalcNoteDur( cmMidiTrackMsg_t* m0, cmMidiTrackMsg_t* m1, int noteGateFl, bool sustainGateFl, bool sostGateFl )
1342
 {
1339
 {
1343
   // if the note is being kept sounding because the key is still depressed,
1340
   // if the note is being kept sounding because the key is still depressed,
1344
   //    the sustain pedal is down or it is being held by the sostenuto pedal ....
1341
   //    the sustain pedal is down or it is being held by the sostenuto pedal ....
1345
-  if( noteGateFl || sustainGateFl || sostGateFl )
1342
+  if( noteGateFl>0 || sustainGateFl || sostGateFl )
1346
     return false;  // ... do nothing
1343
     return false;  // ... do nothing
1347
 
1344
 
1348
   // calculate the duration of the sounding note
1345
   // calculate the duration of the sounding note
1363
 
1360
 
1364
   unsigned          mi = cmInvalidId;
1361
   unsigned          mi = cmInvalidId;
1365
   cmMidiTrackMsg_t* noteM[     kMidiNoteCnt * kMidiChCnt ];  // ptr to note-on or NULL if the note is not sounding
1362
   cmMidiTrackMsg_t* noteM[     kMidiNoteCnt * kMidiChCnt ];  // ptr to note-on or NULL if the note is not sounding
1366
-  bool              noteGateM[ kMidiNoteCnt * kMidiChCnt ];  // true if the associated note key is depressed
1363
+  int               noteGateM[ kMidiNoteCnt * kMidiChCnt ];  // true if the associated note key is depressed
1367
   bool              sostGateM[ kMidiNoteCnt * kMidiChCnt ];  // true if the associated note was active when the sost. pedal went down
1364
   bool              sostGateM[ kMidiNoteCnt * kMidiChCnt ];  // true if the associated note was active when the sost. pedal went down
1368
   bool              sustV[kMidiChCnt];                       // true if the associated sustain pedal is down
1365
   bool              sustV[kMidiChCnt];                       // true if the associated sustain pedal is down
1369
   bool              sostV[kMidiChCnt];                       // true if the associated sostenuto pedal is down
1366
   bool              sostV[kMidiChCnt];                       // true if the associated sostenuto pedal is down
1377
     for(j=0; j<kMidiNoteCnt; ++j)
1374
     for(j=0; j<kMidiNoteCnt; ++j)
1378
     {
1375
     {
1379
       noteM[     i*kMidiNoteCnt + j ] = NULL;
1376
       noteM[     i*kMidiNoteCnt + j ] = NULL;
1380
-      noteGateM[ i*kMidiNoteCnt + j ] = false;
1377
+      noteGateM[ i*kMidiNoteCnt + j ] = 0;
1381
       sostGateM[ i*kMidiNoteCnt + j ] = false;
1378
       sostGateM[ i*kMidiNoteCnt + j ] = false;
1382
     }
1379
     }
1383
   }
1380
   }
1401
     if( cmMidiFileIsNoteOn(m) )
1398
     if( cmMidiFileIsNoteOn(m) )
1402
     {
1399
     {
1403
       unsigned  k = ch*kMidiNoteCnt + d0;
1400
       unsigned  k = ch*kMidiNoteCnt + d0;
1404
-      
1405
-      // a key was pressed - so it should not be currently down
1406
-      if( noteGateM[k] )
1407
-        cmErrWarnMsg(&p->err,kMissingNoteOffMfRC,"Missing note-off for note-on:%s",cmMidiToSciPitch(d0,NULL,0));
1408
 
1401
 
1409
       // there should be no existing sounding note instance for this pitch
1402
       // there should be no existing sounding note instance for this pitch
1410
-      if( noteM[k] != NULL )
1411
-        cmErrWarnMsg(&p->err,kMissingNoteOffMfRC,"Missing note-off instance for note on:%s",cmMidiToSciPitch(d0,NULL,0));
1403
+      //if( noteGateM[k] == 0 && noteM[k] != NULL )
1404
+      //  cmErrWarnMsg(&p->err,kMissingNoteOffMfRC,"%i : Missing note-off instance for note on:%s",m->uid,cmMidiToSciPitch(d0,NULL,0));
1412
 
1405
 
1413
-      noteM[k]     = m;
1414
-      noteGateM[k] = true;
1406
+      if( noteM[k] != NULL )
1407
+        noteGateM[k] += 1;
1408
+      else
1409
+      {
1410
+        noteM[k]     = m;
1411
+        noteGateM[k] = 1;
1412
+      }
1413
+        
1414
+      
1415
     }
1415
     }
1416
     else
1416
     else
1417
       
1417
       
1422
         cmMidiTrackMsg_t*  m0 = noteM[k];
1422
         cmMidiTrackMsg_t*  m0 = noteM[k];
1423
 
1423
 
1424
         if( m0 == NULL )
1424
         if( m0 == NULL )
1425
-          cmErrWarnMsg(&p->err,kMissingNoteOffMfRC,"Missing note-on instance for note-off:%s",cmMidiToSciPitch(d0,NULL,0));
1425
+          cmErrWarnMsg(&p->err,kMissingNoteOffMfRC,"%i : Missing note-on instance for note-off:%s",m->uid,cmMidiToSciPitch(d0,NULL,0));
1426
         else
1426
         else
1427
         {
1427
         {
1428
           // a key was released - so it should not already be up
1428
           // a key was released - so it should not already be up
1429
-          if( noteGateM[k]==false )
1430
-            cmErrWarnMsg(&p->err,kMissingNoteOffMfRC,"Missing note-on for note-off:%s",cmMidiToSciPitch(d0,NULL,0));
1431
-
1432
-          noteGateM[k] = false; // update the note gate state
1429
+          if( noteGateM[k]==0 )
1430
+            cmErrWarnMsg(&p->err,kMissingNoteOffMfRC,"%i : Missing note-on for note-off:%s",m->uid,cmMidiToSciPitch(d0,NULL,0));
1431
+          else
1432
+          {
1433
+            noteGateM[k] -= 1; // update the note gate state
1433
 
1434
 
1434
-          // update the sounding note status
1435
-          if( _cmMidiFileCalcNoteDur(m0, m, noteGateM[k], sustV[ch], sostGateM[k]) )
1436
-            noteM[k] = NULL;
1435
+            // update the sounding note status
1436
+            if( _cmMidiFileCalcNoteDur(m0, m, noteGateM[k], sustV[ch], sostGateM[k]) )
1437
+              noteM[k] = NULL;
1438
+          }
1437
         }
1439
         }
1438
       }
1440
       }
1439
       else
1441
       else
1443
         {
1445
         {
1444
           // if the sustain channel is already down
1446
           // if the sustain channel is already down
1445
           if( sustV[ch] )
1447
           if( sustV[ch] )
1446
-            cmErrWarnMsg(&p->err,kSustainPedalMfRC,"The sustain pedal went down twice with no intervening release.");
1448
+            cmErrWarnMsg(&p->err,kSustainPedalMfRC,"%i : The sustain pedal went down twice with no intervening release.",m->uid);
1447
 
1449
 
1448
           sustV[ch] = true;          
1450
           sustV[ch] = true;          
1449
         }
1451
         }
1454
           {
1456
           {
1455
             // if the sustain channel is already up
1457
             // if the sustain channel is already up
1456
             if( sustV[ch]==false )
1458
             if( sustV[ch]==false )
1457
-              cmErrWarnMsg(&p->err,kSustainPedalMfRC,"The sustain pedal release message was received with no previous pedal down.");
1459
+              cmErrWarnMsg(&p->err,kSustainPedalMfRC,"%i : The sustain pedal release message was received with no previous pedal down.",m->uid);
1458
 
1460
 
1459
             sustV[ch] = false;
1461
             sustV[ch] = false;
1460
 
1462
 
1473
             {
1475
             {
1474
               // if the sustain channel is already down
1476
               // if the sustain channel is already down
1475
               if( sostV[ch] )
1477
               if( sostV[ch] )
1476
-                cmErrWarnMsg(&p->err,kSostenutoPedalMfRC,"The sostenuto pedal went down twice with no intervening release.");
1478
+                cmErrWarnMsg(&p->err,kSostenutoPedalMfRC,"%i : The sostenuto pedal went down twice with no intervening release.",m->uid);
1477
 
1479
 
1478
               // record the notes that are active when the sostenuto pedal went down
1480
               // record the notes that are active when the sostenuto pedal went down
1479
               unsigned k = ch * kMidiNoteCnt;
1481
               unsigned k = ch * kMidiNoteCnt;
1480
-              cmVOB_Copy( sostGateM + k, kMidiNoteCnt, noteGateM + k);
1482
+              for(i=0; i<kMidiNoteCnt; ++i)
1483
+                sostGateM[k+i] = noteGateM[k+i] > 0;
1481
               
1484
               
1482
               sostV[ch] = true;          
1485
               sostV[ch] = true;          
1483
             }
1486
             }
1488
               {
1491
               {
1489
                 // if the sustain channel is already up
1492
                 // if the sustain channel is already up
1490
                 if( sostV[ch]==false )
1493
                 if( sostV[ch]==false )
1491
-                  cmErrWarnMsg(&p->err,kSostenutoPedalMfRC,"The sostenuto pedal release message was received with no previous pedal down.");
1494
+                  cmErrWarnMsg(&p->err,kSostenutoPedalMfRC,"%i : The sostenuto pedal release message was received with no previous pedal down.",m->uid);
1492
 
1495
 
1493
                 sostV[ch] = false;
1496
                 sostV[ch] = false;
1494
 
1497
 
1721
     return;
1724
     return;
1722
   }
1725
   }
1723
 
1726
 
1724
-  //cmMidiFileCalcNoteDurations(  h );
1727
+  cmMidiFileCalcNoteDurations(  h );
1725
 
1728
 
1726
   if( 1 )
1729
   if( 1 )
1727
   {
1730
   {

Loading…
Cancelar
Guardar