cmMidiFile: Debug Note duration calculation

This commit is contained in:
kpl 2012-11-23 21:27:50 -08:00
parent 59cbd9c297
commit b7191065bb

View File

@ -828,22 +828,27 @@ typedef struct _cmMidiVoice_str
struct _cmMidiVoice_str* link; struct _cmMidiVoice_str* link;
} _cmMidiVoice_t; } _cmMidiVoice_t;
void _cmMidFileCalcNoteDurationReleaseNote( _cmMidiVoice_t** listPtrPtr, _cmMidiVoice_t* pp, _cmMidiVoice_t* vp ) void _cmMidFileCalcNoteDurationReleaseNote( _cmMidiVoice_t** listPtrPtr, _cmMidiVoice_t* pp, _cmMidiVoice_t* vp )
{ {
assert( (pp==NULL && vp==*listPtrPtr) || pp->link==vp);
// store the duration of the note into the track msg // store the duration of the note into the track msg
// assoc'd with the note-on msg // assoc'd with the note-on msg
cmMidiChMsg_t* cmp = (cmMidiChMsg_t*)vp->mp->u.chMsgPtr; // cast away const cmMidiChMsg_t* cmp = (cmMidiChMsg_t*)vp->mp->u.chMsgPtr; // cast away const
cmp->durTicks = vp->durTicks; cmp->durTicks = vp->durTicks;
// unlink the active voice msg _cmMidiVoice_t* np = vp->link;
if( pp == NULL )
*listPtrPtr = vp->link;
else
pp->link = vp->link;
// release the voice msg // release the voice msg
cmMemFree(vp); cmMemFree(vp);
// unlink the active voice msg
if( pp == NULL )
*listPtrPtr = np;
else
pp->link = np;
} }
void cmMidiFileCalcNoteDurations( cmMidiFileH_t h ) void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
@ -856,48 +861,43 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
if( p->msgN == 0 ) if( p->msgN == 0 )
return; return;
unsigned mi; unsigned mi = cmInvalidId;
_cmMidiVoice_t* list = NULL; _cmMidiVoice_t* list = NULL; // list of active voices
_cmMidiVoice_t* vp; _cmMidiVoice_t* vp = NULL;
bool sustainFlagV[ kMidiChCnt ]; bool sustainFlagV[ kMidiChCnt ];
// clear the sustain pedal flag
for(mi=0; mi<kMidiChCnt; ++mi) for(mi=0; mi<kMidiChCnt; ++mi)
sustainFlagV[mi]=false; sustainFlagV[mi]=false;
for(mi=0; mi<p->msgN; ++mi) for(mi=0; mi<p->msgN; ++mi)
{ {
cmMidiTrackMsg_t* mp = p->msgV[mi]; cmMidiTrackMsg_t* mp = p->msgV[mi];
// update the duration of the sounding notes // update the duration of the sounding notes
//int ii=0;
//printf("---- %i ------\n",mi);
for(vp = list; vp!=NULL; vp=vp->link) for(vp = list; vp!=NULL; vp=vp->link)
{
vp->durTicks += mp->dtick; vp->durTicks += mp->dtick;
//printf("%i %i %p %p\n",ii,vp->sustainFl,vp,vp->link);
//++ii;
}
// //
// If this is sustain pedal msg // If this is sustain pedal msg
// //
if( mp->status==kCtlMdId && mp->u.chMsgPtr->d0 == kSustainCtlMdId ) if( mp->status==kCtlMdId && mp->u.chMsgPtr->d0 == kSustainCtlMdId )
{ {
assert( mp->u.chMsgPtr->ch < kMidiChCnt ); unsigned chIdx = mp->u.chMsgPtr->ch;
assert( chIdx < kMidiChCnt );
// set the state of the sustain pedal flags // set the state of the sustain pedal flags
sustainFlagV[mp->u.chMsgPtr->ch] = mp->u.chMsgPtr->d1 >= 64; sustainFlagV[chIdx] = mp->u.chMsgPtr->d1 >= 64;
// if the pedal went up ... // if the pedal went up ...
if( sustainFlagV[mp->u.chMsgPtr->ch] == false ) if( sustainFlagV[chIdx] == false )
{ {
// ... then release sustaining notes // ... then release sustaining notes
_cmMidiVoice_t* pp = NULL; _cmMidiVoice_t* pp = NULL;
for(vp=list; vp != NULL; ) for(vp=list; vp != NULL; )
{ {
_cmMidiVoice_t* np = vp->link; _cmMidiVoice_t* np = vp->link;
if( vp->sustainFl && (vp->mp->u.chMsgPtr->ch == mp->u.chMsgPtr->ch) ) if( vp->sustainFl && (vp->mp->u.chMsgPtr->ch == chIdx) )
_cmMidFileCalcNoteDurationReleaseNote(&list,pp,vp); _cmMidFileCalcNoteDurationReleaseNote(&list,pp,vp);
else else
pp = vp; pp = vp;
@ -925,16 +925,18 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
if( (mp->status==kNoteOnMdId && mp->u.chMsgPtr->d1==0) || (mp->status==kNoteOffMdId) ) if( (mp->status==kNoteOnMdId && mp->u.chMsgPtr->d1==0) || (mp->status==kNoteOffMdId) )
{ {
_cmMidiVoice_t* pp = NULL; _cmMidiVoice_t* pp = NULL;
unsigned chIdx = mp->u.chMsgPtr->ch;
assert( chIdx < kMidiChCnt );
// for each active voice // for each active voice
for(vp=list; vp!=NULL; vp=vp->link ) for(vp=list; vp!=NULL; vp=vp->link )
{ {
// if this active voice ch/pitch matches the note-off msg ch pitch // if this active voice ch/pitch matches the note-off msg ch pitch
if( (vp->mp->u.chMsgPtr->d0==mp->u.chMsgPtr->d0) && (vp->mp->u.chMsgPtr->ch==mp->u.chMsgPtr->ch) ) if( (vp->mp->u.chMsgPtr->d0==mp->u.chMsgPtr->d0) && (vp->mp->u.chMsgPtr->ch==chIdx) )
{ {
assert( mp->u.chMsgPtr->ch < kMidiChCnt ); // if the sustain pedal is down for this channel - then defer turning the note off
if( sustainFlagV[chIdx] )
if( sustainFlagV[mp->u.chMsgPtr->ch] )
vp->sustainFl = true; vp->sustainFl = true;
else else
_cmMidFileCalcNoteDurationReleaseNote(&list,pp,vp); _cmMidFileCalcNoteDurationReleaseNote(&list,pp,vp);
@ -942,7 +944,7 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
} }
pp = vp; pp = vp;
} // end while } // end for
} // end if } // end if
} // end-for } // end-for