diff --git a/cmMidiFile.c b/cmMidiFile.c index 2dba64d..f99a267 100644 --- a/cmMidiFile.c +++ b/cmMidiFile.c @@ -266,6 +266,10 @@ cmMfRC_t _cmMidiFileReadChannelMsg( _cmMidiFile_t* mfp, cmMidiByte_t* rsPtr, cmM return rc; } + // convert note-on velocity=0 to note off + if( tmp->status == kNoteOnMdId && p->d1==0 ) + tmp->status = kNoteOffMdId; + tmp->u.chMsgPtr = p; return rc; @@ -833,13 +837,23 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h ) _cmMidiVoice_t* vp; bool sustainFlagV[ kMidiChCnt ]; + for(mi=0; mimsgN; ++mi) { cmMidiTrackMsg_t* mp = p->msgV[mi]; // update the duration of the sounding notes + //int ii=0; + //printf("---- %i ------\n",mi); for(vp = list; vp!=NULL; vp=vp->link) + { vp->durTicks += mp->dtick; + //printf("%i %i %p %p\n",ii,vp->sustainFl,vp,vp->link); + //++ii; + } + // // If this is sustain pedal msg @@ -894,6 +908,8 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h ) // 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) ) { + assert( mp->u.chMsgPtr->ch < kMidiChCnt ); + if( sustainFlagV[mp->u.chMsgPtr->ch] ) vp->sustainFl = true; else diff --git a/cmMidiFile.h b/cmMidiFile.h index 345e80f..40c1693 100644 --- a/cmMidiFile.h +++ b/cmMidiFile.h @@ -1,6 +1,10 @@ #ifndef cmMidiFile_h #define cmMidiFile_h +#ifdef __cplusplus +extern "C" { +#endif + // MIDI file timing: // Messages in the MIDI file are time tagged with a delta offset in 'ticks' // from the previous message in the same track. @@ -15,6 +19,10 @@ // MpQN is given as the value of the MIDI file tempo message. // // See cmMidiFileSeekUSecs() for an example of converting ticks to milliseconds. +// +// As part of the file reading process, the status byte of note-on messages +// with velocity=0 are is changed to a note-off message. See _cmMidiFileReadChannelMsg(). + typedef cmHandle_t cmMidiFileH_t; @@ -159,5 +167,9 @@ unsigned cmMidiFilePackTrackMsgBufByteCount( const cmMidiTrackMsg_t void cmMidiFilePrint( cmMidiFileH_t h, unsigned trkIdx, cmRpt_t* rpt ); bool cmMidiFileIsNull( cmMidiFileH_t h ); void cmMidiFileTest( const char* fn, cmCtx_t* ctx ); + +#ifdef __cplusplus +} +#endif #endif