Duration problems

Hi!

First, sorry for my bad English, it isn’t my first language.

I’m currently writing a script for mAirList 2.2 but I have some problems to get the duration of a song.
I would like to get the effective duration of a song (from cue in to start next) but I cannot find a way to do it.
I’m currently using GetEffectiveDuration but apparently it gives the duration between cue in and cue out.
Worse: sometimes the value returned by the function is negative and incorrect!

Here is an excerpt of my script:

[code]procedure OnPlayerStart(PlayerControl: IPlayerControl; Item: IPlaylistItem);
var sl: TStringList;
begin
sl := TStringList.Create;
sl.Append(IntToStr(Item.GetEffectiveDuration));
sl.Append(Item.GetArtist + ’ - ’ + Item.GetTitle);
sl.SaveToFile(‘C:\synchro.txt’);
sl.Free;
end;

begin
end.
[/code]

Could you help me?

Thanks!

In mAirList 2.2, you need to devide all duration values by 10,000,000. That is, one second corresponds to the value 10,000,000. That’s a very precise time unit from DirectX.

In mAirList 3, you should use the Function TimeValueToSeconds instead. Which does the same thing, but which is future-proof, because the internal time format is likely to change.

Thanks for the answer Torben!

I know about the mAirList unit ; the problem doesn’t come from here.
The thing is that GetEffectiveDuration give me sometimes a negative value (!) and I suspect it to give the duration between cue in and cue out. I would like to get the duration between cue in and start next (which is the real “effective duration” of broadcasting).
I hope I’m clear, sorry for my English :wink:

Item.GetCuePosition(ptStartNext).GetValue - Item.GetCuePosition(ptCueIn).GetValue
will give you the duration you want (which you need to divide by 10 million to get seconds).

Note that if StartNext is not set for any item, the result of the above statement will be -(CueIn) because a ‘not set’ cue point will return zero.

It might be better to write a function like:

function MyDuration(piItem: IPlaylistItem): Integer; var iCueIn, iStartNext: integer; begin iCueIn := piItem.GetCuePosition(ptCueIn).GetValue / 10000000; iStartNext := piItem.GetCuePosition(ptStartNext).GetValue / 10000000; if iStartNext = 0 then Result := piItem.GetEffectiveDuration / 10000000 else Result := iStartNext - iCueIn; end;
and then use:
sl.Append(IntToStr(MyDuration(Item))); in your main OnPlayerStart procedure.

BFN
CAD

GetEffectiveDuration should never return a negative value. It’s an intelligent function that looks at each cue point before taking it into account for the calculation.

I rather suspect this is some kind of typecase/overflow issue.

Thanks for your help!

Here is the code I have now:

[code]{-------------------------------------------------------------------------------
DecroPro.mls - mAirList/DecroPro interface (main server)

Writes some information in a file about the item currently playing.

Author: Francois Veevaete francois@best-radio.net
Date: 2010-01-09

See http://www.mAirList.com for further information.
-------------------------------------------------------------------------------}

function MyDuration(piItem: IPlaylistItem): Integer;
var
iCueIn, iStartNext: integer;
begin
iCueIn := piItem.GetCuePosition(ptCueIn).GetValue / 10000000;
iStartNext := piItem.GetCuePosition(ptStartNext).GetValue / 10000000;
if iStartNext = 0 then
Result := piItem.GetEffectiveDuration / 10000000
else
Result := iStartNext - iCueIn;
end;

procedure OnPlayerStart(PlayerControl: IPlayerControl; Item: IPlaylistItem);
var sl: TStringList;
begin
sl := TStringList.Create;
sl.Append(FormatDateTime(‘c.zzz’, PlayerControl.GetPlaybackStartTime));
sl.Append(IntToStr(MyDuration(Item)));
sl.Append(Item.GetArtist + ’ - ’ + Item.GetTitle);
sl.SaveToFile(‘C:\Decro\synchro.txt’);
sl.Free;
end;

begin
end.
[/code]

Unfortunately I still have sometimes negative value (now in seconds, not anymore in 10 000 000th/seconds). Sometimes it just seems to work well, sometimes the value is negative (and if I “Abs” it, it’s not correct).

What can I do to correct that? I’m using v2.2.3.

You may want to try using Int64 or LongInt rather than Integer - I had a similar problem with converting v2 timings to milliseconds (I was exporting mAirList data to BCX3 files). I ended up with “funny” values and a play around with the definitions got it working.

Thanks Charlie, it did the trick! :smiley:

That’s what I was talking about when I suspected an “overflow” problem above.

The duration values get fairly large, so they are stored in 64-bit integers. When you pass the value directly to another (int64-aware) function like e.g. IntToStr, everything should be fine. But when you need to store the value in a variable, it must be a 64-bit one of course.

mAirList 3 introduced a new type “TTimeValue” which is now used in all places where a duration or cue position is referenced. It’s currently only an alias for int64, but I plan to change it to floating point numbers in the future. That’s why you should not do any manual conversion (division or multiplication by 10,000,000) in mAirList 3 anymore, but use the two new functions TimeValueToSeconds and SecondsToTimeValue instead. That will guarantee that your scripts will still work after the change.