cmMidiFile.h/c : Added cmMidiFileGenSvgFile()
This commit is contained in:
parent
88fdfd998d
commit
a37e2e2c71
96
cmMidiFile.c
96
cmMidiFile.c
@ -8,8 +8,11 @@
|
||||
#include "cmMallocDebug.h"
|
||||
#include "cmLinkedHeap.h"
|
||||
#include "cmTime.h"
|
||||
#include "cmText.h"
|
||||
#include "cmMidi.h"
|
||||
#include "cmMidiFile.h"
|
||||
#include "cmSvgWriter.h"
|
||||
|
||||
|
||||
#ifdef cmBIG_ENDIAN
|
||||
#define mfSwap16(v) (v)
|
||||
@ -1975,6 +1978,99 @@ cmMfRC_t cmMidiFileGenPlotFile( cmCtx_t* ctx, const cmChar_t* midiFn, const cmCh
|
||||
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 )
|
||||
{
|
||||
cmMidiFileH_t h = cmMidiFileNullHandle;
|
||||
|
10
cmMidiFile.h
10
cmMidiFile.h
@ -117,7 +117,8 @@ extern "C" {
|
||||
kLargeDeltaTickMfRC, // 12 (a large delta tick value was filtered)
|
||||
kUidNotFoundMfRC, // 13
|
||||
kUidNotANoteMsgMfRC, // 14
|
||||
kInvalidTrkIndexMfRC // 15
|
||||
kInvalidTrkIndexMfRC,// 15
|
||||
kSvgFailMfRC // 16
|
||||
};
|
||||
|
||||
extern cmMidiFileH_t cmMidiFileNullHandle;
|
||||
@ -220,11 +221,16 @@ extern "C" {
|
||||
unsigned density;
|
||||
|
||||
} cmMidiFileDensity_t;
|
||||
cmMidiFileDensity_t* cmMidiFileNoteTimeDensity( cmMidiFileH_t h, unsigned* cntRef );
|
||||
|
||||
// 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
|
||||
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 );
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user