Merge branch 'master' of klarke.webfactional.com:webapps/gitweb/repos/libcm
This commit is contained in:
commit
e426f5dbd1
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1,3 @@
|
|||||||
Makefile.in
|
Makefile.in
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
@ -112,6 +112,14 @@ void _cmMsf_ReportMidiErrors( const _cmMsf_ScoreFollow_t* f, cmScH_t scH, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _cmMsf_WriteMatchFileHeader( cmFileH_t fH )
|
||||||
|
{
|
||||||
|
cmFilePrintf(fH," Score Score Score MIDI MIDI MIDI\n");
|
||||||
|
cmFilePrintf(fH," Bar UUID Pitch UUID Ptch Vel.\n");
|
||||||
|
cmFilePrintf(fH,"- ----- ----- ----- ----- ---- ----\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Write one scScoreMatcherResult_t record to the file fH.
|
// Write one scScoreMatcherResult_t record to the file fH.
|
||||||
unsigned _cmMsf_WriteMatchFileLine( cmFileH_t fH, cmScH_t scH, const cmScMatcherResult_t* r )
|
unsigned _cmMsf_WriteMatchFileLine( cmFileH_t fH, cmScH_t scH, const cmScMatcherResult_t* r )
|
||||||
{
|
{
|
||||||
@ -130,7 +138,7 @@ unsigned _cmMsf_WriteMatchFileLine( cmFileH_t fH, cmScH_t scH, const cmScMatcher
|
|||||||
cmMidiToSciPitch(e->pitch,buf,5);
|
cmMidiToSciPitch(e->pitch,buf,5);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmFilePrintf(fH,"m %3i %5i %4s %5i %4s %3i\n",
|
cmFilePrintf(fH,"m %5i %5i %5s %5i %4s %3i\n",
|
||||||
loc==NULL ? 0 : loc->barNumb, // score evt bar
|
loc==NULL ? 0 : loc->barNumb, // score evt bar
|
||||||
scUid, // score event uuid
|
scUid, // score event uuid
|
||||||
buf, // score event pitch
|
buf, // score event pitch
|
||||||
@ -147,17 +155,17 @@ void _cmMsf_ScoreFollowCb( struct cmScMatcher_str* p, void* arg, cmScMatcherResu
|
|||||||
r->rV[r->rN++] = *rp;
|
r->rV[r->rN++] = *rp;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmMsfRC_t cmMidiScoreFollowMain( cmCtx_t* ctx )
|
cmMsfRC_t cmMidiScoreFollowMain(
|
||||||
|
cmCtx_t* ctx,
|
||||||
|
const cmChar_t* scoreCsvFn, // score CSV file as generated from cmXScoreTest().
|
||||||
|
const cmChar_t* midiFn, // MIDI file to track
|
||||||
|
const cmChar_t* matchRptOutFn, // Score follow status report
|
||||||
|
const cmChar_t* matchSvgOutFn, // Score follow graphic report
|
||||||
|
const cmChar_t* midiOutFn, // (optional) midiFn with apply sostenuto and velocities from the score to the MIDI file
|
||||||
|
const cmChar_t* tlBarOutFn // (optional) bar positions sutiable for use in a cmTimeLine description file.
|
||||||
|
)
|
||||||
{
|
{
|
||||||
cmMsfRC_t rc = kOkMsfRC;
|
cmMsfRC_t rc = kOkMsfRC;
|
||||||
//const cmChar_t* scoreFn = cmFsMakeUserDirFn("src/kc/src/kc/data","mod2e.csv");
|
|
||||||
const cmChar_t* scoreFn = cmFsMakeUserDirFn("temp","a7.csv");
|
|
||||||
const cmChar_t* midiFn = cmFsMakeUserDirFn("media/projects/imag_themes/scores/gen","round1-utf8_11.mid");
|
|
||||||
const cmChar_t* outFn = cmFsMakeUserDirFn("temp","match.txt");
|
|
||||||
const cmChar_t* svgFn = cmFsMakeUserDirFn("temp","score0.html");
|
|
||||||
const cmChar_t* newMidiFn= cmFsMakeUserDirFn("temp","a7.mid");
|
|
||||||
const cmChar_t* tlBarFn = cmFsMakeUserDirFn("temp","time_line_temp.txt");
|
|
||||||
|
|
||||||
double srate = 96000.0;
|
double srate = 96000.0;
|
||||||
cmScMatcher* smp = NULL;
|
cmScMatcher* smp = NULL;
|
||||||
cmScH_t scH = cmScNullHandle;
|
cmScH_t scH = cmScNullHandle;
|
||||||
@ -179,16 +187,16 @@ cmMsfRC_t cmMidiScoreFollowMain( cmCtx_t* ctx )
|
|||||||
cmCtx* prCtx = cmCtxAlloc(NULL, err.rpt, cmLHeapNullHandle, cmSymTblNullHandle );
|
cmCtx* prCtx = cmCtxAlloc(NULL, err.rpt, cmLHeapNullHandle, cmSymTblNullHandle );
|
||||||
|
|
||||||
// initialize the score
|
// initialize the score
|
||||||
if( cmScoreInitialize( ctx, &scH, scoreFn, srate, NULL, 0, NULL, NULL, cmSymTblNullHandle) != kOkScRC )
|
if( cmScoreInitialize( ctx, &scH, scoreCsvFn, srate, NULL, 0, NULL, NULL, cmSymTblNullHandle) != kOkScRC )
|
||||||
{
|
{
|
||||||
rc = cmErrMsg(&err,kFailMsfRC,"cmScoreInitialize() failed on %s",cmStringNullGuard(scoreFn));
|
rc = cmErrMsg(&err,kFailMsfRC,"cmScoreInitialize() failed on %s",cmStringNullGuard(scoreCsvFn));
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup the callback record
|
// setup the callback record
|
||||||
if((sfr.rAllocN = cmScoreEvtCount( scH )*2) == 0)
|
if((sfr.rAllocN = cmScoreEvtCount( scH )*2) == 0)
|
||||||
{
|
{
|
||||||
rc = cmErrMsg(&err,kFailMsfRC,"The score %s appears to be empty.",cmStringNullGuard(scoreFn));
|
rc = cmErrMsg(&err,kFailMsfRC,"The score %s appears to be empty.",cmStringNullGuard(scoreCsvFn));
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,19 +237,21 @@ cmMsfRC_t cmMidiScoreFollowMain( cmCtx_t* ctx )
|
|||||||
printf("MIDI notes:%i Score Events:%i\n",mN,cmScoreEvtCount(scH));
|
printf("MIDI notes:%i Score Events:%i\n",mN,cmScoreEvtCount(scH));
|
||||||
|
|
||||||
// create the output file
|
// create the output file
|
||||||
if( cmFileOpen(&fH,outFn,kWriteFileFl,&ctx->rpt) != kOkFileRC )
|
if( cmFileOpen(&fH,matchRptOutFn,kWriteFileFl,&ctx->rpt) != kOkFileRC )
|
||||||
{
|
{
|
||||||
rc = cmErrMsg(&err,kFailMsfRC,"Unable to create the file '%s'.",cmStringNullGuard(outFn));
|
rc = cmErrMsg(&err,kFailMsfRC,"Unable to create the file '%s'.",cmStringNullGuard(matchRptOutFn));
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate the graphics object
|
// allocate the graphics object
|
||||||
if( cmScoreMatchGraphicAlloc( ctx, &smgH, scoreFn, midiFn ) != kOkSmgRC )
|
if( cmScoreMatchGraphicAlloc( ctx, &smgH, scoreCsvFn, midiFn ) != kOkSmgRC )
|
||||||
{
|
{
|
||||||
rc = cmErrMsg(&err,kFailMsfRC,"Score Match Graphics allocation failed..");
|
rc = cmErrMsg(&err,kFailMsfRC,"Score Match Graphics allocation failed..");
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write the match report output file header
|
||||||
|
_cmMsf_WriteMatchFileHeader(fH);
|
||||||
|
|
||||||
// for each score follower callback record
|
// for each score follower callback record
|
||||||
for(i=0; i<sfr.rN; ++i)
|
for(i=0; i<sfr.rN; ++i)
|
||||||
@ -267,12 +277,14 @@ cmMsfRC_t cmMidiScoreFollowMain( cmCtx_t* ctx )
|
|||||||
//cmMidiFilePrintMsgs( mfH, &ctx->rpt );
|
//cmMidiFilePrintMsgs( mfH, &ctx->rpt );
|
||||||
|
|
||||||
// write the tracking match file as an SVG file.
|
// write the tracking match file as an SVG file.
|
||||||
cmScoreMatchGraphicWrite( smgH, svgFn );
|
cmScoreMatchGraphicWrite( smgH, matchSvgOutFn );
|
||||||
|
|
||||||
// write a cmTimeLine file which contains markers at each bar position
|
// write a cmTimeLine file which contains markers at each bar position
|
||||||
cmScoreMatchGraphicGenTimeLineBars(smgH, tlBarFn, srate );
|
if( tlBarOutFn != NULL )
|
||||||
|
cmScoreMatchGraphicGenTimeLineBars(smgH, tlBarOutFn, srate );
|
||||||
|
|
||||||
cmScoreMatchGraphicUpdateMidiFromScore( ctx, smgH, newMidiFn );
|
if( midiOutFn != NULL )
|
||||||
|
cmScoreMatchGraphicUpdateMidiFromScore( ctx, smgH, midiOutFn );
|
||||||
|
|
||||||
|
|
||||||
errLabel:
|
errLabel:
|
||||||
@ -286,12 +298,12 @@ cmMsfRC_t cmMidiScoreFollowMain( cmCtx_t* ctx )
|
|||||||
|
|
||||||
cmCtxFree(&prCtx);
|
cmCtxFree(&prCtx);
|
||||||
|
|
||||||
cmFsFreeFn(scoreFn);
|
//cmFsFreeFn(scoreCsvFn);
|
||||||
cmFsFreeFn(midiFn);
|
//cmFsFreeFn(midiFn);
|
||||||
cmFsFreeFn(outFn);
|
//cmFsFreeFn(matchRptOutFn);
|
||||||
cmFsFreeFn(svgFn);
|
//cmFsFreeFn(matchSvgOutFn);
|
||||||
cmFsFreeFn(newMidiFn);
|
//cmFsFreeFn(outMidiFn);
|
||||||
cmFsFreeFn(tlBarFn);
|
//cmFsFreeFn(tlBarFn);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,15 @@ extern "C" {
|
|||||||
typedef cmRC_t cmMsfRC_t;
|
typedef cmRC_t cmMsfRC_t;
|
||||||
|
|
||||||
|
|
||||||
cmMsfRC_t cmMidiScoreFollowMain( cmCtx_t* ctx );
|
cmMsfRC_t cmMidiScoreFollowMain(
|
||||||
|
cmCtx_t* ctx,
|
||||||
|
const cmChar_t* scoreCsvFn, // score CSV file as generated from cmXScoreTest().
|
||||||
|
const cmChar_t* midiFn, // MIDI file to track
|
||||||
|
const cmChar_t* matchRptOutFn, // Score follow status report
|
||||||
|
const cmChar_t* matchSvgOutFn, // Score follow graphic report
|
||||||
|
const cmChar_t* midiOutFn, // (optional) midiFn with apply sostenuto and velocities from the score to the MIDI file
|
||||||
|
const cmChar_t* tlBarOutFn // (optional) bar positions sutiable for use in a cmTimeLine description file.
|
||||||
|
);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -154,15 +154,16 @@ cmScEvtRef_t _cmScEvtRefArray[] =
|
|||||||
|
|
||||||
cmScEvtRef_t _cmScDynRefArray[] =
|
cmScEvtRef_t _cmScDynRefArray[] =
|
||||||
{
|
{
|
||||||
{ 1, 0, "pppp"},
|
{ 1, 0, "silent"},
|
||||||
{ 2, 0, "ppp" },
|
{ 2, 0, "pppp"},
|
||||||
{ 3, 0, "pp" },
|
{ 3, 0, "ppp" },
|
||||||
{ 4, 0, "p" },
|
{ 4, 0, "pp" },
|
||||||
{ 5, 0, "mp" },
|
{ 5, 0, "p" },
|
||||||
{ 6, 0, "mf" },
|
{ 6, 0, "mp" },
|
||||||
{ 7, 0, "f" },
|
{ 7, 0, "mf" },
|
||||||
{ 8, 0, "ff" },
|
{ 8, 0, "f" },
|
||||||
{ 9, 0, "fff" },
|
{ 9, 0, "ff" },
|
||||||
|
{ 10, 0, "fff" },
|
||||||
{ kInvalidDynScId,0, "***" },
|
{ kInvalidDynScId,0, "***" },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -361,6 +362,22 @@ void _cmScFreeMarkList( cmScMark_t* markList )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _cmScFreeSectList( cmSc_t* p )
|
||||||
|
{
|
||||||
|
|
||||||
|
// release the section linked list
|
||||||
|
cmScSect_t* sp = p->sectList;
|
||||||
|
cmScSect_t* np = NULL;
|
||||||
|
while(sp!=NULL)
|
||||||
|
{
|
||||||
|
np = sp->link;
|
||||||
|
cmMemFree(sp);
|
||||||
|
sp = np;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->sectList = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void _cmScFreeSetList( cmScSet_t* setList )
|
void _cmScFreeSetList( cmScSet_t* setList )
|
||||||
{
|
{
|
||||||
cmScSet_t* tp = setList;
|
cmScSet_t* tp = setList;
|
||||||
@ -412,6 +429,8 @@ cmScRC_t _cmScFinalize( cmSc_t* p )
|
|||||||
cmMemFree(p->sets);
|
cmMemFree(p->sets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_cmScFreeSectList( p );
|
||||||
|
|
||||||
_cmScFreeSetList(p->setList);
|
_cmScFreeSetList(p->setList);
|
||||||
|
|
||||||
_cmScFreeMarkList(p->markList);
|
_cmScFreeMarkList(p->markList);
|
||||||
@ -1124,9 +1143,10 @@ cmScRC_t _cmScProcSets( cmSc_t* p )
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
cmScRC_t _cmScProcSections( cmSc_t* p, cmScSect_t* sectList )
|
cmScRC_t _cmScProcSections( cmSc_t* p )
|
||||||
{
|
{
|
||||||
cmScRC_t rc = kOkScRC;
|
cmScRC_t rc = kOkScRC;
|
||||||
|
cmScSect_t* sectList = p->sectList;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
// count the sections
|
// count the sections
|
||||||
@ -1171,16 +1191,9 @@ cmScRC_t _cmScProcSections( cmSc_t* p, cmScSect_t* sectList )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// release the section linked list
|
|
||||||
sp = sectList;
|
|
||||||
cmScSect_t* np = NULL;
|
|
||||||
while(sp!=NULL)
|
|
||||||
{
|
|
||||||
np = sp->link;
|
|
||||||
cmMemFree(sp);
|
|
||||||
sp = np;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
_cmScFreeSectList(p);
|
||||||
|
|
||||||
//_cmScPrintSets("Sets",p->setList );
|
//_cmScPrintSets("Sets",p->setList );
|
||||||
|
|
||||||
_cmScProcSets(p);
|
_cmScProcSets(p);
|
||||||
@ -1592,7 +1605,7 @@ cmScRC_t cmScoreInitialize( cmCtx_t* ctx, cmScH_t* hp, const cmChar_t* fn, doubl
|
|||||||
if((rc = _cmScInitLocArray(p)) != kOkScRC )
|
if((rc = _cmScInitLocArray(p)) != kOkScRC )
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
|
|
||||||
if((rc = _cmScProcSections(p,p->sectList)) != kOkScRC )
|
if((rc = _cmScProcSections(p)) != kOkScRC )
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
|
|
||||||
if((rc = _cmScProcMarkers(p)) != kOkScRC )
|
if((rc = _cmScProcMarkers(p)) != kOkScRC )
|
||||||
@ -2409,6 +2422,16 @@ cmScRC_t cmScoreDecode( const void* msg, unsigned msgByteCnt, cmScMsg_t* m)
|
|||||||
return kOkScRC;
|
return kOkScRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cmChar_t* _cmScoreSectionLabel( cmSc_t* p, const cmScoreEvt_t* r )
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for(i=0; i<p->sectCnt; ++i)
|
||||||
|
if( p->sect[i].locPtr != NULL && p->sect[i].locPtr->index == r->locIdx && p->sect[i].begEvtIndex == r->index )
|
||||||
|
return p->sect[i].label;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void _cmScorePrintHdr( cmRpt_t* rpt )
|
void _cmScorePrintHdr( cmRpt_t* rpt )
|
||||||
{
|
{
|
||||||
cmRptPrintf(rpt,"evnt CSV bar\n");
|
cmRptPrintf(rpt,"evnt CSV bar\n");
|
||||||
@ -2416,12 +2439,13 @@ void _cmScorePrintHdr( cmRpt_t* rpt )
|
|||||||
cmRptPrintf(rpt,"----- ----- ----- --- --- ----- ----- --- -------\n");
|
cmRptPrintf(rpt,"----- ----- ----- --- --- ----- ----- --- -------\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void _cmScorePrintEvent( const cmScoreEvt_t* r, unsigned i, cmRpt_t* rpt )
|
void _cmScorePrintEvent( cmSc_t* p, const cmScoreEvt_t* r, unsigned i, cmRpt_t* rpt )
|
||||||
{
|
{
|
||||||
|
bool eolFl = true;
|
||||||
switch(r->type)
|
switch(r->type)
|
||||||
{
|
{
|
||||||
case kBarEvtScId:
|
case kBarEvtScId:
|
||||||
cmRptPrintf(rpt,"%5i %5i %3i bar\n",
|
cmRptPrintf(rpt,"%5i %5i %3i bar ",
|
||||||
i,
|
i,
|
||||||
r->line,
|
r->line,
|
||||||
r->barNumb );
|
r->barNumb );
|
||||||
@ -2429,7 +2453,7 @@ void _cmScorePrintEvent( const cmScoreEvt_t* r, unsigned i, cmRpt_t* rpt )
|
|||||||
|
|
||||||
case kPedalEvtScId:
|
case kPedalEvtScId:
|
||||||
case kNonEvtScId:
|
case kNonEvtScId:
|
||||||
cmRptPrintf(rpt,"%5i %5i %5i %3i %3i %s %5s %c%c%c %s\n",
|
cmRptPrintf(rpt,"%5i %5i %5i %3i %3i %s %5s %c%c%c %-7s ",
|
||||||
i,
|
i,
|
||||||
r->line,
|
r->line,
|
||||||
r->locIdx,
|
r->locIdx,
|
||||||
@ -2440,12 +2464,20 @@ void _cmScorePrintEvent( const cmScoreEvt_t* r, unsigned i, cmRpt_t* rpt )
|
|||||||
cmIsFlag(r->flags,kEvenScFl) ? 'e' : ' ',
|
cmIsFlag(r->flags,kEvenScFl) ? 'e' : ' ',
|
||||||
cmIsFlag(r->flags,kTempoScFl) ? 't' : ' ',
|
cmIsFlag(r->flags,kTempoScFl) ? 't' : ' ',
|
||||||
cmIsFlag(r->flags,kDynScFl) ? 'd' : ' ',
|
cmIsFlag(r->flags,kDynScFl) ? 'd' : ' ',
|
||||||
|
//cmIsFlag(r->flags,kDynScFl) ? 7-strlen(cmScDynIdToLabel(r->dynVal)) : 7,
|
||||||
cmIsFlag(r->flags,kDynScFl) ? cmScDynIdToLabel(r->dynVal) : "");
|
cmIsFlag(r->flags,kDynScFl) ? cmScDynIdToLabel(r->dynVal) : "");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
eolFl = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cmChar_t* sectionLabel;
|
||||||
|
if((sectionLabel = _cmScoreSectionLabel(p,r)) != NULL )
|
||||||
|
cmRptPrintf(rpt,"section:%s ",sectionLabel);
|
||||||
|
|
||||||
|
cmRptPrintf(rpt,"\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2458,7 +2490,7 @@ void cmScorePrint( cmScH_t h, cmRpt_t* rpt )
|
|||||||
_cmScorePrintHdr(rpt);
|
_cmScorePrintHdr(rpt);
|
||||||
|
|
||||||
for(i=0; i<p->cnt; ++i)
|
for(i=0; i<p->cnt; ++i)
|
||||||
_cmScorePrintEvent(p->array+i,i,rpt);
|
_cmScorePrintEvent(p,p->array+i,i,rpt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2483,7 +2515,7 @@ void cmScorePrintSets( cmScH_t h, cmRpt_t* rpt )
|
|||||||
|
|
||||||
_cmScorePrintHdr(rpt);
|
_cmScorePrintHdr(rpt);
|
||||||
for(j=0; j<s->eleCnt; ++j)
|
for(j=0; j<s->eleCnt; ++j)
|
||||||
_cmScorePrintEvent(*s->eleArray+j,j,rpt);
|
_cmScorePrintEvent(p,*s->eleArray+j,j,rpt);
|
||||||
|
|
||||||
cmRptPrintf(rpt,"Targets Section: ");
|
cmRptPrintf(rpt,"Targets Section: ");
|
||||||
for(j=0; j<s->sectCnt; ++j)
|
for(j=0; j<s->sectCnt; ++j)
|
||||||
@ -2709,7 +2741,7 @@ cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const c
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn )
|
void cmScoreReport( cmCtx_t* ctx, const cmChar_t* fn )
|
||||||
{
|
{
|
||||||
cmScH_t h = cmScNullHandle;
|
cmScH_t h = cmScNullHandle;
|
||||||
if( cmScoreInitialize(ctx,&h,fn,0,NULL,0,NULL,NULL, cmSymTblNullHandle ) != kOkScRC )
|
if( cmScoreInitialize(ctx,&h,fn,0,NULL,0,NULL,NULL, cmSymTblNullHandle ) != kOkScRC )
|
||||||
@ -2720,6 +2752,11 @@ void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn )
|
|||||||
cmScoreFinalize(&h);
|
cmScoreFinalize(&h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 1. Fix absolute message time which was incorrect on original score file.
|
// 1. Fix absolute message time which was incorrect on original score file.
|
||||||
// 2.
|
// 2.
|
||||||
void cmScoreFix( cmCtx_t* ctx )
|
void cmScoreFix( cmCtx_t* ctx )
|
||||||
|
@ -280,8 +280,12 @@ extern "C" {
|
|||||||
// Generate a new score file from a MIDI file.
|
// Generate a new score file from a MIDI file.
|
||||||
cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* scoreFn );
|
cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* scoreFn );
|
||||||
|
|
||||||
void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn );
|
// Print open the score file 'fn' and report the contents. This function
|
||||||
|
// simply wraps calls to cmScoreInitialize() and cmScorePrint().
|
||||||
|
void cmScoreReport( cmCtx_t* ctx, const cmChar_t* fn );
|
||||||
|
|
||||||
|
void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn );
|
||||||
|
|
||||||
//)
|
//)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -538,7 +538,7 @@ cmSmgRC_t cmScoreMatchGraphicWrite( cmSmgH_t h, const cmChar_t* fn )
|
|||||||
svgHeight += 10; // add a right and lower border
|
svgHeight += 10; // add a right and lower border
|
||||||
svgWidth += 10;
|
svgWidth += 10;
|
||||||
|
|
||||||
cmFilePrintf(fH,"<!DOCTYPE html>\n<html>\n<head><link rel=\"stylesheet\" type=\"text/css\" href=\"score0.css\"></head><body>\n<svg width=\"%i\" height=\"%i\">\n",svgWidth,svgHeight);
|
cmFilePrintf(fH,"<!DOCTYPE html>\n<html>\n<head><link rel=\"stylesheet\" type=\"text/css\" href=\"cmScoreMatchGraphic.css\"></head><body>\n<svg width=\"%i\" height=\"%i\">\n",svgWidth,svgHeight);
|
||||||
|
|
||||||
for(i=0; i<p->locN; ++i)
|
for(i=0; i<p->locN; ++i)
|
||||||
{
|
{
|
||||||
@ -690,7 +690,7 @@ cmSmgRC_t _cmScoreMatchGraphicInsertMidiMsg( cmSmg_t* p, cmMidiFileH_t mfH, bool
|
|||||||
cmMidiByte_t midi_vel = pedalDnFl ? 64 : 0;
|
cmMidiByte_t midi_vel = pedalDnFl ? 64 : 0;
|
||||||
cmMidiByte_t midi_ch = 0;
|
cmMidiByte_t midi_ch = 0;
|
||||||
|
|
||||||
printf("pedal:%s\n",pedalDnFl?"down":"up");
|
//printf("pedal:%s\n",pedalDnFl?"down":"up");
|
||||||
|
|
||||||
// insert a pedal msg relative to the reference event
|
// insert a pedal msg relative to the reference event
|
||||||
if( cmMidiFileInsertMsg(mfH, m->uid, dtick_offset, midi_ch, kCtlMdId, kSostenutoCtlMdId, midi_vel ) != kOkMfRC )
|
if( cmMidiFileInsertMsg(mfH, m->uid, dtick_offset, midi_ch, kCtlMdId, kSostenutoCtlMdId, midi_vel ) != kOkMfRC )
|
||||||
@ -798,8 +798,6 @@ cmSmgRC_t cmScoreMatchGraphicUpdateMidiFromScore( cmCtx_t* ctx, cmSmgH_t h, cons
|
|||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmMidiFilePrintMsgs(mfH, p->err.rpt );
|
|
||||||
|
|
||||||
|
|
||||||
errLabel:
|
errLabel:
|
||||||
cmMidiFileClose(&mfH);
|
cmMidiFileClose(&mfH);
|
||||||
|
@ -134,7 +134,7 @@ cmTlMidiFile_t* _cmTlMidiFileObjPtr( _cmTl_t* p, cmTlObj_t* op, bool errFl )
|
|||||||
if( op==NULL || op->typeId != kMidiFileTlId )
|
if( op==NULL || op->typeId != kMidiFileTlId )
|
||||||
{
|
{
|
||||||
if( errFl && p != NULL)
|
if( errFl && p != NULL)
|
||||||
cmErrMsg(&p->err,kTypeCvtFailTlRC,"A time line object type promotion failed.");
|
cmErrMsg(&p->err,kTypeCvtFailTlRC,"A time line object type promotion to MIDI file failed.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ cmTlMidiEvt_t* _cmTlMidiEvtObjPtr( _cmTl_t* p, cmTlObj_t* op, bool errFl )
|
|||||||
if( op==NULL || op->typeId != kMidiEvtTlId )
|
if( op==NULL || op->typeId != kMidiEvtTlId )
|
||||||
{
|
{
|
||||||
if( errFl && p != NULL )
|
if( errFl && p != NULL )
|
||||||
cmErrMsg(&p->err,kTypeCvtFailTlRC,"A time line object type promotion failed.");
|
cmErrMsg(&p->err,kTypeCvtFailTlRC,"A time line object type promotion to MIDI event failed.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ cmTlAudioEvt_t* _cmTlAudioEvtObjPtr( _cmTl_t* p, cmTlObj_t* op, bool errFl )
|
|||||||
if( op==NULL || op->typeId != kAudioEvtTlId )
|
if( op==NULL || op->typeId != kAudioEvtTlId )
|
||||||
{
|
{
|
||||||
if( errFl && p != NULL)
|
if( errFl && p != NULL)
|
||||||
cmErrMsg(&p->err,kTypeCvtFailTlRC,"A time line object type promotion failed.");
|
cmErrMsg(&p->err,kTypeCvtFailTlRC,"A time line object type promotion to audio event failed.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return (cmTlAudioEvt_t*)op;
|
return (cmTlAudioEvt_t*)op;
|
||||||
@ -186,7 +186,7 @@ cmTlMarker_t* _cmTlMarkerObjPtr( _cmTl_t* p, cmTlObj_t* op, bool errFl )
|
|||||||
if( op==NULL || op->typeId != kMarkerTlId )
|
if( op==NULL || op->typeId != kMarkerTlId )
|
||||||
{
|
{
|
||||||
if( errFl && p != NULL)
|
if( errFl && p != NULL)
|
||||||
cmErrMsg(&p->err,kTypeCvtFailTlRC,"A time line object type promotion failed.");
|
cmErrMsg(&p->err,kTypeCvtFailTlRC,"A time line object type promotion to marker object failed.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return (cmTlMarker_t*)op;
|
return (cmTlMarker_t*)op;
|
||||||
@ -1227,31 +1227,37 @@ _cmTlObj_t* _cmTimeLineObjAtTime( _cmTl_t* p, unsigned seqId, unsigned seqSmpIdx
|
|||||||
_cmTlObj_t* op = p->seq[seqId].first;
|
_cmTlObj_t* op = p->seq[seqId].first;
|
||||||
_cmTlObj_t* min_op = NULL;
|
_cmTlObj_t* min_op = NULL;
|
||||||
unsigned minDist = UINT_MAX;
|
unsigned minDist = UINT_MAX;
|
||||||
|
bool inFl = false;
|
||||||
|
|
||||||
|
// for each object in the requested sequence
|
||||||
for(; op!=NULL; op=op->next)
|
for(; op!=NULL; op=op->next)
|
||||||
if( typeId==cmInvalidId || op->obj->typeId == typeId )
|
if( typeId==cmInvalidId || op->obj->typeId == typeId )
|
||||||
{
|
{
|
||||||
// if seqSmpIdx is inside this object - then return it as the solution
|
bool in0Fl = false;
|
||||||
|
|
||||||
|
// if seqSmpIdx is inside this object - then the returned object must contain seqSmpIdx
|
||||||
|
// (but the ideal point to return is the one which contains seqSmpIdx and also has
|
||||||
|
// a begin or end point very close to seqSmpIdx - so this defer selecting an object
|
||||||
|
// until all objects which may contain seqSmpIdx have been examined
|
||||||
if((op->obj->seqSmpIdx <= seqSmpIdx && seqSmpIdx < (op->obj->seqSmpIdx + op->obj->durSmpCnt)))
|
if((op->obj->seqSmpIdx <= seqSmpIdx && seqSmpIdx < (op->obj->seqSmpIdx + op->obj->durSmpCnt)))
|
||||||
return op;
|
{
|
||||||
|
inFl = true; // the returned object must contain seqSmpIdx
|
||||||
|
in0Fl = true; // this object contains seqSmpIdx
|
||||||
|
}
|
||||||
|
|
||||||
// measure the distance from seqSmpIdx to the begin and end of this object
|
// measure the distance from seqSmpIdx to the begin and end of this object
|
||||||
unsigned d0 = op->obj->seqSmpIdx < seqSmpIdx ? seqSmpIdx - op->obj->seqSmpIdx : op->obj->seqSmpIdx - seqSmpIdx;
|
unsigned d0 = op->obj->seqSmpIdx < seqSmpIdx ? seqSmpIdx - op->obj->seqSmpIdx : op->obj->seqSmpIdx - seqSmpIdx;
|
||||||
unsigned d1 = op->obj->seqSmpIdx+op->obj->durSmpCnt < seqSmpIdx ? seqSmpIdx - op->obj->seqSmpIdx+op->obj->durSmpCnt : op->obj->seqSmpIdx+op->obj->durSmpCnt - seqSmpIdx;
|
unsigned d1 = op->obj->seqSmpIdx+op->obj->durSmpCnt < seqSmpIdx ? seqSmpIdx - op->obj->seqSmpIdx+op->obj->durSmpCnt : op->obj->seqSmpIdx+op->obj->durSmpCnt - seqSmpIdx;
|
||||||
|
|
||||||
// d0 and d1 should decrease as the cur object approaches seqSmpIdx
|
|
||||||
// If they do not then the search is over - return the closest point.
|
|
||||||
if( d0>minDist && d1>minDist)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// track the min dist and the assoc'd obj
|
// track the min dist and the assoc'd obj
|
||||||
if( d0 < minDist )
|
if( d0 < minDist && (inFl==false || inFl==in0Fl))
|
||||||
{
|
{
|
||||||
minDist = d0;
|
minDist = d0;
|
||||||
min_op = op;
|
min_op = op;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( d1 < minDist )
|
if( d1 < minDist && (inFl==false || inFl==in0Fl))
|
||||||
{
|
{
|
||||||
minDist = d1;
|
minDist = d1;
|
||||||
min_op = op;
|
min_op = op;
|
||||||
|
1015
app/cmXScore.c
1015
app/cmXScore.c
File diff suppressed because it is too large
Load Diff
@ -18,7 +18,9 @@ extern "C" {
|
|||||||
kPedalStateErrorXsRc,
|
kPedalStateErrorXsRc,
|
||||||
kMidiFailXsRC,
|
kMidiFailXsRC,
|
||||||
kFileFailXsRC,
|
kFileFailXsRC,
|
||||||
kSvgFailXsRC
|
kSvgFailXsRC,
|
||||||
|
kOverlapWarnXsRC,
|
||||||
|
kZeroLengthEventXsRC
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef cmRC_t cmXsRC_t;
|
typedef cmRC_t cmXsRC_t;
|
||||||
@ -41,32 +43,23 @@ extern "C" {
|
|||||||
//
|
//
|
||||||
// M-x load-file ~/src/emacs/proc_music_xml.el
|
// M-x load-file ~/src/emacs/proc_music_xml.el
|
||||||
//
|
//
|
||||||
// 3) How to assigned dynamic markings (they are not attached to notes). (from MIDI file?)
|
|
||||||
// 4) Tempo syntax is inconsistent (only a problem in full part2 score)
|
// Initialize an cmXScore object from a Sibelius generated MusicXML file.
|
||||||
// 5) Heel is being parsed but not used.
|
// Optionally include an 'edit' file to attach additional score information.
|
||||||
// 6) Sostenuto pedal events are not being parsed because they are not pedal events.
|
// Note that the 'edit' file is created by marking up a file created via
|
||||||
// 7) What is a 'pedal-change' event vs. a 'pedal-stop' event.
|
// cmXScoreReport().
|
||||||
// 8) Verify the colors. (done)
|
cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn, const cmChar_t* editFn );
|
||||||
// 9) Remove blank bars at end (done in xml - do in score)
|
|
||||||
//10) Need to assign section targets (always default to next section)
|
|
||||||
//11) Mark tied notes for skip. (done)
|
|
||||||
//12) Determine note off locations based on ties and slurs - defer 'pedal' to player
|
|
||||||
//13) Check that the measures are given in sorted order.
|
|
||||||
//14) Current implementation assumes meter changes only occur at measure boundaries.
|
|
||||||
//15) Score Fixes: Add meter to bar 1, fix time errors (shown in voice report)
|
|
||||||
//16) The order of notes is now correct (4/6/16) after applying
|
|
||||||
// the grace note ordering changed specified in 'score_print_mk_edit.txt',
|
|
||||||
// via cmXScoreReorder() however the ticks are now incorrect - fix them.
|
|
||||||
|
|
||||||
cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn );
|
|
||||||
cmXsRC_t cmXScoreFinalize( cmXsH_t* hp );
|
cmXsRC_t cmXScoreFinalize( cmXsH_t* hp );
|
||||||
|
|
||||||
|
|
||||||
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, const cmChar_t* csvFn );
|
||||||
|
|
||||||
void cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl );
|
void cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl );
|
||||||
|
|
||||||
|
cmXsRC_t cmXScoreGenEditFile( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* outFn );
|
||||||
|
|
||||||
// Generate the CSV file suitable for use by cmScore.
|
// Generate the CSV file suitable for use by cmScore.
|
||||||
cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* reorderFn, const cmChar_t* csvOutFn, const cmChar_t* midiOutFn );
|
cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* reorderFn, const cmChar_t* csvOutFn, const cmChar_t* midiOutFn );
|
||||||
|
|
||||||
|
207
cmMidiFile.c
207
cmMidiFile.c
@ -8,8 +8,11 @@
|
|||||||
#include "cmMallocDebug.h"
|
#include "cmMallocDebug.h"
|
||||||
#include "cmLinkedHeap.h"
|
#include "cmLinkedHeap.h"
|
||||||
#include "cmTime.h"
|
#include "cmTime.h"
|
||||||
|
#include "cmText.h"
|
||||||
#include "cmMidi.h"
|
#include "cmMidi.h"
|
||||||
#include "cmMidiFile.h"
|
#include "cmMidiFile.h"
|
||||||
|
#include "cmSvgWriter.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef cmBIG_ENDIAN
|
#ifdef cmBIG_ENDIAN
|
||||||
#define mfSwap16(v) (v)
|
#define mfSwap16(v) (v)
|
||||||
@ -256,7 +259,7 @@ cmMfRC_t _cmMidiFileReadChannelMsg( _cmMidiFile_t* mfp, cmMidiByte_t* rsPtr, cmM
|
|||||||
unsigned byteN = cmMidiStatusToByteCount(tmp->status);
|
unsigned byteN = cmMidiStatusToByteCount(tmp->status);
|
||||||
|
|
||||||
if( byteN==kInvalidMidiByte || byteN > 2 )
|
if( byteN==kInvalidMidiByte || byteN > 2 )
|
||||||
return cmErrMsg(&mfp->err,kInvalidStatusMfRC,"Invalid status:0x%x %i.",tmp->status,tmp->status);
|
return cmErrMsg(&mfp->err,kInvalidStatusMfRC,"Invalid status:0x%x %i byte cnt:%i.",tmp->status,tmp->status,byteN);
|
||||||
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for(i=useRsFl; i<byteN; ++i)
|
for(i=useRsFl; i<byteN; ++i)
|
||||||
@ -339,7 +342,7 @@ cmMfRC_t _cmMidiFileReadTrack( _cmMidiFile_t* mfp, unsigned short trkIdx )
|
|||||||
if((rc = _cmMidiFileRead8(mfp,&status)) != kOkMfRC )
|
if((rc = _cmMidiFileRead8(mfp,&status)) != kOkMfRC )
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
//printf("st:%i 0x%x\n",status,status);
|
//printf("%5i st:%i 0x%x\n",dticks,status,status);
|
||||||
|
|
||||||
// append a track msg
|
// append a track msg
|
||||||
if((rc = _cmMidiFileAppendTrackMsg( mfp, trkIdx, dticks, status, &tmp )) != kOkMfRC )
|
if((rc = _cmMidiFileAppendTrackMsg( mfp, trkIdx, dticks, status, &tmp )) != kOkMfRC )
|
||||||
@ -677,8 +680,11 @@ cmMfRC_t cmMidiFileOpen( cmCtx_t* ctx, cmMidiFileH_t* hp, const char* fn )
|
|||||||
rc = cmErrMsg(&p->err,kFileFailMfRC,"MIDI file close failed.");
|
rc = cmErrMsg(&p->err,kFileFailMfRC,"MIDI file close failed.");
|
||||||
|
|
||||||
if( rc != kOkMfRC )
|
if( rc != kOkMfRC )
|
||||||
|
{
|
||||||
_cmMidiFileClose(p);
|
_cmMidiFileClose(p);
|
||||||
|
hp->h = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -971,12 +977,75 @@ cmMfRC_t _cmMidiFileWriteMetaMsg( _cmMidiFile_t* mfp, const cmMidiTrackMsg_t* tm
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmMfRC_t _cmMidiFileInsertEotMsg( _cmMidiFile_t* p, unsigned trkIdx )
|
||||||
|
{
|
||||||
|
_cmMidiTrack_t* trk = p->trkV + trkIdx;
|
||||||
|
cmMidiTrackMsg_t* m0 = NULL;
|
||||||
|
cmMidiTrackMsg_t* m = trk->base;
|
||||||
|
|
||||||
|
// locate the current EOT msg on this track
|
||||||
|
for(; m!=NULL; m=m->link)
|
||||||
|
{
|
||||||
|
if( m->status == kMetaStId && m->metaId == kEndOfTrkMdId )
|
||||||
|
{
|
||||||
|
// If this EOT msg is the last msg in the track ...
|
||||||
|
if( m->link == NULL )
|
||||||
|
{
|
||||||
|
assert( m == trk->last );
|
||||||
|
return kOkMfRC; // ... then there is nothing else to do
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this EOT msg is not the last in the track ...
|
||||||
|
if( m0 != NULL )
|
||||||
|
m0->link = m->link; // ... then unlink it
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m0 = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we get here then the last msg in the track was not an EOT msg
|
||||||
|
|
||||||
|
// if there was no previously allocated EOT msg
|
||||||
|
if( m == NULL )
|
||||||
|
{
|
||||||
|
m = _cmMidiFileAllocMsg(p, trkIdx, 1, kMetaStId );
|
||||||
|
m->metaId = kEndOfTrkMdId;
|
||||||
|
trk->cnt += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// link an EOT msg as the last msg on the track
|
||||||
|
|
||||||
|
// if the track is currently empty
|
||||||
|
if( m0 == NULL )
|
||||||
|
{
|
||||||
|
trk->base = m;
|
||||||
|
trk->last = m;
|
||||||
|
}
|
||||||
|
else // link the msg as the last on on the track
|
||||||
|
{
|
||||||
|
assert( m0 == trk->last);
|
||||||
|
m0->link = m;
|
||||||
|
m->link = NULL;
|
||||||
|
trk->last = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kOkMfRC;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
cmMfRC_t _cmMidiFileWriteTrack( _cmMidiFile_t* mfp, unsigned trkIdx )
|
cmMfRC_t _cmMidiFileWriteTrack( _cmMidiFile_t* mfp, unsigned trkIdx )
|
||||||
{
|
{
|
||||||
cmMfRC_t rc = kOkMfRC;
|
cmMfRC_t rc = kOkMfRC;
|
||||||
cmMidiTrackMsg_t* tmp = mfp->trkV[trkIdx].base;
|
cmMidiTrackMsg_t* tmp = mfp->trkV[trkIdx].base;
|
||||||
cmMidiByte_t runStatus = 0;
|
cmMidiByte_t runStatus = 0;
|
||||||
|
|
||||||
|
// be sure there is a EOT msg at the end of this track
|
||||||
|
if((rc = _cmMidiFileInsertEotMsg(mfp, trkIdx )) != kOkMfRC )
|
||||||
|
return rc;
|
||||||
|
|
||||||
for(; tmp != NULL; tmp=tmp->link)
|
for(; tmp != NULL; tmp=tmp->link)
|
||||||
{
|
{
|
||||||
// write the msg tick count
|
// write the msg tick count
|
||||||
@ -1379,8 +1448,11 @@ cmMfRC_t cmMidiFileInsertTrackMsg( cmMidiFileH_t h, unsigned trkIdx, const cmMi
|
|||||||
assert( m1->atick >= m->atick );
|
assert( m1->atick >= m->atick );
|
||||||
m1->dtick = m1->atick - m->atick;
|
m1->dtick = m1->atick - m->atick;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p->trkV[trkIdx].cnt += 1;
|
||||||
p->msgVDirtyFl = true;
|
p->msgVDirtyFl = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return kOkMfRC;
|
return kOkMfRC;
|
||||||
|
|
||||||
@ -1402,6 +1474,8 @@ cmMfRC_t cmMidiFileInsertTrackChMsg( cmMidiFileH_t h, unsigned trkIdx, unsigned
|
|||||||
m.status = status & 0xf0;
|
m.status = status & 0xf0;
|
||||||
m.byteCnt = sizeof(cm);
|
m.byteCnt = sizeof(cm);
|
||||||
m.u.chMsgPtr = &cm;
|
m.u.chMsgPtr = &cm;
|
||||||
|
|
||||||
|
assert( m.status >= kNoteOffMdId && m.status <= kPbendMdId );
|
||||||
|
|
||||||
return cmMidiFileInsertTrackMsg(h,trkIdx,&m);
|
return cmMidiFileInsertTrackMsg(h,trkIdx,&m);
|
||||||
}
|
}
|
||||||
@ -1836,6 +1910,38 @@ void cmMidiFilePrintTracks( cmMidiFileH_t h, unsigned trkIdx, cmRpt_t* rpt )
|
|||||||
void cmMidiFileTestPrint( void* printDataPtr, const char* fmt, va_list vl )
|
void cmMidiFileTestPrint( void* printDataPtr, const char* fmt, va_list vl )
|
||||||
{ vprintf(fmt,vl); }
|
{ vprintf(fmt,vl); }
|
||||||
|
|
||||||
|
cmMidiFileDensity_t* cmMidiFileNoteDensity( cmMidiFileH_t h, unsigned* cntRef )
|
||||||
|
{
|
||||||
|
int msgN = cmMidiFileMsgCount(h);
|
||||||
|
const cmMidiTrackMsg_t** msgs = cmMidiFileMsgArray(h);
|
||||||
|
cmMidiFileDensity_t* dV = cmMemAllocZ(cmMidiFileDensity_t,msgN);
|
||||||
|
|
||||||
|
int i,j,k;
|
||||||
|
for(i=0,k=0; i<msgN && k<msgN; ++i)
|
||||||
|
if( msgs[i]->status == kNoteOnMdId && msgs[i]->u.chMsgPtr->d1 > 0 )
|
||||||
|
{
|
||||||
|
dV[k].uid = msgs[i]->uid;
|
||||||
|
dV[k].amicro = msgs[i]->amicro;
|
||||||
|
|
||||||
|
for(j=i; j>=0; --j)
|
||||||
|
{
|
||||||
|
if( msgs[i]->amicro - msgs[j]->amicro > 1000000 )
|
||||||
|
break;
|
||||||
|
|
||||||
|
dV[k].density += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
k += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cntRef != NULL )
|
||||||
|
*cntRef = k;
|
||||||
|
|
||||||
|
return dV;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
cmMfRC_t cmMidiFileGenPlotFile( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* outFn )
|
cmMfRC_t cmMidiFileGenPlotFile( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* outFn )
|
||||||
{
|
{
|
||||||
cmMfRC_t rc = kOkMfRC;
|
cmMfRC_t rc = kOkMfRC;
|
||||||
@ -1872,6 +1978,99 @@ cmMfRC_t cmMidiFileGenPlotFile( cmCtx_t* ctx, const cmChar_t* midiFn, const cmCh
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmMfRC_t cmMidiFileGenSvgFile( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* outSvgFn, const cmChar_t* cssFn )
|
||||||
|
{
|
||||||
|
cmMfRC_t rc = kOkMfRC;
|
||||||
|
cmSvgH_t svgH = cmSvgNullHandle;
|
||||||
|
cmMidiFileH_t mfH = cmMidiFileNullHandle;
|
||||||
|
unsigned msgN = 0;
|
||||||
|
const cmMidiTrackMsg_t** msgs = NULL;
|
||||||
|
unsigned noteHeight = 10;
|
||||||
|
double micros_per_sec = 1000.0;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
if((rc = cmMidiFileOpen(ctx,&mfH,midiFn)) != kOkMfRC )
|
||||||
|
{
|
||||||
|
rc = cmErrMsg(&ctx->err,rc,"Unable to open the MIDI file '%s'.",cmStringNullGuard(midiFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmMidiFileCalcNoteDurations( mfH );
|
||||||
|
|
||||||
|
msgN = cmMidiFileMsgCount(mfH);
|
||||||
|
msgs = cmMidiFileMsgArray(mfH);
|
||||||
|
|
||||||
|
|
||||||
|
if( cmSvgWriterAlloc(ctx,&svgH) != kOkSvgRC )
|
||||||
|
{
|
||||||
|
rc = cmErrMsg(&ctx->err,kSvgFailMfRC,"Unable to create the MIDI SVG output file '%s'.",cmStringNullGuard(outSvgFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for(i=0; i<msgN && rc==kOkMfRC; ++i)
|
||||||
|
if( msgs[i]->status == kNoteOnMdId && msgs[i]->u.chMsgPtr->d1 > 0 )
|
||||||
|
{
|
||||||
|
const cmMidiTrackMsg_t* m = msgs[i];
|
||||||
|
|
||||||
|
|
||||||
|
if( cmSvgWriterRect(svgH, m->amicro/micros_per_sec, m->u.chMsgPtr->d0 * noteHeight, m->u.chMsgPtr->durMicros/micros_per_sec, noteHeight-1, "note" ) != kOkSvgRC )
|
||||||
|
rc = kSvgFailMfRC;
|
||||||
|
|
||||||
|
const cmChar_t* t0 = cmMidiToSciPitch(m->u.chMsgPtr->d0,NULL,0);
|
||||||
|
|
||||||
|
if( cmSvgWriterText(svgH, (m->amicro + (m->u.chMsgPtr->durMicros/2)) / micros_per_sec, m->u.chMsgPtr->d0 * noteHeight, t0, "text" ) != kOkSvgRC )
|
||||||
|
rc = kSvgFailMfRC;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if( rc != kOkMfRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&ctx->err,rc,"SVG Shape insertion failed.");
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned dN = 0;
|
||||||
|
cmMidiFileDensity_t* dV = cmMidiFileNoteDensity( mfH, &dN );
|
||||||
|
double t0 = 0;
|
||||||
|
double y0 = 64.0;
|
||||||
|
cmChar_t* tx = NULL;
|
||||||
|
|
||||||
|
for(i=0; i<dN; ++i)
|
||||||
|
{
|
||||||
|
const cmMidiTrackMsg_t* m;
|
||||||
|
|
||||||
|
if((m = _cmMidiFileUidToMsg( _cmMidiFileHandleToPtr(mfH), dV[i].uid )) == NULL )
|
||||||
|
rc = cmErrMsg(&ctx->err,kUidNotFoundMfRC,"The MIDI msg form UID:%i was not found.",dV[i].uid);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double t1 = m->amicro / micros_per_sec;
|
||||||
|
double y1 = dV[i].density * noteHeight;
|
||||||
|
|
||||||
|
cmSvgWriterLine(svgH, t0, y0, t1, y1, "density" );
|
||||||
|
cmSvgWriterText(svgH, t1, y1, tx = cmTsPrintfP(tx,"%i",dV[i].density),"dtext");
|
||||||
|
|
||||||
|
t0 = t1;
|
||||||
|
y0 = y1;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmMemFree(dV);
|
||||||
|
cmMemFree(tx);
|
||||||
|
|
||||||
|
if( rc == kOkMfRC )
|
||||||
|
if( cmSvgWriterWrite(svgH,cssFn,outSvgFn) != kOkSvgRC )
|
||||||
|
rc = cmErrMsg(&ctx->err,kSvgFailMfRC,"SVG file write to '%s' failed.",cmStringNullGuard(outSvgFn));
|
||||||
|
|
||||||
|
|
||||||
|
errLabel:
|
||||||
|
cmMidiFileClose(&mfH);
|
||||||
|
cmSvgWriterFree(&svgH);
|
||||||
|
|
||||||
|
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;
|
||||||
|
21
cmMidiFile.h
21
cmMidiFile.h
@ -117,7 +117,8 @@ extern "C" {
|
|||||||
kLargeDeltaTickMfRC, // 12 (a large delta tick value was filtered)
|
kLargeDeltaTickMfRC, // 12 (a large delta tick value was filtered)
|
||||||
kUidNotFoundMfRC, // 13
|
kUidNotFoundMfRC, // 13
|
||||||
kUidNotANoteMsgMfRC, // 14
|
kUidNotANoteMsgMfRC, // 14
|
||||||
kInvalidTrkIndexMfRC // 15
|
kInvalidTrkIndexMfRC,// 15
|
||||||
|
kSvgFailMfRC // 16
|
||||||
};
|
};
|
||||||
|
|
||||||
extern cmMidiFileH_t cmMidiFileNullHandle;
|
extern cmMidiFileH_t cmMidiFileNullHandle;
|
||||||
@ -212,11 +213,27 @@ extern "C" {
|
|||||||
|
|
||||||
void cmMidiFilePrintMsgs( cmMidiFileH_t h, cmRpt_t* rpt );
|
void cmMidiFilePrintMsgs( cmMidiFileH_t h, cmRpt_t* rpt );
|
||||||
void cmMidiFilePrintTrack( cmMidiFileH_t h, unsigned trkIdx, cmRpt_t* rpt );
|
void cmMidiFilePrintTrack( cmMidiFileH_t h, unsigned trkIdx, cmRpt_t* rpt );
|
||||||
void cmMidiFileTest( const char* fn, cmCtx_t* ctx );
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned uid;
|
||||||
|
unsigned long long amicro;
|
||||||
|
unsigned density;
|
||||||
|
|
||||||
|
} cmMidiFileDensity_t;
|
||||||
|
|
||||||
|
// Generate the note onset density measure for each note in the MIDI file.
|
||||||
|
// Delete the returned memory with a call to cmMemFree().
|
||||||
|
cmMidiFileDensity_t* cmMidiFileNoteDensity( cmMidiFileH_t h, unsigned* cntRef );
|
||||||
|
|
||||||
// Generate a piano-roll plot description file which can be displayed with cmXScore.m
|
// Generate a piano-roll plot description file which can be displayed with cmXScore.m
|
||||||
cmMfRC_t cmMidiFileGenPlotFile( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* outFn );
|
cmMfRC_t cmMidiFileGenPlotFile( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* outFn );
|
||||||
|
|
||||||
|
cmMfRC_t cmMidiFileGenSvgFile( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* outSvgFn, const cmChar_t* cssFn );
|
||||||
|
|
||||||
|
void cmMidiFileTest( const char* fn, cmCtx_t* ctx );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//)
|
//)
|
||||||
|
|
||||||
|
@ -167,6 +167,32 @@ void _cmSvgSize( cmSvg_t* p, double* widthRef, double* heightRef )
|
|||||||
*heightRef = max_y - min_y;
|
*heightRef = max_y - min_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _cmSvgWriterFlipY( cmSvg_t* p, unsigned height )
|
||||||
|
{
|
||||||
|
cmSvgEle_t* e = p->elist;
|
||||||
|
for(; e!=NULL; e=e->link)
|
||||||
|
{
|
||||||
|
e->y0 = (-e->y0) + height;
|
||||||
|
e->y1 = (-e->y1) + height;
|
||||||
|
|
||||||
|
if( e->id == kRectSvgId )
|
||||||
|
{
|
||||||
|
double t = e->y1;
|
||||||
|
e->y1 = e->y0;
|
||||||
|
e->y0 = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
"<script type=\"text/javascript\" src=\"svg-pan-zoom.min.js\"></script>\n"
|
||||||
|
"<script>\n"
|
||||||
|
" var panZoom = null;\n"
|
||||||
|
" function doOnLoad() { panZoom = svgPanZoom(document.querySelector('#mysvg'), { controlIconsEnabled:true } ) }\n"
|
||||||
|
"</script>\n"
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
cmSvgRC_t cmSvgWriterWrite( cmSvgH_t h, const cmChar_t* cssFn, const cmChar_t* outFn )
|
cmSvgRC_t cmSvgWriterWrite( cmSvgH_t h, const cmChar_t* cssFn, const cmChar_t* outFn )
|
||||||
{
|
{
|
||||||
@ -176,15 +202,29 @@ cmSvgRC_t cmSvgWriterWrite( cmSvgH_t h, const cmChar_t* cssFn, const cmChar_t*
|
|||||||
double svgHeight = 0;
|
double svgHeight = 0;
|
||||||
cmSvgEle_t* e = p->elist;
|
cmSvgEle_t* e = p->elist;
|
||||||
cmFileH_t fH = cmFileNullHandle;
|
cmFileH_t fH = cmFileNullHandle;
|
||||||
|
cmChar_t* s0 = NULL;
|
||||||
|
cmChar_t* s1 = NULL;
|
||||||
|
|
||||||
|
cmChar_t hdr[] =
|
||||||
|
"<!DOCTYPE html>\n"
|
||||||
|
"<html>\n"
|
||||||
|
"<head>\n"
|
||||||
|
"<meta charset=\"utf-8\">\n"
|
||||||
|
"<link rel=\"stylesheet\" type=\"text/css\" href=\"%s\">\n"
|
||||||
|
"</head>\n"
|
||||||
|
"<body onload=\"doOnLoad()\">\n"
|
||||||
|
"<svg id=\"mysvg\" width=\"%f\" height=\"%f\">\n";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_cmSvgSize(p, &svgWidth, &svgHeight );
|
_cmSvgSize(p, &svgWidth, &svgHeight );
|
||||||
|
|
||||||
if( cmFileOpen(&fH,outFn,kWriteFileFl,p->err.rpt) != kOkFileRC )
|
|
||||||
return cmErrMsg(&p->err,kFileFailSvgRC,"SVG file create failed for '%s'.",cmStringNullGuard(outFn));
|
|
||||||
|
|
||||||
if( cmFilePrintf(fH,"<!DOCTYPE html>\n<html>\n<head><link rel=\"stylesheet\" type=\"text/css\" href=\"%s\"></head><body>\n<svg width=\"%f\" height=\"%f\">\n",svgWidth,svgHeight,cssFn) != kOkFileRC )
|
_cmSvgWriterFlipY( p, svgHeight );
|
||||||
|
|
||||||
|
// print the file header
|
||||||
|
if( (s0 = cmTsPrintfP(s0,hdr,cssFn,svgWidth,svgHeight)) == NULL )
|
||||||
{
|
{
|
||||||
rc = cmErrMsg(&p->err,kFileFailSvgRC,"File prefix write failed.");
|
rc = cmErrMsg(&p->err,kPrintFailSvgRC,"File prefix write failed.");
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,18 +233,18 @@ cmSvgRC_t cmSvgWriterWrite( cmSvgH_t h, const cmChar_t* cssFn, const cmChar_t*
|
|||||||
switch( e->id )
|
switch( e->id )
|
||||||
{
|
{
|
||||||
case kRectSvgId:
|
case kRectSvgId:
|
||||||
if( cmFilePrintf(fH,"<rect x=\"%f\" y=\"%f\" width=\"%f\" height=\"%f\" class=\"%s\"/>\n",e->x0,e->y0,e->x1-e->x0,e->y1-e->y0,e->cssClass) != kOkFileRC )
|
if( (s1 = cmTsPrintfP(s1,"<rect x=\"%f\" y=\"%f\" width=\"%f\" height=\"%f\" class=\"%s\"/>\n",e->x0,e->y0,e->x1-e->x0,e->y1-e->y0,e->cssClass)) == NULL )
|
||||||
rc = kFileFailSvgRC;
|
rc = kPrintFailSvgRC;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kLineSvgId:
|
case kLineSvgId:
|
||||||
if( cmFilePrintf(fH,"<line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" class=\"%s\"/>\n",e->x0,e->y0,e->x1,e->y1,e->cssClass) != kOkFileRC )
|
if( (s1 = cmTsPrintfP(s1,"<line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" class=\"%s\"/>\n",e->x0,e->y0,e->x1,e->y1,e->cssClass)) == NULL )
|
||||||
rc = kFileFailSvgRC;
|
rc = kPrintFailSvgRC;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kTextSvgId:
|
case kTextSvgId:
|
||||||
if( cmFilePrintf(fH,"<text x=\"%f\" y=\"%f\" class=\"%s\">%s</text>\n",e->x0,e->y0,e->cssClass,e->text) != kOkFileRC )
|
if( (s1 = cmTsPrintfP(s1,"<text x=\"%f\" y=\"%f\" class=\"%s\">%s</text>\n",e->x0,e->y0,e->cssClass,e->text)) == NULL )
|
||||||
rc = kFileFailSvgRC;
|
rc = kPrintFailSvgRC;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -214,21 +254,38 @@ cmSvgRC_t cmSvgWriterWrite( cmSvgH_t h, const cmChar_t* cssFn, const cmChar_t*
|
|||||||
|
|
||||||
if( rc != kOkSvgRC )
|
if( rc != kOkSvgRC )
|
||||||
{
|
{
|
||||||
rc = cmErrMsg(&p->err,kFileFailSvgRC,"Element write failed.");
|
rc = cmErrMsg(&p->err,kPrintFailSvgRC,"Element write failed.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s0 = cmTextAppendSS(s0,s1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( cmFilePrint(fH,"</svg>\n</body>\n</html>\n") != kOkFileRC )
|
if( (s1 = cmTsPrintfP(s1,"</svg>\n</body>\n</html>\n")) == NULL )
|
||||||
{
|
{
|
||||||
rc = cmErrMsg(&p->err,kFileFailSvgRC,"File suffix write failed.");
|
rc = cmErrMsg(&p->err,kPrintFailSvgRC,"File suffix write failed.");
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( cmFileOpen(&fH,outFn,kWriteFileFl,p->err.rpt) != kOkFileRC )
|
||||||
|
{
|
||||||
|
rc = cmErrMsg(&p->err,kFileFailSvgRC,"SVG file create failed for '%s'.",cmStringNullGuard(outFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cmFilePrint(fH,s0 = cmTextAppendSS(s0,s1)) != kOkFileRC )
|
||||||
|
{
|
||||||
|
rc = cmErrMsg(&p->err,kFileFailSvgRC,"File write failed.");
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
errLabel:
|
errLabel:
|
||||||
cmFileClose(&fH);
|
cmFileClose(&fH);
|
||||||
|
|
||||||
|
cmMemFree(s0);
|
||||||
|
cmMemFree(s1);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ enum
|
|||||||
{
|
{
|
||||||
kOkSvgRC = cmOkRC,
|
kOkSvgRC = cmOkRC,
|
||||||
kFileFailSvgRC,
|
kFileFailSvgRC,
|
||||||
|
kPrintFailSvgRC,
|
||||||
kLHeapFailSvgRC
|
kLHeapFailSvgRC
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -21,10 +22,14 @@ enum
|
|||||||
cmSvgRC_t cmSvgWriterFree( cmSvgH_t* hp );
|
cmSvgRC_t cmSvgWriterFree( cmSvgH_t* hp );
|
||||||
bool cmSvgWriterIsValid( cmSvgH_t h );
|
bool cmSvgWriterIsValid( cmSvgH_t h );
|
||||||
|
|
||||||
cmSvgRC_t cmSvgWriterRect( cmSvgH_t h, double x, double y, double ww, double hh, const cmChar_t* cssClassLabel );
|
cmSvgRC_t cmSvgWriterRect( cmSvgH_t h, double x, double y, double ww, double hh, const cmChar_t* cssClassLabel );
|
||||||
cmSvgRC_t cmSvgWriterLine( cmSvgH_t h, double x0, double y0, double x1, double y1, const cmChar_t* cssClassLabel );
|
cmSvgRC_t cmSvgWriterLine( cmSvgH_t h, double x0, double y0, double x1, double y1, const cmChar_t* cssClassLabel );
|
||||||
cmSvgRC_t cmSvgWriterText( cmSvgH_t h, double x, double y, const cmChar_t* text, const cmChar_t* cssClassLabel );
|
cmSvgRC_t cmSvgWriterText( cmSvgH_t h, double x, double y, const cmChar_t* text, const cmChar_t* cssClassLabel );
|
||||||
|
|
||||||
|
// Write the SVG file. Note that header on this file references the CSS file 'cssFn'
|
||||||
|
// and the Javascript file svg-pan-zoom.min.js from https://github.com/ariutta/svg-pan-zoom.
|
||||||
|
// Both the CSS file and svg-pan-zoom.min.js should therefore be in the same directory
|
||||||
|
// as the output HTML file.
|
||||||
cmSvgRC_t cmSvgWriterWrite( cmSvgH_t h, const cmChar_t* cssFn, const cmChar_t* outFn );
|
cmSvgRC_t cmSvgWriterWrite( cmSvgH_t h, const cmChar_t* cssFn, const cmChar_t* outFn );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -657,7 +657,7 @@ cmDspRC_t _cmDspTimeLineRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
|
|||||||
cmTlObj_t* op;
|
cmTlObj_t* op;
|
||||||
if((op = cmTimeLineIdToObj(p->tlH, cmInvalidId, markerId )) != NULL )
|
if((op = cmTimeLineIdToObj(p->tlH, cmInvalidId, markerId )) != NULL )
|
||||||
{
|
{
|
||||||
assert(op->typeId == kMarkerTlId);
|
assert(op->typeId == kMarkerTlId || op->typeId == kMidiEvtTlId );
|
||||||
|
|
||||||
p->afIdx = op->begSmpIdx;
|
p->afIdx = op->begSmpIdx;
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c, unsigned preGrpS
|
|||||||
cmDspInst_t* max_lwr_ctl = cmDspSysAllocScalarP( h,preGrpSymId, NULL, lbl("Max Lwr"), 0.0, -1.0, 5.0, 3.0);
|
cmDspInst_t* max_lwr_ctl = cmDspSysAllocScalarP( h,preGrpSymId, NULL, lbl("Max Lwr"), 0.0, -1.0, 5.0, 3.0);
|
||||||
cmDspInst_t* min_off_ctl = cmDspSysAllocScalarP( h,preGrpSymId, NULL, lbl("Min Off"), 0.0, 50.0, 0.1, 30.0);
|
cmDspInst_t* min_off_ctl = cmDspSysAllocScalarP( h,preGrpSymId, NULL, lbl("Min Off"), 0.0, 50.0, 0.1, 30.0);
|
||||||
cmDspInst_t* max_off_ctl = cmDspSysAllocScalarP( h,preGrpSymId, NULL, lbl("Max Off"), 0.0, 50.0, 0.1, 30.0);
|
cmDspInst_t* max_off_ctl = cmDspSysAllocScalarP( h,preGrpSymId, NULL, lbl("Max Off"), 0.0, 50.0, 0.1, 30.0);
|
||||||
cmDspInst_t* min_wet_ctl = cmDspSysAllocScalarP( h,preGrpSymId, NULL, lbl("Min Wet"), 0.0, 1.0, 0.01, 1.0);
|
cmDspInst_t* min_wet_ctl = cmDspSysAllocScalarP( h,preGrpSymId, NULL, lbl("Min Wet"), 0.0, 1.0, 0.01, 0.0);
|
||||||
cmDspInst_t* max_wet_ctl = cmDspSysAllocScalarP( h,preGrpSymId, NULL, lbl("Max Wet"), 0.0, 1.0, 0.01, 1.0);
|
cmDspInst_t* max_wet_ctl = cmDspSysAllocScalarP( h,preGrpSymId, NULL, lbl("Max Wet"), 0.0, 1.0, 0.01, 1.0);
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user