2020 * along with this program. If not, see <https://www.gnu.org/licenses/>.
2121 */
2222#include " importtef.h"
23+ #include " measurehandler.h"
2324#include " tuplethandler.h"
2425
2526#include " engraving/dom/box.h"
@@ -265,19 +266,20 @@ static void addGraceNotesToChord(mu::engraving::Chord* chord, int pitch, int fre
265266 chord->add (cr);
266267}
267268
268- static void addRest (Segment* segment, track_idx_t track, TDuration tDuration, Fraction length, muse::draw::Color color)
269+ static void addRest (Segment* segment, track_idx_t track, TDuration tDuration, Fraction length, muse::draw::Color color, bool visible = true )
269270{
270271 mu::engraving::Rest* rest = Factory::createRest (segment);
271272 if (rest) {
272273 rest->setTrack (track);
273274 rest->setDurationType (tDuration);
274275 rest->setTicks (length);
275276 rest->setColor (color);
277+ rest->setVisible (visible);
276278 segment->add (rest);
277279 }
278280}
279281
280- void TablEdit::createContents ()
282+ void TablEdit::createContents (const MeasureHandler& measureHandler )
281283{
282284 if (tefInstruments.size () == 0 ) {
283285 LOGD (" error: no instruments" );
@@ -315,10 +317,14 @@ void TablEdit::createContents()
315317 if (firstNote->dots ) {
316318 tDuration.setDots (firstNote->dots );
317319 }
320+
321+ const auto idx { measureHandler.measureIndex (firstNote->position , tefMeasures) };
322+ const Fraction gapCorrection { measureHandler.sumPreviousGaps (idx), 64 };
318323 const auto positionCorrection = tupletHandler.doTuplet (firstNote);
319324
320325 Fraction tick { firstNote->position , 64 }; // position is in 64th
321326 tick += positionCorrection;
327+ tick -= gapCorrection;
322328 LOGN (" positionCorrection %d/%d tick %d/%d length %d/%d" ,
323329 positionCorrection.numerator (), positionCorrection.denominator (),
324330 tick.numerator (), tick.denominator (),
@@ -413,19 +419,38 @@ void TablEdit::createLinkedTabs()
413419 }
414420}
415421
416- void TablEdit::createMeasures ()
422+ static Fraction reducedActualLength (const int actual, const int nominalDenominator)
423+ {
424+ Fraction res { actual, 64 };
425+ while (res.denominator () >= 2 * nominalDenominator && res.numerator () % 2 == 0 ) {
426+ res.setNumerator (res.numerator () / 2 );
427+ res.setDenominator (res.denominator () / 2 );
428+ }
429+ LOGN (" actual %d nominalDenominator %d res %d/%d" , actual, nominalDenominator, res.numerator (), res.denominator ());
430+ return res;
431+ }
432+
433+ void TablEdit::createMeasures (const MeasureHandler& measureHandler)
417434{
418435 int lastKey { 0 }; // safe default
419436 Fraction lastTimeSig { -1 , -1 }; // impossible value
420437 Fraction tick { 0 , 1 };
421- for (const auto & tefMeasure : tefMeasures) {
438+ for (size_t idx = 0 ; idx < tefMeasures.size (); ++idx) {
439+ TefMeasure& tefMeasure { tefMeasures.at (idx) };
422440 // create measure
423441 auto measure = Factory::createMeasure (score->dummy ()->system ());
424442 measure->setTick (tick);
425- Fraction length{ tefMeasure.numerator , tefMeasure.denominator };
426- measure->setTimesig (length);
427- measure->setTicks (length);
443+ Fraction nominalLength{ tefMeasure.numerator , tefMeasure.denominator };
444+ Fraction actualLength{ reducedActualLength (measureHandler.actualSize (tefMeasures, idx), tefMeasure.denominator ) };
445+ measure->setTimesig (nominalLength);
446+ measure->setTicks (actualLength);
428447 measure->setEndBarLineType (BarLineType::NORMAL, 0 );
448+ LOGN (" measure %p tick %d/%d nominalLength %d/%d actualLength %d/%d" ,
449+ measure,
450+ tick.numerator (), tick.denominator (),
451+ nominalLength.numerator (), nominalLength.denominator (),
452+ actualLength.numerator (), actualLength.denominator ()
453+ );
429454 score->measures ()->add (measure);
430455
431456 if (tick == Fraction { 0 , 1 }) {
@@ -441,11 +466,11 @@ void TablEdit::createMeasures()
441466 auto s2 = measure->getSegment (mu::engraving::SegmentType::TimeSig, tick);
442467 for (size_t i = 0 ; i < tefInstruments.size (); ++i) {
443468 mu::engraving::TimeSig* timesig = Factory::createTimeSig (s2);
444- timesig->setSig (length );
469+ timesig->setSig (nominalLength );
445470 timesig->setTrack (i * VOICES);
446471 s2->add (timesig);
447472 }
448- lastTimeSig = length ;
473+ lastTimeSig = nominalLength ;
449474 createTempo ();
450475 } else {
451476 if (tefMeasure.key != lastKey) {
@@ -458,19 +483,19 @@ void TablEdit::createMeasures()
458483 }
459484 lastKey = tefMeasure.key ;
460485 }
461- if (length != lastTimeSig) {
486+ if (nominalLength != lastTimeSig) {
462487 auto s2 = measure->getSegment (mu::engraving::SegmentType::TimeSig, tick);
463488 for (size_t i = 0 ; i < tefInstruments.size (); ++i) {
464489 mu::engraving::TimeSig* timesig = Factory::createTimeSig (s2);
465- timesig->setSig (length );
490+ timesig->setSig (nominalLength );
466491 timesig->setTrack (i * VOICES);
467492 s2->add (timesig);
468493 }
469- lastTimeSig = length ;
494+ lastTimeSig = nominalLength ;
470495 }
471496 }
472497
473- tick += length ;
498+ tick += actualLength ;
474499 }
475500 score->setUpTempoMap ();
476501}
@@ -569,14 +594,81 @@ static void setInstrumentIDs(const std::vector<Part*>& parts)
569594 }
570595}
571596
597+ // ---------------------------------------------------------
598+ // fillGap
599+ // ---------------------------------------------------------
600+
601+ // Fill one gap (tstart - tend) in this track in this measure with rest(s).
602+
603+ static void fillGap (Measure* measure, track_idx_t track, const Fraction& tstart, const Fraction& tend)
604+ {
605+ Fraction ctick = tstart;
606+ Fraction restLen = tend - tstart;
607+ LOGN (" measure %p track %zu tstart %d tend %d restLen %d len" ,
608+ measure, track, tstart.ticks (), tend.ticks (), restLen.ticks ());
609+ auto durList = toDurationList (restLen, true );
610+ LOGN (" durList.size %zu" , durList.size ());
611+ for (const auto & dur : durList) {
612+ LOGN (" type %d dots %d fraction %d/%d" , dur.type (), dur.dots (), dur.fraction ().numerator (), dur.fraction ().denominator ());
613+ Segment* s = measure->getSegment (SegmentType::ChordRest, ctick);
614+ addRest (s, track, dur, dur.fraction (), muse::draw::Color::BLACK, false );
615+ ctick += dur.fraction ();
616+ }
617+ }
618+
619+ // ---------------------------------------------------------
620+ // fillGapsInFirstVoices
621+ // ---------------------------------------------------------
622+
623+ // Fill gaps in first voice of every staff in this measure for this part with rest(s).
624+
625+ static void fillGapsInFirstVoices (MasterScore* score)
626+ {
627+ IF_ASSERT_FAILED (score) {
628+ return ;
629+ }
630+
631+ for (staff_idx_t idx = 0 ; idx < score->nstaves (); ++idx) {
632+ for (Measure* measure = score->firstMeasure (); measure; measure = measure->nextMeasure ()) {
633+ Fraction measTick = measure->tick ();
634+ Fraction measLen = measure->ticks ();
635+ Fraction nextMeasTick = measTick + measLen;
636+ LOGN (" measure %p idx %zu tick %d - %d (len %d)" ,
637+ measure, idx, measTick.ticks (), nextMeasTick.ticks (), measLen.ticks ());
638+ track_idx_t track = idx * VOICES;
639+ Fraction endOfLastCR = measTick;
640+ for (Segment* s = measure->first (); s; s = s->next ()) {
641+ EngravingItem* el = s->element (track);
642+ if (el) {
643+ if (s->isChordRestType ()) {
644+ ChordRest* cr = static_cast <ChordRest*>(el);
645+ Fraction crTick = cr->tick ();
646+ Fraction crLen = cr->globalTicks ();
647+ if (crTick > endOfLastCR) {
648+ fillGap (measure, track, endOfLastCR, crTick);
649+ }
650+ endOfLastCR = crTick + crLen;
651+ }
652+ }
653+ }
654+ if (nextMeasTick > endOfLastCR) {
655+ fillGap (measure, track, endOfLastCR, nextMeasTick);
656+ }
657+ }
658+ }
659+ }
660+
572661void TablEdit::createScore ()
573662{
663+ MeasureHandler measureHandler;
664+ measureHandler.calculate (tefContents, tefMeasures);
574665 createProperties ();
575666 createParts ();
576667 createTitleFrame ();
577- createMeasures ();
668+ createMeasures (measureHandler );
578669 createNotesFrame ();
579- createContents ();
670+ createContents (measureHandler);
671+ fillGapsInFirstVoices (score);
580672 createRepeats ();
581673 createTexts ();
582674 createLinkedTabs ();
@@ -877,6 +969,7 @@ void TablEdit::readTefMeasures()
877969 for (uint16_t i = 0 ; i < numberOfMeasures; ++i) {
878970 TefMeasure measure;
879971 measure.flag = readUInt8 ();
972+ measure.isPickup = measure.flag & 0x08 ;
880973 /* uint8_t uTmp = */ readUInt8 ();
881974 measure.key = readInt8 ();
882975 measure.size = readUInt8 ();
0 commit comments