Timecode mystery when using Measures and Beats

JohanAlthoff wrote on 1/15/2010, 4:31 AM
My project is set to 120 BPM, RulerFormat is "Measures and Beats," and I have a region at 19.1.010. However, when I run my render script, the timecode shows up as 18.0.010. The problem comes here:

RenderQueueItem.RenderArgs.Start = RenderQueueItem.ParentRegion.Position;

Despite having the same Nanosecond count (360825931) RenderArgs.Start becomes 18.0.010, but ParentRegion.Position is 19.1.010 (the correct value). Can I possibly be missing something here, or is it simply a bug in how Vegas treats Measures and Beats?


JohanAlthoff wrote on 1/15/2010, 5:24 AM
Is this simply because the "Ruler start time" is a minimum of 1.1.0, and this somehow should get added to the Timestamp string? Meaning, the ruler starts at 1.1.0, but a Measures and Beats timecode starts at 0.0.0?

EDIT: This can better be explained thus:
Timecode.FromPositionString("1.1.0", RulerFormat.MeasuresAndBeats) // 1.1.000
Timecode.FromPositionString("0.0.0", RulerFormat.MeasuresAndBeats) // 1.1.000

I'm at a loss as to whether this is a bug or an intended feature.
JohnnyRoy wrote on 1/15/2010, 5:49 AM
All of the other ruler formats are zero based. All of the TimeCodes are zero based. I'm guessing that this is an intended feature to be consistent even though we think of the beginning of the first measure as 1.1.0. It's like the difference between Track.Index and Track.DisplayIndex. People think of the first track as 1 but internally the first track is 0 so ((Track.Index = 0) == (Track.DisplayIndex = 1)). Just add the offset in your code and you should be fine.

JohanAlthoff wrote on 2/1/2010, 5:47 AM
I would suggest you replicate the issue I've described above, as I'm not sure you understand the problem.

The two timecodes reflect the same point in time (since their .Nanos members have the same value) but they have two different M&B representations. This cannot be solved by a simple offset, since that would actually change the value.
JohnnyRoy wrote on 2/1/2010, 8:09 AM
> I would suggest you replicate the issue I've described above, as I'm not sure you understand the problem.

I did before I answered your post. I'm sorry I wasn't clearer. It's important to understand the difference between Duration timecode and Positional timecode because that is at the core of what you are seeing. This is why I used the specific example of Index and DisplayIndex. So let me try explaining it again differently:

The duration timecode that the timeline uses is zero based and has no regard for rule format. Postional timecode takes the ruler format into account. Here is a simple example:

(1) Set your timeline ruler to Measures and Beats
(2) Place the cursor at 1.2.000
(3) Run this line of code:
MessageBox.Show(vegas.Cursor.ToString() + " = " + vegas.Cursor.ToPositionString());
What you should see is:

0.1.000 = 1.2.000

This indicates that what you perceive to be the position 1.2.000 on the timeline, is really internally measured as 0.1.000. The ToPositionString() and FromPositionString() are new API's for Sony Vegas 8. Before that we had to accommodate for the difference in our code (which is why I am "painfully" aware of this). ;-)

Your original problem is that RenderQueueItem.RenderArgs.Start is a duration timeline measurement and RenderQueueItem.ParentRegion.Position is measured as a position and therefore takes the timeline ruler into account. RenderArgs needs to know internally where to start regardless of what the ruler says.

In your original example Start=18.0.010 is equal to Position=19.1.010 because the "position" 19.1.010 is really 18.0.010 internally. The internal timeline format is always one beat and one measure behind because it is zero based and starts at 0.0.000 and not 1.1.000 (hence my reference to Index and DisplayIndex... i.e., what is "internal" and what you "see").

If you change your second example to use FromString() instead of FromPositionString() you would get the results you expected:

Timecode.FromString("1.1.0", RulerFormat.MeasuresAndBeats); // 1.1.000
Timecode.FromString("0.0.0", RulerFormat.MeasuresAndBeats); // 0.0.000
It's only because the call to FromPositionString is taking the timeline ruler format into account and the musical timeline does not start at zero. It starts at one measure and one beat.

To drive this point even further, place the cursor at the start of the timeline and right-click the timeline ruler and select Set Time at Cursor... and type in 12.1.000. Now run the code again that was
MessageBox.Show(vegas.Cursor.ToString() + " = " + vegas.Cursor.ToPositionString());
and this time it should say:

0.0.000 = 12.1.000

Because it's taking into account the timeline ruler and you told Vegas that the timeline should start on the first beat of measure 12.

When I referred to the offset in my original post, I was not suggesting that you needed to change the offset in your code because you are correct, it would change the Nanos and be a different time. I was just explaining that there was an offset between the internal time and the ruler time.

Does this explain it better?

JohanAlthoff wrote on 2/2/2010, 4:34 AM
Ah, it's all very clear now.

I do remember the early days of "position vs duration" not being reflected in the object model, I just wasn't clear on what Sony did to address it.

I'll go over my code again, this explanation should be very helpful.

Keep being awesome, Sir.