cmXScore.h,c : Began MIDI output file generation coding. Added _cmXsWriteMidiSvg().
This commit is contained in:
parent
a4ed9ba98b
commit
38cdd3012b
196
app/cmXScore.c
196
app/cmXScore.c
@ -10,6 +10,7 @@
|
|||||||
#include "cmLinkedHeap.h"
|
#include "cmLinkedHeap.h"
|
||||||
#include "cmXml.h"
|
#include "cmXml.h"
|
||||||
#include "cmText.h"
|
#include "cmText.h"
|
||||||
|
#include "cmFileSys.h"
|
||||||
#include "cmXScore.h"
|
#include "cmXScore.h"
|
||||||
#include "cmTime.h"
|
#include "cmTime.h"
|
||||||
#include "cmMidi.h"
|
#include "cmMidi.h"
|
||||||
@ -19,6 +20,7 @@
|
|||||||
#include "cmSymTbl.h"
|
#include "cmSymTbl.h"
|
||||||
#include "cmScore.h"
|
#include "cmScore.h"
|
||||||
|
|
||||||
|
|
||||||
#include "cmFile.h"
|
#include "cmFile.h"
|
||||||
#include "cmSymTbl.h"
|
#include "cmSymTbl.h"
|
||||||
#include "cmAudioFile.h"
|
#include "cmAudioFile.h"
|
||||||
@ -29,6 +31,8 @@
|
|||||||
#include "cmProc2.h"
|
#include "cmProc2.h"
|
||||||
#include "cmProc5.h"
|
#include "cmProc5.h"
|
||||||
|
|
||||||
|
#include "cmSvgWriter.h"
|
||||||
|
|
||||||
cmXsH_t cmXsNullHandle = cmSTATIC_NULL_HANDLE;
|
cmXsH_t cmXsNullHandle = cmSTATIC_NULL_HANDLE;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@ -89,6 +93,8 @@ typedef struct cmXsNote_str
|
|||||||
|
|
||||||
const cmXmlNode_t* xmlNode; // note xml ptr
|
const cmXmlNode_t* xmlNode; // note xml ptr
|
||||||
|
|
||||||
|
struct cmXsNote_str* tied; // subsequent note tied to this note
|
||||||
|
|
||||||
struct cmXsNote_str* mlink; // measure note list
|
struct cmXsNote_str* mlink; // measure note list
|
||||||
struct cmXsNote_str* slink; // time sorted event list
|
struct cmXsNote_str* slink; // time sorted event list
|
||||||
|
|
||||||
@ -374,11 +380,8 @@ cmXsRC_t _cmXScoreParsePitch( cmXScore_t* p, const cmXmlNode_t* nnp, cmXsNote_t
|
|||||||
|
|
||||||
cmXmlNodeDouble( nnp,&alter,"pitch","alter",NULL);
|
cmXmlNodeDouble( nnp,&alter,"pitch","alter",NULL);
|
||||||
|
|
||||||
cmChar_t buf[3] = { *step, '0', '\0'};
|
int acc = alter;
|
||||||
unsigned midi = cmSciPitchToMidi(buf);
|
unsigned midi = cmSciPitchToMidiPitch(*step,acc,octave);
|
||||||
|
|
||||||
midi += (12 * octave);
|
|
||||||
midi += alter;
|
|
||||||
|
|
||||||
np->pitch = midi;
|
np->pitch = midi;
|
||||||
np->step = *step;
|
np->step = *step;
|
||||||
@ -1044,10 +1047,8 @@ void _cmXScoreSpreadGraceNotes( cmXScore_t* p )
|
|||||||
tick1 = _cmXsSpreadGraceNotes(a,ai);
|
tick1 = _cmXsSpreadGraceNotes(a,ai);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool _cmXScoreFindTiedNote( cmXScore_t* p, cmXsMeas_t* mp, cmXsNote_t* n0p, bool rptFl )
|
bool _cmXScoreFindTiedNote( cmXScore_t* p, cmXsMeas_t* mp, cmXsNote_t* n0p, bool rptFl )
|
||||||
{
|
{
|
||||||
cmXsNote_t* nnp = n0p->slink; // begin w/ note following np
|
cmXsNote_t* nnp = n0p->slink; // begin w/ note following np
|
||||||
@ -1080,6 +1081,7 @@ bool _cmXScoreFindTiedNote( cmXScore_t* p, cmXsMeas_t* mp, cmXsNote_t* n0p, boo
|
|||||||
{
|
{
|
||||||
nnp->flags |= kTieProcXsFl;
|
nnp->flags |= kTieProcXsFl;
|
||||||
nnp->flags = cmClrFlag(nnp->flags,kOnsetXsFl);
|
nnp->flags = cmClrFlag(nnp->flags,kOnsetXsFl);
|
||||||
|
n0p->tied = nnp;
|
||||||
|
|
||||||
if( rptFl )
|
if( rptFl )
|
||||||
printf("---> %i %i %s ",nnp->meas->number,nnp->tick,cmMidiToSciPitch(nnp->pitch,NULL,0));
|
printf("---> %i %i %s ",nnp->meas->number,nnp->tick,cmMidiToSciPitch(nnp->pitch,NULL,0));
|
||||||
@ -1088,6 +1090,8 @@ bool _cmXScoreFindTiedNote( cmXScore_t* p, cmXsMeas_t* mp, cmXsNote_t* n0p, boo
|
|||||||
if( cmIsNotFlag(nnp->flags,kTieBegXsFl) )
|
if( cmIsNotFlag(nnp->flags,kTieBegXsFl) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
n0p = nnp;
|
||||||
|
|
||||||
// record the measure number of the last note with a tie-start
|
// record the measure number of the last note with a tie-start
|
||||||
measNumb = mp->number;
|
measNumb = mp->number;
|
||||||
}
|
}
|
||||||
@ -1134,15 +1138,19 @@ void _cmXScoreResolveTiesAndLoc( cmXScore_t* p )
|
|||||||
n += 1;
|
n += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate the tie state of the current note.
|
||||||
if( cmIsFlag(np->flags,kTieEndXsFl) && cmIsFlag(np->flags,kOnsetXsFl) )
|
if( cmIsFlag(np->flags,kTieEndXsFl) && cmIsFlag(np->flags,kOnsetXsFl) )
|
||||||
{
|
{
|
||||||
cmChar_t acc = np->alter==-1?'b' : (np->alter==1?'#':' ');
|
cmChar_t acc = np->alter==-1?'b' : (np->alter==1?'#':' ');
|
||||||
cmErrWarnMsg(&p->err,kUnterminatedTieXsRC,"The tied %c%c%i in measure %i marked as a tied note but is also marked to sound.",np->step,acc,np->octave,mp->number);
|
cmErrWarnMsg(&p->err,kUnterminatedTieXsRC,"The tied %c%c%i in measure %i marked as a tied note but is also marked to sound.",np->step,acc,np->octave,mp->number);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the location
|
//
|
||||||
|
// Set the score location of notes marked for onset and bar lines.
|
||||||
|
//
|
||||||
if( cmIsFlag(np->flags,kOnsetXsFl|kBarXsFl) )
|
if( cmIsFlag(np->flags,kOnsetXsFl|kBarXsFl) )
|
||||||
{
|
{
|
||||||
|
// if this note does not share the same location as the previous 'located' note then increment the 'loc' index
|
||||||
if( cmIsFlag(np->flags,kBarXsFl) || (n0!=NULL && n0->tick!=np->tick))
|
if( cmIsFlag(np->flags,kBarXsFl) || (n0!=NULL && n0->tick!=np->tick))
|
||||||
locIdx += 1;
|
locIdx += 1;
|
||||||
|
|
||||||
@ -1153,7 +1161,7 @@ void _cmXScoreResolveTiesAndLoc( cmXScore_t* p )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Found:%i Not Found:%i\n",m,n-m);
|
printf("Tied notes found:%i Not found:%i\n",m,n-m);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmXsRC_t _cmXScoreResolveOctaveShift( cmXScore_t* p )
|
cmXsRC_t _cmXScoreResolveOctaveShift( cmXScore_t* p )
|
||||||
@ -1362,7 +1370,7 @@ void _cmXScoreFixBarLines( cmXScore_t* p )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn, const cmChar_t* midiFn )
|
cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn )
|
||||||
{
|
{
|
||||||
cmXsRC_t rc = kOkXsRC;
|
cmXsRC_t rc = kOkXsRC;
|
||||||
|
|
||||||
@ -2511,13 +2519,125 @@ void cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct cmXsMidiEvt_str
|
||||||
cmXsRC_t cmXScoreWriteMidi( cmXsH_t h, const cmChar_t* fn )
|
{
|
||||||
|
unsigned flags; // k???XsFl
|
||||||
|
unsigned tick; // start tick
|
||||||
|
unsigned durTicks; // dur-ticks
|
||||||
|
unsigned voice; // score voice number
|
||||||
|
unsigned d0; // MIDI d0 (barNumb)
|
||||||
|
unsigned d1; // MIDI d1
|
||||||
|
struct cmXsMidiEvt_str* link;
|
||||||
|
} cmXsMidiEvt_t;
|
||||||
|
|
||||||
|
typedef struct cmXsMidiFile_str
|
||||||
|
{
|
||||||
|
cmXsMidiEvt_t* elist;
|
||||||
|
cmXsMidiEvt_t* eol;
|
||||||
|
|
||||||
|
unsigned pitch_min;
|
||||||
|
unsigned pitch_max;
|
||||||
|
|
||||||
|
} cmXsMidiFile_t;
|
||||||
|
|
||||||
|
cmXsRC_t _cmXsWriteMidiSvg( cmCtx_t* ctx, cmXScore_t* p, cmXsMidiFile_t* mf, const cmChar_t* dir, const cmChar_t* fn )
|
||||||
|
{
|
||||||
|
cmXsRC_t rc = kOkXsRC;
|
||||||
|
cmSvgH_t svgH = cmSvgNullHandle;
|
||||||
|
cmXsMidiEvt_t* e = mf->elist;
|
||||||
|
unsigned noteHeight = 10;
|
||||||
|
const cmChar_t* svgFn = cmFsMakeFn(dir,fn,"html",NULL);
|
||||||
|
const cmChar_t* cssFn = cmFsMakeFn(NULL,fn,"css",NULL);
|
||||||
|
cmChar_t* t0 = NULL; // temporary dynamic string
|
||||||
|
// create the SVG writer
|
||||||
|
if( cmSvgWriterAlloc(ctx,&svgH) != kOkSvgRC )
|
||||||
|
{
|
||||||
|
rc = cmErrMsg(&p->err,kSvgFailXsRC,"Unable to create the MIDI SVG output file '%s'.",cmStringNullGuard(svgFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for each MIDI file element
|
||||||
|
for(; e!=NULL && rc==kOkXsRC; e=e->link)
|
||||||
|
{
|
||||||
|
// if this is a note
|
||||||
|
if( cmIsFlag(e->flags,kOnsetXsFl) )
|
||||||
|
{
|
||||||
|
const cmChar_t* classLabel = "note";
|
||||||
|
|
||||||
|
|
||||||
|
t0 = cmTsPrintfP(t0,"note_%i%s",e->voice, cmIsFlag(e->flags,kGraceXsFl) ? "_g":"");
|
||||||
|
|
||||||
|
if( cmIsFlag(e->flags,kGraceXsFl) )
|
||||||
|
classLabel = "grace";
|
||||||
|
|
||||||
|
if( cmSvgWriterRect(svgH, e->tick, e->d0 * noteHeight, e->durTicks, noteHeight-1, t0 ) != kOkSvgRC )
|
||||||
|
rc = kSvgFailXsRC;
|
||||||
|
else
|
||||||
|
if( cmSvgWriterText(svgH, e->tick + e->durTicks/2, e->d0 * noteHeight + noteHeight/2, cmMidiToSciPitch( e->d0, NULL, 0), "pitch") != kOkSvgRC )
|
||||||
|
rc = kSvgFailXsRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if this is a bar
|
||||||
|
if( cmIsFlag(e->flags,kBarXsFl) )
|
||||||
|
{
|
||||||
|
if( cmSvgWriterLine(svgH, e->tick, 0, e->tick, 127*noteHeight, "bar") != kOkSvgRC )
|
||||||
|
rc = kSvgFailXsRC;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( cmSvgWriterText(svgH, e->tick, 10, t0 = cmTsPrintfP(t0,"%i",e->d0), "text" ) != kOkSvgRC )
|
||||||
|
rc = kSvgFailXsRC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( rc != kOkXsRC )
|
||||||
|
cmErrMsg(&p->err,kSvgFailXsRC,"SVG element insert failed.");
|
||||||
|
|
||||||
|
if( rc == kOkXsRC )
|
||||||
|
if( cmSvgWriterWrite(svgH,cssFn,svgFn) != kOkSvgRC )
|
||||||
|
rc = cmErrMsg(&p->err,kSvgFailXsRC,"SVG file write to '%s' failed.",cmStringNullGuard(svgFn));
|
||||||
|
|
||||||
|
errLabel:
|
||||||
|
cmSvgWriterFree(&svgH);
|
||||||
|
cmFsFreeFn(svgFn);
|
||||||
|
cmFsFreeFn(cssFn);
|
||||||
|
cmMemFree(t0);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _cmXsPushMidiEvent( cmXScore_t* p, cmXsMidiFile_t* mf, unsigned flags, unsigned tick, unsigned durTick, unsigned voice, unsigned d0, unsigned d1 )
|
||||||
|
{
|
||||||
|
cmXsMidiEvt_t* e = cmLhAllocZ(p->lhH,cmXsMidiEvt_t,1);
|
||||||
|
e->flags = flags;
|
||||||
|
e->tick = tick;
|
||||||
|
e->durTicks = durTick;
|
||||||
|
e->voice = voice;
|
||||||
|
e->d0 = d0;
|
||||||
|
e->d1 = d1;
|
||||||
|
if( mf->eol != NULL )
|
||||||
|
mf->eol->link = e;
|
||||||
|
else
|
||||||
|
mf->elist = e;
|
||||||
|
|
||||||
|
// track the min/max pitch
|
||||||
|
if( cmIsFlag(flags,kOnsetXsFl) )
|
||||||
|
{
|
||||||
|
mf->pitch_min = mf->eol==NULL ? d0 : cmMin(mf->pitch_min,d0);
|
||||||
|
mf->pitch_max = mf->eol==NULL ? d0 : cmMin(mf->pitch_max,d0);
|
||||||
|
}
|
||||||
|
|
||||||
|
mf->eol = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmXsRC_t _cmXScoreWriteMidi( cmCtx_t* ctx, cmXsH_t h, const cmChar_t* dir, const cmChar_t* fn )
|
||||||
{
|
{
|
||||||
assert(0); // function not implemented
|
|
||||||
cmXScore_t* p = _cmXScoreHandleToPtr(h);
|
cmXScore_t* p = _cmXScoreHandleToPtr(h);
|
||||||
cmXsPart_t* pp = p->partL;
|
cmXsPart_t* pp = p->partL;
|
||||||
|
|
||||||
|
cmXsMidiFile_t mf;
|
||||||
|
memset(&mf,0,sizeof(mf));
|
||||||
|
|
||||||
for(; pp!=NULL; pp=pp->link)
|
for(; pp!=NULL; pp=pp->link)
|
||||||
{
|
{
|
||||||
const cmXsMeas_t* meas = pp->measL;
|
const cmXsMeas_t* meas = pp->measL;
|
||||||
@ -2527,39 +2647,62 @@ cmXsRC_t cmXScoreWriteMidi( cmXsH_t h, const cmChar_t* fn )
|
|||||||
const cmXsNote_t* note = meas->noteL;
|
const cmXsNote_t* note = meas->noteL;
|
||||||
for(; note!=NULL; note=note->slink)
|
for(; note!=NULL; note=note->slink)
|
||||||
{
|
{
|
||||||
|
// if this is a sounding note
|
||||||
|
if( cmIsFlag(note->flags,kOnsetXsFl) )
|
||||||
|
{
|
||||||
|
unsigned d0 = cmSciPitchToMidiPitch( note->step, note->alter, note->octave );
|
||||||
|
unsigned durTick = note->duration;
|
||||||
|
if( note->tied != NULL )
|
||||||
|
{
|
||||||
|
cmXsNote_t* tn = note->tied;
|
||||||
|
for(; tn!=NULL; tn=tn->tied)
|
||||||
|
durTick += tn->duration;
|
||||||
|
}
|
||||||
|
_cmXsPushMidiEvent(p,&mf,note->flags,note->tick,durTick,note->voice->id,d0,note->vel);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if this is a bar event
|
||||||
|
if( cmIsFlag(note->flags,kBarXsFl) )
|
||||||
|
{
|
||||||
|
_cmXsPushMidiEvent(p,&mf,note->flags,note->tick,0,0,note->meas->number,0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return _cmXsWriteMidiSvg( ctx, p, &mf, dir, fn );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmXsRC_t cmXScoreTest(
|
cmXsRC_t cmXScoreTest(
|
||||||
cmCtx_t* ctx,
|
cmCtx_t* ctx,
|
||||||
const cmChar_t* xmlFn,
|
const cmChar_t* xmlFn,
|
||||||
const cmChar_t* midiFn,
|
const cmChar_t* reorderFn,
|
||||||
const cmChar_t* outFn,
|
const cmChar_t* csvOutFn,
|
||||||
const cmChar_t* reorderFn )
|
const cmChar_t* midiOutFn)
|
||||||
{
|
{
|
||||||
cmXsRC_t rc;
|
cmXsRC_t rc;
|
||||||
cmXsH_t h = cmXsNullHandle;
|
cmXsH_t h = cmXsNullHandle;
|
||||||
|
|
||||||
if((rc = cmXScoreInitialize( ctx, &h, xmlFn, midiFn)) != kOkXsRC )
|
if((rc = cmXScoreInitialize( ctx, &h, xmlFn)) != kOkXsRC )
|
||||||
return cmErrMsg(&ctx->err,rc,"XScore alloc failed.");
|
return cmErrMsg(&ctx->err,rc,"XScore alloc failed.");
|
||||||
|
|
||||||
if( reorderFn != NULL )
|
if( reorderFn != NULL )
|
||||||
cmXScoreReorder(h,reorderFn);
|
cmXScoreReorder(h,reorderFn);
|
||||||
|
|
||||||
if( outFn != NULL )
|
if( csvOutFn != NULL )
|
||||||
{
|
{
|
||||||
cmScH_t scH = cmScNullHandle;
|
cmScH_t scH = cmScNullHandle;
|
||||||
double srate = 44100.0;
|
double srate = 44100.0;
|
||||||
|
|
||||||
cmXScoreWriteCsv(h,outFn);
|
cmXScoreWriteCsv(h,csvOutFn);
|
||||||
|
|
||||||
|
|
||||||
cmSymTblH_t stH = cmSymTblCreate(cmSymTblNullHandle, 0, ctx );
|
cmSymTblH_t stH = cmSymTblCreate(cmSymTblNullHandle, 0, ctx );
|
||||||
|
|
||||||
if( cmScoreInitialize( ctx, &scH, outFn, srate, NULL, 0, NULL, NULL, stH) != kOkScRC )
|
if( cmScoreInitialize( ctx, &scH, csvOutFn, srate, NULL, 0, NULL, NULL, stH) != kOkScRC )
|
||||||
cmErrMsg(&ctx->err,kFileFailXsRC,"The generated CSV file could not be parsed.");
|
cmErrMsg(&ctx->err,kFileFailXsRC,"The generated CSV file could not be parsed.");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2570,10 +2713,19 @@ cmXsRC_t cmXScoreTest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmSymTblDestroy(&stH);
|
cmSymTblDestroy(&stH);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( midiOutFn != NULL )
|
||||||
|
{
|
||||||
|
cmFileSysPathPart_t* pp = cmFsPathParts(midiOutFn);
|
||||||
|
|
||||||
|
_cmXScoreWriteMidi( ctx, h, pp->dirStr, pp->fnStr );
|
||||||
|
|
||||||
|
cmFsFreePathParts(pp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmXScoreReport(h,&ctx->rpt,true);
|
//cmXScoreReport(h,&ctx->rpt,true);
|
||||||
|
|
||||||
return cmXScoreFinalize(&h);
|
return cmXScoreFinalize(&h);
|
||||||
|
|
||||||
|
@ -16,7 +16,8 @@ extern "C" {
|
|||||||
kUnterminatedSlurXsRC,
|
kUnterminatedSlurXsRC,
|
||||||
kUnterminatedOctaveShiftXsrRC,
|
kUnterminatedOctaveShiftXsrRC,
|
||||||
kMidiFailXsRC,
|
kMidiFailXsRC,
|
||||||
kFileFailXsRC
|
kFileFailXsRC,
|
||||||
|
kSvgFailXsRC
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef cmRC_t cmXsRC_t;
|
typedef cmRC_t cmXsRC_t;
|
||||||
@ -56,18 +57,17 @@ extern "C" {
|
|||||||
// the grace note ordering changed specified in 'score_print_mk_edit.txt',
|
// the grace note ordering changed specified in 'score_print_mk_edit.txt',
|
||||||
// via cmXScoreReorder() however the ticks are now incorrect - fix them.
|
// via cmXScoreReorder() however the ticks are now incorrect - fix them.
|
||||||
|
|
||||||
cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn, const cmChar_t* midiFn );
|
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 );
|
||||||
|
|
||||||
cmXsRC_t cmXScoreWriteMidi( cmXsH_t h, const cmChar_t* fn );
|
|
||||||
|
|
||||||
void cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl );
|
void cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl );
|
||||||
|
|
||||||
cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* midiFn, const cmChar_t* outFn, const cmChar_t* reorderFn );
|
// 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 );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user