Merge branch 'master' of klarke.webfactional.com:webapps/gitweb/repos/libcm
This commit is contained in:
commit
e0a683e8b1
@ -3,8 +3,8 @@
|
|||||||
cmHDR =
|
cmHDR =
|
||||||
cmSRC =
|
cmSRC =
|
||||||
|
|
||||||
cmHDR += src/libcm/cmErr.h src/libcm/cmCtx.h src/libcm/cmRpt.h src/libcm/cmGlobal.h src/libcm/cmComplexTypes.h src/libcm/cmFloatTypes.h src/libcm/cmPrefix.h
|
cmHDR += src/libcm/cmErr.h src/libcm/cmCtx.h src/libcm/cmRpt.h src/libcm/cmRptFile.h src/libcm/cmGlobal.h src/libcm/cmComplexTypes.h src/libcm/cmFloatTypes.h src/libcm/cmPrefix.h
|
||||||
cmSRC += src/libcm/cmErr.c src/libcm/cmCtx.c src/libcm/cmRpt.c src/libcm/cmGlobal.c src/libcm/cmComplexTypes.c
|
cmSRC += src/libcm/cmErr.c src/libcm/cmCtx.c src/libcm/cmRpt.c src/libcm/cmRptFile.c src/libcm/cmGlobal.c src/libcm/cmComplexTypes.c
|
||||||
|
|
||||||
cmHDR += src/libcm/cmSerialize.h src/libcm/cmSymTbl.h src/libcm/cmHashTbl.h src/libcm/cmFileSys.h src/libcm/cmFile.h
|
cmHDR += src/libcm/cmSerialize.h src/libcm/cmSymTbl.h src/libcm/cmHashTbl.h src/libcm/cmFileSys.h src/libcm/cmFile.h
|
||||||
cmSRC += src/libcm/cmSerialize.c src/libcm/cmSymTbl.c src/libcm/cmHashTbl.c src/libcm/cmFileSys.c src/libcm/cmFile.c
|
cmSRC += src/libcm/cmSerialize.c src/libcm/cmSymTbl.c src/libcm/cmHashTbl.c src/libcm/cmFileSys.c src/libcm/cmFile.c
|
||||||
|
@ -269,7 +269,7 @@ cmMsfRC_t cmMidiScoreFollowMain(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//_cmMsf_ReportScoreErrors(&sfr, scH );
|
_cmMsf_ReportScoreErrors(&sfr, scH );
|
||||||
|
|
||||||
//_cmMsf_ReportMidiErrors(&sfr, scH, m, mN);
|
//_cmMsf_ReportMidiErrors(&sfr, scH, m, mN);
|
||||||
|
|
||||||
|
292
app/cmXScore.c
292
app/cmXScore.c
@ -69,7 +69,11 @@ enum
|
|||||||
kNFirstGraceXsFl = 0x08000000, // (n) grace notes start as soon as possible after first note and add time
|
kNFirstGraceXsFl = 0x08000000, // (n) grace notes start as soon as possible after first note and add time
|
||||||
kDeleteXsFl = 0x10000000,
|
kDeleteXsFl = 0x10000000,
|
||||||
kDynBegForkXsFl = 0x20000000,
|
kDynBegForkXsFl = 0x20000000,
|
||||||
kDynEndForkXsFl = 0x40000000
|
kDynEndForkXsFl = 0x40000000,
|
||||||
|
|
||||||
|
kDynEndXsFl = 0x100000000,
|
||||||
|
kEvenEndXsFl = 0x200000000,
|
||||||
|
kTempoEndXsFl = 0x400000000
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -90,7 +94,7 @@ typedef struct cmXsComplexity_str
|
|||||||
typedef struct cmXsNote_str
|
typedef struct cmXsNote_str
|
||||||
{
|
{
|
||||||
unsigned uid; // unique id of this note record
|
unsigned uid; // unique id of this note record
|
||||||
unsigned flags; // See k???XsFl
|
unsigned long long flags; // See k???XsFl
|
||||||
unsigned pitch; // midi pitch
|
unsigned pitch; // midi pitch
|
||||||
unsigned dynamics; // dynamic level 1=pppp 9=fff
|
unsigned dynamics; // dynamic level 1=pppp 9=fff
|
||||||
unsigned vel; // score specified MIDI velocity
|
unsigned vel; // score specified MIDI velocity
|
||||||
@ -270,12 +274,13 @@ cmXsRC_t _cmXScorePushNote( cmXScore_t* p, cmXsMeas_t* meas, unsigned voiceId, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _cmXScoreRemoveNote( cmXsNote_t* note )
|
cmXsRC_t _cmXScoreRemoveNote( cmXsNote_t* note )
|
||||||
{
|
{
|
||||||
cmXsNote_t* n0 = NULL;
|
cmXsNote_t* n0 = NULL;
|
||||||
cmXsNote_t* n1 = note->voice->noteL;
|
cmXsNote_t* n1 = note->voice->noteL;
|
||||||
|
unsigned cnt = 0;
|
||||||
for(; n1!=NULL; n1=n1->mlink)
|
for(; n1!=NULL; n1=n1->mlink)
|
||||||
|
{
|
||||||
if( n1->uid == note->uid )
|
if( n1->uid == note->uid )
|
||||||
{
|
{
|
||||||
if( n0 == NULL )
|
if( n0 == NULL )
|
||||||
@ -283,12 +288,17 @@ void _cmXScoreRemoveNote( cmXsNote_t* note )
|
|||||||
else
|
else
|
||||||
n0->mlink = n1->mlink;
|
n0->mlink = n1->mlink;
|
||||||
|
|
||||||
|
cnt = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n0 = n1;
|
||||||
|
}
|
||||||
|
|
||||||
n0 = NULL;
|
n0 = NULL;
|
||||||
n1 = note->meas->noteL;
|
n1 = note->meas->noteL;
|
||||||
for(; n1!=NULL; n1=n1->slink)
|
for(; n1!=NULL; n1=n1->slink)
|
||||||
|
{
|
||||||
if( n1->uid == note->uid )
|
if( n1->uid == note->uid )
|
||||||
{
|
{
|
||||||
if( n0 == NULL )
|
if( n0 == NULL )
|
||||||
@ -296,13 +306,20 @@ void _cmXScoreRemoveNote( cmXsNote_t* note )
|
|||||||
else
|
else
|
||||||
n0->slink = n1->slink;
|
n0->slink = n1->slink;
|
||||||
|
|
||||||
|
cnt = 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n0 = n1;
|
||||||
|
}
|
||||||
|
return cnt == 2 ? kOkXsRC : kSyntaxErrorXsRC;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _cmXScoreInsertNoteBefore( cmXsNote_t* note, cmXsNote_t* nn )
|
void _cmXScoreInsertNoteBefore( cmXsNote_t* note, cmXsNote_t* nn )
|
||||||
{
|
{
|
||||||
|
assert( note != NULL );
|
||||||
|
|
||||||
// insert the new note into the voice list before 'note'
|
// insert the new note into the voice list before 'note'
|
||||||
cmXsNote_t* n0 = NULL;
|
cmXsNote_t* n0 = NULL;
|
||||||
cmXsNote_t* n1 = note->voice->noteL;
|
cmXsNote_t* n1 = note->voice->noteL;
|
||||||
@ -515,33 +532,44 @@ cmXsRC_t _cmXScoreParseColor( cmXScore_t* p, const cmXmlNode_t* nnp, cmXsNote_t
|
|||||||
|
|
||||||
typedef struct map_str
|
typedef struct map_str
|
||||||
{
|
{
|
||||||
unsigned value;
|
unsigned long long value;
|
||||||
const cmChar_t* label;
|
const cmChar_t* label;
|
||||||
} map_t;
|
} map_t;
|
||||||
|
|
||||||
map_t mapV[] =
|
map_t mapV[] =
|
||||||
{
|
{
|
||||||
{ kEvenXsFl, "#0000FF" }, // blue (even)
|
{ kEvenXsFl, "#0000FF" }, // blue (even)
|
||||||
{ kTempoXsFl, "#00FF00" }, // green (tempo)
|
{ kEvenXsFl | kEvenEndXsFl, "#0000FE" }, // blue (even end)
|
||||||
{ kDynXsFl, "#FF0000" }, // red (dynamics)
|
{ kEvenXsFl | kEvenEndXsFl, "#0000FD" }, // blue (even end)
|
||||||
{ kTempoXsFl | kEvenXsFl, "#00FFFF" }, // green + blue (turquoise)
|
{ kTempoXsFl, "#00FF00" }, // green (tempo)
|
||||||
{ kDynXsFl | kEvenXsFl, "#FF00FF" }, // red + blue
|
{ kTempoXsFl | kTempoEndXsFl, "#00FE00" }, // green (tempo end)
|
||||||
{ kDynXsFl | kEvenXsFl, "#FF0CF7" }, // magenta (even+dyn)
|
{ kDynXsFl, "#FF0000" }, // red (dynamics)
|
||||||
{ kDynXsFl | kTempoXsFl, "#FF7F00" }, // red + green (brown)
|
{ kDynXsFl | kDynEndXsFl, "#FE0000" }, // red (dynamics end)
|
||||||
{ kTempoXsFl | kEvenXsFl | kDynXsFl, "#996633" }, // (purple)
|
{ kDynXsFl | kDynEndXsFl, "#FD0000" }, // red (dynamics end)
|
||||||
{ kDynXsFl, "#FF6A03" }, // 176 orange (dynamics)
|
{ kTempoXsFl | kEvenXsFl, "#00FFFF" }, // green + blue (turquoise)
|
||||||
{ kEvenXsFl, "#2F00E8" }, // 1001 blue (even)
|
{ kTempoXsFl | kEvenXsFl | kEvenEndXsFl, "#00FFFE" }, // green + blue (turquoise) (end)
|
||||||
{ kTempoXsFl, "#01CD1F" }, // 1196 green (tempo)
|
{ kDynXsFl | kEvenXsFl, "#FF00FF" }, // red + blue
|
||||||
{ kEvenXsFl, "#3600E8" }, // 1627 blue (even)
|
{ kDynXsFl | kEvenXsFl | kEvenEndXsFl, "#FF00FE" }, // red + blue (end)
|
||||||
{ kDynXsFl | kTempoXsFl, "#9E8F15" }, // 8827 brown (dyn + tempo)
|
{ kDynXsFl | kEvenXsFl | kEvenEndXsFl, "#FF00FD" }, // red + blue (end)
|
||||||
{ kEvenXsFl, "#2E00E6" }, // 5393 blue (even)
|
{ kDynXsFl | kEvenXsFl, "#FF0CF7" }, // magenta (even+dyn)
|
||||||
{ kEvenXsFl, "#2C00DD" }, // 5895 blue (even)
|
{ kDynXsFl | kTempoXsFl, "#FF7F00" }, // red + green (brown)
|
||||||
{ kDynXsFl, "#FF5B03" }, // 6498 orange (dyn)
|
{ kDynXsFl | kTempoXsFl, "#FE7F00" }, // red + green (brown) (end)
|
||||||
{ kDynXsFl, "#FF6104" }, // 6896 orange
|
{ kDynXsFl | kTempoXsFl, "#FD7F00" }, // red + green (brown) (end)
|
||||||
{ kEvenXsFl, "#2A00E6" }, // 7781 blue
|
{ kTempoXsFl | kEvenXsFl | kDynXsFl, "#996633" }, // (purple)
|
||||||
{ kEvenXsFl, "#2300DD" }, // 8300 blue (even)
|
{ kTempoXsFl | kEvenXsFl | kDynXsFl | kDynEndXsFl, "#996632" }, // (purple)
|
||||||
{ kTempoXsFl, "#03CD22" }, // 10820 green (tempo)
|
{ kDynXsFl, "#FF6A03" }, // 176 orange (dynamics)
|
||||||
{ kEvenXsFl, "#3400DB" }, // 11627 blue (dyn)
|
{ kEvenXsFl, "#2F00E8" }, // 1001 blue (even)
|
||||||
|
{ kTempoXsFl, "#01CD1F" }, // 1196 green (tempo)
|
||||||
|
{ kEvenXsFl, "#3600E8" }, // 1627 blue (even)
|
||||||
|
{ kDynXsFl | kTempoXsFl, "#9E8F15" }, // 8827 brown (dyn + tempo)
|
||||||
|
{ kEvenXsFl, "#2E00E6" }, // 5393 blue (even)
|
||||||
|
{ kEvenXsFl, "#2C00DD" }, // 5895 blue (even)
|
||||||
|
{ kDynXsFl, "#FF5B03" }, // 6498 orange (dyn)
|
||||||
|
{ kDynXsFl, "#FF6104" }, // 6896 orange
|
||||||
|
{ kEvenXsFl, "#2A00E6" }, // 7781 blue
|
||||||
|
{ kEvenXsFl, "#2300DD" }, // 8300 blue (even)
|
||||||
|
{ kTempoXsFl, "#03CD22" }, // 10820 green (tempo)
|
||||||
|
{ kEvenXsFl, "#3400DB" }, // 11627 blue (dyn)
|
||||||
{ -1, "" }
|
{ -1, "" }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1785,7 +1813,7 @@ cmXsRC_t _cmXScoreProcessGraceNotes( cmXScore_t* p, unsigned nextGraceGroupId )
|
|||||||
// grace note groups must have at least 3 members
|
// grace note groups must have at least 3 members
|
||||||
if( gN < 3 )
|
if( gN < 3 )
|
||||||
{
|
{
|
||||||
rc = cmErrMsg(&p->err,kSyntaxErrorXsRC,"The grace not group (groupid=%i) ending in meas %i has fewer than 3 (%i) members.", gn1p->graceGroupId, gn1p->meas->number, gN );
|
rc = cmErrMsg(&p->err,kSyntaxErrorXsRC,"The grace note group (groupid=%i) ending in meas %i has fewer than 3 (%i) members.", gn1p->graceGroupId, gn1p->meas->number, gN );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2130,7 +2158,8 @@ cmXsRC_t _cmXScoreReorderMeas( cmXScore_t* p, unsigned measNumb, cmXsReorder_t*
|
|||||||
// remove deleted notes
|
// remove deleted notes
|
||||||
for(i=0; i<rN; ++i)
|
for(i=0; i<rN; ++i)
|
||||||
if( cmIsFlag(rV[i].newFlags,kDeleteXsFl) )
|
if( cmIsFlag(rV[i].newFlags,kDeleteXsFl) )
|
||||||
_cmXScoreRemoveNote( rV[i].note );
|
if( _cmXScoreRemoveNote( rV[i].note ) != kOkXsRC )
|
||||||
|
return cmErrMsg(&p->err,kSyntaxErrorXsRC,"Event marked to skip was not found in measure: %i",measNumb);
|
||||||
|
|
||||||
cmXsMeas_t* mp = rV[0].note->meas;
|
cmXsMeas_t* mp = rV[0].note->meas;
|
||||||
cmXsNote_t* n0p = NULL;
|
cmXsNote_t* n0p = NULL;
|
||||||
@ -2214,7 +2243,7 @@ cmXsRC_t _cmXScoreReorderMeas( cmXScore_t* p, unsigned measNumb, cmXsReorder_t*
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmXsRC_t _cmXScoreReorderParseDyn(cmXScore_t* p, const cmChar_t* b, unsigned lineNumb, unsigned* dynIdxRef, unsigned* flagsRef )
|
cmXsRC_t _cmXScoreReorderParseDyn(cmXScore_t* p, const cmChar_t* b, unsigned lineNumb, unsigned* dynIdxRef, unsigned* flagsRef, int measNumb )
|
||||||
{
|
{
|
||||||
cmXsRC_t rc = kOkXsRC;
|
cmXsRC_t rc = kOkXsRC;
|
||||||
const cmChar_t* s = NULL;
|
const cmChar_t* s = NULL;
|
||||||
@ -2239,6 +2268,7 @@ cmXsRC_t _cmXScoreReorderParseDyn(cmXScore_t* p, const cmChar_t* b, unsigned lin
|
|||||||
|
|
||||||
if( *s == '!')
|
if( *s == '!')
|
||||||
{
|
{
|
||||||
|
//printf("E %3i %5i %s\n",measNumb,lineNumb,b);
|
||||||
endForkFl = true;
|
endForkFl = true;
|
||||||
++s;
|
++s;
|
||||||
}
|
}
|
||||||
@ -2251,7 +2281,11 @@ cmXsRC_t _cmXScoreReorderParseDyn(cmXScore_t* p, const cmChar_t* b, unsigned lin
|
|||||||
if( isupper(*s) )
|
if( isupper(*s) )
|
||||||
{
|
{
|
||||||
if( !endForkFl)
|
if( !endForkFl)
|
||||||
|
{
|
||||||
begForkFl=true;
|
begForkFl=true;
|
||||||
|
//printf("B %3i %5i %s\n",measNumb,lineNumb,b);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2431,7 +2465,11 @@ cmXsRC_t _cmXScoreReorderParseGrace(cmXScore_t* p, const cmChar_t* b, unsigned
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{ assert(0); }
|
{
|
||||||
|
return cmErrMsg(&p->err,kSyntaxErrorXsRC,"Unexpected grace note reorder character code %c on line %i.",*s,line);
|
||||||
|
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -2457,7 +2495,7 @@ cmXsRC_t _cmXScoreReorderParsePitch(cmXScore_t* p, const cmChar_t* b, unsigned
|
|||||||
++s;
|
++s;
|
||||||
|
|
||||||
j=2;
|
j=2;
|
||||||
for(i=0; i<j && s[i]; ++i,++s)
|
for(i=0; i<j && *s; ++i,++s)
|
||||||
{
|
{
|
||||||
buf[i] = *s;
|
buf[i] = *s;
|
||||||
|
|
||||||
@ -2479,8 +2517,9 @@ cmXsRC_t _cmXScoreReorderParsePitch(cmXScore_t* p, const cmChar_t* b, unsigned
|
|||||||
if( pitch<kInvalidMidiByte)
|
if( pitch<kInvalidMidiByte)
|
||||||
*pitchRef = pitch;
|
*pitchRef = pitch;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
rc = cmErrMsg(&p->err,kSyntaxErrorXsRC,"Pitch conversion from '%s' failed on line %i.",buf,line);
|
rc = cmErrMsg(&p->err,kSyntaxErrorXsRC,"Pitch conversion from '%s' failed on line %i.",buf,line);
|
||||||
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2563,7 +2602,7 @@ cmXsRC_t _cmXsApplyEditFile( cmXScore_t* p, const cmChar_t* fn )
|
|||||||
goto errLabel;
|
goto errLabel;
|
||||||
|
|
||||||
// parse the dynamic marking following a '!'
|
// parse the dynamic marking following a '!'
|
||||||
if((rc = _cmXScoreReorderParseDyn(p,b,ln+1,&r.dynIdx, &r.newFlags)) != kOkXsRC )
|
if((rc = _cmXScoreReorderParseDyn(p,b,ln+1,&r.dynIdx, &r.newFlags, measNumb)) != kOkXsRC )
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
|
|
||||||
// parse the @newtick marker
|
// parse the @newtick marker
|
||||||
@ -3062,12 +3101,13 @@ cmXsRC_t _cmXScoreWriteCsvRow(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn )
|
cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, int begMeasNumb, const cmChar_t* csvFn )
|
||||||
{
|
{
|
||||||
cmXsRC_t rc = kOkXsRC;
|
cmXsRC_t rc = kOkXsRC;
|
||||||
cmXScore_t* p = _cmXScoreHandleToPtr(h);
|
cmXScore_t* p = _cmXScoreHandleToPtr(h);
|
||||||
unsigned rowIdx = 1;
|
unsigned rowIdx = 1;
|
||||||
const cmChar_t* sectionIdStr = NULL;
|
const cmChar_t* sectionIdStr = NULL;
|
||||||
|
double baseSecs = -1;
|
||||||
|
|
||||||
if( !cmCsvIsValid(p->csvH) )
|
if( !cmCsvIsValid(p->csvH) )
|
||||||
return cmErrMsg(&p->err,kCsvFailXsRC,"The CSV output object is not initialized.");
|
return cmErrMsg(&p->err,kCsvFailXsRC,"The CSV output object is not initialized.");
|
||||||
@ -3079,11 +3119,21 @@ cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn )
|
|||||||
for(; pp!=NULL; pp=pp->link)
|
for(; pp!=NULL; pp=pp->link)
|
||||||
{
|
{
|
||||||
cmXsMeas_t* mp = pp->measL;
|
cmXsMeas_t* mp = pp->measL;
|
||||||
|
|
||||||
for(; mp!=NULL; mp=mp->link)
|
for(; mp!=NULL; mp=mp->link)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if( mp->number < begMeasNumb)
|
||||||
|
continue;
|
||||||
|
|
||||||
cmXsNote_t* np = mp->noteL;
|
cmXsNote_t* np = mp->noteL;
|
||||||
|
|
||||||
|
if( baseSecs == -1 )
|
||||||
|
baseSecs = np->secs;
|
||||||
|
|
||||||
for(; np!=NULL; np=np->slink)
|
for(; np!=NULL; np=np->slink)
|
||||||
{
|
{
|
||||||
|
double thisSecs = np->secs - baseSecs;
|
||||||
|
|
||||||
// if this is a section event
|
// if this is a section event
|
||||||
if( cmIsFlag(np->flags,kSectionXsFl) )
|
if( cmIsFlag(np->flags,kSectionXsFl) )
|
||||||
@ -3092,7 +3142,7 @@ cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn )
|
|||||||
// if this is a bar event
|
// if this is a bar event
|
||||||
if( cmIsFlag(np->flags,kBarXsFl) )
|
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,thisSecs,0,0,-1,0,"",np->flags,"","");
|
||||||
sectionIdStr = NULL;
|
sectionIdStr = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3102,14 +3152,14 @@ cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn )
|
|||||||
{
|
{
|
||||||
unsigned d0 = cmIsFlag(np->flags,kSostDnXsFl |kSostUpXsFl) ? 66 : 64; // pedal MIDI ctl id
|
unsigned d0 = cmIsFlag(np->flags,kSostDnXsFl |kSostUpXsFl) ? 66 : 64; // pedal MIDI ctl id
|
||||||
unsigned d1 = cmIsFlag(np->flags,kDampDnXsFl|kSostDnXsFl) ? 64 : 0; // pedal-dn: d1>=64 pedal-up:<64
|
unsigned d1 = cmIsFlag(np->flags,kDampDnXsFl|kSostDnXsFl) ? 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,thisSecs,d0,d1,-1,0,"",np->flags,"","");
|
||||||
sectionIdStr = NULL;
|
sectionIdStr = NULL;
|
||||||
|
|
||||||
if( cmIsFlag(np->flags,kDampUpDnXsFl) )
|
if( cmIsFlag(np->flags,kDampUpDnXsFl) )
|
||||||
{
|
{
|
||||||
rowIdx += 1;
|
rowIdx += 1;
|
||||||
double millisecond = 0.0;
|
double millisecond = 0.0;
|
||||||
_cmXScoreWriteCsvRow(p,rowIdx,-1,mp->number,sectionIdStr,"ctl",millisecond,np->secs+millisecond,d0,64,-1,0,"",np->flags,"","");
|
_cmXScoreWriteCsvRow(p,rowIdx,-1,mp->number,sectionIdStr,"ctl",millisecond,thisSecs+millisecond,d0,64,-1,0,"",np->flags,"","");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -3124,13 +3174,12 @@ cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn )
|
|||||||
cmChar_t dbuf[ bufN+1]; dbuf[bufN] = 0;
|
cmChar_t dbuf[ bufN+1]; dbuf[bufN] = 0;
|
||||||
cmChar_t tbuf[ bufN+1]; tbuf[bufN] = 0;
|
cmChar_t tbuf[ bufN+1]; tbuf[bufN] = 0;
|
||||||
|
|
||||||
|
|
||||||
double frac = np->rvalue + (cmIsFlag(np->flags,kDotXsFl) ? (np->rvalue/2) : 0);
|
double frac = np->rvalue + (cmIsFlag(np->flags,kDotXsFl) ? (np->rvalue/2) : 0);
|
||||||
const cmChar_t* dyn = _cmXScoreTranslateDynamics( p, np, dbuf, bufN );
|
const cmChar_t* dyn = _cmXScoreTranslateDynamics( p, np, dbuf, bufN );
|
||||||
unsigned vel = np->vel==0 ? 60 : np->vel;
|
unsigned vel = np->vel==0 ? 60 : np->vel;
|
||||||
|
|
||||||
//
|
//
|
||||||
_cmXScoreWriteCsvRow(p,rowIdx,np->uid,mp->number,sectionIdStr,"non",np->dsecs,np->secs,np->pitch,vel,np->pitch,frac,dyn,np->flags,
|
_cmXScoreWriteCsvRow(p,rowIdx,np->uid,mp->number,sectionIdStr,"non",np->dsecs,thisSecs,np->pitch,vel,np->pitch,frac,dyn,np->flags,
|
||||||
cmXsFormatMeasurementCsvField(np->flags, kEvenXsFl, 'e', np->evenGroupId, ebuf, bufN ),
|
cmXsFormatMeasurementCsvField(np->flags, kEvenXsFl, 'e', np->evenGroupId, ebuf, bufN ),
|
||||||
cmXsFormatMeasurementCsvField(np->flags, kTempoXsFl,'t', np->tempoGroupId, tbuf, bufN ));
|
cmXsFormatMeasurementCsvField(np->flags, kTempoXsFl,'t', np->tempoGroupId, tbuf, bufN ));
|
||||||
|
|
||||||
@ -3157,6 +3206,30 @@ cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn )
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _cmXsIsCsvValid(cmCtx_t* ctx, cmXsH_t h, const cmChar_t* outFn)
|
||||||
|
{
|
||||||
|
bool retFl = true;
|
||||||
|
cmScH_t scH = cmScNullHandle;
|
||||||
|
double srate = 44100.0;
|
||||||
|
cmSymTblH_t stH = cmSymTblCreate(cmSymTblNullHandle, 0, ctx );
|
||||||
|
|
||||||
|
if( cmScoreInitialize( ctx, &scH, outFn, srate, NULL, 0, NULL, NULL, stH) != kOkScRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&ctx->err,kFileFailXsRC,"The generated CSV file (%s) could not be parsed.",cmStringNullGuard(outFn));
|
||||||
|
retFl = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//cmScorePrintSets(scH,&ctx->rpt);
|
||||||
|
//cmScorePrint(scH,&ctx->rpt);
|
||||||
|
|
||||||
|
cmScoreFinalize(&scH);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmSymTblDestroy(&stH);
|
||||||
|
|
||||||
|
return retFl;
|
||||||
|
}
|
||||||
|
|
||||||
void _cmXScoreReportTitle( cmRpt_t* rpt )
|
void _cmXScoreReportTitle( cmRpt_t* rpt )
|
||||||
{
|
{
|
||||||
@ -3171,9 +3244,6 @@ void _cmXScoreReportNote( cmRpt_t* rpt, const cmXsNote_t* note,unsigned index )
|
|||||||
const cmChar_t* G = cmIsFlag(note->flags,kGraceXsFl) ? "G" : "-";
|
const cmChar_t* G = cmIsFlag(note->flags,kGraceXsFl) ? "G" : "-";
|
||||||
const cmChar_t* D = cmIsFlag(note->flags,kDotXsFl) ? "." : "-";
|
const cmChar_t* D = cmIsFlag(note->flags,kDotXsFl) ? "." : "-";
|
||||||
const cmChar_t* C = cmIsFlag(note->flags,kChordXsFl) ? "C" : "-";
|
const cmChar_t* C = cmIsFlag(note->flags,kChordXsFl) ? "C" : "-";
|
||||||
const cmChar_t* e = cmIsFlag(note->flags,kEvenXsFl) ? "e" : "-";
|
|
||||||
const cmChar_t* d = cmIsFlag(note->flags,kDynXsFl) ? "d" : "-";
|
|
||||||
const cmChar_t* t = cmIsFlag(note->flags,kTempoXsFl) ? "t" : "-";
|
|
||||||
const cmChar_t* P = cmIsFlag(note->flags,kDampDnXsFl) ? "V" : "-";
|
const cmChar_t* P = cmIsFlag(note->flags,kDampDnXsFl) ? "V" : "-";
|
||||||
const cmChar_t* s = cmIsFlag(note->flags,kSostDnXsFl) ? "{" : "-";
|
const cmChar_t* s = cmIsFlag(note->flags,kSostDnXsFl) ? "{" : "-";
|
||||||
const cmChar_t* S = cmIsFlag(note->flags,kSectionXsFl) ? "S" : "-";
|
const cmChar_t* S = cmIsFlag(note->flags,kSectionXsFl) ? "S" : "-";
|
||||||
@ -3181,6 +3251,15 @@ void _cmXScoreReportNote( cmRpt_t* rpt, const cmXsNote_t* note,unsigned index )
|
|||||||
const cmChar_t* T0 = cmIsFlag(note->flags,kTieBegXsFl) ? "T" : "-";
|
const cmChar_t* T0 = cmIsFlag(note->flags,kTieBegXsFl) ? "T" : "-";
|
||||||
const cmChar_t* T1 = cmIsFlag(note->flags,kTieEndXsFl) ? "_" : "-";
|
const cmChar_t* T1 = cmIsFlag(note->flags,kTieEndXsFl) ? "_" : "-";
|
||||||
const cmChar_t* O = cmIsFlag(note->flags,kOnsetXsFl) ? "*" : "-";
|
const cmChar_t* O = cmIsFlag(note->flags,kOnsetXsFl) ? "*" : "-";
|
||||||
|
|
||||||
|
const cmChar_t* e = cmIsFlag(note->flags,kEvenXsFl) ? "e" : "-";
|
||||||
|
const cmChar_t* d = cmIsFlag(note->flags,kDynXsFl) ? "d" : "-";
|
||||||
|
const cmChar_t* t = cmIsFlag(note->flags,kTempoXsFl) ? "t" : "-";
|
||||||
|
|
||||||
|
if( cmIsFlag(note->flags,kEvenEndXsFl) ) e="E";
|
||||||
|
if( cmIsFlag(note->flags,kDynEndXsFl) ) d="D";
|
||||||
|
if( cmIsFlag(note->flags,kTempoEndXsFl) ) t="T";
|
||||||
|
|
||||||
P = cmIsFlag(note->flags,kDampUpXsFl) ? "^" : P;
|
P = cmIsFlag(note->flags,kDampUpXsFl) ? "^" : P;
|
||||||
P = cmIsFlag(note->flags,kDampUpDnXsFl) ? "X" : P;
|
P = cmIsFlag(note->flags,kDampUpDnXsFl) ? "X" : P;
|
||||||
s = cmIsFlag(note->flags,kSostUpXsFl) ? "}" : s;
|
s = cmIsFlag(note->flags,kSostUpXsFl) ? "}" : s;
|
||||||
@ -3227,13 +3306,13 @@ void _cmXScoreReportNote( cmRpt_t* rpt, const cmXsNote_t* note,unsigned index )
|
|||||||
if( cmIsFlag(note->flags,kEndGraceXsFl) )
|
if( cmIsFlag(note->flags,kEndGraceXsFl) )
|
||||||
cmRptPrintf(rpt," E");
|
cmRptPrintf(rpt," E");
|
||||||
|
|
||||||
|
|
||||||
if( cmIsFlag(note->flags,kDynBegForkXsFl) )
|
if( cmIsFlag(note->flags,kDynBegForkXsFl) )
|
||||||
cmRptPrintf(rpt," B");
|
cmRptPrintf(rpt," B");
|
||||||
|
|
||||||
if( cmIsFlag(note->flags,kDynEndForkXsFl) )
|
if( cmIsFlag(note->flags,kDynEndForkXsFl) )
|
||||||
cmRptPrintf(rpt," E");
|
cmRptPrintf(rpt," E");
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3547,7 +3626,7 @@ cmXsRC_t _cmXsMeasComplexity( cmXsH_t h, double wndSecs )
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmXsRC_t _cmXsWriteMidiFile( cmCtx_t* ctx, cmXsH_t h, const cmChar_t* dir, const cmChar_t* fn )
|
cmXsRC_t _cmXsWriteMidiFile( cmCtx_t* ctx, cmXsH_t h, int beginMeasNumb, int beginBPM, const cmChar_t* dir, const cmChar_t* fn )
|
||||||
{
|
{
|
||||||
cmXsRC_t rc = kOkXsRC;
|
cmXsRC_t rc = kOkXsRC;
|
||||||
cmXScore_t* p = _cmXScoreHandleToPtr(h);
|
cmXScore_t* p = _cmXScoreHandleToPtr(h);
|
||||||
@ -3559,9 +3638,11 @@ cmXsRC_t _cmXsWriteMidiFile( cmCtx_t* ctx, cmXsH_t h, const cmChar_t* dir, const
|
|||||||
unsigned trkN = 2;
|
unsigned trkN = 2;
|
||||||
unsigned ticksPerQN = p->partL->measL->divisions;
|
unsigned ticksPerQN = p->partL->measL->divisions;
|
||||||
const cmChar_t* outFn = cmFsMakeFn(dir,fn,"mid",NULL);
|
const cmChar_t* outFn = cmFsMakeFn(dir,fn,"mid",NULL);
|
||||||
|
unsigned baseTick = -1;
|
||||||
|
unsigned bpm = beginBPM==0 ? 60 : beginBPM;
|
||||||
|
|
||||||
if( cmMidiFileCreate( ctx, &mfH, trkN, ticksPerQN ) != kOkMfRC )
|
//if( cmMidiFileCreate( ctx, &mfH, trkN, ticksPerQN ) != kOkMfRC )
|
||||||
return cmErrMsg(&p->err,kMidiFailXsRC,"Unable to create the MIDI file object.");
|
// return cmErrMsg(&p->err,kMidiFailXsRC,"Unable to create the MIDI file object.");
|
||||||
|
|
||||||
cmXsPart_t* pp = p->partL;
|
cmXsPart_t* pp = p->partL;
|
||||||
|
|
||||||
@ -3573,8 +3654,33 @@ cmXsRC_t _cmXsWriteMidiFile( cmCtx_t* ctx, cmXsH_t h, const cmChar_t* dir, const
|
|||||||
// for each measure
|
// for each measure
|
||||||
for(; mp!=NULL; mp=mp->link)
|
for(; mp!=NULL; mp=mp->link)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// skip all measures until we reach the first measure to output
|
||||||
|
if(mp->number < beginMeasNumb)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// if the MIDI file has not yet been created
|
||||||
|
if( !cmMidiFileIsValid(mfH) )
|
||||||
|
{
|
||||||
|
ticksPerQN = mp->divisions;
|
||||||
|
|
||||||
|
// create the MIDI file
|
||||||
|
if( cmMidiFileCreate( ctx, &mfH, trkN, ticksPerQN ) != kOkMfRC )
|
||||||
|
{
|
||||||
|
rc = cmErrMsg(&p->err,kMidiFailXsRC,"Unable to create the MIDI file object.");
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the starting tempo
|
||||||
|
cmMidFileInsertTrackTempoMsg(mfH, 0, 0, bpm );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
cmXsNote_t* np = mp->noteL;
|
cmXsNote_t* np = mp->noteL;
|
||||||
|
|
||||||
|
if( baseTick == -1 )
|
||||||
|
baseTick = np->tick;
|
||||||
|
|
||||||
if( mp->divisions != ticksPerQN )
|
if( mp->divisions != ticksPerQN )
|
||||||
cmErrWarnMsg(&p->err,kMidiFailXsRC,"The 'tick per quarter note' (divisions) field in measure %i does not match the value in the first measure (%i).",mp->divisions,ticksPerQN);
|
cmErrWarnMsg(&p->err,kMidiFailXsRC,"The 'tick per quarter note' (divisions) field in measure %i does not match the value in the first measure (%i).",mp->divisions,ticksPerQN);
|
||||||
|
|
||||||
@ -3582,12 +3688,15 @@ cmXsRC_t _cmXsWriteMidiFile( cmCtx_t* ctx, cmXsH_t h, const cmChar_t* dir, const
|
|||||||
// for each note in this measure
|
// for each note in this measure
|
||||||
for(; np!=NULL; np=np->slink,++ni)
|
for(; np!=NULL; np=np->slink,++ni)
|
||||||
{
|
{
|
||||||
|
unsigned thisTick = np->tick - baseTick;
|
||||||
|
|
||||||
switch( np->flags & (kOnsetXsFl|kMetronomeXsFl|kDampDnXsFl|kDampUpDnXsFl|kSostDnXsFl) )
|
switch( np->flags & (kOnsetXsFl|kMetronomeXsFl|kDampDnXsFl|kDampUpDnXsFl|kSostDnXsFl) )
|
||||||
{
|
{
|
||||||
case kOnsetXsFl:
|
case kOnsetXsFl:
|
||||||
|
if( cmMidiFileIsValid(mfH) )
|
||||||
{
|
{
|
||||||
if( np->tied_dur <= 0 )
|
if( np->tied_dur <= 0 )
|
||||||
cmErrWarnMsg(&p->err,kOkXsRC,"A zero length note was encountered bar:%i tick:%i %s",np->meas->number,np->tick,cmMidiToSciPitch(np->pitch,NULL,0));
|
cmErrWarnMsg(&p->err,kOkXsRC,"A zero length note was encountered bar:%i tick:%i (%i) %s",np->meas->number,np->tick,thisTick,cmMidiToSciPitch(np->pitch,NULL,0));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if( mp->number == 20 )
|
if( mp->number == 20 )
|
||||||
@ -3597,8 +3706,11 @@ cmXsRC_t _cmXsWriteMidiFile( cmCtx_t* ctx, cmXsH_t h, const cmChar_t* dir, const
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if( cmMidiFileInsertTrackChMsg(mfH, 1, np->tick, kNoteOnMdId, np->pitch, np->vel ) != kOkMfRC
|
if( np->vel == 0 )
|
||||||
||cmMidiFileInsertTrackChMsg(mfH, 1, np->tick + np->tied_dur, kNoteOffMdId, np->pitch, 0 ) != kOkMfRC )
|
cmErrWarnMsg(&p->err,kOkXsRC,"A sounding note with zero velocity was encountered at bar:%i tick:%i pitch:%s.",np->meas->number,np->tick,cmMidiToSciPitch(np->pitch,NULL,0));
|
||||||
|
|
||||||
|
if( cmMidiFileInsertTrackChMsg(mfH, 1, thisTick, kNoteOnMdId, np->pitch, np->vel ) != kOkMfRC
|
||||||
|
||cmMidiFileInsertTrackChMsg(mfH, 1, thisTick + np->tied_dur, kNoteOffMdId, np->pitch, 0 ) != kOkMfRC )
|
||||||
{
|
{
|
||||||
rc = kMidiFailXsRC;
|
rc = kMidiFailXsRC;
|
||||||
}
|
}
|
||||||
@ -3608,13 +3720,14 @@ cmXsRC_t _cmXsWriteMidiFile( cmCtx_t* ctx, cmXsH_t h, const cmChar_t* dir, const
|
|||||||
case kDampDnXsFl:
|
case kDampDnXsFl:
|
||||||
case kDampUpDnXsFl:
|
case kDampUpDnXsFl:
|
||||||
case kSostDnXsFl:
|
case kSostDnXsFl:
|
||||||
|
if( cmMidiFileIsValid(mfH) )
|
||||||
{
|
{
|
||||||
if( np->duration <= 0 )
|
if( np->duration <= 0 )
|
||||||
cmErrWarnMsg(&p->err,kOkXsRC,"A zero length pedal event was encountered bar:%i tick:%i",np->meas->number,np->tick);
|
cmErrWarnMsg(&p->err,kOkXsRC,"A zero length pedal event was encountered bar:%i tick:%i (%i)",np->meas->number,np->tick,thisTick);
|
||||||
|
|
||||||
cmMidiByte_t d0 = cmIsFlag(np->flags,kSostDnXsFl) ? kSostenutoCtlMdId : kSustainCtlMdId;
|
cmMidiByte_t d0 = cmIsFlag(np->flags,kSostDnXsFl) ? kSostenutoCtlMdId : kSustainCtlMdId;
|
||||||
if( (cmMidiFileInsertTrackChMsg(mfH, 1, np->tick, kCtlMdId, d0, 127 ) != kOkMfRC )
|
if( (cmMidiFileInsertTrackChMsg(mfH, 1, thisTick, kCtlMdId, d0, 127 ) != kOkMfRC )
|
||||||
||(cmMidiFileInsertTrackChMsg(mfH, 1, np->tick + np->duration, kCtlMdId, d0, 0 ) != kOkMfRC ) )
|
||(cmMidiFileInsertTrackChMsg(mfH, 1, thisTick + np->duration, kCtlMdId, d0, 0 ) != kOkMfRC ) )
|
||||||
{
|
{
|
||||||
rc = kMidiFailXsRC;
|
rc = kMidiFailXsRC;
|
||||||
}
|
}
|
||||||
@ -3622,8 +3735,10 @@ cmXsRC_t _cmXsWriteMidiFile( cmCtx_t* ctx, cmXsH_t h, const cmChar_t* dir, const
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case kMetronomeXsFl:
|
case kMetronomeXsFl:
|
||||||
if( cmMidFileInsertTrackTempoMsg(mfH, 0, np->tick, np->duration ) != kOkMfRC )
|
bpm = np->duration;
|
||||||
rc = kMidiFailXsRC;
|
if( cmMidiFileIsValid(mfH) )
|
||||||
|
if( cmMidFileInsertTrackTempoMsg(mfH, 0, thisTick, bpm ) != kOkMfRC )
|
||||||
|
rc = kMidiFailXsRC;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
@ -3642,11 +3757,12 @@ cmXsRC_t _cmXsWriteMidiFile( cmCtx_t* ctx, cmXsH_t h, const cmChar_t* dir, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( cmMidiFileWrite(mfH,outFn) != kOkMfRC )
|
if( cmMidiFileIsValid(mfH) )
|
||||||
{
|
if( cmMidiFileWrite(mfH,outFn) != kOkMfRC )
|
||||||
rc = cmErrMsg(&p->err,kMidiFailXsRC,"MIDI file write failed on '%s'.",cmStringNullGuard(outFn));
|
{
|
||||||
goto errLabel;
|
rc = cmErrMsg(&p->err,kMidiFailXsRC,"MIDI file write failed on '%s'.",cmStringNullGuard(outFn));
|
||||||
}
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
errLabel:
|
errLabel:
|
||||||
cmFsFreeFn(outFn);
|
cmFsFreeFn(outFn);
|
||||||
@ -3659,6 +3775,23 @@ cmXsRC_t _cmXsWriteMidiFile( cmCtx_t* ctx, cmXsH_t h, const cmChar_t* dir, const
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _cmXsIsMidiFileValid( cmCtx_t* ctx, cmXsH_t h, const cmChar_t* dir, const cmChar_t* fn )
|
||||||
|
{
|
||||||
|
const cmChar_t* midiFn = cmFsMakeFn(dir,fn,"mid",NULL);
|
||||||
|
cmMidiFileH_t mfH = cmMidiFileNullHandle;
|
||||||
|
|
||||||
|
if( cmMidiFileOpen( ctx, &mfH, midiFn ) == kOkMfRC )
|
||||||
|
{
|
||||||
|
cmMidiFileClose(&mfH);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmXScore_t* p = _cmXScoreHandleToPtr(h);
|
||||||
|
cmErrMsg(&p->err,kMidiFailXsRC,"The generated MIDI file '%s' is not valid.", cmStringNullGuard(midiFn));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct cmXsSvgEvt_str
|
typedef struct cmXsSvgEvt_str
|
||||||
{
|
{
|
||||||
unsigned flags; // k???XsFl
|
unsigned flags; // k???XsFl
|
||||||
@ -3864,7 +3997,7 @@ void _cmXsPushSvgEvent( cmXScore_t* p, cmXsMidiFile_t* mf, unsigned flags, unsig
|
|||||||
mf->eol = e;
|
mf->eol = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmXsRC_t _cmXScoreGenSvg( cmCtx_t* ctx, cmXsH_t h, const cmChar_t* dir, const cmChar_t* fn )
|
cmXsRC_t _cmXScoreGenSvg( cmCtx_t* ctx, cmXsH_t h, int beginMeasNumb, const cmChar_t* dir, const cmChar_t* fn )
|
||||||
{
|
{
|
||||||
cmXScore_t* p = _cmXScoreHandleToPtr(h);
|
cmXScore_t* p = _cmXScoreHandleToPtr(h);
|
||||||
cmXsPart_t* pp = p->partL;
|
cmXsPart_t* pp = p->partL;
|
||||||
@ -3877,6 +4010,8 @@ cmXsRC_t _cmXScoreGenSvg( cmCtx_t* ctx, cmXsH_t h, const cmChar_t* dir, const cm
|
|||||||
const cmXsMeas_t* meas = pp->measL;
|
const cmXsMeas_t* meas = pp->measL;
|
||||||
for(; meas!=NULL; meas=meas->link)
|
for(; meas!=NULL; meas=meas->link)
|
||||||
{
|
{
|
||||||
|
if( meas->number < beginMeasNumb )
|
||||||
|
continue;
|
||||||
|
|
||||||
const cmXsNote_t* note = meas->noteL;
|
const cmXsNote_t* note = meas->noteL;
|
||||||
for(; note!=NULL; note=note->slink)
|
for(; note!=NULL; note=note->slink)
|
||||||
@ -3929,11 +4064,14 @@ cmXsRC_t _cmXScoreGenSvg( cmCtx_t* ctx, cmXsH_t h, const cmChar_t* dir, const cm
|
|||||||
|
|
||||||
|
|
||||||
cmXsRC_t cmXScoreTest(
|
cmXsRC_t cmXScoreTest(
|
||||||
cmCtx_t* ctx,
|
cmCtx_t* ctx,
|
||||||
const cmChar_t* xmlFn,
|
const cmChar_t* xmlFn,
|
||||||
const cmChar_t* editFn,
|
const cmChar_t* editFn,
|
||||||
const cmChar_t* csvOutFn,
|
const cmChar_t* csvOutFn,
|
||||||
const cmChar_t* midiOutFn)
|
const cmChar_t* midiOutFn,
|
||||||
|
bool reportFl,
|
||||||
|
int beginMeasNumb,
|
||||||
|
int beginBPM )
|
||||||
{
|
{
|
||||||
cmXsRC_t rc;
|
cmXsRC_t rc;
|
||||||
cmXsH_t h = cmXsNullHandle;
|
cmXsH_t h = cmXsNullHandle;
|
||||||
@ -3952,45 +4090,33 @@ cmXsRC_t cmXScoreTest(
|
|||||||
|
|
||||||
if( csvOutFn != NULL )
|
if( csvOutFn != NULL )
|
||||||
{
|
{
|
||||||
cmScH_t scH = cmScNullHandle;
|
|
||||||
double srate = 44100.0;
|
|
||||||
|
|
||||||
cmXScoreWriteCsv(h,csvOutFn);
|
cmXScoreWriteCsv(h,beginMeasNumb,csvOutFn);
|
||||||
|
|
||||||
cmSymTblH_t stH = cmSymTblCreate(cmSymTblNullHandle, 0, ctx );
|
_cmXsIsCsvValid(ctx,h,csvOutFn);
|
||||||
|
|
||||||
if( cmScoreInitialize( ctx, &scH, csvOutFn, srate, NULL, 0, NULL, NULL, stH) != kOkScRC )
|
|
||||||
cmErrMsg(&ctx->err,kFileFailXsRC,"The generated CSV file could not be parsed.");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//cmScorePrintSets(scH,&ctx->rpt);
|
|
||||||
//cmScorePrint(scH,&ctx->rpt);
|
|
||||||
|
|
||||||
cmScoreFinalize(&scH);
|
|
||||||
}
|
|
||||||
|
|
||||||
cmSymTblDestroy(&stH);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( midiOutFn != NULL )
|
if( midiOutFn != NULL )
|
||||||
{
|
{
|
||||||
|
|
||||||
// measure the score complexity
|
// measure the score complexity
|
||||||
double wndSecs = 1.0;
|
double wndSecs = 1.0;
|
||||||
_cmXsMeasComplexity(h,wndSecs);
|
|
||||||
|
|
||||||
|
_cmXsMeasComplexity(h,wndSecs);
|
||||||
|
|
||||||
cmFileSysPathPart_t* pp = cmFsPathParts(midiOutFn);
|
cmFileSysPathPart_t* pp = cmFsPathParts(midiOutFn);
|
||||||
|
|
||||||
_cmXsWriteMidiFile(ctx, h, pp->dirStr, pp->fnStr );
|
_cmXsWriteMidiFile(ctx, h, beginMeasNumb, beginBPM, pp->dirStr, pp->fnStr );
|
||||||
|
|
||||||
_cmXScoreGenSvg( ctx, h, pp->dirStr, pp->fnStr );
|
_cmXsIsMidiFileValid(ctx, h, pp->dirStr, pp->fnStr );
|
||||||
|
|
||||||
|
_cmXScoreGenSvg( ctx, h, beginMeasNumb, pp->dirStr, pp->fnStr );
|
||||||
|
|
||||||
cmFsFreePathParts(pp);
|
cmFsFreePathParts(pp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmXScoreReport(h,&ctx->rpt,true);
|
if(reportFl)
|
||||||
|
cmXScoreReport(h,&ctx->rpt,true);
|
||||||
|
|
||||||
return cmXScoreFinalize(&h);
|
return cmXScoreFinalize(&h);
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ extern "C" {
|
|||||||
|
|
||||||
bool cmXScoreIsValid( cmXsH_t h );
|
bool cmXScoreIsValid( cmXsH_t h );
|
||||||
|
|
||||||
cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn );
|
cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, int beginMeasNumb, const cmChar_t* csvFn );
|
||||||
|
|
||||||
void cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl );
|
void cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl );
|
||||||
|
|
||||||
@ -69,7 +69,10 @@ extern "C" {
|
|||||||
// internal call to cmXScoreGenEditFile(). This file can then be edited
|
// internal call to cmXScoreGenEditFile(). This file can then be edited
|
||||||
// to include the additional score file information and passed back by a later
|
// to include the additional score file information and passed back by a later
|
||||||
// call to this same function.
|
// call to this same function.
|
||||||
cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* reorderFn, const cmChar_t* csvOutFn, const cmChar_t* midiOutFn );
|
// Set reportFl to true to print a report of the score following processing.
|
||||||
|
// Set begMeasNumb to the first measure the to be written to the output csv, MIDI and SVG files.
|
||||||
|
// Set begBPM to 0 to use the tempo from the score otherwise set it to the tempo at begMeasNumb.
|
||||||
|
cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* reorderFn, const cmChar_t* csvOutFn, const cmChar_t* midiOutFn, bool reportFl, int begMeasNumb, int begBPM );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
3
cmFile.c
3
cmFile.c
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
#include "cmPrefix.h"
|
#include "cmPrefix.h"
|
||||||
#include "cmGlobal.h"
|
#include "cmGlobal.h"
|
||||||
#include "cmRpt.h"
|
#include "cmRpt.h"
|
||||||
@ -11,7 +10,7 @@
|
|||||||
#include "cmLinkedHeap.h"
|
#include "cmLinkedHeap.h"
|
||||||
#include "cmText.h"
|
#include "cmText.h"
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
cmFileH_t cmFileNullHandle = { NULL };
|
cmFileH_t cmFileNullHandle = cmSTATIC_NULL_HANDLE;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
30
cmMidiFile.c
30
cmMidiFile.c
@ -4,6 +4,7 @@
|
|||||||
#include "cmErr.h"
|
#include "cmErr.h"
|
||||||
#include "cmCtx.h"
|
#include "cmCtx.h"
|
||||||
#include "cmFile.h"
|
#include "cmFile.h"
|
||||||
|
#include "cmRptFile.h"
|
||||||
#include "cmMem.h"
|
#include "cmMem.h"
|
||||||
#include "cmMallocDebug.h"
|
#include "cmMallocDebug.h"
|
||||||
#include "cmLinkedHeap.h"
|
#include "cmLinkedHeap.h"
|
||||||
@ -2071,6 +2072,35 @@ cmMfRC_t cmMidiFileGenSvgFile( cmCtx_t* ctx, const cmChar_t* midiFn, const cmCha
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmMfRC_t cmMidiFileReport( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* outTextFn )
|
||||||
|
{
|
||||||
|
cmMidiFileH_t mfH = cmMidiFileNullHandle;
|
||||||
|
cmRptFileH_t rptH = cmRptFileNullHandle;
|
||||||
|
cmMfRC_t rc;
|
||||||
|
|
||||||
|
if((rc = cmMidiFileOpen(ctx,&mfH,midiFn)) != kOkMfRC )
|
||||||
|
{
|
||||||
|
rc = cmErrMsg(&ctx->err,rc,"Unable to open the MIDI file: %s\n",cmStringNullGuard(midiFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(( rc = cmRptFileCreate(ctx,&rptH, outTextFn, NULL )) != kOkRfRC )
|
||||||
|
{
|
||||||
|
rc = cmErrMsg(&ctx->err,rc,"Unable to open the report file: %s\n",cmStringNullGuard(outTextFn));
|
||||||
|
goto errLabel;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cmMidiFilePrintMsgs(mfH, cmRptFileRpt(rptH) );
|
||||||
|
|
||||||
|
errLabel:
|
||||||
|
cmRptFileClose(&rptH);
|
||||||
|
cmMidiFileClose(&mfH);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void cmMidiFilePrintControlNumbers( cmCtx_t* ctx, const char* fn )
|
void cmMidiFilePrintControlNumbers( cmCtx_t* ctx, const char* fn )
|
||||||
{
|
{
|
||||||
cmMidiFileH_t h = cmMidiFileNullHandle;
|
cmMidiFileH_t h = cmMidiFileNullHandle;
|
||||||
|
@ -231,6 +231,9 @@ extern "C" {
|
|||||||
|
|
||||||
cmMfRC_t cmMidiFileGenSvgFile( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* outSvgFn, const cmChar_t* cssFn );
|
cmMfRC_t cmMidiFileGenSvgFile( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* outSvgFn, const cmChar_t* cssFn );
|
||||||
|
|
||||||
|
// Generate a text file reportusing cmMIdiFilePrintMsgs()
|
||||||
|
cmMfRC_t cmMidiFileReport( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* outTextFn );
|
||||||
|
|
||||||
void cmMidiFileTest( const char* fn, cmCtx_t* ctx );
|
void cmMidiFileTest( const char* fn, cmCtx_t* ctx );
|
||||||
|
|
||||||
|
|
||||||
|
128
cmRptFile.c
Normal file
128
cmRptFile.c
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
#include "cmPrefix.h"
|
||||||
|
#include "cmGlobal.h"
|
||||||
|
#include "cmRpt.h"
|
||||||
|
#include "cmErr.h"
|
||||||
|
#include "cmCtx.h"
|
||||||
|
#include "cmFile.h"
|
||||||
|
#include "cmMem.h"
|
||||||
|
#include "cmMallocDebug.h"
|
||||||
|
#include "cmRptFile.h"
|
||||||
|
|
||||||
|
cmRptFileH_t cmRptFileNullHandle = cmSTATIC_NULL_HANDLE;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
cmErr_t err;
|
||||||
|
cmFileH_t printFileH;
|
||||||
|
cmFileH_t errorFileH;
|
||||||
|
cmRpt_t rpt;
|
||||||
|
|
||||||
|
} cmRptFile_t;
|
||||||
|
|
||||||
|
cmRptFile_t* _cmRptFileHandleToPtr( cmRptFileH_t h )
|
||||||
|
{
|
||||||
|
cmRptFile_t* p = (cmRptFile_t*)h.h;
|
||||||
|
assert(p != NULL );
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _cmRptFilePrintFunc(void* cmRptUserPtr, const cmChar_t* text)
|
||||||
|
{
|
||||||
|
cmRptFile_t* p = (cmRptFile_t*)cmRptUserPtr;
|
||||||
|
if( cmFileIsValid(p->printFileH))
|
||||||
|
cmFilePrint(p->printFileH,text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _cmRptFileErrorFunc(void* cmRptUserPtr, const cmChar_t* text)
|
||||||
|
{
|
||||||
|
cmRptFile_t* p = (cmRptFile_t*)cmRptUserPtr;
|
||||||
|
if( cmFileIsValid(p->errorFileH))
|
||||||
|
cmFilePrint(p->errorFileH,text);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmRfRC_t _cmRptFileClose( cmRptFile_t* p )
|
||||||
|
{
|
||||||
|
if( cmFileClose( &p->printFileH ) != kOkFileRC )
|
||||||
|
cmErrMsg(&p->err,kFileFailRfRC,"Unable to close the print file.");
|
||||||
|
|
||||||
|
if( cmFileClose( &p->errorFileH ) != kOkFileRC )
|
||||||
|
cmErrMsg(&p->err,kFileFailRfRC,"Unable to close the error file.");
|
||||||
|
|
||||||
|
cmMemFree(p);
|
||||||
|
|
||||||
|
return kOkRfRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmRfRC_t cmRptFileCreate( cmCtx_t* ctx, cmRptFileH_t* hp, const cmChar_t* printFn, const cmChar_t* errorFn )
|
||||||
|
{
|
||||||
|
cmRptPrintFunc_t printFunc = NULL;
|
||||||
|
cmRptPrintFunc_t errorFunc = NULL;
|
||||||
|
cmRfRC_t rc;
|
||||||
|
if((rc = cmRptFileClose(hp)) != kOkRfRC )
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
cmRptFile_t* p = cmMemAllocZ( cmRptFile_t, 1 );
|
||||||
|
|
||||||
|
cmErrSetup(&p->err,&ctx->rpt,"Rpt File");
|
||||||
|
|
||||||
|
if( printFn != NULL )
|
||||||
|
{
|
||||||
|
if((rc = cmFileOpen(&p->printFileH,printFn,kWriteFileFl,p->err.rpt)) == kOkFileRC )
|
||||||
|
printFunc = _cmRptFilePrintFunc;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = cmErrMsg(&p->err,kFileFailRfRC,"Unable to open the print file '%s'.", cmStringNullGuard(printFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( errorFn != NULL )
|
||||||
|
{
|
||||||
|
if((rc = cmFileOpen(&p->errorFileH,errorFn,kWriteFileFl,p->err.rpt)) == kOkFileRC )
|
||||||
|
errorFunc = _cmRptFileErrorFunc;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = cmErrMsg(&p->err,kFileFailRfRC,"Unable to open the error file '%s'.", cmStringNullGuard(errorFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( errorFunc == NULL )
|
||||||
|
errorFunc = printFunc;
|
||||||
|
|
||||||
|
cmRptSetup(&p->rpt,printFunc,errorFunc,p);
|
||||||
|
|
||||||
|
hp->h = p;
|
||||||
|
|
||||||
|
errLabel:
|
||||||
|
if( rc != kOkRfRC )
|
||||||
|
_cmRptFileClose(p);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmRfRC_t cmRptFileClose( cmRptFileH_t* hp )
|
||||||
|
{
|
||||||
|
cmRfRC_t rc = kOkRfRC;
|
||||||
|
|
||||||
|
if( hp==NULL || cmRptFileIsValid(*hp)==false)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
cmRptFile_t* p = _cmRptFileHandleToPtr( *hp );
|
||||||
|
|
||||||
|
if((rc = _cmRptFileClose(p)) != kOkRfRC )
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
hp->h = NULL;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cmRptFileIsValid( cmRptFileH_t h )
|
||||||
|
{ return h.h != NULL; }
|
||||||
|
|
||||||
|
cmRpt_t* cmRptFileRpt( cmRptFileH_t h )
|
||||||
|
{
|
||||||
|
cmRptFile_t* p = _cmRptFileHandleToPtr( h );
|
||||||
|
return &p->rpt;
|
||||||
|
}
|
30
cmRptFile.h
Normal file
30
cmRptFile.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef cmRptFile_h
|
||||||
|
#define cmRptFile_h
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kOkRfRC = cmOkRC,
|
||||||
|
kFileFailRfRC
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef unsigned cmRfRC_t;
|
||||||
|
typedef cmHandle_t cmRptFileH_t;
|
||||||
|
|
||||||
|
extern cmRptFileH_t cmRptFileNullHandle;
|
||||||
|
|
||||||
|
cmRfRC_t cmRptFileCreate( cmCtx_t* ctx, cmRptFileH_t* hp, const cmChar_t* printFn, const cmChar_t* errorFn );
|
||||||
|
cmRfRC_t cmRptFileClose( cmRptFileH_t* hp );
|
||||||
|
|
||||||
|
bool cmRptFileIsValid( cmRptFileH_t h );
|
||||||
|
|
||||||
|
cmRpt_t* cmRptFileRpt( cmRptFileH_t h );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user