Przeglądaj źródła

cmMidiFile.h/c : Added 'end' field to cmMidiChMsg_t and setting code. Not yet tested.

master
kevin 8 lat temu
rodzic
commit
2b01371684
2 zmienionych plików z 12 dodań i 176 usunięć
  1. 9
    176
      cmMidiFile.c
  2. 3
    0
      cmMidiFile.h

+ 9
- 176
cmMidiFile.c Wyświetl plik

894
 
894
 
895
     case kMidiChMdId: 
895
     case kMidiChMdId: 
896
         if((rc = _cmMidiFileWrite8(mfp,sizeof(tmp->u.bVal))) == kOkMfRC )
896
         if((rc = _cmMidiFileWrite8(mfp,sizeof(tmp->u.bVal))) == kOkMfRC )
897
-          rc                                                  = _cmMidiFileWrite8(mfp,tmp->u.bVal);
897
+          rc  = _cmMidiFileWrite8(mfp,tmp->u.bVal);
898
         break;
898
         break;
899
 
899
 
900
     case kEndOfTrkMdId:  
900
     case kEndOfTrkMdId:  
1304
 } _cmMidiVoice_t;
1304
 } _cmMidiVoice_t;
1305
 
1305
 
1306
 
1306
 
1307
-void _cmMidFileCalcNoteDurationReleaseNote( _cmMidiVoice_t** listPtrPtr, _cmMidiVoice_t* pp, _cmMidiVoice_t* vp )
1308
-{
1309
-  assert( (pp==NULL && vp==*listPtrPtr) || pp->link==vp);
1310
-
1311
-  // store the duration of the note into the track msg 
1312
-  // assoc'd with the note-on msg
1313
-  cmMidiChMsg_t* cmp = (cmMidiChMsg_t*)vp->mp->u.chMsgPtr; // cast away const
1314
-  cmp->durMicros = vp->durMicros;
1315
-
1316
-  _cmMidiVoice_t* np = vp->link;
1317
-
1318
-  // release the voice msg
1319
-  cmMemFree(vp);
1320
-
1321
-  // unlink the active voice msg
1322
-  if( pp == NULL )
1323
-    *listPtrPtr = np;
1324
-  else
1325
-    pp->link = np;
1326
-  
1327
-}
1328
-
1329
-void  _cmMidiFileCalcNoteDurationsAllocVoice( _cmMidiVoice_t** listPtrPtr, cmMidiTrackMsg_t* mp, bool sustainFl )
1330
-{
1331
-  _cmMidiVoice_t* vp = cmMemAllocZ(_cmMidiVoice_t,1);
1332
-  vp->mp        = mp;
1333
-  vp->sustainFl = sustainFl;
1334
-  vp->link      = *listPtrPtr;
1335
-  *listPtrPtr   = vp;
1336
-}
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
-  _cmMidiVoice_t*   list                = NULL; // list of active voices
1350
-  _cmMidiVoice_t*   vp                  = NULL;
1351
-  cmMidiTrackMsg_t* sustainPedalDownMsg = NULL;
1352
-  bool              sustainFlagV[ kMidiChCnt ];
1353
-
1354
-  // clear the sustain pedal flag
1355
-  for(mi=0; mi<kMidiChCnt; ++mi)
1356
-    sustainFlagV[mi]=false;
1357
-
1358
-  for(mi=0; mi<p->msgN; ++mi)
1359
-  {
1360
-    cmMidiTrackMsg_t* mp    = p->msgV[mi];
1361
-
1362
-    unsigned d_amicro = 0;
1363
-    if( mi > 0 )
1364
-    {
1365
-      assert(    mp->amicro >= p->msgV[mi-1]->amicro );
1366
-      d_amicro = mp->amicro -  p->msgV[mi-1]->amicro;
1367
-    }
1368
-    
1369
-    // update the duration of the sounding notes
1370
-    for(vp = list; vp!=NULL; vp=vp->link)
1371
-      vp->durMicros += d_amicro;    
1372
-
1373
-    // update the sustain pedal duration
1374
-    if( sustainPedalDownMsg != NULL )
1375
-      ((cmMidiChMsg_t*)(sustainPedalDownMsg->u.chMsgPtr))->durMicros += d_amicro;  // cast away const
1376
-
1377
-    //
1378
-    // If this is sustain pedal msg
1379
-    //
1380
-    if( mp->status==kCtlMdId && mp->u.chMsgPtr->d0 == kSustainCtlMdId )
1381
-    {
1382
-      unsigned  chIdx = mp->u.chMsgPtr->ch;
1383
-      assert(  chIdx < kMidiChCnt );
1384
-
1385
-      // set the state of the sustain pedal flags
1386
-      sustainFlagV[chIdx] = mp->u.chMsgPtr->d1 >= 64;
1387
-
1388
-      // if the pedal went down ...
1389
-      if( sustainFlagV[chIdx]  )
1390
-      {
1391
-
1392
-        if( sustainPedalDownMsg != NULL )
1393
-        {
1394
-          // TODO:  the correct way to handle this is to maintain multiple sustain pedals 
1395
-          //cmErrMsg(&p->err,kSustainPedalMfRC,"Sustain pedal down with no intervening sustain pedal up.");
1396
-        }
1397
-        else
1398
-        {
1399
-          sustainPedalDownMsg = mp;
1400
-          ((cmMidiChMsg_t*)(sustainPedalDownMsg->u.chMsgPtr))->durMicros = 0;  // cast away const
1401
-        }
1402
-
1403
-        _cmMidiFileCalcNoteDurationsAllocVoice( &list, mp, true );
1404
-      }
1405
-      else // ... if the pedal went up
1406
-      {
1407
-
1408
-        sustainPedalDownMsg = NULL;
1409
-
1410
-        // ... then release sustaining notes
1411
-        _cmMidiVoice_t* pp = NULL;
1412
-        for(vp=list; vp != NULL; )
1413
-        {
1414
-          _cmMidiVoice_t* np = vp->link;
1415
-          if( vp->sustainFl && (vp->mp->u.chMsgPtr->ch == chIdx) )
1416
-            _cmMidFileCalcNoteDurationReleaseNote(&list,pp,vp);
1417
-          else
1418
-            pp = vp;
1419
-
1420
-          vp = np;
1421
-        }
1422
-      }
1423
-    }
1424
-    
1425
-    //
1426
-    // if this is a note-on msg
1427
-    //
1428
-    if( mp->status==kNoteOnMdId && mp->u.chMsgPtr->d1>0 )
1429
-    {
1430
-      _cmMidiFileCalcNoteDurationsAllocVoice( &list, mp, false );
1431
-    }
1432
-    else
1433
-      //
1434
-      // if this is a note-off msg
1435
-      //
1436
-      if( (mp->status==kNoteOnMdId && mp->u.chMsgPtr->d1==0) || (mp->status==kNoteOffMdId) )
1437
-      {
1438
-        _cmMidiVoice_t* pp = NULL;
1439
-        unsigned        chIdx = mp->u.chMsgPtr->ch;
1440
-        assert(  chIdx < kMidiChCnt );
1441
-
1442
-
1443
-        // for each active voice
1444
-        for(vp=list; vp!=NULL; vp=vp->link )
1445
-        {
1446
-          // if this active voice ch/pitch matches the note-off msg ch pitch 
1447
-          if( (vp->mp->u.chMsgPtr->d0==mp->u.chMsgPtr->d0) && (vp->mp->u.chMsgPtr->ch==chIdx) )
1448
-          {
1449
-            // if the sustain pedal is down for this channel - then defer turning the note off
1450
-            if( sustainFlagV[chIdx] )
1451
-              vp->sustainFl = true;
1452
-            else
1453
-              _cmMidFileCalcNoteDurationReleaseNote(&list,pp,vp);
1454
-            break;
1455
-          }
1456
-
1457
-          pp = vp;
1458
-        } // end for
1459
-      } // end if
1460
-
1461
-  } // end-for
1462
- 
1463
-
1464
-  // check for hung notes
1465
-  _cmMidiVoice_t* np = NULL;
1466
-  vp = list;
1467
-  while( vp != NULL )
1468
-  {
1469
-    np = vp->link;    
1470
-
1471
-    if( cmMidiIsNoteOn(vp->mp->status) == false )
1472
-      cmErrMsg(&p->err,kMissingNoteOffMfRC,"Missing note-off for note-on:%s",cmMidiToSciPitch(vp->mp->u.chMsgPtr->d0,NULL,0));
1473
-
1474
-    cmMemFree(vp);
1475
-    vp = np;
1476
-  }
1477
-}
1478
-
1479
 void _cmMidiFileSetDur( cmMidiTrackMsg_t* m0, cmMidiTrackMsg_t* m1 )
1307
 void _cmMidiFileSetDur( cmMidiTrackMsg_t* m0, cmMidiTrackMsg_t* m1 )
1480
 {
1308
 {
1481
   // calculate the duration of the sounding note
1309
   // calculate the duration of the sounding note
1482
   ((cmMidiChMsg_t*)m0->u.chMsgPtr)->durMicros = m1->amicro - m0->amicro;
1310
   ((cmMidiChMsg_t*)m0->u.chMsgPtr)->durMicros = m1->amicro - m0->amicro;
1311
+
1312
+  // set the note-off msg pointer
1313
+  ((cmMidiChMsg_t*)m0->u.chMsgPtr)->end       = m1;
1483
 }
1314
 }
1484
 
1315
 
1485
 bool _cmMidiFileCalcNoteDur( cmMidiTrackMsg_t* m0, cmMidiTrackMsg_t* m1, int noteGateFl, int sustainGateFl, bool sostGateFl )
1316
 bool _cmMidiFileCalcNoteDur( cmMidiTrackMsg_t* m0, cmMidiTrackMsg_t* m1, int noteGateFl, int sustainGateFl, bool sostGateFl )
1628
                 if( sustV[ch] != NULL )
1459
                 if( sustV[ch] != NULL )
1629
                 {
1460
                 {
1630
                   _cmMidiFileSetDur(sustV[ch],m);
1461
                   _cmMidiFileSetDur(sustV[ch],m);
1462
+                  ((cmMidiChMsg_t*)sustV[ch]->u.chMsgPtr)->end = m; // set the pedal-up msg ptr. in the pedal-down msg.
1631
                   sustV[ch] = NULL;
1463
                   sustV[ch] = NULL;
1632
                 }
1464
                 }
1633
               }
1465
               }
1635
           }
1467
           }
1636
           else
1468
           else
1637
 
1469
 
1638
-            // This is a sostenuto-pedal down msg
1470
+            // This is a sostenuto pedal-down msg
1639
             if( cmMidiFileIsSostenutoPedalDown(m) )
1471
             if( cmMidiFileIsSostenutoPedalDown(m) )
1640
             {
1472
             {
1641
               // if the sustain channel is already down
1473
               // if the sustain channel is already down
1651
             }
1483
             }
1652
             else
1484
             else
1653
 
1485
 
1654
-              // This is a sostenuto-pedal up msg
1486
+              // This is a sostenuto pedal-up msg
1655
               if( cmMidiFileIsSostenutoPedalUp(m) )
1487
               if( cmMidiFileIsSostenutoPedalUp(m) )
1656
               {
1488
               {
1657
                 // if the sustain channel is already up
1489
                 // if the sustain channel is already up
1677
                     
1509
                     
1678
                     if( sostV[ch] != NULL )
1510
                     if( sostV[ch] != NULL )
1679
                     {
1511
                     {
1680
-                      _cmMidiFileSetDur(sostV[ch],m);
1512
+                      _cmMidiFileSetDur(sostV[ch],m);                      
1513
+                      ((cmMidiChMsg_t*)sostV[ch]->u.chMsgPtr)->end = m; // set the pedal-up msg ptr. in the pedal-down msg.
1681
                       sostV[ch] = NULL;
1514
                       sostV[ch] = NULL;
1682
                     }
1515
                     }
1683
 
1516
 

+ 3
- 0
cmMidiFile.h Wyświetl plik

52
     cmMidiByte_t scale;
52
     cmMidiByte_t scale;
53
   } cmMidiKeySig_t;
53
   } cmMidiKeySig_t;
54
 
54
 
55
+  struct cmMidiTrackMsg_str;
56
+  
55
   typedef struct
57
   typedef struct
56
   {
58
   {
57
     cmMidiByte_t ch;
59
     cmMidiByte_t ch;
58
     cmMidiByte_t d0;
60
     cmMidiByte_t d0;
59
     cmMidiByte_t d1;
61
     cmMidiByte_t d1;
60
     unsigned     durMicros;  // note duration in microseconds (corrected for tempo changes)
62
     unsigned     durMicros;  // note duration in microseconds (corrected for tempo changes)
63
+    struct cmMidiTrackMsg_str* end; // note-off or pedal-up message
61
   } cmMidiChMsg_t;
64
   } cmMidiChMsg_t;
62
 
65
 
63
 
66
 

Ładowanie…
Anuluj
Zapisz