Author Topic: ChannelBytes2Seconds in milliseconds  (Read 3013 times)

Graham1

  • Posts: 35
ChannelBytes2Seconds in milliseconds
« on: 2 Nov '12 - 11:03 »
I saw a reply to this posted some time ago, but does that actually work. If ChannelBytes2Seconds returns a value either rounded or truncated to the nearest second, how can you ever get any milliseconds values that may have been present.

Ops2011

  • Guest
Re: ChannelBytes2Seconds in milliseconds
« Reply #1 on: 2 Nov '12 - 12:40 »
Take a look at this code, hope it helps a little bit.

Code: [Select]
TotalBytes := BASS_ChannelGetLength(Stream, BASS_POS_BYTE); // NORMAL
TotalPlayingTime := BASS_ChannelBytes2Seconds(Stream, TotalBytes); // Double

BASS_Sec2Time(BASS_DoubleToCardinal(Round(TotalPlayingTime)), bHours, bMinutes, bSeconds, bFractions);
// Format('%.2d:%.2d%.2d', [bMinutes, bSeconds, bFractions]);

function BASS_DoubleToCardinal(Value: Double): Cardinal;
begin
  Result := Round(Value * 1000);
end;

function BASS_Sec2Time(BASS_Sec: Cardinal; var tHours, tMinutes, tSecs, tFractions: Cardinal): Int64;
var
  MilliSec, Seconds: Int64;
begin
  MilliSec := BASS_Sec; // BASS_DoubleToCardinal(BASS_Sec);
  Seconds := MilliSec div 1000;
  tHours := (Seconds div 3600);
  tMinutes := (((Seconds - ((tHours) * 3600)) div 60));
  tSecs := (Seconds - ((tHours) * 3600 + (tMinutes) * 60));
  tFractions := (MilliSec - (((tHours) * 3600 + (tMinutes) * 60) + (tSecs)) * 1000);
  tFractions := Round(tFractions / 10);
  if (tFractions > 99) then
    tFractions := 99; // Dec(tFractions);
  Result := MilliSec;
end;

Graham1

  • Posts: 35
Re: ChannelBytes2Seconds in milliseconds
« Reply #2 on: 2 Nov '12 - 14:46 »
Your routine just seems to create Hours, Mins, Secs etc. from a a number of seconds.

I was interested in knowing if there was a way of determining the length of an audio file in milliseconds.

This whole issue arose because I have a callback to signify the end of a file. On some files this callback was generated early (maybe up to 500mS). Hovever this has now been solved:

  BASS_ChannelSetSync(local_chan,BASS_SYNC_END or BASS_SYNC_MIXTIME,0,LoopSyncProcLocal, nil);

should be

  BASS_ChannelSetSync(local_chan,BASS_SYNC_END,0,LoopSyncProcLocal, nil);

Ian @ un4seen

  • Administrator
  • Posts: 20424
Re: ChannelBytes2Seconds in milliseconds
« Reply #3 on: 2 Nov '12 - 16:30 »
The BASS_SYNC_MIXTIME flag will result in your SYNCPROC function being called when the decoder reaches the end, rather than delaying it until the end is actually heard, which will be later due to buffering. The playback buffer (BASS_CONFIG_BUFFER setting) defaults to 500ms long, so that will be why you noticed the sync was around 500ms early when using the BASS_SYNC_MIXTIME flag.

Regarding BASS_ChannelBytes2Seconds, it returns a 64-bit floating-point ("double") value. It won't be truncated/rounded to the nearest second unless the variable receiving the return value causes that, eg. assigning it to an "int".