cmProc4.h/c: Refinements to cmScAlign and initial interface for cmScMeas.
This commit is contained in:
parent
78c9c3064b
commit
85393d61c9
202
cmProc4.c
202
cmProc4.c
@ -1246,11 +1246,11 @@ cmRC_t cmScAlignInit( cmScAlign* p, cmScAlignCb_t cbFunc, void* cbArg, cmRea
|
|||||||
p->loc[ei+i].evtV = cmMemAllocZ(cmScAlignScEvt_t,n);
|
p->loc[ei+i].evtV = cmMemAllocZ(cmScAlignScEvt_t,n);
|
||||||
p->loc[ei+i].scLocIdx = li;
|
p->loc[ei+i].scLocIdx = li;
|
||||||
p->loc[ei+i].barNumb = lp->barNumb;
|
p->loc[ei+i].barNumb = lp->barNumb;
|
||||||
|
|
||||||
for(j=0,k=0; j<lp->evtCnt; ++j)
|
for(j=0,k=0; j<lp->evtCnt; ++j)
|
||||||
if( lp->evtArray[j]->type == kNonEvtScId )
|
if( lp->evtArray[j]->type == kNonEvtScId )
|
||||||
{
|
{
|
||||||
p->loc[ei+i].evtV[k].pitch = lp->evtArray[j]->pitch;
|
p->loc[ei+i].evtV[k].pitch = lp->evtArray[j]->pitch;
|
||||||
p->loc[ei+i].evtV[k].scEvtIdx = lp->evtArray[j]->index;
|
|
||||||
++k;
|
++k;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1311,6 +1311,8 @@ cmRC_t cmScAlignInit( cmScAlign* p, cmScAlignCb_t cbFunc, void* cbArg, cmRea
|
|||||||
|
|
||||||
//_cmScAlignPrint(p);
|
//_cmScAlignPrint(p);
|
||||||
|
|
||||||
|
cmScAlignReset(p,0);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1329,7 +1331,9 @@ void cmScAlignReset( cmScAlign* p, unsigned begScanLocIdx )
|
|||||||
p->mbi = p->mn;
|
p->mbi = p->mn;
|
||||||
p->mni = 0;
|
p->mni = 0;
|
||||||
p->begScanLocIdx = begScanLocIdx;
|
p->begScanLocIdx = begScanLocIdx;
|
||||||
|
p->begSyncLocIdx = cmInvalidIdx;
|
||||||
p->s_opt = DBL_MAX;
|
p->s_opt = DBL_MAX;
|
||||||
|
p->esi = cmInvalidIdx;
|
||||||
p->missCnt = 0;
|
p->missCnt = 0;
|
||||||
p->scanCnt = 0;
|
p->scanCnt = 0;
|
||||||
p->ri = 0;
|
p->ri = 0;
|
||||||
@ -1391,8 +1395,9 @@ bool _cmScAlignCalcMtx( cmScAlign* p )
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned i,j;
|
unsigned i,j;
|
||||||
for(i=1; i<p->rn; ++i)
|
|
||||||
for(j=1; j<p->cn; ++j)
|
for(j=1; j<p->cn; ++j)
|
||||||
|
for(i=1; i<p->rn; ++i)
|
||||||
{
|
{
|
||||||
cmScAlignLoc_t* loc = p->loc + p->begScanLocIdx + j - 1;
|
cmScAlignLoc_t* loc = p->loc + p->begScanLocIdx + j - 1;
|
||||||
unsigned pitch = p->midiBuf[i-1].pitch;
|
unsigned pitch = p->midiBuf[i-1].pitch;
|
||||||
@ -1585,26 +1590,28 @@ double _cmScAlign( cmScAlign* p )
|
|||||||
return p->s_opt;
|
return p->s_opt;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmScAlignExec( cmScAlign* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 )
|
cmRC_t cmScAlignExec( cmScAlign* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 )
|
||||||
{
|
{
|
||||||
bool fl = p->mbi > 0;
|
bool fl = p->mbi > 0;
|
||||||
bool retFl = true;
|
cmRC_t rc = cmOkRC;
|
||||||
|
|
||||||
|
// update the MIDI buffer with the incoming note
|
||||||
cmScAlignInputMidi(p,smpIdx,status,d0,d1);
|
cmScAlignInputMidi(p,smpIdx,status,d0,d1);
|
||||||
|
|
||||||
|
// if the MIDI buffer transitioned to full then perform an initial scan sync.
|
||||||
if( fl && p->mbi == 0 )
|
if( fl && p->mbi == 0 )
|
||||||
{
|
{
|
||||||
if( cmScAlignScan(p,cmInvalidCnt) == cmInvalidIdx )
|
if( (p->begSyncLocIdx = cmScAlignScan(p,cmInvalidCnt)) == cmInvalidIdx )
|
||||||
retFl = false;
|
rc = cmInvalidArgRC; // signal init. scan sync. fail
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( !fl && p->mbi == 0 )
|
// if the MIDI buffer is full then perform a step sync.
|
||||||
if( !cmScAlignStep(p) )
|
if( !fl && p->mbi == 0 )
|
||||||
retFl = false;
|
rc = cmScAlignStep(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retFl;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmScAlignInputMidi( cmScAlign* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 )
|
bool cmScAlignInputMidi( cmScAlign* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 )
|
||||||
@ -1922,7 +1929,7 @@ unsigned cmScAlignScan( cmScAlign* p, unsigned scanCnt )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool cmScAlignStep( cmScAlign* p )
|
cmRC_t cmScAlignStep( cmScAlign* p )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned pitch = p->midiBuf[ p->mn-1 ].pitch;
|
unsigned pitch = p->midiBuf[ p->mn-1 ].pitch;
|
||||||
@ -1930,11 +1937,11 @@ bool cmScAlignStep( cmScAlign* p )
|
|||||||
|
|
||||||
// the tracker must be sync'd to step
|
// the tracker must be sync'd to step
|
||||||
if( p->esi == cmInvalidIdx )
|
if( p->esi == cmInvalidIdx )
|
||||||
return false;
|
return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The p->esi value must be valid to perform a step operation.");
|
||||||
|
|
||||||
// if the end of the score has been reached
|
// if the end of the score has been reached
|
||||||
if( p->esi + 1 >= p->locN )
|
if( p->esi + 1 >= p->locN )
|
||||||
return cmInvalidIdx;
|
return cmEofRC;
|
||||||
|
|
||||||
// attempt to match to next location first
|
// attempt to match to next location first
|
||||||
if( _cmScAlignIsMatch(p->loc + p->esi + 1, pitch) )
|
if( _cmScAlignIsMatch(p->loc + p->esi + 1, pitch) )
|
||||||
@ -1982,13 +1989,13 @@ bool cmScAlignStep( cmScAlign* p )
|
|||||||
|
|
||||||
// if the scan failed find a match
|
// if the scan failed find a match
|
||||||
if( bsi == cmInvalidIdx )
|
if( bsi == cmInvalidIdx )
|
||||||
return false;
|
return cmCtxRtCondition( &p->obj, cmSubSysFailRC, "Scan resync. failed.");
|
||||||
|
|
||||||
//if( bsi != cmInvalidIdx )
|
//if( bsi != cmInvalidIdx )
|
||||||
// _cmScAlignPrintPath(p, p->p_opt, bsi );
|
// _cmScAlignPrintPath(p, p->p_opt, bsi );
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return cmOkRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2227,7 +2234,26 @@ void _cmScAlignPrintReport( cmScAlign* p, cmScAlignPrint_t* a, unsigned an, unsi
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _cmScAlignPrintResult( cmScAlign* p )
|
// The goal of this function is to create a cmScAlignPrint_t array containing
|
||||||
|
// one record for each score bar, score note and errant MIDI note.
|
||||||
|
// The function works by first creating a record for each score bar and note
|
||||||
|
// and then scanning the cmScAlignResult_t array (p->res[]) for each result
|
||||||
|
// record create by an earlier call to _cmScAlignCb(). A result record can
|
||||||
|
// uniquely indicates one of the following result states based on receiving
|
||||||
|
// a MIDI event.
|
||||||
|
// Match - locIdx!=cmInvalidIdx matchFl==true mni!=cmInvalidIdx
|
||||||
|
// Mis-match - locIdx!=cmInvalidIdx matchFl==false mni!=cmInvalidIdx
|
||||||
|
// Delete - locIdx==cmInvalidIdx matchFl==false mni!=cmInvalidIdx
|
||||||
|
// Insert - locIdx==cmInvalidIdx matchFl==false mni==cmInvalidIdx
|
||||||
|
//
|
||||||
|
// This is made slightly more complicated by the fact that a given MIDI event
|
||||||
|
// may generate more than one result record. This can occur when the
|
||||||
|
// tracker is in 'step' mode and generates a result record with a given state
|
||||||
|
// as a result of a given MIDI note and then reconsiders that MIDI note
|
||||||
|
// while during a subsequent 'scan' mode resync. operation. For example
|
||||||
|
// a MIDI note which generate a 'delete' result during a step operation
|
||||||
|
// may later generate a match result during a scan.
|
||||||
|
double _cmScAlignPrintResult( cmScAlign* p )
|
||||||
{
|
{
|
||||||
// determine the scH score begin and end indexes
|
// determine the scH score begin and end indexes
|
||||||
unsigned bsi = cmScoreLocCount(p->scH);
|
unsigned bsi = cmScoreLocCount(p->scH);
|
||||||
@ -2256,9 +2282,10 @@ void _cmScAlignPrintResult( cmScAlign* p )
|
|||||||
|
|
||||||
cmScAlignPrint_t* a = cmMemAllocZ(cmScAlignPrint_t,aan);
|
cmScAlignPrint_t* a = cmMemAllocZ(cmScAlignPrint_t,aan);
|
||||||
unsigned an = 0;
|
unsigned an = 0;
|
||||||
unsigned scNoteCnt = 0;
|
unsigned scNoteCnt = 0; // notes in the score
|
||||||
unsigned matchCnt = 0; // matched score notes
|
unsigned matchCnt = 0; // matched score notes
|
||||||
unsigned wrongCnt = 0; // unmatched midi notes
|
unsigned wrongCnt = 0; // errant midi notes
|
||||||
|
unsigned skipCnt = 0; // skipped score events
|
||||||
|
|
||||||
// create a record for each score event
|
// create a record for each score event
|
||||||
for(i=bsi; i<=esi; ++i)
|
for(i=bsi; i<=esi; ++i)
|
||||||
@ -2364,11 +2391,14 @@ void _cmScAlignPrintResult( cmScAlign* p )
|
|||||||
|
|
||||||
//_cmScAlignPrintList(a,an);
|
//_cmScAlignPrintList(a,an);
|
||||||
|
|
||||||
|
// Insert records into the print record array (a[](
|
||||||
|
// to represent errant MIDI notes. (Notes which
|
||||||
|
// were played but do not match any notes in the score.)
|
||||||
|
|
||||||
// for each result record ...
|
// for each result record ...
|
||||||
for(i=0; i<p->ri; ++i)
|
for(i=0; i<p->ri; ++i)
|
||||||
{
|
{
|
||||||
cmScAlignResult_t* rp = p->res + i;
|
cmScAlignResult_t* rp = p->res + i;
|
||||||
unsigned scLocIdx = cmInvalidIdx;
|
|
||||||
cmScAlignPrint_t* pp = NULL;
|
cmScAlignPrint_t* pp = NULL;
|
||||||
cmScAlignPrint_t* dpp = NULL;
|
cmScAlignPrint_t* dpp = NULL;
|
||||||
unsigned dmin;
|
unsigned dmin;
|
||||||
@ -2377,6 +2407,7 @@ void _cmScAlignPrintResult( cmScAlign* p )
|
|||||||
if(rp->foundFl)
|
if(rp->foundFl)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// find the print recd with the closest mni
|
||||||
for(j=0; j<an; ++j)
|
for(j=0; j<an; ++j)
|
||||||
{
|
{
|
||||||
pp = a + j;
|
pp = a + j;
|
||||||
@ -2402,36 +2433,45 @@ void _cmScAlignPrintResult( cmScAlign* p )
|
|||||||
|
|
||||||
if( rp->mni > dpp->mni )
|
if( rp->mni > dpp->mni )
|
||||||
++j;
|
++j;
|
||||||
|
|
||||||
scLocIdx = dpp->scLocIdx;
|
|
||||||
|
|
||||||
|
assert( rp->locIdx == cmInvalidIdx );
|
||||||
|
|
||||||
|
// insert a print recd before or after the closest print recd
|
||||||
an = _cmScAlignPrintExpand(a,aan,j,an);
|
an = _cmScAlignPrintExpand(a,aan,j,an);
|
||||||
|
_cmScAlignPrintSet(a + j, rp, kMidiErrSaFl, dpp->scLocIdx );
|
||||||
if( rp->locIdx != cmInvalidIdx )
|
|
||||||
{
|
|
||||||
assert( rp->locIdx != cmInvalidIdx && rp->locIdx < p->locN );
|
|
||||||
scLocIdx = p->loc[ rp->locIdx ].scLocIdx;
|
|
||||||
}
|
|
||||||
|
|
||||||
++wrongCnt;
|
++wrongCnt;
|
||||||
|
|
||||||
_cmScAlignPrintSet(a + j, rp, kMidiErrSaFl, scLocIdx );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(i=0; i<an; ++i)
|
||||||
|
if( cmIsFlag(a[i].flags,kScNoteSaFl) && (a[i].mni == cmInvalidIdx || cmIsFlag(a[i].flags,kSubsErrSaFl)))
|
||||||
|
++skipCnt;
|
||||||
|
|
||||||
//_cmScAlignPrintList(a,an);
|
//_cmScAlignPrintList(a,an);
|
||||||
|
|
||||||
//_cmScAlignPrintReport(p,a,an,bsi,esi);
|
//_cmScAlignPrintReport(p,a,an,bsi,esi);
|
||||||
printf("score notes:%i match:%i wrong:%i \n",scNoteCnt,matchCnt,wrongCnt);
|
|
||||||
|
double prec = (double)2.0 * matchCnt / (matchCnt + wrongCnt);
|
||||||
|
double rcal = (double)2.0 * matchCnt / (matchCnt + skipCnt);
|
||||||
|
double fmeas = prec * rcal / (prec + rcal);
|
||||||
|
|
||||||
|
printf("midi:%i scans:%i score notes:%i match:%i skip:%i wrong:%i : %f\n",p->mni,p->scanCnt,scNoteCnt,matchCnt,skipCnt,wrongCnt,fmeas);
|
||||||
|
|
||||||
|
cmMemFree(a);
|
||||||
|
|
||||||
|
return fmeas;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned cmScAlignScanToTimeLineEvent( cmScAlign* p, cmTlH_t tlH, cmTlObj_t* top, unsigned endSmpIdx )
|
|
||||||
|
cmRC_t cmScAlignScanToTimeLineEvent( cmScAlign* p, cmTlH_t tlH, cmTlObj_t* top, unsigned endSmpIdx )
|
||||||
{
|
{
|
||||||
assert( top != NULL );
|
assert( top != NULL );
|
||||||
cmTlMidiEvt_t* mep = NULL;
|
cmTlMidiEvt_t* mep = NULL;
|
||||||
|
cmRC_t rc = cmOkRC;
|
||||||
|
|
||||||
// get the next time MIDI msg
|
// as long as more MIDI events are available get the next MIDI msg
|
||||||
while( (mep = cmTlNextMidiEvtObjPtr(tlH, top, top->seqId )) != NULL )
|
while( rc==cmOkRC && (mep = cmTlNextMidiEvtObjPtr(tlH, top, top->seqId )) != NULL )
|
||||||
{
|
{
|
||||||
top = &mep->obj;
|
top = &mep->obj;
|
||||||
|
|
||||||
@ -2441,13 +2481,31 @@ unsigned cmScAlignScanToTimeLineEvent( cmScAlign* p, cmTlH_t tlH, cmTlObj_t* top
|
|||||||
|
|
||||||
// if the time line MIDI msg a note-on
|
// if the time line MIDI msg a note-on
|
||||||
if( mep->msg->status == kNoteOnMdId )
|
if( mep->msg->status == kNoteOnMdId )
|
||||||
if( !cmScAlignExec(p, mep->obj.seqSmpIdx, mep->msg->status, mep->msg->u.chMsgPtr->d0, mep->msg->u.chMsgPtr->d1 ) )
|
{
|
||||||
return cmInvalidIdx;
|
rc = cmScAlignExec(p, mep->obj.seqSmpIdx, mep->msg->status, mep->msg->u.chMsgPtr->d0, mep->msg->u.chMsgPtr->d1 );
|
||||||
|
|
||||||
|
switch( rc )
|
||||||
|
{
|
||||||
|
case cmOkRC: // continue processing MIDI events
|
||||||
|
break;
|
||||||
|
|
||||||
|
case cmEofRC: // end of the score was encountered
|
||||||
|
break;
|
||||||
|
|
||||||
|
case cmInvalidArgRC: // p->esi was not set correctly
|
||||||
|
break;
|
||||||
|
|
||||||
|
case cmSubSysFailRC: // scan resync failed
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return p->esi;
|
if( rc == cmEofRC )
|
||||||
}
|
rc = cmOkRC;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
void cmScAlignCb( void* cbArg, unsigned scLocIdx, unsigned mni, unsigned pitch, unsigned vel )
|
void cmScAlignCb( void* cbArg, unsigned scLocIdx, unsigned mni, unsigned pitch, unsigned vel )
|
||||||
{
|
{
|
||||||
@ -2467,6 +2525,12 @@ void cmScAlignScanMarkers( cmRpt_t* rpt, cmTlH_t tlH, cmScH_t scH )
|
|||||||
unsigned markCharCnt = 31;
|
unsigned markCharCnt = 31;
|
||||||
cmChar_t markText[ markCharCnt+1 ];
|
cmChar_t markText[ markCharCnt+1 ];
|
||||||
|
|
||||||
|
double scoreThresh = 0.5;
|
||||||
|
unsigned candCnt = 0;
|
||||||
|
unsigned initFailCnt = 0;
|
||||||
|
unsigned otherFailCnt = 0;
|
||||||
|
unsigned scoreFailCnt = 0;
|
||||||
|
|
||||||
p->cbArg = p; // set the callback arg.
|
p->cbArg = p; // set the callback arg.
|
||||||
|
|
||||||
// for each marker
|
// for each marker
|
||||||
@ -2479,43 +2543,79 @@ void cmScAlignScanMarkers( cmRpt_t* rpt, cmTlH_t tlH, cmScH_t scH )
|
|||||||
cmTlMarker_t* mp = cmTimeLineMarkerFind( tlH, markText );
|
cmTlMarker_t* mp = cmTimeLineMarkerFind( tlH, markText );
|
||||||
if( mp == NULL )
|
if( mp == NULL )
|
||||||
{
|
{
|
||||||
printf("The marker '%s' was not found.\n",markText);
|
printf("The marker '%s' was not found.\n\n",markText);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip markers which do not contain text
|
// skip markers which do not contain text
|
||||||
if( cmTextIsEmpty(mp->text) )
|
if( cmTextIsEmpty(mp->text) )
|
||||||
{
|
{
|
||||||
printf("The marker '%s' is being skipped because it has no text.\n",markText);
|
printf("The marker '%s' is being skipped because it has no text.\n\n",markText);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset the score follower to the beginnig of the score
|
// reset the score follower to the beginnig of the score
|
||||||
cmScAlignReset(p,0);
|
cmScAlignReset(p,0);
|
||||||
|
|
||||||
//printf("%s %5.2f %5.2f %5.2f\n",markText,(double)(mp->obj.begSmpIdx)/p->srate,(double)(mp->obj.durSmpCnt)/p->srate,(double)(mp->obj.begSmpIdx+mp->obj.durSmpCnt)/p->srate);
|
++candCnt;
|
||||||
|
|
||||||
// scan to the beginning of the marker
|
// scan to the beginning of the marker
|
||||||
unsigned bsi = cmScAlignScanToTimeLineEvent(p,tlH,&mp->obj,mp->obj.seqSmpIdx+mp->obj.durSmpCnt);
|
cmRC_t rc = cmScAlignScanToTimeLineEvent(p,tlH,&mp->obj,mp->obj.seqSmpIdx+mp->obj.durSmpCnt);
|
||||||
|
bool pfl = true;
|
||||||
if( bsi != cmInvalidIdx )
|
|
||||||
|
if( rc != cmOkRC || p->begSyncLocIdx==cmInvalidIdx)
|
||||||
|
{
|
||||||
|
if( p->begSyncLocIdx == cmInvalidIdx )
|
||||||
|
rc = cmInvalidArgRC;
|
||||||
|
|
||||||
|
if( p->mni == 0 )
|
||||||
|
{
|
||||||
|
printf("mark:%i midi:%i Not enough MIDI notes to fill the scan buffer.\n",i,p->mni);
|
||||||
|
pfl = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(rc)
|
||||||
|
{
|
||||||
|
case cmInvalidArgRC:
|
||||||
|
printf("mark:%i INITIAL SYNC FAIL\n",i);
|
||||||
|
++initFailCnt;
|
||||||
|
pfl = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case cmSubSysFailRC:
|
||||||
|
printf("mark:%i SCAN RESYNC FAIL\n",i);
|
||||||
|
++otherFailCnt;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("mark:%i UNKNOWN FAIL\n",i);
|
||||||
|
++otherFailCnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pfl )
|
||||||
{
|
{
|
||||||
//_cmScAlignPrintMtx(p);
|
//_cmScAlignPrintMtx(p);
|
||||||
printf("mark:%i scans:%4i loc:%4i bar:%4i score:%5.2f miss:%i text:'%s'\n",i,p->scanCnt,bsi,p->loc[bsi].barNumb,p->s_opt,p->missCnt,mp->text);
|
printf("mark:%i scans:%4i loc:%4i bar:%4i score:%5.2f miss:%i text:'%s'\n",i,p->scanCnt,p->begSyncLocIdx,p->loc[p->begSyncLocIdx].barNumb,p->s_opt,p->missCnt,mp->text);
|
||||||
//_cmScAlignPrintPath(p, p->p_opt, bsi );
|
//_cmScAlignPrintPath(p, p->p_opt, bsi );
|
||||||
|
|
||||||
printf("mark:%i scans:%i midi:%i text:'%s'\n",i,p->scanCnt,p->mni,mp->text);
|
//printf("mark:%i scans:%i midi:%i text:'%s'\n",i,p->scanCnt,p->mni,mp->text);
|
||||||
|
|
||||||
_cmScAlignPrintResult(p);
|
if( _cmScAlignPrintResult(p) < scoreThresh )
|
||||||
|
++scoreFailCnt;
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//break; // ONLY USE ONE MARKER DURING TESTING
|
//break; // ONLY USE ONE MARKER DURING TESTING
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("cand:%i fail:%i - init:%i score:%i other:%i\n\n",candCnt,initFailCnt+scoreFailCnt+otherFailCnt,initFailCnt,scoreFailCnt,otherFailCnt);
|
||||||
|
|
||||||
cmScAlignFree(&p);
|
cmScAlignFree(&p);
|
||||||
cmCtxFree(&ctx);
|
cmCtxFree(&ctx);
|
||||||
|
54
cmProc4.h
54
cmProc4.h
@ -196,9 +196,10 @@ void ed_free(ed_r* r);
|
|||||||
|
|
||||||
// Main test function.
|
// Main test function.
|
||||||
void ed_main();
|
void ed_main();
|
||||||
|
|
||||||
//=======================================================================================================================
|
//=======================================================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
//=======================================================================================================================
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
kSaMinIdx,
|
kSaMinIdx,
|
||||||
@ -208,13 +209,15 @@ enum
|
|||||||
kSaCnt
|
kSaCnt
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Dynamic Programming (DP) matrix element
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned v[kSaCnt];
|
unsigned v[kSaCnt]; //
|
||||||
bool matchFl; // if this is a substitute; is it also a match?
|
bool matchFl; // if this is a substitute; is it also a match?
|
||||||
bool transFl; // if this is a substitute; is this the second element in a reversed pair?
|
bool transFl; // if this is a substitute; is this the second element in a reversed pair?
|
||||||
} cmScAlignVal_t;
|
} cmScAlignVal_t;
|
||||||
|
|
||||||
|
// List record used to track a path through the DP matrix p->m[,]
|
||||||
typedef struct cmScAlignPath_str
|
typedef struct cmScAlignPath_str
|
||||||
{
|
{
|
||||||
unsigned code;
|
unsigned code;
|
||||||
@ -226,13 +229,13 @@ typedef struct cmScAlignPath_str
|
|||||||
struct cmScAlignPath_str* next;
|
struct cmScAlignPath_str* next;
|
||||||
} cmScAlignPath_t;
|
} cmScAlignPath_t;
|
||||||
|
|
||||||
|
// Score note event record
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned pitch;
|
unsigned pitch;
|
||||||
unsigned scEvtIdx;
|
|
||||||
bool matchFl;
|
|
||||||
} cmScAlignScEvt_t;
|
} cmScAlignScEvt_t;
|
||||||
|
|
||||||
|
// Score location record.
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned evtCnt; //
|
unsigned evtCnt; //
|
||||||
@ -296,6 +299,7 @@ typedef struct
|
|||||||
bool printFl;
|
bool printFl;
|
||||||
|
|
||||||
unsigned begScanLocIdx; // begin the search at this score locations scWnd[begScanLocIdx:begScanLocIdx+p->cn-1]
|
unsigned begScanLocIdx; // begin the search at this score locations scWnd[begScanLocIdx:begScanLocIdx+p->cn-1]
|
||||||
|
unsigned begSyncLocIdx; // initial sync location
|
||||||
|
|
||||||
unsigned resN; // count of records in res[] == 2*cmScoreEvtCount()
|
unsigned resN; // count of records in res[] == 2*cmScoreEvtCount()
|
||||||
cmScAlignResult_t* res; // res[resN]
|
cmScAlignResult_t* res; // res[resN]
|
||||||
@ -313,7 +317,7 @@ cmRC_t cmScAlignInit( cmScAlign* p, cmScAlignCb_t cbFunc, void* cbArg, cmRea
|
|||||||
cmRC_t cmScAlignFinal( cmScAlign* p );
|
cmRC_t cmScAlignFinal( cmScAlign* p );
|
||||||
void cmScAlignReset( cmScAlign* p, unsigned begScanLocIdx );
|
void cmScAlignReset( cmScAlign* p, unsigned begScanLocIdx );
|
||||||
|
|
||||||
bool cmScAlignExec( cmScAlign* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 );
|
cmRC_t cmScAlignExec( cmScAlign* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 );
|
||||||
|
|
||||||
bool cmScAlignInputMidi( cmScAlign* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 );
|
bool cmScAlignInputMidi( cmScAlign* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 );
|
||||||
|
|
||||||
@ -327,7 +331,9 @@ unsigned cmScAlignScan( cmScAlign* p, unsigned scanCnt );
|
|||||||
// Step forward/back by p->stepCnt from p->esi.
|
// Step forward/back by p->stepCnt from p->esi.
|
||||||
// If more than p->maxStepMissCnt consecutive MIDI events are
|
// If more than p->maxStepMissCnt consecutive MIDI events are
|
||||||
// missed then automatically run cmScAlignScan().
|
// missed then automatically run cmScAlignScan().
|
||||||
bool cmScAlignStep( cmScAlign* p );
|
// Return cmEofRC if the end of the score is encountered.
|
||||||
|
// Return cmSubSysFailRC if an internal scan resync. failed.
|
||||||
|
cmRC_t cmScAlignStep( cmScAlign* p );
|
||||||
|
|
||||||
unsigned cmScAlignScanToTimeLineEvent( cmScAlign* p, cmTlH_t tlH, cmTlObj_t* top, unsigned endSmpIdx );
|
unsigned cmScAlignScanToTimeLineEvent( cmScAlign* p, cmTlH_t tlH, cmTlObj_t* top, unsigned endSmpIdx );
|
||||||
|
|
||||||
@ -336,6 +342,42 @@ unsigned cmScAlignScanToTimeLineEvent( cmScAlign* p, cmTlH_t tlH, cmTlObj_t* t
|
|||||||
// notes in each marker region and the score.
|
// notes in each marker region and the score.
|
||||||
void cmScAlignScanMarkers( cmRpt_t* rpt, cmTlH_t tlH, cmScH_t scH );
|
void cmScAlignScanMarkers( cmRpt_t* rpt, cmTlH_t tlH, cmScH_t scH );
|
||||||
|
|
||||||
|
//=======================================================================================================================
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned mni;
|
||||||
|
unsigned locIdx;
|
||||||
|
unsigned pitch;
|
||||||
|
unsigned vel;
|
||||||
|
unsigned smpIdx;
|
||||||
|
} cmScMeasMidi_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
cmScoreSet_t* set; // A pointer to defining score set
|
||||||
|
unsigned bli; // Begin index into sap->loc[].
|
||||||
|
unsigned eli; // End index into sap->loc[].
|
||||||
|
unsigned bmi; // Begin index into midi[].
|
||||||
|
unsigned emi; // End index into midi[].
|
||||||
|
double* val; // val[sap->eleCnt]
|
||||||
|
} cmScMeasSet_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
cmObj obj;
|
||||||
|
cmScAlign* sap;
|
||||||
|
unsigned mn;
|
||||||
|
cmScMeasMidi_t* midi;
|
||||||
|
} cmScMeas;
|
||||||
|
|
||||||
|
cmScMeas* cmScMeasAlloc( cmCtx* c, cmScMeas* p, double srate, cmScH_t scH );
|
||||||
|
cmRC_t cmScMeasFree( cmScMeas** pp );
|
||||||
|
cmRC_t cmScMeasInit( cmScMeas* p, double srate, cmScH_t scH );
|
||||||
|
cmRC_t cmScMeasFinal( cmScMeas* p );
|
||||||
|
cmRC_t cmScMeasExec( cmScMeas* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1, unsigned scLocIdx );
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user