|
@@ -65,7 +65,9 @@ enum
|
65
|
65
|
kSubGraceXsFl = 0x02000000, // (s) " " " " " " - subtract time
|
66
|
66
|
kAFirstGraceXsFl = 0x04000000, // (A) add time after first note
|
67
|
67
|
kNFirstGraceXsFl = 0x08000000, // (n) grace notes start as soon as possible after first note and add time
|
68
|
|
- kDeleteXsFl = 0x10000000
|
|
68
|
+ kDeleteXsFl = 0x10000000,
|
|
69
|
+ kDynBegForkXsFl = 0x20000000,
|
|
70
|
+ kDynEndForkXsFl = 0x40000000
|
69
|
71
|
|
70
|
72
|
};
|
71
|
73
|
|
|
@@ -175,6 +177,8 @@ typedef struct
|
175
|
177
|
cmXsComplexity_t cplx_max;
|
176
|
178
|
} cmXScore_t;
|
177
|
179
|
|
|
180
|
+void _cmXScoreReport( cmXScore_t* p, cmRpt_t* rpt, bool sortFl );
|
|
181
|
+
|
178
|
182
|
cmXScore_t* _cmXScoreHandleToPtr( cmXsH_t h )
|
179
|
183
|
{
|
180
|
184
|
cmXScore_t* p = (cmXScore_t*)h.h;
|
|
@@ -1165,7 +1169,7 @@ bool _cmXScoreFindTiedNote( cmXScore_t* p, cmXsMeas_t* mp, cmXsNote_t* n0p, boo
|
1165
|
1169
|
}
|
1166
|
1170
|
}
|
1167
|
1171
|
|
1168
|
|
- cmErrWarnMsg(&p->err,kUnterminatedTieXsRC,"The tied %c%c%i in measure %i was not terminated.",n0p->step,acc,n0p->octave,measNumb);
|
|
1172
|
+ cmErrWarnMsg(&p->err,kUnterminatedTieXsRC,"The tied %c%c%i in measure %i (tick:%i) was not terminated.",n0p->step,acc,n0p->octave,measNumb,n0p->tick);
|
1169
|
1173
|
return false;
|
1170
|
1174
|
}
|
1171
|
1175
|
|
|
@@ -1789,7 +1793,7 @@ cmXsRC_t _cmXScoreProcessGraceNotes( cmXScore_t* p )
|
1789
|
1793
|
// verify that the first note is marked with kBegGraceXsFl
|
1790
|
1794
|
if( cmIsNotFlag(gn0p->flags,kBegGraceXsFl) )
|
1791
|
1795
|
{
|
1792
|
|
- rc = cmErrMsg(&p->err,kSyntaxErrorXsRC,"The first note in a grace note group in meas %i is not marked with a 'b'.", gn0p->meas->number );
|
|
1796
|
+ rc = cmErrMsg(&p->err,kSyntaxErrorXsRC,"The first note in a grace note group in meas %i tick %i groupid:%i is not marked with a 'b'.", gn0p->meas->number, gn0p->tick, graceGroupId );
|
1793
|
1797
|
break;
|
1794
|
1798
|
}
|
1795
|
1799
|
|
|
@@ -1876,6 +1880,88 @@ cmXsRC_t _cmXScoreProcessGraceNotes( cmXScore_t* p )
|
1876
|
1880
|
}
|
1877
|
1881
|
|
1878
|
1882
|
|
|
1883
|
+cmXsNote_t* _cmXScoreDynamicForkEndNote( cmXsNote_t* bnp )
|
|
1884
|
+{
|
|
1885
|
+ assert( cmIsFlag(bnp->flags,kDynBegForkXsFl) );
|
|
1886
|
+
|
|
1887
|
+ cmXsMeas_t* mp = bnp->meas;
|
|
1888
|
+ cmXsNote_t* np = bnp->slink;
|
|
1889
|
+
|
|
1890
|
+ for(; mp!=NULL; mp=mp->link,np = mp==NULL?NULL : mp->noteL)
|
|
1891
|
+ {
|
|
1892
|
+ for(; np!=NULL; np=np->slink)
|
|
1893
|
+ {
|
|
1894
|
+ if( cmIsFlag(np->flags,kDynEndForkXsFl) && np->voice->id == bnp->voice->id )
|
|
1895
|
+ return np;
|
|
1896
|
+ }
|
|
1897
|
+ }
|
|
1898
|
+
|
|
1899
|
+ return NULL;
|
|
1900
|
+}
|
|
1901
|
+
|
|
1902
|
+cmXsRC_t _cmXScoreProcessDynamicFork( cmXScore_t* p, cmXsNote_t* bnp )
|
|
1903
|
+{
|
|
1904
|
+ cmXsNote_t* enp;
|
|
1905
|
+
|
|
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
|
+
|
|
1909
|
+
|
|
1910
|
+ double begDynFrac = bnp->dynamics;
|
|
1911
|
+ double begVelFrac = bnp->vel;
|
|
1912
|
+ double endDynFrac = enp->dynamics;
|
|
1913
|
+ double endVelFrac = enp->vel;
|
|
1914
|
+
|
|
1915
|
+ cmXsMeas_t* mp = bnp->meas;
|
|
1916
|
+ cmXsNote_t* np = bnp->slink;
|
|
1917
|
+
|
|
1918
|
+ for(; mp!=NULL && np!=enp; mp=mp->link,np=mp==NULL ? NULL : mp->noteL)
|
|
1919
|
+ {
|
|
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
|
+
|
|
1930
|
+ */
|
|
1931
|
+ if( np->voice == bnp->voice && np->dynamics == 0 )
|
|
1932
|
+ {
|
|
1933
|
+ double frac = ((double)np->tick - bnp->tick) / (enp->tick - bnp->tick);
|
|
1934
|
+ np->dynamics = lround(begDynFrac + ((endDynFrac - begDynFrac) * frac));
|
|
1935
|
+ np->vel = lround(begVelFrac + ((endVelFrac - begVelFrac) * frac));
|
|
1936
|
+ }
|
|
1937
|
+ }
|
|
1938
|
+
|
|
1939
|
+ return kOkXsRC;
|
|
1940
|
+}
|
|
1941
|
+
|
|
1942
|
+
|
|
1943
|
+cmXsRC_t _cmXScoreProcessDynamicForks( cmXScore_t* p )
|
|
1944
|
+{
|
|
1945
|
+ cmXsRC_t rc = kOkXsRC;
|
|
1946
|
+ cmXsPart_t* pp = p->partL;
|
|
1947
|
+
|
|
1948
|
+ for(; pp!=NULL; pp=pp->link)
|
|
1949
|
+ {
|
|
1950
|
+ cmXsMeas_t* mp = pp->measL;
|
|
1951
|
+ for(; mp!=NULL; mp=mp->link)
|
|
1952
|
+ {
|
|
1953
|
+ cmXsNote_t* np = mp->noteL;
|
|
1954
|
+ for(; np!=NULL; np=np->slink )
|
|
1955
|
+ {
|
|
1956
|
+ if( cmIsFlag(np->flags,kDynBegForkXsFl) )
|
|
1957
|
+ if((rc = _cmXScoreProcessDynamicFork(p,np)) != kOkXsRC )
|
|
1958
|
+ return rc;
|
|
1959
|
+ }
|
|
1960
|
+ }
|
|
1961
|
+ }
|
|
1962
|
+
|
|
1963
|
+ return rc;
|
|
1964
|
+}
|
1879
|
1965
|
//-------------------------------------------------------------------------------------------
|
1880
|
1966
|
|
1881
|
1967
|
|
|
@@ -1956,7 +2042,7 @@ cmXsNote_t* _cmXsReorderFindNote( cmXScore_t* p, unsigned measNumb, const cmXsR
|
1956
|
2042
|
{
|
1957
|
2043
|
|
1958
|
2044
|
|
1959
|
|
- if( 0 /*mp->number==17*/)
|
|
2045
|
+ if( 0 /*mp->number==43*/ )
|
1960
|
2046
|
printf("voice: %i %i loc:%i %i tick:%i %i pitch:%i %i idx:%i %i\n",
|
1961
|
2047
|
np->voice->id, r->voice,
|
1962
|
2048
|
np->locIdx , r->locIdx ,
|
|
@@ -1969,10 +2055,11 @@ cmXsNote_t* _cmXsReorderFindNote( cmXScore_t* p, unsigned measNumb, const cmXsR
|
1969
|
2055
|
np->locIdx == r->locIdx &&
|
1970
|
2056
|
np->tick == r->tick &&
|
1971
|
2057
|
//np->duration == r->durtn &&
|
1972
|
|
- //np->rvalue == r->rval &&
|
|
2058
|
+ np->rvalue == r->rval &&
|
1973
|
2059
|
np->pitch == r->midi &&
|
1974
|
2060
|
index == r->idx )
|
1975
|
2061
|
{
|
|
2062
|
+ //printf("Found: %i \n", r->midi);
|
1976
|
2063
|
return np;
|
1977
|
2064
|
}
|
1978
|
2065
|
}
|
|
@@ -2061,6 +2148,14 @@ cmXsRC_t _cmXScoreReorderMeas( cmXScore_t* p, unsigned measNumb, cmXsReorder_t*
|
2061
|
2148
|
rV[i].note->vel = _cmXScoreDynMarkArray[ rV[i].dynIdx ].vel;
|
2062
|
2149
|
}
|
2063
|
2150
|
|
|
2151
|
+ // Set the dynamic fork begin/end flags for later _cmXScoreProcessDynamicForks()
|
|
2152
|
+ if( cmIsFlag(rV[i].newFlags,kDynBegForkXsFl) )
|
|
2153
|
+ rV[i].note->flags = cmSetFlag(rV[i].note->flags,kDynBegForkXsFl);
|
|
2154
|
+
|
|
2155
|
+ if( cmIsFlag(rV[i].newFlags,kDynEndForkXsFl) )
|
|
2156
|
+ rV[i].note->flags = cmSetFlag(rV[i].note->flags,kDynEndForkXsFl);
|
|
2157
|
+
|
|
2158
|
+
|
2064
|
2159
|
// if the tie end flag was set
|
2065
|
2160
|
if( cmIsFlag(rV[i].newFlags,kTieEndXsFl) )
|
2066
|
2161
|
{
|
|
@@ -2106,10 +2201,13 @@ cmXsRC_t _cmXScoreReorderMeas( cmXScore_t* p, unsigned measNumb, cmXsReorder_t*
|
2106
|
2201
|
|
2107
|
2202
|
}
|
2108
|
2203
|
|
2109
|
|
-cmXsRC_t _cmXScoreReorderParseDyn(cmXScore_t* p, const cmChar_t* b, unsigned lineNumb, unsigned* dynIdxRef )
|
|
2204
|
+cmXsRC_t _cmXScoreReorderParseDyn(cmXScore_t* p, const cmChar_t* b, unsigned lineNumb, unsigned* dynIdxRef, unsigned* flagsRef )
|
2110
|
2205
|
{
|
2111
|
|
- cmXsRC_t rc = kOkXsRC;
|
2112
|
|
- const cmChar_t* s;
|
|
2206
|
+ cmXsRC_t rc = kOkXsRC;
|
|
2207
|
+ const cmChar_t* s = NULL;
|
|
2208
|
+ bool begForkFl = false;
|
|
2209
|
+ bool endForkFl = false;
|
|
2210
|
+
|
2113
|
2211
|
|
2114
|
2212
|
*dynIdxRef = cmInvalidIdx;
|
2115
|
2213
|
|
|
@@ -2126,9 +2224,28 @@ cmXsRC_t _cmXScoreReorderParseDyn(cmXScore_t* p, const cmChar_t* b, unsigned lin
|
2126
|
2224
|
if( *s == '(' )
|
2127
|
2225
|
++s; // skip the paren.
|
2128
|
2226
|
|
|
2227
|
+ if( *s == '!')
|
|
2228
|
+ {
|
|
2229
|
+ endForkFl = true;
|
|
2230
|
+ ++s;
|
|
2231
|
+ }
|
|
2232
|
+
|
2129
|
2233
|
if( *s == 0 )
|
2130
|
2234
|
return cmErrMsg(&p->err,kSyntaxErrorXsRC,"Unexpected end-of-line on dynamics parsing on line:%i.",lineNumb);
|
2131
|
2235
|
|
|
2236
|
+
|
|
2237
|
+ // check for beg/end fork dynamic
|
|
2238
|
+ if( isupper(*s) )
|
|
2239
|
+ {
|
|
2240
|
+ if( !endForkFl)
|
|
2241
|
+ begForkFl=true;
|
|
2242
|
+ }
|
|
2243
|
+ else
|
|
2244
|
+ {
|
|
2245
|
+ if( endForkFl )
|
|
2246
|
+ return cmErrMsg(&p->err,kSyntaxErrorXsRC,"A double exclaimation point (end-of-dynamic fork) must always be followed by an upper case M,P, or F. See line:%i",lineNumb);
|
|
2247
|
+ }
|
|
2248
|
+
|
2132
|
2249
|
unsigned i = 0;
|
2133
|
2250
|
unsigned j = 0;
|
2134
|
2251
|
unsigned n = 6;
|
|
@@ -2138,7 +2255,9 @@ cmXsRC_t _cmXScoreReorderParseDyn(cmXScore_t* p, const cmChar_t* b, unsigned lin
|
2138
|
2255
|
|
2139
|
2256
|
for(i=0; j<n && doneFl==false; ++i)
|
2140
|
2257
|
{
|
2141
|
|
- switch(s[i])
|
|
2258
|
+ char c = tolower(s[i]);
|
|
2259
|
+
|
|
2260
|
+ switch(c)
|
2142
|
2261
|
{
|
2143
|
2262
|
case 's':
|
2144
|
2263
|
case 'm':
|
|
@@ -2146,7 +2265,7 @@ cmXsRC_t _cmXScoreReorderParseDyn(cmXScore_t* p, const cmChar_t* b, unsigned lin
|
2146
|
2265
|
case 'f':
|
2147
|
2266
|
case '+':
|
2148
|
2267
|
case '-':
|
2149
|
|
- mark[j++] = s[i];
|
|
2268
|
+ mark[j++] = c;
|
2150
|
2269
|
break;
|
2151
|
2270
|
|
2152
|
2271
|
case ')': // ending paren.
|
|
@@ -2173,6 +2292,12 @@ cmXsRC_t _cmXScoreReorderParseDyn(cmXScore_t* p, const cmChar_t* b, unsigned lin
|
2173
|
2292
|
|
2174
|
2293
|
|
2175
|
2294
|
*dynIdxRef = j;
|
|
2295
|
+
|
|
2296
|
+ if( begForkFl )
|
|
2297
|
+ *flagsRef = cmSetFlag(*flagsRef,kDynBegForkXsFl);
|
|
2298
|
+
|
|
2299
|
+ if( endForkFl )
|
|
2300
|
+ *flagsRef = cmSetFlag(*flagsRef,kDynEndForkXsFl);
|
2176
|
2301
|
|
2177
|
2302
|
return rc;
|
2178
|
2303
|
}
|
|
@@ -2414,14 +2539,14 @@ cmXsRC_t _cmXsApplyEditFile( cmXScore_t* p, const cmChar_t* fn )
|
2414
|
2539
|
}
|
2415
|
2540
|
|
2416
|
2541
|
|
2417
|
|
- // parse the dynamic marking following a '!'
|
2418
|
|
- if((rc = _cmXScoreReorderParseDyn(p,b,ln+1,&r.dynIdx)) != kOkXsRC )
|
2419
|
|
- goto errLabel;
|
2420
|
|
-
|
2421
|
2542
|
// parse the flag edits following a '~'
|
2422
|
2543
|
if((rc = _cmXScoreReorderParseFlags(p,b,ln+1, &r.newFlags)) != kOkXsRC )
|
2423
|
2544
|
goto errLabel;
|
2424
|
2545
|
|
|
2546
|
+ // parse the dynamic marking following a '!'
|
|
2547
|
+ if((rc = _cmXScoreReorderParseDyn(p,b,ln+1,&r.dynIdx, &r.newFlags)) != kOkXsRC )
|
|
2548
|
+ goto errLabel;
|
|
2549
|
+
|
2425
|
2550
|
// parse the @newtick marker
|
2426
|
2551
|
if((rc = _cmXScoreReorderParseTick(p, b, ln+1, &r.newTick)) != kOkXsRC )
|
2427
|
2552
|
goto errLabel;
|
|
@@ -2505,6 +2630,15 @@ cmXsRC_t _cmXsApplyEditFile( cmXScore_t* p, const cmChar_t* fn )
|
2505
|
2630
|
// inserting grace notes may have left the score unsorted
|
2506
|
2631
|
_cmXScoreSort(p);
|
2507
|
2632
|
|
|
2633
|
+ // process the dynamic forks
|
|
2634
|
+ _cmXScoreProcessDynamicForks(p);
|
|
2635
|
+
|
|
2636
|
+
|
|
2637
|
+
|
|
2638
|
+ _cmXScoreReport(p, NULL, true );
|
|
2639
|
+
|
|
2640
|
+
|
|
2641
|
+
|
2508
|
2642
|
errLabel:
|
2509
|
2643
|
cmFileClose(&fH);
|
2510
|
2644
|
cmMemFree(b);
|
|
@@ -3067,12 +3201,31 @@ void _cmXScoreReportNote( cmRpt_t* rpt, const cmXsNote_t* note,unsigned index )
|
3067
|
3201
|
if( note->graceGroupId != 0)
|
3068
|
3202
|
cmRptPrintf(rpt," g=%i",note->graceGroupId);
|
3069
|
3203
|
|
|
3204
|
+ /*
|
|
3205
|
+ if( cmIsFlag(note->flags,kBegGraceXsFl) )
|
|
3206
|
+ cmRptPrintf(rpt," B");
|
|
3207
|
+
|
|
3208
|
+ if( cmIsFlag(note->flags,kEndGraceXsFl) )
|
|
3209
|
+ cmRptPrintf(rpt," E");
|
|
3210
|
+
|
|
3211
|
+ if( note->dynamics != 0)
|
|
3212
|
+ cmRptPrintf(rpt," dyn=%i",note->dynamics);
|
|
3213
|
+
|
|
3214
|
+ if( cmIsFlag(note->flags,kDynBegForkXsFl) )
|
|
3215
|
+ cmRptPrintf(rpt," B");
|
|
3216
|
+
|
|
3217
|
+ if( cmIsFlag(note->flags,kDynEndForkXsFl) )
|
|
3218
|
+ cmRptPrintf(rpt," E");
|
|
3219
|
+
|
|
3220
|
+ */
|
3070
|
3221
|
}
|
3071
|
3222
|
|
3072
|
3223
|
|
3073
|
|
-void cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl )
|
|
3224
|
+void _cmXScoreReport( cmXScore_t* p, cmRpt_t* rpt, bool sortFl )
|
3074
|
3225
|
{
|
3075
|
|
- cmXScore_t* p = _cmXScoreHandleToPtr(h);
|
|
3226
|
+ if( rpt == NULL )
|
|
3227
|
+ rpt = p->err.rpt;
|
|
3228
|
+
|
3076
|
3229
|
cmXsPart_t* pp = p->partL;
|
3077
|
3230
|
|
3078
|
3231
|
for(; pp!=NULL; pp=pp->link)
|
|
@@ -3141,6 +3294,12 @@ void cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl )
|
3141
|
3294
|
}
|
3142
|
3295
|
}
|
3143
|
3296
|
|
|
3297
|
+void cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl )
|
|
3298
|
+{
|
|
3299
|
+ cmXScore_t* p = _cmXScoreHandleToPtr(h);
|
|
3300
|
+ return _cmXScoreReport(p,rpt,sortFl);
|
|
3301
|
+}
|
|
3302
|
+
|
3144
|
3303
|
void _cmXScoreGenEditFileWrite( void* arg, const cmChar_t* text )
|
3145
|
3304
|
{
|
3146
|
3305
|
if( text != NULL && arg != NULL )
|
|
@@ -3756,7 +3915,7 @@ cmXsRC_t cmXScoreTest(
|
3756
|
3915
|
|
3757
|
3916
|
if( editFn!=NULL && !cmFsIsFile(editFn) )
|
3758
|
3917
|
{
|
3759
|
|
- cmRptPrintf(&ctx->rpt,"The edit file %s does not exist. A new edit file is therefore being created.",editFn);
|
|
3918
|
+ cmRptPrintf(&ctx->rpt,"The edit file %s does not exist. A new edit file will be created.",editFn);
|
3760
|
3919
|
cmXScoreGenEditFile(ctx,xmlFn,editFn);
|
3761
|
3920
|
editFn = NULL;
|
3762
|
3921
|
}
|