cmMidiFile.h/c,cmMidiFilePlay.c : Added cmMidiFileCreate(), cmMidiFileInsertTrack???Msg(). Removed cmMidiFileIsNull() and _cmMidiFileMalloc().
This commit is contained in:
parent
9036de70ba
commit
bf8f641d22
239
cmMidiFile.c
239
cmMidiFile.c
@ -54,10 +54,6 @@ _cmMidiFile_t* _cmMidiFileHandleToPtr( cmMidiFileH_t h )
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* _cmMidiFileMalloc( _cmMidiFile_t* mfp, unsigned byteN )
|
|
||||||
{ return cmLHeapAllocZ(mfp->lhH,byteN); }
|
|
||||||
|
|
||||||
|
|
||||||
cmMfRC_t _cmMidiFileRead8( _cmMidiFile_t* mfp, cmMidiByte_t* p )
|
cmMfRC_t _cmMidiFileRead8( _cmMidiFile_t* mfp, cmMidiByte_t* p )
|
||||||
{
|
{
|
||||||
if( cmFileReadUChar(mfp->fh,p,1) != kOkFileRC )
|
if( cmFileReadUChar(mfp->fh,p,1) != kOkFileRC )
|
||||||
@ -107,7 +103,7 @@ cmMfRC_t _cmMidiFileReadText( _cmMidiFile_t* mfp, cmMidiTrackMsg_t* tmp, unsigne
|
|||||||
if( byteN == 0 )
|
if( byteN == 0 )
|
||||||
return kOkMfRC;
|
return kOkMfRC;
|
||||||
|
|
||||||
char* t = (char*)_cmMidiFileMalloc(mfp,byteN+1);
|
char* t = cmLhAllocZ(mfp->lhH,char,byteN+1);
|
||||||
t[byteN] = 0;
|
t[byteN] = 0;
|
||||||
|
|
||||||
if( cmFileReadChar(mfp->fh,t,byteN) != kOkFileRC )
|
if( cmFileReadChar(mfp->fh,t,byteN) != kOkFileRC )
|
||||||
@ -120,7 +116,7 @@ cmMfRC_t _cmMidiFileReadText( _cmMidiFile_t* mfp, cmMidiTrackMsg_t* tmp, unsigne
|
|||||||
|
|
||||||
cmMfRC_t _cmMidiFileReadRecd( _cmMidiFile_t* mfp, cmMidiTrackMsg_t* tmp, unsigned byteN )
|
cmMfRC_t _cmMidiFileReadRecd( _cmMidiFile_t* mfp, cmMidiTrackMsg_t* tmp, unsigned byteN )
|
||||||
{
|
{
|
||||||
char* t = (char*)_cmMidiFileMalloc(mfp,byteN);
|
char* t = cmLhAllocZ(mfp->lhH,char,byteN);
|
||||||
|
|
||||||
if( cmFileReadChar(mfp->fh,t,byteN) != kOkFileRC )
|
if( cmFileReadChar(mfp->fh,t,byteN) != kOkFileRC )
|
||||||
return cmErrMsg(&mfp->err,kFileFailMfRC,"MIDI read record failed.");
|
return cmErrMsg(&mfp->err,kFileFailMfRC,"MIDI read record failed.");
|
||||||
@ -160,7 +156,7 @@ cmMfRC_t _cmMidiFileReadVarLen( _cmMidiFile_t* mfp, unsigned* p )
|
|||||||
|
|
||||||
cmMidiTrackMsg_t* _cmMidiFileAllocMsg( _cmMidiFile_t* mfp, unsigned short trkIdx, unsigned dtick, cmMidiByte_t status )
|
cmMidiTrackMsg_t* _cmMidiFileAllocMsg( _cmMidiFile_t* mfp, unsigned short trkIdx, unsigned dtick, cmMidiByte_t status )
|
||||||
{
|
{
|
||||||
cmMidiTrackMsg_t* tmp = (cmMidiTrackMsg_t*)_cmMidiFileMalloc(mfp, sizeof(cmMidiTrackMsg_t) );
|
cmMidiTrackMsg_t* tmp = cmLhAllocZ(mfp->lhH,cmMidiTrackMsg_t, 1 );
|
||||||
|
|
||||||
// set the generic track record fields
|
// set the generic track record fields
|
||||||
tmp->dtick = dtick;
|
tmp->dtick = dtick;
|
||||||
@ -226,7 +222,7 @@ cmMfRC_t _cmMidiFileReadSysEx( _cmMidiFile_t* mfp, cmMidiTrackMsg_t* tmp, unsign
|
|||||||
}
|
}
|
||||||
|
|
||||||
// allocate memory to hold the sys-ex msg
|
// allocate memory to hold the sys-ex msg
|
||||||
cmMidiByte_t* mp = (cmMidiByte_t *)_cmMidiFileMalloc(mfp, byteN );
|
cmMidiByte_t* mp = cmLhAllocZ(mfp->lhH,cmMidiByte_t, byteN );
|
||||||
|
|
||||||
// read the sys-ex msg from the file into msg memory
|
// read the sys-ex msg from the file into msg memory
|
||||||
if( cmFileReadUChar(mfp->fh,mp,byteN) != kOkFileRC )
|
if( cmFileReadUChar(mfp->fh,mp,byteN) != kOkFileRC )
|
||||||
@ -241,7 +237,7 @@ cmMfRC_t _cmMidiFileReadSysEx( _cmMidiFile_t* mfp, cmMidiTrackMsg_t* tmp, unsign
|
|||||||
cmMfRC_t _cmMidiFileReadChannelMsg( _cmMidiFile_t* mfp, cmMidiByte_t* rsPtr, cmMidiByte_t status, cmMidiTrackMsg_t* tmp )
|
cmMfRC_t _cmMidiFileReadChannelMsg( _cmMidiFile_t* mfp, cmMidiByte_t* rsPtr, cmMidiByte_t status, cmMidiTrackMsg_t* tmp )
|
||||||
{
|
{
|
||||||
cmMfRC_t rc = kOkMfRC;
|
cmMfRC_t rc = kOkMfRC;
|
||||||
cmMidiChMsg_t* p = (cmMidiChMsg_t*)_cmMidiFileMalloc(mfp,sizeof(cmMidiChMsg_t));
|
cmMidiChMsg_t* p = cmLhAllocZ(mfp->lhH,cmMidiChMsg_t,1);
|
||||||
unsigned useRsFl = status <= 0x7f;
|
unsigned useRsFl = status <= 0x7f;
|
||||||
cmMidiByte_t statusCh = useRsFl ? *rsPtr : status;
|
cmMidiByte_t statusCh = useRsFl ? *rsPtr : status;
|
||||||
|
|
||||||
@ -409,14 +405,14 @@ cmMfRC_t _cmMidiFileReadHdr( _cmMidiFile_t* mfp )
|
|||||||
// if the division field was given in smpte
|
// if the division field was given in smpte
|
||||||
if( mfp->ticksPerQN & 0x8000 )
|
if( mfp->ticksPerQN & 0x8000 )
|
||||||
{
|
{
|
||||||
mfp->smpteFmtId = (mfp->ticksPerQN & 0x7f00) >> 8;
|
mfp->smpteFmtId = (mfp->ticksPerQN & 0x7f00) >> 8;
|
||||||
mfp->smpteTicksPerFrame = (mfp->ticksPerQN & 0xFF);
|
mfp->smpteTicksPerFrame = (mfp->ticksPerQN & 0xFF);
|
||||||
mfp->ticksPerQN = 0;
|
mfp->ticksPerQN = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate and zero the track array
|
// allocate and zero the track array
|
||||||
if( mfp->trkN )
|
if( mfp->trkN )
|
||||||
mfp->trkV = _cmMidiFileMalloc( mfp, sizeof(_cmMidiTrack_t)*mfp->trkN);
|
mfp->trkV = cmLhAllocZ(mfp->lhH, _cmMidiTrack_t, mfp->trkN);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -565,69 +561,79 @@ void _cmMidiFileLinearize( _cmMidiFile_t* mfp )
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmMfRC_t _cmMidiFileCreate( cmCtx_t* ctx, cmMidiFileH_t* hp )
|
||||||
cmMfRC_t cmMidiFileOpen( cmCtx_t* ctx, cmMidiFileH_t* hPtr, const char* fn )
|
|
||||||
{
|
{
|
||||||
cmMfRC_t rc = kOkMfRC;
|
cmMfRC_t rc = kOkMfRC;
|
||||||
_cmMidiFile_t* mfp = NULL;
|
_cmMidiFile_t* p = NULL;
|
||||||
unsigned short trkIdx = 0;
|
|
||||||
cmErr_t err;
|
|
||||||
|
|
||||||
if( cmMidiFileIsValid(*hPtr) )
|
if((rc = cmMidiFileClose(hp)) != kOkMfRC )
|
||||||
if((rc = _cmMidiFileClose(_cmMidiFileHandleToPtr(*hPtr))) != kOkMfRC )
|
return rc;
|
||||||
return rc;
|
|
||||||
|
|
||||||
cmErrSetup(&err,&ctx->rpt,"MIDI File");
|
|
||||||
|
|
||||||
// allocate the midi file object
|
// allocate the midi file object
|
||||||
if(( mfp = cmMemAllocZ( _cmMidiFile_t, 1)) == NULL )
|
if(( p = cmMemAllocZ( _cmMidiFile_t, 1)) == NULL )
|
||||||
return rc = cmErrMsg(&err,kMemAllocFailMfRC,"MIDI file memory allocation failed.");
|
return rc = cmErrMsg(&ctx->err,kMemAllocFailMfRC,"MIDI file memory allocation failed.");
|
||||||
|
|
||||||
cmErrClone(&mfp->err,&err);
|
cmErrSetup(&p->err,&ctx->rpt,"MIDI File");
|
||||||
|
|
||||||
// allocate the linked heap
|
// allocate the linked heap
|
||||||
if( cmLHeapIsValid( mfp->lhH = cmLHeapCreate( 1024, ctx )) == false )
|
if( cmLHeapIsValid( p->lhH = cmLHeapCreate( 1024, ctx )) == false )
|
||||||
{
|
rc = cmErrMsg(&p->err,kMemAllocFailMfRC,"MIDI heap allocation failed.");
|
||||||
rc = cmErrMsg(&err,kMemAllocFailMfRC,"MIDI heap allocation failed.");
|
|
||||||
goto errLabel;
|
if( rc != kOkMfRC )
|
||||||
}
|
_cmMidiFileClose(p);
|
||||||
|
else
|
||||||
|
hp->h = p;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cmMfRC_t cmMidiFileOpen( cmCtx_t* ctx, cmMidiFileH_t* hp, const char* fn )
|
||||||
|
{
|
||||||
|
cmMfRC_t rc = kOkMfRC;
|
||||||
|
unsigned short trkIdx = 0;
|
||||||
|
|
||||||
|
if((rc = _cmMidiFileCreate(ctx,hp)) != kOkMfRC )
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
_cmMidiFile_t* p = _cmMidiFileHandleToPtr(*hp);
|
||||||
|
|
||||||
// open the file
|
// open the file
|
||||||
if(cmFileOpen(&mfp->fh,fn,kReadFileFl | kBinaryFileFl,mfp->err.rpt) != kOkFileRC )
|
if(cmFileOpen(&p->fh,fn,kReadFileFl | kBinaryFileFl,p->err.rpt) != kOkFileRC )
|
||||||
{
|
{
|
||||||
rc = cmErrMsg(&mfp->err,kFileFailMfRC,"MIDI file open failed.");
|
rc = cmErrMsg(&p->err,kFileFailMfRC,"MIDI file open failed.");
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read header and setup track array
|
// read header and setup track array
|
||||||
if(( rc = _cmMidiFileReadHdr(mfp)) != kOkMfRC )
|
if(( rc = _cmMidiFileReadHdr(p)) != kOkMfRC )
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
|
|
||||||
while( !cmFileEof(mfp->fh) && trkIdx < mfp->trkN )
|
while( !cmFileEof(p->fh) && trkIdx < p->trkN )
|
||||||
{
|
{
|
||||||
unsigned chkId = 0,chkN=0;
|
unsigned chkId = 0,chkN=0;
|
||||||
|
|
||||||
// read the chunk id
|
// read the chunk id
|
||||||
if((rc = _cmMidiFileRead32(mfp,&chkId)) != kOkMfRC )
|
if((rc = _cmMidiFileRead32(p,&chkId)) != kOkMfRC )
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
|
|
||||||
// read the chunk size
|
// read the chunk size
|
||||||
if((rc = _cmMidiFileRead32(mfp,&chkN)) != kOkMfRC )
|
if((rc = _cmMidiFileRead32(p,&chkN)) != kOkMfRC )
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
|
|
||||||
// if this is not a trk chunk then skip it
|
// if this is not a trk chunk then skip it
|
||||||
if( chkId != (unsigned)'MTrk')
|
if( chkId != (unsigned)'MTrk')
|
||||||
{
|
{
|
||||||
//if( fseek( mfp->fp, chkN, SEEK_CUR) != 0 )
|
//if( fseek( p->fp, chkN, SEEK_CUR) != 0 )
|
||||||
if( cmFileSeek(mfp->fh,kCurFileFl,chkN) != kOkFileRC )
|
if( cmFileSeek(p->fh,kCurFileFl,chkN) != kOkFileRC )
|
||||||
{
|
{
|
||||||
rc = cmErrMsg(&mfp->err,kFileFailMfRC,"MIDI file seek failed.");
|
rc = cmErrMsg(&p->err,kFileFailMfRC,"MIDI file seek failed.");
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if((rc = _cmMidiFileReadTrack(mfp,trkIdx)) != kOkMfRC )
|
if((rc = _cmMidiFileReadTrack(p,trkIdx)) != kOkMfRC )
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
|
|
||||||
++trkIdx;
|
++trkIdx;
|
||||||
@ -635,38 +641,55 @@ cmMfRC_t cmMidiFileOpen( cmCtx_t* ctx, cmMidiFileH_t* hPtr, const char* fn )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// store the file name
|
// store the file name
|
||||||
mfp->fn = _cmMidiFileMalloc(mfp,strlen(fn)+1);
|
p->fn = cmLhAllocZ(p->lhH,char,strlen(fn)+1);
|
||||||
assert( mfp->fn != NULL );
|
assert( p->fn != NULL );
|
||||||
strcpy(mfp->fn,fn);
|
strcpy(p->fn,fn);
|
||||||
|
|
||||||
_cmMidiFileLinearize(mfp);
|
_cmMidiFileLinearize(p);
|
||||||
|
|
||||||
hPtr->h = mfp;
|
|
||||||
|
|
||||||
errLabel:
|
errLabel:
|
||||||
|
|
||||||
if( cmFileClose(&mfp->fh) != kOkFileRC )
|
if( cmFileClose(&p->fh) != kOkFileRC )
|
||||||
rc = cmErrMsg(&mfp->err,kFileFailMfRC,"MIDI file close failed.");
|
rc = cmErrMsg(&p->err,kFileFailMfRC,"MIDI file close failed.");
|
||||||
|
|
||||||
if( rc != kOkMfRC )
|
if( rc != kOkMfRC )
|
||||||
_cmMidiFileClose(mfp);
|
_cmMidiFileClose(p);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmMfRC_t cmMidiFileCreate( cmCtx_t* ctx, cmMidiFileH_t* hp, unsigned trkN, unsigned ticksPerQN )
|
||||||
|
{
|
||||||
|
cmMfRC_t rc = kOkMfRC;
|
||||||
|
|
||||||
|
if((rc = _cmMidiFileCreate(ctx,hp)) != kOkMfRC )
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
_cmMidiFile_t* p = _cmMidiFileHandleToPtr(*hp);
|
||||||
|
|
||||||
|
p->ticksPerQN = ticksPerQN;
|
||||||
|
p->fmtId = 1;
|
||||||
|
p->trkN = trkN;
|
||||||
|
p->trkV = cmLhAllocZ(p->lhH, _cmMidiTrack_t, p->trkN);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cmMfRC_t cmMidiFileClose( cmMidiFileH_t* hp )
|
||||||
cmMfRC_t cmMidiFileClose( cmMidiFileH_t* h )
|
|
||||||
{
|
{
|
||||||
cmMfRC_t rc;
|
cmMfRC_t rc = kOkMfRC;
|
||||||
|
|
||||||
if( cmMidiFileIsNull(*h) )
|
if( hp==NULL || cmMidiFileIsValid(*hp)==false )
|
||||||
return kOkMfRC;
|
return kOkMfRC;
|
||||||
|
|
||||||
if((rc = _cmMidiFileClose(_cmMidiFileHandleToPtr(*h))) == kOkMfRC )
|
_cmMidiFile_t* p = _cmMidiFileHandleToPtr(*hp);
|
||||||
|
|
||||||
|
if((rc = _cmMidiFileClose(p)) != kOkMfRC )
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
h->h = NULL;
|
hp->h = NULL;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1013,7 +1036,7 @@ cmMfRC_t cmMidiFileWrite( cmMidiFileH_t h, const char* fn )
|
|||||||
|
|
||||||
|
|
||||||
bool cmMidiFileIsValid( cmMidiFileH_t h )
|
bool cmMidiFileIsValid( cmMidiFileH_t h )
|
||||||
{ return !cmMidiFileIsNull(h); }
|
{ return h.h != NULL; }
|
||||||
|
|
||||||
unsigned cmMidiFileTrackCount( cmMidiFileH_t h )
|
unsigned cmMidiFileTrackCount( cmMidiFileH_t h )
|
||||||
{
|
{
|
||||||
@ -1220,7 +1243,7 @@ cmMfRC_t cmMidiFileInsertMsg( cmMidiFileH_t h, unsigned uid, int dtick, cmMidiBy
|
|||||||
// complete the msg setup
|
// complete the msg setup
|
||||||
_cmMidiTrack_t* trk = mfp->trkV + trkIdx;
|
_cmMidiTrack_t* trk = mfp->trkV + trkIdx;
|
||||||
cmMidiTrackMsg_t* m = _cmMidiFileAllocMsg(mfp, trkIdx, abs(dtick), status );
|
cmMidiTrackMsg_t* m = _cmMidiFileAllocMsg(mfp, trkIdx, abs(dtick), status );
|
||||||
cmMidiChMsg_t* c = (cmMidiChMsg_t*)_cmMidiFileMalloc(mfp,sizeof(cmMidiChMsg_t));
|
cmMidiChMsg_t* c = cmLhAllocZ(mfp->lhH,cmMidiChMsg_t,1);
|
||||||
|
|
||||||
m->u.chMsgPtr = c;
|
m->u.chMsgPtr = c;
|
||||||
|
|
||||||
@ -1255,6 +1278,105 @@ cmMfRC_t cmMidiFileInsertMsg( cmMidiFileH_t h, unsigned uid, int dtick, cmMidiBy
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only set
|
||||||
|
// atick - used to position the msg in the track
|
||||||
|
// status - this field is always set (Note that channel information must stripped from the status byte and included in the channel msg data)
|
||||||
|
// metaId - this field is optional depending on the msg type
|
||||||
|
// byteCnt - used to allocate storage for the data element in 'cmMidiTrackMsg_t.u'
|
||||||
|
// u - the message data
|
||||||
|
cmMfRC_t cmMidiFileInsertTrackMsg( cmMidiFileH_t h, unsigned trkIdx, const cmMidiTrackMsg_t* msg )
|
||||||
|
{
|
||||||
|
_cmMidiFile_t* p = _cmMidiFileHandleToPtr(h);
|
||||||
|
|
||||||
|
// validate the track index
|
||||||
|
if( trkIdx >= p->trkN )
|
||||||
|
return cmErrMsg(&p->err,kInvalidTrkIndexMfRC,"The track index (%i) is invalid.",trkIdx);
|
||||||
|
|
||||||
|
// allocate a new track record
|
||||||
|
cmMidiTrackMsg_t* m = (cmMidiTrackMsg_t*)cmLhAllocZ(p->lhH,char,sizeof(cmMidiTrackMsg_t)+msg->byteCnt);
|
||||||
|
|
||||||
|
// fill the track record
|
||||||
|
m->uid = p->nextUid++;
|
||||||
|
m->atick = msg->atick;
|
||||||
|
m->status = msg->status;
|
||||||
|
m->metaId = msg->metaId;
|
||||||
|
m->trkIdx = trkIdx;
|
||||||
|
m->byteCnt = msg->byteCnt;
|
||||||
|
memcpy(&m->u,&msg->u,sizeof(msg->u));
|
||||||
|
|
||||||
|
// copy the exernal data
|
||||||
|
if( msg->byteCnt > 0 )
|
||||||
|
{
|
||||||
|
m->u.voidPtr = (m+1);
|
||||||
|
memcpy((void*)m->u.voidPtr,msg->u.voidPtr,msg->byteCnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmMidiTrackMsg_t* m0 = NULL;
|
||||||
|
cmMidiTrackMsg_t* m1 = p->trkV[trkIdx].base;
|
||||||
|
|
||||||
|
// locate the track record before and after the new msg
|
||||||
|
for(; m1!=NULL; m1=m1->link)
|
||||||
|
if( m1->atick > m->atick )
|
||||||
|
{
|
||||||
|
if( m0 == NULL )
|
||||||
|
p->trkV[trkIdx].base = m;
|
||||||
|
else
|
||||||
|
m0->link = m;
|
||||||
|
|
||||||
|
m->link = m1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the new track record is the last msg
|
||||||
|
if( m1 == NULL )
|
||||||
|
{
|
||||||
|
m1 = p->trkV[trkIdx].last;
|
||||||
|
m1->link = m;
|
||||||
|
p->trkV[trkIdx].last = m;
|
||||||
|
if( p->trkV[trkIdx].base == NULL )
|
||||||
|
p->trkV[trkIdx].base = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return kOkMfRC;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cmMfRC_t cmMidiFileInsertTrackChMsg( cmMidiFileH_t h, unsigned trkIdx, unsigned atick, cmMidiByte_t status, cmMidiByte_t d0, cmMidiByte_t d1 )
|
||||||
|
{
|
||||||
|
cmMidiTrackMsg_t m;
|
||||||
|
cmMidiChMsg_t cm;
|
||||||
|
|
||||||
|
memset(&m,0,sizeof(m));
|
||||||
|
memset(&cm,0,sizeof(cm));
|
||||||
|
|
||||||
|
cm.ch = status & 0x0f;
|
||||||
|
cm.d0 = d0;
|
||||||
|
cm.d1 = d1;
|
||||||
|
|
||||||
|
m.atick = atick;
|
||||||
|
m.status = status & 0xf0;
|
||||||
|
m.byteCnt = sizeof(cm);
|
||||||
|
m.u.chMsgPtr = &cm;
|
||||||
|
|
||||||
|
return cmMidiFileInsertTrackMsg(h,trkIdx,&m);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmMfRC_t cmMidFileInsertTrackTempoMsg( cmMidiFileH_t h, unsigned trkIdx, unsigned atick, unsigned bpm )
|
||||||
|
{
|
||||||
|
cmMidiTrackMsg_t m;
|
||||||
|
|
||||||
|
memset(&m,0,sizeof(m));
|
||||||
|
|
||||||
|
m.atick = atick;
|
||||||
|
m.status = kMetaStId;
|
||||||
|
m.metaId = kTempoMdId;
|
||||||
|
m.u.iVal = 60000000/bpm; // convert BPM to microsPerQN
|
||||||
|
|
||||||
|
return cmMidiFileInsertTrackMsg(h,trkIdx,&m);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned cmMidiFileSeekUsecs( cmMidiFileH_t h, unsigned long long offsUSecs, unsigned* msgUsecsPtr, unsigned* microsPerTickPtr )
|
unsigned cmMidiFileSeekUsecs( cmMidiFileH_t h, unsigned long long offsUSecs, unsigned* msgUsecsPtr, unsigned* microsPerTickPtr )
|
||||||
{
|
{
|
||||||
_cmMidiFile_t* p;
|
_cmMidiFile_t* p;
|
||||||
@ -1657,9 +1779,6 @@ void cmMidiFilePrintTracks( cmMidiFileH_t h, unsigned trkIdx, cmRpt_t* rpt )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmMidiFileIsNull( cmMidiFileH_t h )
|
|
||||||
{ return (_cmMidiFile_t*)h.h == NULL; }
|
|
||||||
|
|
||||||
|
|
||||||
void cmMidiFileTestPrint( void* printDataPtr, const char* fmt, va_list vl )
|
void cmMidiFileTestPrint( void* printDataPtr, const char* fmt, va_list vl )
|
||||||
{ vprintf(fmt,vl); }
|
{ vprintf(fmt,vl); }
|
||||||
|
11
cmMidiFile.h
11
cmMidiFile.h
@ -116,12 +116,14 @@ extern "C" {
|
|||||||
kSostenutoPedalMfRC, // 11
|
kSostenutoPedalMfRC, // 11
|
||||||
kLargeDeltaTickMfRC, // 12 (a large delta tick value was filtered)
|
kLargeDeltaTickMfRC, // 12 (a large delta tick value was filtered)
|
||||||
kUidNotFoundMfRC, // 13
|
kUidNotFoundMfRC, // 13
|
||||||
kUidNotANoteMsgMfRC // 14
|
kUidNotANoteMsgMfRC, // 14
|
||||||
|
kInvalidTrkIndexMfRC // 15
|
||||||
};
|
};
|
||||||
|
|
||||||
extern cmMidiFileH_t cmMidiFileNullHandle;
|
extern cmMidiFileH_t cmMidiFileNullHandle;
|
||||||
|
|
||||||
cmMfRC_t cmMidiFileOpen( cmCtx_t* ctx, cmMidiFileH_t* hPtr, const char* fn );
|
cmMfRC_t cmMidiFileOpen( cmCtx_t* ctx, cmMidiFileH_t* h, const char* fn );
|
||||||
|
cmMfRC_t cmMidiFileCreate( cmCtx_t* ctx, cmMidiFileH_t* hp, unsigned trkN, unsigned ticksPerQN );
|
||||||
cmMfRC_t cmMidiFileClose( cmMidiFileH_t* hp );
|
cmMfRC_t cmMidiFileClose( cmMidiFileH_t* hp );
|
||||||
|
|
||||||
cmMfRC_t cmMidiFileWrite( cmMidiFileH_t h, const char* fn );
|
cmMfRC_t cmMidiFileWrite( cmMidiFileH_t h, const char* fn );
|
||||||
@ -168,6 +170,10 @@ extern "C" {
|
|||||||
// If dtick is positive/negative then the new msg is inserted after/before the reference msg.
|
// If dtick is positive/negative then the new msg is inserted after/before the reference msg.
|
||||||
cmMfRC_t cmMidiFileInsertMsg( cmMidiFileH_t h, unsigned uid, int dtick, cmMidiByte_t ch, cmMidiByte_t status, cmMidiByte_t d0, cmMidiByte_t d1 );
|
cmMfRC_t cmMidiFileInsertMsg( cmMidiFileH_t h, unsigned uid, int dtick, cmMidiByte_t ch, cmMidiByte_t status, cmMidiByte_t d0, cmMidiByte_t d1 );
|
||||||
|
|
||||||
|
cmMfRC_t cmMidiFileInsertTrackMsg( cmMidiFileH_t h, unsigned trkIdx, const cmMidiTrackMsg_t* msg );
|
||||||
|
cmMfRC_t cmMidiFileInsertTrackChMsg( cmMidiFileH_t h, unsigned trkIdx, unsigned atick, cmMidiByte_t status, cmMidiByte_t d0, cmMidiByte_t d1 );
|
||||||
|
cmMfRC_t cmMidFileInsertTrackTempoMsg( cmMidiFileH_t h, unsigned trkIdx, unsigned atick, unsigned bpm );
|
||||||
|
|
||||||
// Return a pointer to the first msg at or after 'usecsOffs' or kInvalidIdx if no
|
// Return a pointer to the first msg at or after 'usecsOffs' or kInvalidIdx if no
|
||||||
// msg exists after 'usecsOffs'. Note that 'usecOffs' is an offset from the beginning
|
// msg exists after 'usecsOffs'. Note that 'usecOffs' is an offset from the beginning
|
||||||
// of the file.
|
// of the file.
|
||||||
@ -191,7 +197,6 @@ extern "C" {
|
|||||||
|
|
||||||
void cmMidiFilePrintMsgs( cmMidiFileH_t h, cmRpt_t* rpt );
|
void cmMidiFilePrintMsgs( cmMidiFileH_t h, cmRpt_t* rpt );
|
||||||
void cmMidiFilePrintTrack( cmMidiFileH_t h, unsigned trkIdx, cmRpt_t* rpt );
|
void cmMidiFilePrintTrack( cmMidiFileH_t h, unsigned trkIdx, cmRpt_t* rpt );
|
||||||
bool cmMidiFileIsNull( cmMidiFileH_t h );
|
|
||||||
void cmMidiFileTest( const char* fn, cmCtx_t* ctx );
|
void cmMidiFileTest( const char* fn, cmCtx_t* ctx );
|
||||||
|
|
||||||
// Generate a piano-roll plot description file which can be displayed with cmXScore.m
|
// Generate a piano-roll plot description file which can be displayed with cmXScore.m
|
||||||
|
@ -88,7 +88,7 @@ cmMfpRC_t cmMfpDestroy( cmMfpH_t* hp )
|
|||||||
{
|
{
|
||||||
cmMfp_t* p = _cmMfpHandleToPtr(*hp);
|
cmMfp_t* p = _cmMfpHandleToPtr(*hp);
|
||||||
|
|
||||||
if( cmMidiFileIsNull(p->mfH)==false && p->closeFileFl==true )
|
if( cmMidiFileIsValid(p->mfH)==false && p->closeFileFl==true )
|
||||||
cmMidiFileClose(&p->mfH);
|
cmMidiFileClose(&p->mfH);
|
||||||
|
|
||||||
cmMemFree(p);
|
cmMemFree(p);
|
||||||
@ -121,7 +121,7 @@ cmMfpRC_t cmMfpLoadHandle( cmMfpH_t h, cmMidiFileH_t mfH )
|
|||||||
cmMfp_t* p = _cmMfpHandleToPtr(h);
|
cmMfp_t* p = _cmMfpHandleToPtr(h);
|
||||||
|
|
||||||
// if a file has already been assigned to this player
|
// if a file has already been assigned to this player
|
||||||
if( (cmMidiFileIsNull(p->mfH) == false) && p->closeFileFl)
|
if( (cmMidiFileIsValid(p->mfH) == false) && p->closeFileFl)
|
||||||
{
|
{
|
||||||
// close the existing file
|
// close the existing file
|
||||||
cmMidiFileClose(&p->mfH);
|
cmMidiFileClose(&p->mfH);
|
||||||
|
Loading…
Reference in New Issue
Block a user