|
@@ -33,6 +33,8 @@
|
33
|
33
|
|
34
|
34
|
#include "cmSvgWriter.h"
|
35
|
35
|
|
|
36
|
+
|
|
37
|
+
|
36
|
38
|
cmXsH_t cmXsNullHandle = cmSTATIC_NULL_HANDLE;
|
37
|
39
|
|
38
|
40
|
enum
|
|
@@ -1880,7 +1882,7 @@ cmXsRC_t _cmXScoreProcessGraceNotes( cmXScore_t* p, unsigned nextGraceGroupId )
|
1880
|
1882
|
}
|
1881
|
1883
|
|
1882
|
1884
|
|
1883
|
|
-cmXsNote_t* _cmXScoreDynamicForkEndNote( cmXsNote_t* bnp )
|
|
1885
|
+cmXsNote_t* _cmXScoreDynamicForkEndNote( cmXScore_t* p, cmXsNote_t* bnp )
|
1884
|
1886
|
{
|
1885
|
1887
|
assert( cmIsFlag(bnp->flags,kDynBegForkXsFl) );
|
1886
|
1888
|
|
|
@@ -1891,7 +1893,13 @@ cmXsNote_t* _cmXScoreDynamicForkEndNote( cmXsNote_t* bnp )
|
1891
|
1893
|
{
|
1892
|
1894
|
for(; np!=NULL; np=np->slink)
|
1893
|
1895
|
{
|
1894
|
|
- if( cmIsFlag(np->flags,kDynEndForkXsFl) && np->voice->id == bnp->voice->id )
|
|
1896
|
+ if( cmIsFlag(np->flags,kDynBegForkXsFl) )
|
|
1897
|
+ {
|
|
1898
|
+ cmErrMsg(&p->err,kSyntaxErrorXsRC,"The a dynamic fork begin (meas:%i loc:%i) was found prior to a matched end.",np->meas->number,np->locIdx);
|
|
1899
|
+ return NULL;
|
|
1900
|
+ }
|
|
1901
|
+
|
|
1902
|
+ if( cmIsFlag(np->flags,kDynEndForkXsFl) /*&& np->voice->id == bnp->voice->id*/ )
|
1895
|
1903
|
return np;
|
1896
|
1904
|
}
|
1897
|
1905
|
}
|
|
@@ -1903,10 +1911,11 @@ cmXsRC_t _cmXScoreProcessDynamicFork( cmXScore_t* p, cmXsNote_t* bnp )
|
1903
|
1911
|
{
|
1904
|
1912
|
cmXsNote_t* enp;
|
1905
|
1913
|
|
1906
|
|
- if((enp = _cmXScoreDynamicForkEndNote(bnp)) == NULL)
|
1907
|
|
- return cmErrMsg(&p->err,kSyntaxErrorXsRC,"The dynamic fork beginning in measure %i at tick %i voice %i was not terminated.", bnp->meas->number,bnp->tick,bnp->voice->id);
|
1908
|
|
-
|
|
1914
|
+ if((enp = _cmXScoreDynamicForkEndNote(p,bnp)) == NULL)
|
|
1915
|
+ return cmErrMsg(&p->err,kSyntaxErrorXsRC,"The dynamic fork beginning in measure %i at tick %i voice %i loc:%i was not terminated.", bnp->meas->number,bnp->tick,bnp->voice->id,bnp->locIdx);
|
1909
|
1916
|
|
|
1917
|
+ //cmRptPrintf( p->err.rpt, "Dynamic Fork: meas:%i tick:%i loc:%i to meas:%i tick:%i loc:%i\n", bnp->meas->number, bnp->tick, bnp->locIdx, enp->meas->number, enp->tick, enp->locIdx );
|
|
1918
|
+
|
1910
|
1919
|
double begDynFrac = bnp->dynamics;
|
1911
|
1920
|
double begVelFrac = bnp->vel;
|
1912
|
1921
|
double endDynFrac = enp->dynamics;
|
|
@@ -1915,25 +1924,29 @@ cmXsRC_t _cmXScoreProcessDynamicFork( cmXScore_t* p, cmXsNote_t* bnp )
|
1915
|
1924
|
cmXsMeas_t* mp = bnp->meas;
|
1916
|
1925
|
cmXsNote_t* np = bnp->slink;
|
1917
|
1926
|
|
1918
|
|
- for(; mp!=NULL && np!=enp; mp=mp->link,np=mp==NULL ? NULL : mp->noteL)
|
|
1927
|
+ while( mp != NULL )
|
1919
|
1928
|
{
|
1920
|
|
- for(; np!=NULL && np!=enp; np=np->slink)
|
1921
|
|
-
|
1922
|
|
- /*
|
1923
|
|
-
|
1924
|
|
- Conditioning this on np->dynamics==0 will may cause 'silent' notes to be assigned
|
1925
|
|
- a non-zero dynamics value - this is best fixed by using a different special value
|
1926
|
|
- for silent notes
|
1927
|
|
-
|
1928
|
|
- BUG BUG BUG BUG BUG
|
|
1929
|
+ for(; np!=NULL; np=np->slink)
|
|
1930
|
+ {
|
1929
|
1931
|
|
1930
|
|
- */
|
1931
|
|
- if( np->voice == bnp->voice && np->dynamics == 0 )
|
|
1932
|
+ //Conditioning this on np->dynamics==0 will may would cause 'silent' notes to be assigned
|
|
1933
|
+ // a non-zero dynamics value - so we condition on np->vel instead.
|
|
1934
|
+ if( cmIsFlag(np->flags,kOnsetXsFl) && np->vel == 0 )
|
1932
|
1935
|
{
|
1933
|
1936
|
double frac = ((double)np->tick - bnp->tick) / (enp->tick - bnp->tick);
|
1934
|
1937
|
np->dynamics = lround(begDynFrac + ((endDynFrac - begDynFrac) * frac));
|
1935
|
1938
|
np->vel = lround(begVelFrac + ((endVelFrac - begVelFrac) * frac));
|
1936
|
1939
|
}
|
|
1940
|
+
|
|
1941
|
+ if( np == enp )
|
|
1942
|
+ break;
|
|
1943
|
+ }
|
|
1944
|
+
|
|
1945
|
+ if( np == enp)
|
|
1946
|
+ break;
|
|
1947
|
+
|
|
1948
|
+ if( (mp=mp->link) != NULL )
|
|
1949
|
+ np=mp->noteL;
|
1937
|
1950
|
}
|
1938
|
1951
|
|
1939
|
1952
|
return kOkXsRC;
|
|
@@ -3203,6 +3216,10 @@ void _cmXScoreReportNote( cmRpt_t* rpt, const cmXsNote_t* note,unsigned index )
|
3203
|
3216
|
|
3204
|
3217
|
if( note->graceGroupId != 0)
|
3205
|
3218
|
cmRptPrintf(rpt," g=%i",note->graceGroupId);
|
|
3219
|
+
|
|
3220
|
+ if( note->dynamics != 0)
|
|
3221
|
+ cmRptPrintf(rpt," dyn=%i %i",note->dynamics,note->vel);
|
|
3222
|
+
|
3206
|
3223
|
/*
|
3207
|
3224
|
if( cmIsFlag(note->flags,kBegGraceXsFl) )
|
3208
|
3225
|
cmRptPrintf(rpt," B");
|
|
@@ -3210,8 +3227,6 @@ void _cmXScoreReportNote( cmRpt_t* rpt, const cmXsNote_t* note,unsigned index )
|
3210
|
3227
|
if( cmIsFlag(note->flags,kEndGraceXsFl) )
|
3211
|
3228
|
cmRptPrintf(rpt," E");
|
3212
|
3229
|
|
3213
|
|
- if( note->dynamics != 0)
|
3214
|
|
- cmRptPrintf(rpt," dyn=%i",note->dynamics);
|
3215
|
3230
|
|
3216
|
3231
|
if( cmIsFlag(note->flags,kDynBegForkXsFl) )
|
3217
|
3232
|
cmRptPrintf(rpt," B");
|
|
@@ -3563,8 +3578,9 @@ cmXsRC_t _cmXsWriteMidiFile( cmCtx_t* ctx, cmXsH_t h, const cmChar_t* dir, const
|
3563
|
3578
|
if( mp->divisions != ticksPerQN )
|
3564
|
3579
|
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);
|
3565
|
3580
|
|
|
3581
|
+ unsigned ni = 0;
|
3566
|
3582
|
// for each note in this measure
|
3567
|
|
- for(; np!=NULL; np=np->slink)
|
|
3583
|
+ for(; np!=NULL; np=np->slink,++ni)
|
3568
|
3584
|
{
|
3569
|
3585
|
switch( np->flags & (kOnsetXsFl|kMetronomeXsFl|kDampDnXsFl|kDampUpDnXsFl|kSostDnXsFl) )
|
3570
|
3586
|
{
|
|
@@ -3572,6 +3588,14 @@ cmXsRC_t _cmXsWriteMidiFile( cmCtx_t* ctx, cmXsH_t h, const cmChar_t* dir, const
|
3572
|
3588
|
{
|
3573
|
3589
|
if( np->tied_dur <= 0 )
|
3574
|
3590
|
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));
|
|
3591
|
+
|
|
3592
|
+ /*
|
|
3593
|
+ if( mp->number == 20 )
|
|
3594
|
+ {
|
|
3595
|
+ _cmXScoreReportNote(ctx->err.rpt,np,ni);
|
|
3596
|
+ cmRptPrintf(ctx->err.rpt,"\n");
|
|
3597
|
+ }
|
|
3598
|
+ */
|
3575
|
3599
|
|
3576
|
3600
|
if( cmMidiFileInsertTrackChMsg(mfH, 1, np->tick, kNoteOnMdId, np->pitch, np->vel ) != kOkMfRC
|
3577
|
3601
|
||cmMidiFileInsertTrackChMsg(mfH, 1, np->tick + np->tied_dur, kNoteOffMdId, np->pitch, 0 ) != kOkMfRC )
|
|
@@ -3732,12 +3756,12 @@ cmXsRC_t _cmXsWriteMidiSvg( cmCtx_t* ctx, cmXScore_t* p, cmXsMidiFile_t* mf, con
|
3732
|
3756
|
// if this is a note
|
3733
|
3757
|
case kOnsetXsFl:
|
3734
|
3758
|
{
|
3735
|
|
- const cmChar_t* classLabel = "note";
|
|
3759
|
+ //const cmChar_t* classLabel = "note";
|
3736
|
3760
|
|
3737
|
3761
|
t0 = cmTsPrintfP(t0,"note_%i%s",e->voice, cmIsFlag(e->flags,kGraceXsFl) ? "_g":"");
|
3738
|
3762
|
|
3739
|
|
- if( cmIsFlag(e->flags,kGraceXsFl) )
|
3740
|
|
- classLabel = "grace";
|
|
3763
|
+ //if( cmIsFlag(e->flags,kGraceXsFl) )
|
|
3764
|
+ // classLabel = "grace";
|
3741
|
3765
|
|
3742
|
3766
|
if( cmSvgWriterRect(svgH, e->tick, e->d0 * noteHeight, e->durTicks, noteHeight-1, t0 ) != kOkSvgRC )
|
3743
|
3767
|
rc = kSvgFailXsRC;
|