|
@@ -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
|
}
|