Pārlūkot izejas kodu

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

master
kevin 8 gadus atpakaļ
vecāks
revīzija
2b01371684
2 mainītis faili ar 12 papildinājumiem un 176 dzēšanām
  1. 9
    176
      cmMidiFile.c
  2. 3
    0
      cmMidiFile.h

+ 9
- 176
cmMidiFile.c Parādīt failu

@@ -894,7 +894,7 @@ cmMfRC_t _cmMidiFileWriteMetaMsg( _cmMidiFile_t* mfp, const cmMidiTrackMsg_t* tm
894 894
 
895 895
     case kMidiChMdId: 
896 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 898
         break;
899 899
 
900 900
     case kEndOfTrkMdId:  
@@ -1304,182 +1304,13 @@ typedef struct _cmMidiVoice_str
1304 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 1307
 void _cmMidiFileSetDur( cmMidiTrackMsg_t* m0, cmMidiTrackMsg_t* m1 )
1480 1308
 {
1481 1309
   // calculate the duration of the sounding note
1482 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 1316
 bool _cmMidiFileCalcNoteDur( cmMidiTrackMsg_t* m0, cmMidiTrackMsg_t* m1, int noteGateFl, int sustainGateFl, bool sostGateFl )
@@ -1628,6 +1459,7 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
1628 1459
                 if( sustV[ch] != NULL )
1629 1460
                 {
1630 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 1463
                   sustV[ch] = NULL;
1632 1464
                 }
1633 1465
               }
@@ -1635,7 +1467,7 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
1635 1467
           }
1636 1468
           else
1637 1469
 
1638
-            // This is a sostenuto-pedal down msg
1470
+            // This is a sostenuto pedal-down msg
1639 1471
             if( cmMidiFileIsSostenutoPedalDown(m) )
1640 1472
             {
1641 1473
               // if the sustain channel is already down
@@ -1651,7 +1483,7 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
1651 1483
             }
1652 1484
             else
1653 1485
 
1654
-              // This is a sostenuto-pedal up msg
1486
+              // This is a sostenuto pedal-up msg
1655 1487
               if( cmMidiFileIsSostenutoPedalUp(m) )
1656 1488
               {
1657 1489
                 // if the sustain channel is already up
@@ -1677,7 +1509,8 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
1677 1509
                     
1678 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 1514
                       sostV[ch] = NULL;
1682 1515
                     }
1683 1516
 

+ 3
- 0
cmMidiFile.h Parādīt failu

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

Notiek ielāde…
Atcelt
Saglabāt