Przeglądaj źródła

cmMidiFile.h/c,cmMidiFilePlay.c : Added cmMidiFileCreate(), cmMidiFileInsertTrack???Msg(). Removed cmMidiFileIsNull() and _cmMidiFileMalloc().

master
kevin 7 lat temu
rodzic
commit
bf8f641d22
3 zmienionych plików z 191 dodań i 67 usunięć
  1. 181
    62
      cmMidiFile.c
  2. 8
    3
      cmMidiFile.h
  3. 2
    2
      cmMidiFilePlay.c

+ 181
- 62
cmMidiFile.c Wyświetl plik

54
   return p;
54
   return p;
55
 }
55
 }
56
 
56
 
57
-void* _cmMidiFileMalloc( _cmMidiFile_t* mfp, unsigned byteN )
58
-{ return cmLHeapAllocZ(mfp->lhH,byteN); }
59
-
60
-
61
 cmMfRC_t _cmMidiFileRead8( _cmMidiFile_t* mfp, cmMidiByte_t* p )
57
 cmMfRC_t _cmMidiFileRead8( _cmMidiFile_t* mfp, cmMidiByte_t* p )
62
 {
58
 {
63
   if( cmFileReadUChar(mfp->fh,p,1) != kOkFileRC )  
59
   if( cmFileReadUChar(mfp->fh,p,1) != kOkFileRC )  
107
   if( byteN == 0 )
103
   if( byteN == 0 )
108
     return kOkMfRC;
104
     return kOkMfRC;
109
 
105
 
110
-  char*  t = (char*)_cmMidiFileMalloc(mfp,byteN+1);
106
+  char*  t = cmLhAllocZ(mfp->lhH,char,byteN+1);
111
   t[byteN] = 0;
107
   t[byteN] = 0;
112
   
108
   
113
   if( cmFileReadChar(mfp->fh,t,byteN) != kOkFileRC )  
109
   if( cmFileReadChar(mfp->fh,t,byteN) != kOkFileRC )  
120
 
116
 
121
 cmMfRC_t _cmMidiFileReadRecd( _cmMidiFile_t* mfp, cmMidiTrackMsg_t* tmp, unsigned byteN )
117
 cmMfRC_t _cmMidiFileReadRecd( _cmMidiFile_t* mfp, cmMidiTrackMsg_t* tmp, unsigned byteN )
122
 {
118
 {
123
-  char*  t = (char*)_cmMidiFileMalloc(mfp,byteN);
119
+  char*  t = cmLhAllocZ(mfp->lhH,char,byteN);
124
   
120
   
125
   if( cmFileReadChar(mfp->fh,t,byteN) != kOkFileRC )  
121
   if( cmFileReadChar(mfp->fh,t,byteN) != kOkFileRC )  
126
     return cmErrMsg(&mfp->err,kFileFailMfRC,"MIDI read record failed.");
122
     return cmErrMsg(&mfp->err,kFileFailMfRC,"MIDI read record failed.");
160
 
156
 
161
 cmMidiTrackMsg_t* _cmMidiFileAllocMsg( _cmMidiFile_t* mfp, unsigned short trkIdx, unsigned dtick, cmMidiByte_t status )
157
 cmMidiTrackMsg_t* _cmMidiFileAllocMsg( _cmMidiFile_t* mfp, unsigned short trkIdx, unsigned dtick, cmMidiByte_t status )
162
 {
158
 {
163
-  cmMidiTrackMsg_t* tmp = (cmMidiTrackMsg_t*)_cmMidiFileMalloc(mfp, sizeof(cmMidiTrackMsg_t) );
159
+  cmMidiTrackMsg_t* tmp = cmLhAllocZ(mfp->lhH,cmMidiTrackMsg_t, 1 );
164
 
160
 
165
   // set the generic track record fields
161
   // set the generic track record fields
166
   tmp->dtick     = dtick;
162
   tmp->dtick     = dtick;
226
   }
222
   }
227
 
223
 
228
   // allocate memory to hold the sys-ex msg
224
   // allocate memory to hold the sys-ex msg
229
-  cmMidiByte_t* mp = (cmMidiByte_t *)_cmMidiFileMalloc(mfp,  byteN );
225
+  cmMidiByte_t* mp = cmLhAllocZ(mfp->lhH,cmMidiByte_t,  byteN );
230
 
226
 
231
   // read the sys-ex msg from the file into msg memory
227
   // read the sys-ex msg from the file into msg memory
232
   if( cmFileReadUChar(mfp->fh,mp,byteN) != kOkFileRC )  
228
   if( cmFileReadUChar(mfp->fh,mp,byteN) != kOkFileRC )  
241
 cmMfRC_t _cmMidiFileReadChannelMsg( _cmMidiFile_t* mfp, cmMidiByte_t* rsPtr, cmMidiByte_t status, cmMidiTrackMsg_t* tmp )
237
 cmMfRC_t _cmMidiFileReadChannelMsg( _cmMidiFile_t* mfp, cmMidiByte_t* rsPtr, cmMidiByte_t status, cmMidiTrackMsg_t* tmp )
242
 {
238
 {
243
   cmMfRC_t       rc       = kOkMfRC;
239
   cmMfRC_t       rc       = kOkMfRC;
244
-  cmMidiChMsg_t* p        = (cmMidiChMsg_t*)_cmMidiFileMalloc(mfp,sizeof(cmMidiChMsg_t));
240
+  cmMidiChMsg_t* p        = cmLhAllocZ(mfp->lhH,cmMidiChMsg_t,1);
245
   unsigned       useRsFl  = status <= 0x7f;
241
   unsigned       useRsFl  = status <= 0x7f;
246
   cmMidiByte_t   statusCh = useRsFl ? *rsPtr : status;
242
   cmMidiByte_t   statusCh = useRsFl ? *rsPtr : status;
247
   
243
   
409
   // if the division field was given in smpte
405
   // if the division field was given in smpte
410
   if( mfp->ticksPerQN & 0x8000 )
406
   if( mfp->ticksPerQN & 0x8000 )
411
   {
407
   {
412
-    mfp->smpteFmtId = (mfp->ticksPerQN & 0x7f00) >> 8;
408
+    mfp->smpteFmtId         = (mfp->ticksPerQN & 0x7f00) >> 8;
413
     mfp->smpteTicksPerFrame = (mfp->ticksPerQN & 0xFF);
409
     mfp->smpteTicksPerFrame = (mfp->ticksPerQN & 0xFF);
414
-    mfp->ticksPerQN = 0;
410
+    mfp->ticksPerQN         = 0;
415
   }
411
   }
416
 
412
 
417
   // allocate and zero the track array
413
   // allocate and zero the track array
418
   if( mfp->trkN )
414
   if( mfp->trkN )
419
-    mfp->trkV = _cmMidiFileMalloc( mfp, sizeof(_cmMidiTrack_t)*mfp->trkN);
415
+    mfp->trkV = cmLhAllocZ(mfp->lhH, _cmMidiTrack_t, mfp->trkN);
420
   
416
   
421
   return rc;
417
   return rc;
422
 }
418
 }
565
   
561
   
566
 }
562
 }
567
 
563
 
568
-
569
-cmMfRC_t cmMidiFileOpen( cmCtx_t* ctx, cmMidiFileH_t* hPtr, const char* fn )
564
+cmMfRC_t _cmMidiFileCreate( cmCtx_t* ctx, cmMidiFileH_t* hp )
570
 {
565
 {
571
-  cmMfRC_t       rc     = kOkMfRC;
572
-  _cmMidiFile_t* mfp    = NULL;
573
-  unsigned short trkIdx = 0;
574
-  cmErr_t        err;
575
-
576
-  if( cmMidiFileIsValid(*hPtr) )
577
-    if((rc = _cmMidiFileClose(_cmMidiFileHandleToPtr(*hPtr))) != kOkMfRC )
578
-      return rc;
566
+  cmMfRC_t rc = kOkMfRC;
567
+  _cmMidiFile_t* p = NULL;
568
+  
569
+  if((rc = cmMidiFileClose(hp)) != kOkMfRC )
570
+    return rc;
571
+  
572
+  // allocate the midi file object 
573
+  if(( p = cmMemAllocZ( _cmMidiFile_t, 1)) == NULL )
574
+    return rc = cmErrMsg(&ctx->err,kMemAllocFailMfRC,"MIDI file memory allocation failed.");
575
+  
576
+  cmErrSetup(&p->err,&ctx->rpt,"MIDI File");
577
+  
578
+  // allocate the linked heap
579
+  if( cmLHeapIsValid( p->lhH = cmLHeapCreate( 1024, ctx )) == false )
580
+    rc = cmErrMsg(&p->err,kMemAllocFailMfRC,"MIDI heap allocation failed.");
579
 
581
 
580
-  cmErrSetup(&err,&ctx->rpt,"MIDI File");
582
+  if( rc != kOkMfRC )
583
+    _cmMidiFileClose(p);
584
+  else
585
+    hp->h = p;
586
+  
587
+  return rc;
588
+  
589
+}
581
 
590
 
582
-  // allocate the midi file object 
583
-  if(( mfp = cmMemAllocZ( _cmMidiFile_t, 1)) == NULL )
584
-    return rc                                 = cmErrMsg(&err,kMemAllocFailMfRC,"MIDI file memory allocation failed.");
591
+cmMfRC_t cmMidiFileOpen( cmCtx_t* ctx, cmMidiFileH_t* hp, const char* fn )
592
+{
593
+  cmMfRC_t       rc     = kOkMfRC;  
594
+  unsigned short trkIdx = 0;
585
 
595
 
586
-  cmErrClone(&mfp->err,&err);
596
+  if((rc = _cmMidiFileCreate(ctx,hp)) != kOkMfRC )
597
+    return rc;
587
 
598
 
588
-  // allocate the linked heap
589
-  if( cmLHeapIsValid( mfp->lhH = cmLHeapCreate( 1024, ctx )) == false )
590
-  {
591
-    rc = cmErrMsg(&err,kMemAllocFailMfRC,"MIDI heap allocation failed.");
592
-    goto errLabel;
593
-  }
599
+  _cmMidiFile_t* p    = _cmMidiFileHandleToPtr(*hp);
594
 
600
 
595
   // open the file
601
   // open the file
596
-  if(cmFileOpen(&mfp->fh,fn,kReadFileFl | kBinaryFileFl,mfp->err.rpt) != kOkFileRC )
602
+  if(cmFileOpen(&p->fh,fn,kReadFileFl | kBinaryFileFl,p->err.rpt) != kOkFileRC )
597
   {
603
   {
598
-    rc = cmErrMsg(&mfp->err,kFileFailMfRC,"MIDI file open failed.");
604
+    rc = cmErrMsg(&p->err,kFileFailMfRC,"MIDI file open failed.");
599
     goto errLabel;
605
     goto errLabel;
600
   }
606
   }
601
 
607
 
602
   // read header and setup track array
608
   // read header and setup track array
603
-  if(( rc = _cmMidiFileReadHdr(mfp)) != kOkMfRC )
609
+  if(( rc = _cmMidiFileReadHdr(p)) != kOkMfRC )
604
     goto errLabel;
610
     goto errLabel;
605
   
611
   
606
-  while( !cmFileEof(mfp->fh) && trkIdx < mfp->trkN )
612
+  while( !cmFileEof(p->fh) && trkIdx < p->trkN )
607
   {
613
   {
608
     unsigned chkId = 0,chkN=0;
614
     unsigned chkId = 0,chkN=0;
609
 
615
 
610
     // read the chunk id
616
     // read the chunk id
611
-    if((rc = _cmMidiFileRead32(mfp,&chkId)) != kOkMfRC )
617
+    if((rc = _cmMidiFileRead32(p,&chkId)) != kOkMfRC )
612
       goto errLabel;
618
       goto errLabel;
613
 
619
 
614
     // read the chunk size
620
     // read the chunk size
615
-    if((rc = _cmMidiFileRead32(mfp,&chkN)) != kOkMfRC )
621
+    if((rc = _cmMidiFileRead32(p,&chkN)) != kOkMfRC )
616
       goto errLabel;
622
       goto errLabel;
617
 
623
 
618
     // if this is not a trk chunk then skip it
624
     // if this is not a trk chunk then skip it
619
     if( chkId != (unsigned)'MTrk')
625
     if( chkId != (unsigned)'MTrk')
620
     {
626
     {
621
-      //if( fseek( mfp->fp, chkN, SEEK_CUR) != 0 )
622
-      if( cmFileSeek(mfp->fh,kCurFileFl,chkN) != kOkFileRC )
627
+      //if( fseek( p->fp, chkN, SEEK_CUR) != 0 )
628
+      if( cmFileSeek(p->fh,kCurFileFl,chkN) != kOkFileRC )
623
       {
629
       {
624
-        rc = cmErrMsg(&mfp->err,kFileFailMfRC,"MIDI file seek failed.");
630
+        rc = cmErrMsg(&p->err,kFileFailMfRC,"MIDI file seek failed.");
625
         goto errLabel;
631
         goto errLabel;
626
       }
632
       }
627
     }  
633
     }  
628
     else
634
     else
629
     {
635
     {
630
-      if((rc = _cmMidiFileReadTrack(mfp,trkIdx)) != kOkMfRC )
636
+      if((rc = _cmMidiFileReadTrack(p,trkIdx)) != kOkMfRC )
631
         goto errLabel;
637
         goto errLabel;
632
 
638
 
633
       ++trkIdx;
639
       ++trkIdx;
635
   }
641
   }
636
 
642
 
637
   // store the file name
643
   // store the file name
638
-  mfp->fn          = _cmMidiFileMalloc(mfp,strlen(fn)+1);
639
-  assert( mfp->fn != NULL );
640
-  strcpy(mfp->fn,fn);
644
+  p->fn          = cmLhAllocZ(p->lhH,char,strlen(fn)+1);
645
+  assert( p->fn != NULL );
646
+  strcpy(p->fn,fn);
641
   
647
   
642
-  _cmMidiFileLinearize(mfp);
648
+  _cmMidiFileLinearize(p);
643
   
649
   
644
-  hPtr->h = mfp;
645
 
650
 
646
  errLabel:
651
  errLabel:
647
 
652
 
648
-  if( cmFileClose(&mfp->fh) != kOkFileRC )
649
-    rc = cmErrMsg(&mfp->err,kFileFailMfRC,"MIDI file close failed.");
653
+  if( cmFileClose(&p->fh) != kOkFileRC )
654
+    rc = cmErrMsg(&p->err,kFileFailMfRC,"MIDI file close failed.");
650
 
655
 
651
   if( rc != kOkMfRC )
656
   if( rc != kOkMfRC )
652
-    _cmMidiFileClose(mfp);
657
+    _cmMidiFileClose(p);
653
 
658
 
654
   return rc;
659
   return rc;
655
 }
660
 }
656
 
661
 
662
+cmMfRC_t        cmMidiFileCreate( cmCtx_t* ctx, cmMidiFileH_t* hp, unsigned trkN, unsigned ticksPerQN )
663
+{
664
+  cmMfRC_t       rc     = kOkMfRC;  
657
 
665
 
666
+  if((rc = _cmMidiFileCreate(ctx,hp)) != kOkMfRC )
667
+    return rc;
668
+  
669
+  _cmMidiFile_t* p    = _cmMidiFileHandleToPtr(*hp);
658
 
670
 
659
-cmMfRC_t        cmMidiFileClose( cmMidiFileH_t* h )
671
+  p->ticksPerQN = ticksPerQN;
672
+  p->fmtId      = 1;
673
+  p->trkN       = trkN;
674
+  p->trkV       = cmLhAllocZ(p->lhH, _cmMidiTrack_t, p->trkN);
675
+  
676
+  return rc;
677
+}
678
+
679
+
680
+cmMfRC_t        cmMidiFileClose( cmMidiFileH_t* hp )
660
 {
681
 {
661
-  cmMfRC_t rc;
682
+  cmMfRC_t rc = kOkMfRC;
662
 
683
 
663
-  if( cmMidiFileIsNull(*h) )
684
+  if( hp==NULL || cmMidiFileIsValid(*hp)==false )
664
     return kOkMfRC;
685
     return kOkMfRC;
686
+  
687
+  _cmMidiFile_t* p = _cmMidiFileHandleToPtr(*hp);
665
 
688
 
666
-  if((rc = _cmMidiFileClose(_cmMidiFileHandleToPtr(*h))) == kOkMfRC )
689
+  if((rc = _cmMidiFileClose(p)) != kOkMfRC )
667
     return rc;
690
     return rc;
668
-
669
-  h->h = NULL;
691
+  
692
+  hp->h = NULL;
670
   return rc;
693
   return rc;
671
 }
694
 }
672
 
695
 
1013
 
1036
 
1014
 
1037
 
1015
 bool   cmMidiFileIsValid( cmMidiFileH_t h )
1038
 bool   cmMidiFileIsValid( cmMidiFileH_t h )
1016
-{ return !cmMidiFileIsNull(h); }
1039
+{ return h.h != NULL; }
1017
 
1040
 
1018
 unsigned    cmMidiFileTrackCount( cmMidiFileH_t h )
1041
 unsigned    cmMidiFileTrackCount( cmMidiFileH_t h )
1019
 {
1042
 {
1220
   // complete the msg setup
1243
   // complete the msg setup
1221
   _cmMidiTrack_t* trk   = mfp->trkV + trkIdx;
1244
   _cmMidiTrack_t* trk   = mfp->trkV + trkIdx;
1222
   cmMidiTrackMsg_t* m   = _cmMidiFileAllocMsg(mfp, trkIdx, abs(dtick), status );
1245
   cmMidiTrackMsg_t* m   = _cmMidiFileAllocMsg(mfp, trkIdx, abs(dtick), status );
1223
-  cmMidiChMsg_t*    c   = (cmMidiChMsg_t*)_cmMidiFileMalloc(mfp,sizeof(cmMidiChMsg_t));
1246
+  cmMidiChMsg_t*    c   = cmLhAllocZ(mfp->lhH,cmMidiChMsg_t,1);
1224
 
1247
 
1225
   m->u.chMsgPtr = c;
1248
   m->u.chMsgPtr = c;
1226
   
1249
   
1255
 
1278
 
1256
 }
1279
 }
1257
 
1280
 
1281
+// Only set
1282
+//   atick    - used to position the msg in the track
1283
+//   status   - this field is always set (Note that channel information must stripped from the status byte and included in the channel msg data)
1284
+//   metaId   - this field is optional depending on the msg type
1285
+//   byteCnt  - used to allocate storage for the data element in 'cmMidiTrackMsg_t.u'
1286
+//   u        - the message data
1287
+cmMfRC_t  cmMidiFileInsertTrackMsg( cmMidiFileH_t h, unsigned trkIdx, const cmMidiTrackMsg_t* msg )
1288
+{
1289
+  _cmMidiFile_t* p = _cmMidiFileHandleToPtr(h);
1290
+
1291
+  // validate the track index
1292
+  if( trkIdx >= p->trkN )
1293
+    return cmErrMsg(&p->err,kInvalidTrkIndexMfRC,"The track index (%i) is invalid.",trkIdx);
1294
+
1295
+  // allocate a new track record
1296
+  cmMidiTrackMsg_t* m = (cmMidiTrackMsg_t*)cmLhAllocZ(p->lhH,char,sizeof(cmMidiTrackMsg_t)+msg->byteCnt);
1297
+
1298
+  // fill the track record
1299
+  m->uid     = p->nextUid++;
1300
+  m->atick   = msg->atick;
1301
+  m->status  = msg->status;
1302
+  m->metaId  = msg->metaId;
1303
+  m->trkIdx  = trkIdx;
1304
+  m->byteCnt = msg->byteCnt;
1305
+  memcpy(&m->u,&msg->u,sizeof(msg->u));
1306
+
1307
+  // copy the exernal data
1308
+  if( msg->byteCnt > 0 )
1309
+  {
1310
+    m->u.voidPtr = (m+1);
1311
+    memcpy((void*)m->u.voidPtr,msg->u.voidPtr,msg->byteCnt);
1312
+  }
1313
+
1314
+  cmMidiTrackMsg_t* m0 = NULL;
1315
+  cmMidiTrackMsg_t* m1 = p->trkV[trkIdx].base;
1316
+
1317
+  // locate the track record before and after the new msg
1318
+  for(; m1!=NULL; m1=m1->link)
1319
+    if( m1->atick > m->atick )
1320
+    {
1321
+      if( m0 == NULL )
1322
+        p->trkV[trkIdx].base = m;
1323
+      else
1324
+        m0->link = m;
1325
+      
1326
+      m->link = m1;
1327
+      break;
1328
+    }
1329
+
1330
+  // the new track record is the last msg
1331
+  if( m1 == NULL )
1332
+  {
1333
+    m1                   = p->trkV[trkIdx].last;
1334
+    m1->link             = m;
1335
+    p->trkV[trkIdx].last = m;
1336
+    if( p->trkV[trkIdx].base == NULL )
1337
+      p->trkV[trkIdx].base = m;
1338
+  }
1339
+
1340
+  
1341
+  return kOkMfRC;
1342
+   
1343
+}
1344
+
1345
+cmMfRC_t  cmMidiFileInsertTrackChMsg( cmMidiFileH_t h, unsigned trkIdx, unsigned atick, cmMidiByte_t status, cmMidiByte_t d0, cmMidiByte_t d1 )
1346
+{
1347
+  cmMidiTrackMsg_t m;
1348
+  cmMidiChMsg_t   cm;
1349
+
1350
+  memset(&m,0,sizeof(m));
1351
+  memset(&cm,0,sizeof(cm));
1352
+
1353
+  cm.ch = status & 0x0f;
1354
+  cm.d0 = d0;
1355
+  cm.d1 = d1;
1356
+  
1357
+  m.atick      = atick;
1358
+  m.status     = status & 0xf0;
1359
+  m.byteCnt    = sizeof(cm);
1360
+  m.u.chMsgPtr = &cm;
1361
+  
1362
+  return cmMidiFileInsertTrackMsg(h,trkIdx,&m);
1363
+}
1364
+
1365
+cmMfRC_t  cmMidFileInsertTrackTempoMsg( cmMidiFileH_t h, unsigned trkIdx, unsigned atick, unsigned bpm )
1366
+{
1367
+  cmMidiTrackMsg_t m;
1368
+
1369
+  memset(&m,0,sizeof(m));
1370
+
1371
+  m.atick      = atick;
1372
+  m.status     = kMetaStId;
1373
+  m.metaId     = kTempoMdId;
1374
+  m.u.iVal     = 60000000/bpm;  // convert BPM to microsPerQN
1375
+  
1376
+  return cmMidiFileInsertTrackMsg(h,trkIdx,&m);
1377
+}
1378
+
1379
+
1258
 unsigned  cmMidiFileSeekUsecs( cmMidiFileH_t h, unsigned long long offsUSecs, unsigned* msgUsecsPtr, unsigned* microsPerTickPtr )
1380
 unsigned  cmMidiFileSeekUsecs( cmMidiFileH_t h, unsigned long long offsUSecs, unsigned* msgUsecsPtr, unsigned* microsPerTickPtr )
1259
 {
1381
 {
1260
   _cmMidiFile_t* p;
1382
   _cmMidiFile_t* p;
1657
   }  
1779
   }  
1658
 }
1780
 }
1659
 
1781
 
1660
-bool cmMidiFileIsNull( cmMidiFileH_t h )
1661
-{ return (_cmMidiFile_t*)h.h == NULL; }
1662
-
1663
 
1782
 
1664
 void cmMidiFileTestPrint( void* printDataPtr, const char* fmt, va_list vl )
1783
 void cmMidiFileTestPrint( void* printDataPtr, const char* fmt, va_list vl )
1665
 { vprintf(fmt,vl); }
1784
 { vprintf(fmt,vl); }

+ 8
- 3
cmMidiFile.h Wyświetl plik

116
     kSostenutoPedalMfRC, // 11
116
     kSostenutoPedalMfRC, // 11
117
     kLargeDeltaTickMfRC, // 12 (a large delta tick value was filtered)
117
     kLargeDeltaTickMfRC, // 12 (a large delta tick value was filtered)
118
     kUidNotFoundMfRC,    // 13
118
     kUidNotFoundMfRC,    // 13
119
-    kUidNotANoteMsgMfRC  // 14
119
+    kUidNotANoteMsgMfRC, // 14
120
+    kInvalidTrkIndexMfRC // 15
120
   };
121
   };
121
 
122
 
122
   extern cmMidiFileH_t cmMidiFileNullHandle;
123
   extern cmMidiFileH_t cmMidiFileNullHandle;
123
 
124
 
124
-  cmMfRC_t              cmMidiFileOpen( cmCtx_t* ctx, cmMidiFileH_t* hPtr, const char* fn );
125
+  cmMfRC_t              cmMidiFileOpen( cmCtx_t* ctx, cmMidiFileH_t* h, const char* fn );
126
+  cmMfRC_t              cmMidiFileCreate( cmCtx_t* ctx, cmMidiFileH_t* hp, unsigned trkN, unsigned ticksPerQN );
125
   cmMfRC_t              cmMidiFileClose( cmMidiFileH_t* hp );
127
   cmMfRC_t              cmMidiFileClose( cmMidiFileH_t* hp );
126
 
128
 
127
   cmMfRC_t              cmMidiFileWrite( cmMidiFileH_t h, const char* fn );
129
   cmMfRC_t              cmMidiFileWrite( cmMidiFileH_t h, const char* fn );
167
   // Insert a MIDI message relative to the reference msg identified by 'uid'.
169
   // Insert a MIDI message relative to the reference msg identified by 'uid'.
168
   // If dtick is positive/negative then the new msg is inserted after/before the reference msg.  
170
   // If dtick is positive/negative then the new msg is inserted after/before the reference msg.  
169
   cmMfRC_t             cmMidiFileInsertMsg( cmMidiFileH_t h, unsigned uid, int dtick, cmMidiByte_t ch, cmMidiByte_t status, cmMidiByte_t d0, cmMidiByte_t d1 );
171
   cmMfRC_t             cmMidiFileInsertMsg( cmMidiFileH_t h, unsigned uid, int dtick, cmMidiByte_t ch, cmMidiByte_t status, cmMidiByte_t d0, cmMidiByte_t d1 );
172
+
173
+  cmMfRC_t             cmMidiFileInsertTrackMsg(     cmMidiFileH_t h, unsigned trkIdx, const cmMidiTrackMsg_t* msg );
174
+  cmMfRC_t             cmMidiFileInsertTrackChMsg(   cmMidiFileH_t h, unsigned trkIdx, unsigned atick, cmMidiByte_t status, cmMidiByte_t d0, cmMidiByte_t d1 );
175
+  cmMfRC_t             cmMidFileInsertTrackTempoMsg( cmMidiFileH_t h, unsigned trkIdx, unsigned atick, unsigned bpm );
170
   
176
   
171
   // Return a pointer to the first msg at or after 'usecsOffs' or kInvalidIdx if no
177
   // Return a pointer to the first msg at or after 'usecsOffs' or kInvalidIdx if no
172
   // msg exists after 'usecsOffs'.  Note that 'usecOffs' is an offset from the beginning
178
   // msg exists after 'usecsOffs'.  Note that 'usecOffs' is an offset from the beginning
191
 
197
 
192
   void                  cmMidiFilePrintMsgs( cmMidiFileH_t h, cmRpt_t* rpt );
198
   void                  cmMidiFilePrintMsgs( cmMidiFileH_t h, cmRpt_t* rpt );
193
   void                  cmMidiFilePrintTrack( cmMidiFileH_t h, unsigned trkIdx, cmRpt_t* rpt );
199
   void                  cmMidiFilePrintTrack( cmMidiFileH_t h, unsigned trkIdx, cmRpt_t* rpt );
194
-  bool                  cmMidiFileIsNull( cmMidiFileH_t h );
195
   void                  cmMidiFileTest( const char* fn, cmCtx_t* ctx );
200
   void                  cmMidiFileTest( const char* fn, cmCtx_t* ctx );
196
 
201
 
197
   // Generate a piano-roll plot description file which can be displayed with cmXScore.m
202
   // Generate a piano-roll plot description file which can be displayed with cmXScore.m

+ 2
- 2
cmMidiFilePlay.c Wyświetl plik

88
   {
88
   {
89
     cmMfp_t* p = _cmMfpHandleToPtr(*hp);
89
     cmMfp_t* p = _cmMfpHandleToPtr(*hp);
90
     
90
     
91
-    if( cmMidiFileIsNull(p->mfH)==false && p->closeFileFl==true )
91
+    if( cmMidiFileIsValid(p->mfH)==false && p->closeFileFl==true )
92
       cmMidiFileClose(&p->mfH);
92
       cmMidiFileClose(&p->mfH);
93
 
93
 
94
     cmMemFree(p);
94
     cmMemFree(p);
121
   cmMfp_t* p = _cmMfpHandleToPtr(h);
121
   cmMfp_t* p = _cmMfpHandleToPtr(h);
122
 
122
 
123
   // if a file has already been assigned to this player
123
   // if a file has already been assigned to this player
124
-  if( (cmMidiFileIsNull(p->mfH) == false) && p->closeFileFl)
124
+  if( (cmMidiFileIsValid(p->mfH) == false) && p->closeFileFl)
125
   {
125
   {
126
     // close the existing file
126
     // close the existing file
127
     cmMidiFileClose(&p->mfH);    
127
     cmMidiFileClose(&p->mfH);    

Ładowanie…
Anuluj
Zapisz