Time to BarsAndBeats bug?

I was working with time to bar and beats in my timeline, I set tempos in this way:

    edit->tempoSequence.getTimeSigs()[0]->setStringTimeSig("4/4");

    edit->tempoSequence.getTempos()[0]->setBpm(60);
    edit->tempoSequence.getTempos()[0]->setCurve(1);
    
    edit->tempoSequence.insertTempo(4);
    edit->tempoSequence.getTempos()[1]->setBpm(120);
    edit->tempoSequence.getTempos()[1]->setCurve(1);
    edit->tempoSequence.insertTempo(8);
    edit->tempoSequence.getTempos()[2]->setBpm(30);
    edit->tempoSequence.getTempos()[2]->setCurve(0);
    edit->tempoSequence.insertTempo(10);
    edit->tempoSequence.getTempos()[3]->setBpm(300);
    edit->tempoSequence.getTempos()[3]->setCurve(1);

Iterating to get xPos of separators in my timeline with this code:

        tracktion_engine::TempoSequence::BarsAndBeats firstBarsBeatsShowed = timelineViewport->edit.tempoSequence.timeToBarsBeats(allocatedTimeRange.start);
        double const firstBeatTimeShowed = timelineViewport->edit.tempoSequence.barsBeatsToBeats(firstBarsBeatsShowed);
        
        tracktion_engine::TempoSequence::BarsAndBeats lastBarsBeatsShowed = timelineViewport->edit.tempoSequence.timeToBarsBeats(allocatedTimeRange.end);
        double const lastBeatTimeShowed = timelineViewport->edit.tempoSequence.barsBeatsToBeats(lastBarsBeatsShowed);
        
        int prevI = 0;
        double currentTime, previousTime;
        
        for (int i = 0; i <= lastBeatTimeShowed; i++)
        {
            if (i >= firstBeatTimeShowed)
            {
                currentTime = timelineViewport->edit.tempoSequence.beatsToTime(i);
                previousTime = timelineViewport->edit.tempoSequence.beatsToTime(prevI);
                DBG("\ni = " + String(i));
                DBG("current time = " + String(currentTime));
                DBG("current time to x= " + String(timelineViewport->convertTimeToX(currentTime)));
                if (i!=0) { DBG("distanza tra questo e quello = " + String(timelineViewport->convertTimeToX(currentTime) - (timelineViewport->convertTimeToX(previousTime)))); }
               
                if (i == 0 || (timelineViewport->convertTimeToX(currentTime) - (timelineViewport->convertTimeToX(previousTime))) >= minWidthBetweenMainSeparators)
                {
                    DBG("currentTime to  beats      ->" + String(timelineViewport->edit.tempoSequence.timeToBarsBeats(currentTime).beats));
                    DBG("currentTime to  wholeBeats ->" + String(timelineViewport->edit.tempoSequence.timeToBarsBeats(currentTime).getWholeBeats()));
                    if (timelineViewport->edit.tempoSequence.timeToBarsBeats(currentTime).getWholeBeats() == 0)
                    {
                        DBG("Bar-------------!!!!!!!!!!!!!!!!!!!!!");
                        mainSeparators.add(new Separator(this, currentTime, String(timelineViewport->edit.tempoSequence.timeToBarsBeats(timelineViewport->edit.tempoSequence.beatsToTime(i)).bars)));
                    }
                }
                prevI = i;
            }
        }

I noticed some wire results! I printed my iteration and lets see what happens for example under i=14 or i=15 or i=19 or i=20
I don’t know what’s the problem because if times I’m passing in iteration to get the beats shoud me wrong with timeToBarsBeats(currentTime).beats I would not have whole results…

i = 0

current time = 0

current time to x= 0

currentTime to beats ->0

currentTime to wholeBeats ->0

Bar-------------!!!

i = 1

current time = 1

current time to x= 100

distanza tra questo e quello = 100

currentTime to beats ->1

currentTime to wholeBeats ->1

i = 2

current time = 2

current time to x= 200

distanza tra questo e quello = 100

currentTime to beats ->2

currentTime to wholeBeats ->2

i = 3

current time = 3

current time to x= 300

distanza tra questo e quello = 100

currentTime to beats ->3

currentTime to wholeBeats ->3

i = 4

current time = 4

current time to x= 400

distanza tra questo e quello = 100

currentTime to beats ->0

currentTime to wholeBeats ->0

Bar-------------!!!

i = 5

current time = 4.5

current time to x= 500

distanza tra questo e quello = 100

currentTime to beats ->1

currentTime to wholeBeats ->1

i = 6

current time = 5

current time to x= 600

distanza tra questo e quello = 100

currentTime to beats ->2

currentTime to wholeBeats ->2

i = 7

current time = 5.5

current time to x= 700

distanza tra questo e quello = 100

currentTime to beats ->3

currentTime to wholeBeats ->3

i = 8

current time = 6

current time to x= 800

distanza tra questo e quello = 100

currentTime to beats ->0

currentTime to wholeBeats ->0

Bar-------------!!!

i = 9

current time = 6.5

current time to x= 900

distanza tra questo e quello = 100

currentTime to beats ->1

currentTime to wholeBeats ->1

i = 10

current time = 7

current time to x= 1000

distanza tra questo e quello = 100

currentTime to beats ->2

currentTime to wholeBeats ->2

i = 11

current time = 7.5

current time to x= 1100

distanza tra questo e quello = 100

currentTime to beats ->3

currentTime to wholeBeats ->3

i = 12

current time = 8

current time to x= 1200

distanza tra questo e quello = 100

currentTime to beats ->0

currentTime to wholeBeats ->0

Bar-------------!!!

i = 13

current time = 8.80927

current time to x= 1300

distanza tra questo e quello = 100

currentTime to beats ->1

currentTime to wholeBeats ->1

i = 14

current time = 9.00927

current time to x= 1400

distanza tra questo e quello = 100

currentTime to beats ->2

currentTime to wholeBeats ->1

i = 15

current time = 9.20927

current time to x= 1500

distanza tra questo e quello = 100

currentTime to beats ->3

currentTime to wholeBeats ->3

i = 16

current time = 9.40927

current time to x= 1600

distanza tra questo e quello = 100

currentTime to beats ->0

currentTime to wholeBeats ->0

Bar-------------!!!

i = 17

current time = 9.60927

current time to x= 1700

distanza tra questo e quello = 100

currentTime to beats ->1

currentTime to wholeBeats ->1

i = 18

current time = 9.80927

current time to x= 1800

distanza tra questo e quello = 100

currentTime to beats ->2

currentTime to wholeBeats ->2

i = 19

current time = 10.0093

current time to x= 1900

distanza tra questo e quello = 100

currentTime to beats ->3

currentTime to wholeBeats ->2

i = 20

current time = 10.2093

current time to x= 2000

distanza tra questo e quello = 100

currentTime to beats ->3.55271e-15

currentTime to wholeBeats ->0

Bar-------------!!!

i = 21

current time = 10.4093

current time to x= 2100

distanza tra questo e quello = 100

currentTime to beats ->1

currentTime to wholeBeats ->1

i = 22

current time = 10.6093

current time to x= 2200

distanza tra questo e quello = 100

currentTime to beats ->2

currentTime to wholeBeats ->2

i = 23

current time = 10.8093

current time to x= 2300

distanza tra questo e quello = 100

currentTime to beats ->3

currentTime to wholeBeats ->3

i = 24

current time = 11.0093

current time to x= 2400

distanza tra questo e quello = 100

currentTime to beats ->4

currentTime to wholeBeats ->3

i = 25

current time = 11.2093

current time to x= 2500

distanza tra questo e quello = 100

currentTime to beats ->1

currentTime to wholeBeats ->1

i = 26

current time = 11.4093

current time to x= 2600

distanza tra questo e quello = 100

currentTime to beats ->2

currentTime to wholeBeats ->2

i = 27

current time = 11.6093

current time to x= 2700

distanza tra questo e quello = 100

currentTime to beats ->3

currentTime to wholeBeats ->3

i = 28

current time = 11.8093

current time to x= 2800

distanza tra questo e quello = 100

currentTime to beats ->1.77636e-15

currentTime to wholeBeats ->0

Bar-------------!!!

i = 29

current time = 12.0093

current time to x= 2900

distanza tra questo e quello = 100

currentTime to beats ->1

currentTime to wholeBeats ->0

Bar-------------!!!

i = 30

current time = 12.2093

current time to x= 3000

distanza tra questo e quello = 100

currentTime to beats ->2

currentTime to wholeBeats ->2

i = 31

current time = 12.4093

current time to x= 3100

distanza tra questo e quello = 100

currentTime to beats ->3

currentTime to wholeBeats ->3

i = 32

current time = 12.6093

current time to x= 3200

distanza tra questo e quello = 100

currentTime to beats ->7.10543e-15

currentTime to wholeBeats ->0

Bar-------------!!!

i = 33

current time = 12.8093

current time to x= 3300

distanza tra questo e quello = 100

currentTime to beats ->1

currentTime to wholeBeats ->1

i = 34

current time = 13.0093

current time to x= 3400

distanza tra questo e quello = 99.9998

i = 35

current time = 13.2093

current time to x= 3500

distanza tra questo e quello = 100

currentTime to beats ->3

currentTime to wholeBeats ->3

i = 36

current time = 13.4093

current time to x= 3600

distanza tra questo e quello = 100

currentTime to beats ->7.10543e-15

currentTime to wholeBeats ->0

Bar-------------!!!

i = 37

current time = 13.6093

current time to x= 3700

distanza tra questo e quello = 100

currentTime to beats ->1

currentTime to wholeBeats ->1

i = 38

current time = 13.8093

current time to x= 3800

distanza tra questo e quello = 100

currentTime to beats ->2

currentTime to wholeBeats ->2

i = 39

current time = 14.0093

current time to x= 3900

distanza tra questo e quello = 100

currentTime to beats ->3

currentTime to wholeBeats ->3

i = 40

current time = 14.2093

current time to x= 4000

distanza tra questo e quello = 100

currentTime to beats ->3.55271e-15

currentTime to wholeBeats ->0

Bar-------------!!!

i = 41

current time = 14.4093

current time to x= 4100

distanza tra questo e quello = 100

currentTime to beats ->1

currentTime to wholeBeats ->1

i = 42

current time = 14.6093

current time to x= 4200

distanza tra questo e quello = 100

currentTime to beats ->2

currentTime to wholeBeats ->2

i = 43

current time = 14.8093

current time to x= 4300

distanza tra questo e quello = 100

currentTime to beats ->3

currentTime to wholeBeats ->3

i = 44

current time = 15.0093

current time to x= 4400

distanza tra questo e quello = 100

currentTime to beats ->0

currentTime to wholeBeats ->0

Bar-------------!!!

i = 45

current time = 15.2093

current time to x= 4500

distanza tra questo e quello = 100

currentTime to beats ->1

currentTime to wholeBeats ->1

i = 46

current time = 15.4093

current time to x= 4600

distanza tra questo e quello = 100

currentTime to beats ->2

currentTime to wholeBeats ->2

i = 47

current time = 15.6093

current time to x= 4700

distanza tra questo e quello = 100

currentTime to beats ->3

currentTime to wholeBeats ->3

i = 48

current time = 15.8093

current time to x= 4800

distanza tra questo e quello = 100

currentTime to beats ->0

currentTime to wholeBeats ->0

Bar-------------!!!

i = 49

current time = 16.0093

current time to x= 4900

distanza tra questo e quello = 100

currentTime to beats ->1

currentTime to wholeBeats ->1

i = 50

current time = 16.2093

current time to x= 5000

distanza tra questo e quello = 100

currentTime to beats ->2

currentTime to wholeBeats ->1

I’m sorry, I can’t really follow what’s going on there.
There are lots of tests for the core::Tempo classes though (tracktion_core/utilities/tracktion_Tempo.test.cpp), perhaps you could adapt one of these to show your problem?

Are you sure it’s not just that you’re misunderstanding what the numbers represent?

    /** Represents a number of bars and then beats in that bar. */
    struct BarsAndBeats
    {
        int bars = 0;       /**< The number of whole bars. */
        BeatDuration beats; /**< The number of beats in the current bar. */
        int numerator = 0;  /**< The number of beats in the current bar. */

You’re not expecting beats to be the total elapsed number of beats are you?

1 Like

Oh no I understand it, to explain you:
I’doing a timeline graphic rappresentation where the options of visualization are:

Playhead with constant velocity in millisecs timecode (so if each second is defined by 100 pixels all separator have the same distance)

Playhead with constant velocity in bars and eats timecode (so if each second is defined by 100 pixels all separator have distance that modified by bpm)

Playhead with variable velocity in bars and beats timecode (so separators showing bars have the same distance)

All works and all is joined to graphic rappresentation but I noticed working that some bars was missed in my time line… So to debug it I printed what time to bars and beats gives me and sometimes it gives me not right results… I don’t think problem is time I’m passing because for example at last time 16.2093 getting double of var it gives me 2 (if time passing would be not precise I expected to have some decimals) while calling method to have whole beat it gives me 1.

Another scenario is in I = 40, calling method the beats is 0 (right) while var is a crazy 3.55271e-15

Another again is in I = 19, calling method the beats is 2 (right) while var is 3 (wrong), but time passed to timeToBarsAndBeats is the same and so the BarsAndBeats object is the same

I think you need to break it down to a simpler example so I can understand it.

Can you write a test similar to this existing one that fails?

        beginTest ("0b: 120bpm 4/4 c=-1 p=60 s=0, 4b: 60bpm 4/4 p=42 s=1");
        {
            Sequence seq ({{ BeatPosition(), 120.0, -1.0f },
                           { BeatPosition::fromBeats (4), 60.0, 0.0f } },
                          {{ BeatPosition(), 4, 4, false }},
                          {{ BeatPosition(), {} },
                           { BeatPosition::fromBeats (4), { 42, 1 } } },
                          tempo::LengthOfOneBeat::dependsOnTimeSignature);

            expect (seq, {}, {});
            expect (seq, BeatPosition::fromBeats (1), 1s);
            expect (seq, BeatPosition::fromBeats (4), 4s);
            expect (seq, BeatPosition::fromBeats (60), 1min);
            expect (seq, BeatPosition::fromBeats (120), 2min);
        }

But use seq.toBarsAndBeats and test the expected bar and beats members?

1 Like

Ok Thankyou, this evening I’ll do it and I’ll give you feedback