|
@@ -8,8 +8,11 @@
|
8
|
8
|
#include "cmMallocDebug.h"
|
9
|
9
|
#include "cmLinkedHeap.h"
|
10
|
10
|
#include "cmTime.h"
|
|
11
|
+#include "cmText.h"
|
11
|
12
|
#include "cmMidi.h"
|
12
|
13
|
#include "cmMidiFile.h"
|
|
14
|
+#include "cmSvgWriter.h"
|
|
15
|
+
|
13
|
16
|
|
14
|
17
|
#ifdef cmBIG_ENDIAN
|
15
|
18
|
#define mfSwap16(v) (v)
|
|
@@ -1975,6 +1978,99 @@ cmMfRC_t cmMidiFileGenPlotFile( cmCtx_t* ctx, const cmChar_t* midiFn, const cmCh
|
1975
|
1978
|
return rc;
|
1976
|
1979
|
}
|
1977
|
1980
|
|
|
1981
|
+cmMfRC_t cmMidiFileGenSvgFile( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* outSvgFn, const cmChar_t* cssFn )
|
|
1982
|
+{
|
|
1983
|
+ cmMfRC_t rc = kOkMfRC;
|
|
1984
|
+ cmSvgH_t svgH = cmSvgNullHandle;
|
|
1985
|
+ cmMidiFileH_t mfH = cmMidiFileNullHandle;
|
|
1986
|
+ unsigned msgN = 0;
|
|
1987
|
+ const cmMidiTrackMsg_t** msgs = NULL;
|
|
1988
|
+ unsigned noteHeight = 10;
|
|
1989
|
+ double micros_per_sec = 1000.0;
|
|
1990
|
+ unsigned i;
|
|
1991
|
+
|
|
1992
|
+ if((rc = cmMidiFileOpen(ctx,&mfH,midiFn)) != kOkMfRC )
|
|
1993
|
+ {
|
|
1994
|
+ rc = cmErrMsg(&ctx->err,rc,"Unable to open the MIDI file '%s'.",cmStringNullGuard(midiFn));
|
|
1995
|
+ goto errLabel;
|
|
1996
|
+ }
|
|
1997
|
+
|
|
1998
|
+ cmMidiFileCalcNoteDurations( mfH );
|
|
1999
|
+
|
|
2000
|
+ msgN = cmMidiFileMsgCount(mfH);
|
|
2001
|
+ msgs = cmMidiFileMsgArray(mfH);
|
|
2002
|
+
|
|
2003
|
+
|
|
2004
|
+ if( cmSvgWriterAlloc(ctx,&svgH) != kOkSvgRC )
|
|
2005
|
+ {
|
|
2006
|
+ rc = cmErrMsg(&ctx->err,kSvgFailMfRC,"Unable to create the MIDI SVG output file '%s'.",cmStringNullGuard(outSvgFn));
|
|
2007
|
+ goto errLabel;
|
|
2008
|
+ }
|
|
2009
|
+
|
|
2010
|
+
|
|
2011
|
+ for(i=0; i<msgN && rc==kOkMfRC; ++i)
|
|
2012
|
+ if( msgs[i]->status == kNoteOnMdId && msgs[i]->u.chMsgPtr->d1 > 0 )
|
|
2013
|
+ {
|
|
2014
|
+ const cmMidiTrackMsg_t* m = msgs[i];
|
|
2015
|
+
|
|
2016
|
+
|
|
2017
|
+ if( cmSvgWriterRect(svgH, m->amicro/micros_per_sec, m->u.chMsgPtr->d0 * noteHeight, m->u.chMsgPtr->durMicros/micros_per_sec, noteHeight-1, "note" ) != kOkSvgRC )
|
|
2018
|
+ rc = kSvgFailMfRC;
|
|
2019
|
+
|
|
2020
|
+ const cmChar_t* t0 = cmMidiToSciPitch(m->u.chMsgPtr->d0,NULL,0);
|
|
2021
|
+
|
|
2022
|
+ if( cmSvgWriterText(svgH, (m->amicro + (m->u.chMsgPtr->durMicros/2)) / micros_per_sec, m->u.chMsgPtr->d0 * noteHeight, t0, "text" ) != kOkSvgRC )
|
|
2023
|
+ rc = kSvgFailMfRC;
|
|
2024
|
+
|
|
2025
|
+ }
|
|
2026
|
+
|
|
2027
|
+ if( rc != kOkMfRC )
|
|
2028
|
+ {
|
|
2029
|
+ cmErrMsg(&ctx->err,rc,"SVG Shape insertion failed.");
|
|
2030
|
+ goto errLabel;
|
|
2031
|
+ }
|
|
2032
|
+
|
|
2033
|
+ unsigned dN = 0;
|
|
2034
|
+ cmMidiFileDensity_t* dV = cmMidiFileNoteDensity( mfH, &dN );
|
|
2035
|
+ double t0 = 0;
|
|
2036
|
+ double y0 = 64.0;
|
|
2037
|
+ cmChar_t* tx = NULL;
|
|
2038
|
+
|
|
2039
|
+ for(i=0; i<dN; ++i)
|
|
2040
|
+ {
|
|
2041
|
+ const cmMidiTrackMsg_t* m;
|
|
2042
|
+
|
|
2043
|
+ if((m = _cmMidiFileUidToMsg( _cmMidiFileHandleToPtr(mfH), dV[i].uid )) == NULL )
|
|
2044
|
+ rc = cmErrMsg(&ctx->err,kUidNotFoundMfRC,"The MIDI msg form UID:%i was not found.",dV[i].uid);
|
|
2045
|
+ else
|
|
2046
|
+ {
|
|
2047
|
+ double t1 = m->amicro / micros_per_sec;
|
|
2048
|
+ double y1 = dV[i].density * noteHeight;
|
|
2049
|
+
|
|
2050
|
+ cmSvgWriterLine(svgH, t0, y0, t1, y1, "density" );
|
|
2051
|
+ cmSvgWriterText(svgH, t1, y1, tx = cmTsPrintfP(tx,"%i",dV[i].density),"dtext");
|
|
2052
|
+
|
|
2053
|
+ t0 = t1;
|
|
2054
|
+ y0 = y1;
|
|
2055
|
+
|
|
2056
|
+ }
|
|
2057
|
+ }
|
|
2058
|
+
|
|
2059
|
+ cmMemFree(dV);
|
|
2060
|
+ cmMemFree(tx);
|
|
2061
|
+
|
|
2062
|
+ if( rc == kOkMfRC )
|
|
2063
|
+ if( cmSvgWriterWrite(svgH,cssFn,outSvgFn) != kOkSvgRC )
|
|
2064
|
+ rc = cmErrMsg(&ctx->err,kSvgFailMfRC,"SVG file write to '%s' failed.",cmStringNullGuard(outSvgFn));
|
|
2065
|
+
|
|
2066
|
+
|
|
2067
|
+ errLabel:
|
|
2068
|
+ cmMidiFileClose(&mfH);
|
|
2069
|
+ cmSvgWriterFree(&svgH);
|
|
2070
|
+
|
|
2071
|
+ return rc;
|
|
2072
|
+}
|
|
2073
|
+
|
1978
|
2074
|
void cmMidiFilePrintControlNumbers( cmCtx_t* ctx, const char* fn )
|
1979
|
2075
|
{
|
1980
|
2076
|
cmMidiFileH_t h = cmMidiFileNullHandle;
|