Browse Source

cmMidiFile.c : Added _cmMidiFileInsertEotMsg(). Fixed bug where _cmMidiFileTrk.cnt was not incremented in cmMidiFileInsertTrkMsg().

master
kevin 7 years ago
parent
commit
227bf8954b
1 changed files with 73 additions and 4 deletions
  1. 73
    4
      cmMidiFile.c

+ 73
- 4
cmMidiFile.c View File

@@ -256,7 +256,7 @@ cmMfRC_t _cmMidiFileReadChannelMsg( _cmMidiFile_t* mfp, cmMidiByte_t* rsPtr, cmM
256 256
   unsigned byteN = cmMidiStatusToByteCount(tmp->status);
257 257
   
258 258
   if( byteN==kInvalidMidiByte || byteN > 2 )
259
-    return cmErrMsg(&mfp->err,kInvalidStatusMfRC,"Invalid status:0x%x %i.",tmp->status,tmp->status);
259
+    return cmErrMsg(&mfp->err,kInvalidStatusMfRC,"Invalid status:0x%x %i byte cnt:%i.",tmp->status,tmp->status,byteN);
260 260
 
261 261
   unsigned i;
262 262
   for(i=useRsFl; i<byteN; ++i)
@@ -339,7 +339,7 @@ cmMfRC_t _cmMidiFileReadTrack( _cmMidiFile_t* mfp, unsigned short trkIdx )
339 339
     if((rc = _cmMidiFileRead8(mfp,&status)) != kOkMfRC )
340 340
       return rc;
341 341
 
342
-    //printf("st:%i 0x%x\n",status,status);
342
+    //printf("%5i st:%i 0x%x\n",dticks,status,status);
343 343
 
344 344
     // append a track msg
345 345
     if((rc = _cmMidiFileAppendTrackMsg( mfp, trkIdx, dticks, status, &tmp )) != kOkMfRC )
@@ -677,8 +677,11 @@ cmMfRC_t cmMidiFileOpen( cmCtx_t* ctx, cmMidiFileH_t* hp, const char* fn )
677 677
     rc = cmErrMsg(&p->err,kFileFailMfRC,"MIDI file close failed.");
678 678
 
679 679
   if( rc != kOkMfRC )
680
+  {
680 681
     _cmMidiFileClose(p);
681
-
682
+    hp->h = NULL;
683
+  }
684
+  
682 685
   return rc;
683 686
 }
684 687
 
@@ -971,12 +974,75 @@ cmMfRC_t _cmMidiFileWriteMetaMsg( _cmMidiFile_t* mfp, const cmMidiTrackMsg_t* tm
971 974
   return rc;
972 975
 }
973 976
 
977
+cmMfRC_t _cmMidiFileInsertEotMsg( _cmMidiFile_t* p, unsigned trkIdx )
978
+{
979
+  _cmMidiTrack_t* trk = p->trkV + trkIdx;
980
+  cmMidiTrackMsg_t* m0 = NULL;
981
+  cmMidiTrackMsg_t* m = trk->base;
982
+
983
+  // locate the current EOT msg on this track
984
+  for(; m!=NULL; m=m->link)
985
+  {
986
+    if( m->status == kMetaStId && m->metaId == kEndOfTrkMdId )
987
+    {
988
+      // If this EOT msg is the last msg in the track  ...
989
+      if( m->link == NULL )
990
+      {
991
+        assert( m == trk->last );
992
+        return kOkMfRC; // ... then there is nothing else to do
993
+      }
994
+
995
+      // If this EOT msg is not the last in the track ...
996
+      if( m0 != NULL )
997
+        m0->link = m->link;  // ... then unlink it
998
+
999
+      break;
1000
+    }
1001
+
1002
+    m0 = m;
1003
+  }
1004
+
1005
+  // if we get here then the last msg in the track was not an EOT msg
1006
+
1007
+  // if there was no previously allocated EOT msg
1008
+  if( m == NULL )
1009
+  {
1010
+    m   = _cmMidiFileAllocMsg(p, trkIdx, 1, kMetaStId );
1011
+    m->metaId = kEndOfTrkMdId;
1012
+    trk->cnt += 1;
1013
+    
1014
+  }
1015
+
1016
+  // link an EOT msg as the last msg on the track
1017
+
1018
+  // if the track is currently empty
1019
+  if( m0 == NULL )
1020
+  {
1021
+    trk->base = m;
1022
+    trk->last = m;
1023
+  }
1024
+  else // link the msg as the last on on the track
1025
+  {
1026
+    assert( m0 == trk->last);
1027
+    m0->link = m;
1028
+    m->link  = NULL;
1029
+    trk->last = m;
1030
+  }
1031
+
1032
+  return kOkMfRC;
1033
+
1034
+}
1035
+
974 1036
 cmMfRC_t _cmMidiFileWriteTrack( _cmMidiFile_t* mfp, unsigned trkIdx )
975 1037
 {
976 1038
   cmMfRC_t          rc        = kOkMfRC;
977 1039
   cmMidiTrackMsg_t* tmp       = mfp->trkV[trkIdx].base;
978 1040
   cmMidiByte_t      runStatus = 0;
979 1041
 
1042
+  // be sure there is a EOT msg at the end of this track
1043
+  if((rc = _cmMidiFileInsertEotMsg(mfp, trkIdx )) != kOkMfRC )
1044
+    return rc;
1045
+  
980 1046
   for(; tmp != NULL; tmp=tmp->link)
981 1047
   {
982 1048
     // write the msg tick count
@@ -1379,7 +1445,8 @@ cmMfRC_t  cmMidiFileInsertTrackMsg( cmMidiFileH_t h, unsigned trkIdx, const cmMi
1379 1445
     assert( m1->atick >= m->atick );
1380 1446
     m1->dtick = m1->atick - m->atick;
1381 1447
   }
1382
-  
1448
+
1449
+  p->trkV[trkIdx].cnt += 1;  
1383 1450
   p->msgVDirtyFl = true;
1384 1451
   
1385 1452
   return kOkMfRC;
@@ -1402,6 +1469,8 @@ cmMfRC_t  cmMidiFileInsertTrackChMsg( cmMidiFileH_t h, unsigned trkIdx, unsigned
1402 1469
   m.status     = status & 0xf0;
1403 1470
   m.byteCnt    = sizeof(cm);
1404 1471
   m.u.chMsgPtr = &cm;
1472
+
1473
+  assert( m.status >= kNoteOffMdId && m.status <= kPbendMdId );
1405 1474
   
1406 1475
   return cmMidiFileInsertTrackMsg(h,trkIdx,&m);
1407 1476
 }

Loading…
Cancel
Save