|
@@ -402,6 +402,10 @@ cmXsRC_t _cmXScoreParseColor( cmXScore_t* p, const cmXmlNode_t* nnp, cmXsNote_t
|
402
|
402
|
return rc;
|
403
|
403
|
}
|
404
|
404
|
|
|
405
|
+// On input tick0Ref is set to the tick of the previous event.
|
|
406
|
+// On input tickRef is set to the tick of this event.
|
|
407
|
+// On output tick0Ref is set to the tick of this event.
|
|
408
|
+// On output tickRef is set to the tick of the next event.
|
405
|
409
|
cmXsRC_t _cmXScoreParseNote(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNode_t* nnp, unsigned* tick0Ref, unsigned* tickRef )
|
406
|
410
|
{
|
407
|
411
|
cmXsRC_t rc = kOkXsRC;
|
|
@@ -623,11 +627,13 @@ cmXsRC_t _cmXScoreParseDirection(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNo
|
623
|
627
|
}
|
624
|
628
|
|
625
|
629
|
|
626
|
|
-cmXsRC_t _cmXScoreParseMeasure(cmXScore_t* p, cmXsPart_t* pp, const cmXmlNode_t* mnp)
|
|
630
|
+// On input tickRef is set to the absolute tick of the bar line and on output it is set
|
|
631
|
+// to the absolute tick of the next bar line.
|
|
632
|
+cmXsRC_t _cmXScoreParseMeasure(cmXScore_t* p, cmXsPart_t* pp, const cmXmlNode_t* mnp, unsigned* tickRef)
|
627
|
633
|
{
|
628
|
634
|
cmXsRC_t rc = kOkXsRC;
|
629
|
635
|
const cmXmlNode_t* np = NULL;
|
630
|
|
- unsigned tick = 0;
|
|
636
|
+ unsigned tick = *tickRef;
|
631
|
637
|
unsigned tick0= 0;
|
632
|
638
|
cmXsMeas_t* m = NULL;
|
633
|
639
|
|
|
@@ -664,7 +670,6 @@ cmXsRC_t _cmXScoreParseMeasure(cmXScore_t* p, cmXsPart_t* pp, const cmXmlNode_t*
|
664
|
670
|
if((rc = _cmXScorePushNonNote(p,meas,mnp,tick,0,0,NULL,kBarXsFl)) != kOkXsRC )
|
665
|
671
|
return rc;
|
666
|
672
|
|
667
|
|
-
|
668
|
673
|
np = mnp->children;
|
669
|
674
|
|
670
|
675
|
// for each child of the 'meas' XML node
|
|
@@ -697,6 +702,7 @@ cmXsRC_t _cmXScoreParseMeasure(cmXScore_t* p, cmXsPart_t* pp, const cmXmlNode_t*
|
697
|
702
|
|
698
|
703
|
}
|
699
|
704
|
|
|
705
|
+ *tickRef = tick;
|
700
|
706
|
return rc;
|
701
|
707
|
}
|
702
|
708
|
|
|
@@ -705,7 +711,7 @@ cmXsRC_t _cmXScoreParsePart( cmXScore_t* p, cmXsPart_t* pp )
|
705
|
711
|
cmXsRC_t rc = kOkXsRC;
|
706
|
712
|
const cmXmlNode_t* xnp;
|
707
|
713
|
cmXmlAttr_t partAttr = { "id", pp->idStr };
|
708
|
|
-
|
|
714
|
+ unsigned barTick = 0;
|
709
|
715
|
// find the 'part'
|
710
|
716
|
if((xnp = cmXmlSearch( cmXmlRoot(p->xmlH), "part", &partAttr, 1)) == NULL )
|
711
|
717
|
return cmErrMsg(&p->err,kSyntaxErrorXsRC,"The part '%s' was not found.",pp->idStr);
|
|
@@ -714,7 +720,7 @@ cmXsRC_t _cmXScoreParsePart( cmXScore_t* p, cmXsPart_t* pp )
|
714
|
720
|
const cmXmlNode_t* cnp = xnp->children;
|
715
|
721
|
for(; cnp!=NULL; cnp=cnp->sibling)
|
716
|
722
|
if( cmTextCmp(cnp->label,"measure") == 0 )
|
717
|
|
- if((rc = _cmXScoreParseMeasure(p,pp,cnp)) != kOkXsRC )
|
|
723
|
+ if((rc = _cmXScoreParseMeasure(p,pp,cnp,&barTick)) != kOkXsRC )
|
718
|
724
|
return rc;
|
719
|
725
|
|
720
|
726
|
return rc;
|
|
@@ -1252,8 +1258,8 @@ bool cmXScoreIsValid( cmXsH_t h )
|
1252
|
1258
|
|
1253
|
1259
|
void _cmXScoreReportTitle( cmRpt_t* rpt )
|
1254
|
1260
|
{
|
1255
|
|
- cmRptPrintf(rpt," voc loc tick durtn rval flags\n");
|
1256
|
|
- cmRptPrintf(rpt," --- ----- ----- ----- ---- --- -------------\n");
|
|
1261
|
+ cmRptPrintf(rpt," voc loc tick durtn rval flags\n");
|
|
1262
|
+ cmRptPrintf(rpt," --- ----- ------- ----- ---- --- -------------\n");
|
1257
|
1263
|
}
|
1258
|
1264
|
|
1259
|
1265
|
void _cmXScoreReportNote( cmRpt_t* rpt, const cmXsNote_t* note )
|
|
@@ -1279,7 +1285,7 @@ void _cmXScoreReportNote( cmRpt_t* rpt, const cmXsNote_t* note )
|
1279
|
1285
|
cmChar_t acc = note->alter==-1?'b':(note->alter==1?'#':' ');
|
1280
|
1286
|
snprintf(N,4,"%c%c%1i",note->step,acc,note->octave);
|
1281
|
1287
|
|
1282
|
|
- cmRptPrintf(rpt," %3i %5i %5i %5i %4.1f %3s %s%s%s%s%s%s%s%s%s%s%s%s%s",
|
|
1288
|
+ cmRptPrintf(rpt," %3i %5i %7i %5i %4.1f %3s %s%s%s%s%s%s%s%s%s%s%s%s%s",
|
1283
|
1289
|
note->voice->id,
|
1284
|
1290
|
note->locIdx,
|
1285
|
1291
|
note->tick,
|
|
@@ -1540,9 +1546,10 @@ cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn )
|
1540
|
1546
|
unsigned rowIdx = 1;
|
1541
|
1547
|
double tpqn = 0; // ticks per quarter note
|
1542
|
1548
|
double tps = 0; // ticks per second
|
1543
|
|
- double sec = 0; // current time in seconds
|
1544
|
1549
|
const cmChar_t* sectionIdStr = NULL;
|
1545
|
|
-
|
|
1550
|
+ unsigned metro_tick = 0;
|
|
1551
|
+ double metro_sec = 0;
|
|
1552
|
+ double sec0 = 0;
|
1546
|
1553
|
|
1547
|
1554
|
if( !cmCsvIsValid(p->csvH) )
|
1548
|
1555
|
return cmErrMsg(&p->err,kCsvFailXsRC,"The CSV output object is not initialized.");
|
|
@@ -1561,24 +1568,28 @@ cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn )
|
1561
|
1568
|
|
1562
|
1569
|
cmXsNote_t* np = mp->noteL;
|
1563
|
1570
|
|
1564
|
|
- double sec0 = sec;
|
1565
|
|
-
|
1566
|
1571
|
for(; np!=NULL; np=np->slink)
|
1567
|
1572
|
{
|
1568
|
1573
|
|
|
1574
|
+ // Seconds are calculated as:
|
|
1575
|
+ // dticks = np->tick - metro_tick; // where metro_tick is the absolute tick of the last metro event
|
|
1576
|
+ // secs = (dticks/tps) + metro_secs; // where metro_secs is the absoute time of the last metro event
|
|
1577
|
+
|
|
1578
|
+ unsigned dticks = np->tick - metro_tick;
|
|
1579
|
+ double secs = tps==0 ? 0 : (dticks/tps) + metro_sec;
|
|
1580
|
+ double dsecs = secs - sec0;
|
|
1581
|
+
|
1569
|
1582
|
//
|
1570
|
1583
|
if( cmIsFlag(np->flags,kMetronomeXsFl) )
|
1571
|
1584
|
{
|
1572
|
1585
|
double bpm = np->duration;
|
1573
|
1586
|
double bps = bpm / 60.0;
|
1574
|
1587
|
tps = bps * tpqn;
|
|
1588
|
+ metro_tick = np->tick;
|
|
1589
|
+ metro_sec = secs;
|
1575
|
1590
|
}
|
1576
|
|
-
|
1577
|
|
- double meas_sec = tps == 0 ? 0 : np->tick / tps;
|
1578
|
|
- double sec1 = sec + meas_sec;
|
1579
|
|
- double dsecs = sec1 - sec0;
|
1580
|
|
- sec0 = sec1;
|
1581
|
|
-
|
|
1591
|
+
|
|
1592
|
+
|
1582
|
1593
|
// if this is a section event
|
1583
|
1594
|
if( cmIsFlag(np->flags,kSectionXsFl) )
|
1584
|
1595
|
sectionIdStr = np->tvalue;
|
|
@@ -1586,7 +1597,8 @@ cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn )
|
1586
|
1597
|
// if this is a bar event
|
1587
|
1598
|
if( cmIsFlag(np->flags,kBarXsFl) )
|
1588
|
1599
|
{
|
1589
|
|
- _cmXScoreWriteCsvRow(p,rowIdx,-1,mp->number,NULL,"bar",dsecs,sec1,0,0,-1,0,np->flags);
|
|
1600
|
+ _cmXScoreWriteCsvRow(p,rowIdx,-1,mp->number,NULL,"bar",dsecs,secs,0,0,-1,0,np->flags);
|
|
1601
|
+ sec0 = secs;
|
1590
|
1602
|
}
|
1591
|
1603
|
else
|
1592
|
1604
|
|
|
@@ -1595,7 +1607,8 @@ cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn )
|
1595
|
1607
|
{
|
1596
|
1608
|
unsigned d0 = 64; // pedal MIDI ctl id
|
1597
|
1609
|
unsigned d1 = cmIsFlag(np->flags,kPedalDnXsFl) ? 64 : 0; // pedal-dn: d1>=64 pedal-up:<64
|
1598
|
|
- _cmXScoreWriteCsvRow(p,rowIdx,-1,mp->number,NULL,"ctl",dsecs,sec1,d0,d1,-1,0,np->flags);
|
|
1610
|
+ _cmXScoreWriteCsvRow(p,rowIdx,-1,mp->number,NULL,"ctl",dsecs,secs,d0,d1,-1,0,np->flags);
|
|
1611
|
+ sec0 = secs;
|
1599
|
1612
|
}
|
1600
|
1613
|
else
|
1601
|
1614
|
|
|
@@ -1606,14 +1619,14 @@ cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn )
|
1606
|
1619
|
double frac = np->rvalue + (cmIsFlag(np->flags,kDotXsFl) ? (np->rvalue/2) : 0);
|
1607
|
1620
|
|
1608
|
1621
|
//
|
1609
|
|
- _cmXScoreWriteCsvRow(p,rowIdx,np->uid,mp->number,sectionIdStr,"non",dsecs,sec1,np->pitch,60,np->pitch,frac,np->flags);
|
|
1622
|
+ _cmXScoreWriteCsvRow(p,rowIdx,np->uid,mp->number,sectionIdStr,"non",dsecs,secs,np->pitch,60,np->pitch,frac,np->flags);
|
|
1623
|
+ sec0 = secs;
|
1610
|
1624
|
sectionIdStr = NULL;
|
1611
|
1625
|
}
|
1612
|
1626
|
|
1613
|
1627
|
rowIdx += 1;
|
1614
|
1628
|
}
|
1615
|
1629
|
|
1616
|
|
- sec = sec0;
|
1617
|
1630
|
}
|
1618
|
1631
|
}
|
1619
|
1632
|
|