cmXScore.h/c :Added 'reorderFn' arg. to cmXScoreTest(). Fixed bug where dynamcics and section number was not output to CSV. Added section number to end of measurement groups.

This commit is contained in:
kevin 2016-04-07 13:39:24 -04:00
parent 4017b8bbaa
commit c07d5fbc8d
2 changed files with 281 additions and 225 deletions

View File

@ -48,7 +48,9 @@ enum
kPedalUpXsFl = 0x04000,
kPedalUpDnXsFl = 0x08000,
kMetronomeXsFl = 0x10000, // duration holds BPM
kOnsetXsFl = 0x20000 // this is a sounding note
kOnsetXsFl = 0x20000, // this is a sounding note
kBegGroupXsFl = 0x40000,
kEndGroupXsFl = 0x80000
};
struct cmXsMeas_str;
@ -1140,19 +1142,35 @@ void _cmXScoreSetMeasGroups( cmXScore_t* p, unsigned flag )
// for each note in this measure
for(; np!=NULL; np=np->slink)
{
// if this note has a heel marker and we are looking for evenness events
if( cmIsFlag(flag,kEvenXsFl) && cmIsFlag(np->flags,kHeelXsFl) )
{
np->flags = cmSetFlag(np->flags,kBegGroupXsFl | kEndGroupXsFl );
np->evenGroupId = sectionId + 1;
}
// if this note is of the type we are looking for
if( cmIsFlag(np->flags,flag) )
{
if( n0 == NULL )
np->flags = cmSetFlag(np->flags,kBegGroupXsFl);
n0 = np;
}
// if this is a section marker
if( cmIsFlag(np->flags,kSectionXsFl) )
{
if( n0 != NULL )
{
np->flags = cmSetFlag(np->flags,kEndGroupXsFl);
switch( flag )
{
case kEvenXsFl: n0->evenGroupId = sectionId; break;
case kDynXsFl: n0->dynGroupId = sectionId; break;
case kTempoXsFl: n0->tempoGroupId= sectionId; break;
case kEvenXsFl: n0->evenGroupId = sectionId+1; break;
case kDynXsFl: n0->dynGroupId = sectionId+1; break;
case kTempoXsFl: n0->tempoGroupId= sectionId+1; break;
}
}
@ -1681,27 +1699,55 @@ cmXsRC_t _cmXScoreWriteCsvBlankCols( cmXScore_t* p, unsigned cnt, cmCsvCell_t**
return kOkCsvRC;
}
const cmChar_t* _cmXScoreTranslateDynamics( cmXScore_t* p, const cmXsNote_t* np )
const cmChar_t* _cmXScoreTranslateDynamics( cmXScore_t* p, const cmXsNote_t* np, cmChar_t* buf, unsigned bufN )
{
if( cmIsFlag(np->flags,kDynXsFl) && np->dynamics != 0 )
{
const cmChar_t* dynStr = NULL;
switch(np->dynamics)
{
case 1: return "pppp";
case 2: return "ppp";
case 3: return "pp";
case 4: return "p";
case 5: return "mp";
case 6: return "mf";
case 7: return "f";
case 8: return "ff";
case 9: return "fff";
case 1: dynStr = "pppp"; break;
case 2: dynStr = "ppp"; break;
case 3: dynStr = "pp"; break;
case 4: dynStr = "p"; break;
case 5: dynStr = "mp"; break;
case 6: dynStr = "mf"; break;
case 7: dynStr = "f"; break;
case 8: dynStr = "ff"; break;
case 9: dynStr = "fff"; break;
default:
cmErrMsg(&p->err,kSyntaxErrorXsRC,"An invalid dynamic value (%i) was encountered.",np->dynamics);
goto errLabel;
}
cmErrMsg(&p->err,kSyntaxErrorXsRC,"An invalid dynamic value (%i) was encountered.",np->dynamics);
if( np->dynGroupId == 0 )
snprintf(buf,bufN,"%s",dynStr);
else
snprintf(buf,bufN,"%s %i",dynStr,np->dynGroupId);
return buf;
}
errLabel:
return "";
}
const cmChar_t* cmXsFormatMeasurementCsvField( unsigned flags, unsigned fl, char abbrev, unsigned sectionId, char* buf, unsigned bufN )
{
assert( bufN > 1 );
buf[0] = ' ';
buf[1] = 0;
if( cmIsFlag(flags,fl) )
{
if( sectionId != 0 )
snprintf(buf,bufN-1,"%c %i %c",abbrev,sectionId, cmIsFlag(flags,kHeelXsFl)?'*':' ');
else
buf[0] = abbrev;
}
return buf;
}
cmXsRC_t _cmXScoreWriteCsvRow(
cmXScore_t* p,
unsigned rowIdx,
@ -1716,7 +1762,9 @@ cmXsRC_t _cmXScoreWriteCsvRow(
unsigned pitch, // set to -1 if the pitch is not valid
double frac,
const cmChar_t* dynStr,
unsigned flags )
unsigned flags,
const cmChar_t* evenStr,
const cmChar_t* tempoStr)
{
cmXsRC_t rc = kOkXsRC;
cmCsvCell_t* lcp = NULL;
@ -1830,7 +1878,7 @@ cmXsRC_t _cmXScoreWriteCsvRow(
goto errLabel;
// col 15: even (all grace notes are 'even' notes
if( cmCsvInsertIdentColAfter(p->csvH,lcp,&lcp, cmIsFlag(flags,kGraceXsFl) | cmIsFlag(flags,kEvenXsFl) ? "e" : "",0) != kOkCsvRC )
if( cmCsvInsertIdentColAfter(p->csvH,lcp,&lcp, evenStr, 0) != kOkCsvRC )
{
rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV insert failed on eveness flag label.");
goto errLabel;
@ -1844,7 +1892,7 @@ cmXsRC_t _cmXScoreWriteCsvRow(
}
// col 17: tempo
if( cmCsvInsertIdentColAfter(p->csvH,lcp,&lcp,cmIsFlag(flags,kTempoXsFl) ? "t" : "",0) != kOkCsvRC )
if( cmCsvInsertIdentColAfter(p->csvH,lcp,&lcp,tempoStr,0) != kOkCsvRC )
{
rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV insert failed on eveness flag label.");
goto errLabel;
@ -1876,7 +1924,7 @@ cmXsRC_t _cmXScoreWriteCsvRow(
// goto errLabel;
// col 20: section
if( cmCsvInsertIdentColAfter(p->csvH,lcp,&lcp,cmIsFlag(flags,kSectionXsFl) ? sectionStr : "",0) != kOkCsvRC )
if( cmCsvInsertIdentColAfter(p->csvH,lcp,&lcp,sectionStr!=NULL ? sectionStr : "",0) != kOkCsvRC )
{
rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV insert failed on eveness flag label.");
goto errLabel;
@ -1891,7 +1939,6 @@ cmXsRC_t _cmXScoreWriteCsvRow(
}
cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn )
{
cmXsRC_t rc = kOkXsRC;
@ -1922,7 +1969,7 @@ cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn )
// if this is a bar event
if( cmIsFlag(np->flags,kBarXsFl) )
{
_cmXScoreWriteCsvRow(p,rowIdx,-1,mp->number,sectionIdStr,"bar",np->dsecs,np->secs,0,0,-1,0,"",np->flags);
_cmXScoreWriteCsvRow(p,rowIdx,-1,mp->number,sectionIdStr,"bar",np->dsecs,np->secs,0,0,-1,0,"",np->flags,"","");
sectionIdStr = NULL;
}
else
@ -1932,7 +1979,7 @@ cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn )
{
unsigned d0 = 64; // pedal MIDI ctl id
unsigned d1 = cmIsFlag(np->flags,kPedalDnXsFl) ? 64 : 0; // pedal-dn: d1>=64 pedal-up:<64
_cmXScoreWriteCsvRow(p,rowIdx,-1,mp->number,sectionIdStr,"ctl",np->dsecs,np->secs,d0,d1,-1,0,"",np->flags);
_cmXScoreWriteCsvRow(p,rowIdx,-1,mp->number,sectionIdStr,"ctl",np->dsecs,np->secs,d0,d1,-1,0,"",np->flags,"","");
sectionIdStr = NULL;
}
else
@ -1941,11 +1988,20 @@ cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn )
// if this is a sounding note event
if( cmIsFlag(np->flags,kOnsetXsFl) )
{
unsigned bufN = 128;
cmChar_t ebuf[ bufN+1]; ebuf[bufN] = 0;
cmChar_t dbuf[ bufN+1]; dbuf[bufN] = 0;
cmChar_t tbuf[ bufN+1]; tbuf[bufN] = 0;
double frac = np->rvalue + (cmIsFlag(np->flags,kDotXsFl) ? (np->rvalue/2) : 0);
const cmChar_t* dyn = _cmXScoreTranslateDynamics( p, np );
const cmChar_t* dyn = _cmXScoreTranslateDynamics( p, np, dbuf, bufN );
//
_cmXScoreWriteCsvRow(p,rowIdx,np->uid,mp->number,sectionIdStr,"non",np->dsecs,np->secs,np->pitch,60,np->pitch,frac,dyn,np->flags);
_cmXScoreWriteCsvRow(p,rowIdx,np->uid,mp->number,sectionIdStr,"non",np->dsecs,np->secs,np->pitch,60,np->pitch,frac,dyn,np->flags,
cmXsFormatMeasurementCsvField(np->flags, kEvenXsFl, 'e', np->evenGroupId, ebuf, bufN ),
cmXsFormatMeasurementCsvField(np->flags, kTempoXsFl,'t', np->tempoGroupId, tbuf, bufN ));
sectionIdStr = NULL;
}
}
@ -2117,7 +2173,7 @@ cmXsRC_t cmXScoreWriteMidi( cmXsH_t h, const cmChar_t* fn )
}
}
cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* midiFn, const cmChar_t* outFn, const cmChar_t* dynFn )
cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* midiFn, const cmChar_t* outFn, const cmChar_t* dynFn, const cmChar_t* reorderFn )
{
cmXsRC_t rc;
cmXsH_t h = cmXsNullHandle;
@ -2125,16 +2181,16 @@ cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* midi
if((rc = cmXScoreInitialize( ctx, &h, xmlFn, midiFn)) != kOkXsRC )
return cmErrMsg(&ctx->err,rc,"XScore alloc failed.");
//if( dynFn != NULL )
// cmXScoreInsertDynamics(h, dynFn );
if( dynFn != NULL )
cmXScoreReorder(h,dynFn);
cmXScoreInsertDynamics(h, dynFn );
if( reorderFn != NULL )
cmXScoreReorder(h,reorderFn);
if( outFn != NULL )
cmXScoreWriteCsv(h,outFn);
cmXScoreReport(h,&ctx->rpt,true);
//cmXScoreReport(h,&ctx->rpt,true);
return cmXScoreFinalize(&h);

View File

@ -65,7 +65,7 @@ extern "C" {
void cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl );
cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* midiFn, const cmChar_t* outFn, const cmChar_t* dynFn );
cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* midiFn, const cmChar_t* outFn, const cmChar_t* dynFn, const cmChar_t* reorderFn );
#ifdef __cplusplus
}