Author Topic: time elapsed / remaining problem  (Read 7321 times)

breakpoint

  • Guest
time elapsed / remaining problem
« on: 27 Jun '03 - 03:32 »
I am having problems displaying the elapsed and reamining time on my mp3 streams using the code below. The problem is that sometimes the elapsed and remaining times do not equal the total time for the song.

Here is an example:

Elapsed 0:10
Remaining 1:20
-------------------
Total: 1:31

and as you can see there is a 1 second differnce between what it shows and what the real value is.

I think the problem is in the code that shows the remaining time because sometimes when I start the song the remaining time is 1 second less then it should be but other times it shows the correct number so again I am not sure what needs to be done to fix this problem and any help would be great.

Here is the code I am using.
Code: [Select]

procedure TForm1.Timer2Timer(Sender: TObject);
var
fillen : Qword;
filtime, curtime, rtime : float;
emin, esec, rmin, rsec : integer;
begin
Progressbar1.Position := BASS_ChannelGetPosition(song); // move slider if song playing

{get total time}
fillen := Bass_StreamGetLength(song);
filtime := Bass_ChannelBytes2Seconds(song,fillen);

{get elapsed time}
curtime := Bass_ChannelBytes2Seconds(song, Bass_ChannelGetPosition(song));
emin := trunc(curtime / 60);
esec := trunc(curtime) mod 60;

{get remaining time}
rtime := (filtime - curtime);
rmin := trunc(rtime / 60);
rsec := trunc(rtime) mod 60;

{show elapsed time on a label}
if esec < 10 then label8.Caption := inttostr(emin) + ':0' + inttostr(esec)
else
label8.Caption := inttostr(emin) + ':' + inttostr(esec);

{show remaining time on a label}
if rsec < 10 then label6.Caption := inttostr(rmin) + ':0' + inttostr(rsec)
else
label6.Caption := inttostr(rmin) + ':' + inttostr(rsec);
end;

DanaPaul

  • Posts: 335
Re: time elapsed / remaining problem
« Reply #1 on: 27 Jun '03 - 08:07 »
I would think that the problem lies in the "Trunc" action on both sets of time values.  Both sets of time values are effectively rounded down.

Try changing this...

rmin := trunc((rtime / 60) + 0.5);
rsec := trunc(rtime + 0.5) mod 60;

Or...[/i]

rtime := (filtime - curtime) + 0.5;



breakpoint

  • Guest
Re: time elapsed / remaining problem
« Reply #2 on: 28 Jun '03 - 00:38 »
Thanks for the reply dana but that does not seem to help. infact it adds (in alot of cases) a minute to the rmin value which is no good.

As I said before this problem seems to be random which means that sometimes the rsec value shows up correctly and at other times it does not (on the exact same song) so again I am stumped because to me if it works once it should work all the time.

I am using the BASS_MP3_SETPOS flag when I create the stream so i'm pretty sure that part is working as it should.

Again any help on this would be great thx.

Creadig

  • Posts: 71
Re: time elapsed / remaining problem
« Reply #3 on: 28 Jun '03 - 03:22 »
works fine for me. If it helps you... here`s my code. is in VB 6.0

The Code:
PosTime = Stream01GetPosition(1)  'get the position in time (seconds)
LenTime = Stream01GetLen(1)       'get the lenght in time (seconds)
PosByte = Stream01GetPosition(2)  'get the position in bytes
LenByte = Stream01GetLen(2)       'get the lengh in bytes

'get the type of visualization in config file (normal o restante)
If TopMenu.LType.Caption = "Normal" Then
  Rst1 = ConvSecToMin(PosTime)
  Call SetDigClock(Rst1, 1, "Normal")     'Set the digital clock for display
Else
  RestTime = LenTime - PosTime
  Rst1 = ConvSecToMin(RestTime)
  Call SetDigClock(Rst1, 1, "Restante")
End If

If TopMenu.OType.Caption = "Normal" Then
  Rst2 = PosByte
  Call SetDigNum(Trim(Rst2), 1, "Normal")    'Set the digital clock for display
Else
  RestTime = LenByte - PosByte
  Rst2 = Trim(Str$(RestTime))
  Call SetDigNum(Trim(Rst2), 1, "Restante")
End If

'positions from advanced mode
Est01.E1Pos.value = PosTime
Est01.E1Pos.ToolTipText = ConvSecToMin(CDbl(Est01.E1Pos.value))
Est01.LblCurrent.Caption = ConvSecToMin(PosTime)
Est01.LblCurrByte.Caption = PosByte

'----------------------------------------
'----------------------------------------
Function Stream01GetPosition(ByVal WTypeDisplay As Long) As Long

Dim PosByte As Long
Dim PosTime As Long

PosByte = BASS_ChannelGetPosition(Strm1)
PosTime = CLng(BASS_ChannelBytes2Seconds(Strm1, PosByte))

Select Case WTypeDisplay
  Case 2
     Stream01GetPosition = PosByte
  Case 1
     Stream01GetPosition = PosTime
End Select

End Function

Chris

  • Posts: 2132
Re: time elapsed / remaining problem
« Reply #4 on: 28 Jun '03 - 04:30 »
I see you writen you code in delphi..I show my component that i have writen myself
Here the code vor the component
-----------------------------------------------------------
Code: [Select]

unit CSTTimeDraw;

interface

uses
 Windows, Messages, SysUtils, Classes,CSTBitmapLEDDigit;

type
 TCSTTimeDraw = class(TComponent)
 private
 fSlider : TCSTBitmapSlider;
 fHour,fMin,fSec,fMsec : TCSTBitmapLEDDigit;

 /// front LEDS;
 front_Hour,front_min,front_sec,front_msec : Integer;
 back_hour , back_min,back_sec ,back_msec  : Integer;
 procedure DrawTimeFront;
  procedure DrawTimeBack;
  procedure TimeDecode(Time: Longint; var Hour, Min, Sec, MSec: Word);


   { Private-Deklarationen }
 protected
   { Protected-Deklarationen }
 public
   { Public-Deklarationen }

  procedure DrawTime (back : Boolean);
  procedure Execute;

 published
 property Slider : TCSTBitmapSlider    read fslider write fslider;
 property Hour   : TCSTBitmapLEDDigit read fHour   write fHour;
 property Min    : TCSTBitmapLEDDigit read fMin    write fMin;
 property Sec    : TCSTBitmapLEDDigit read fSec    write fSec;
 property Msec   : TCSTBitmapLEDDigit read fMsec   write fMsec;



   { Published-Deklarationen }
 end;

procedure Register;

implementation

procedure Register;
begin
 RegisterComponents('CST-Tools', [TCSTTimeDraw]);
end;
procedure TimeDecode(Time: Longint; var Hour, Min, Sec, MSec: Word);
Var
  MinCount, MSecCount: Word;

begin
  if Time > 0 then
  begin
    DivMod32(Time, 60000, MinCount, MSecCount);
    DivMod32(MinCount, 60, Hour, Min);
    DivMod32(MSecCount, 1000, Sec, MSec);
  end
  else
  begin
     Hour := 0;
     Min := 0;
     Sec := 0;
     MSec := 0;
  end;
end;procedure TCSTTimeDraw.DrawTimeFront;
Var
  nHour, nMin, nSec, nMSec: Word;
begin
   TimeDecode(fslider.Position,nHour,nMin,nSec,nMsec);
     front_Hour := nHour;
     front_min  := nMin;
     front_sec  := nsec;
     front_msec := nmsec;
end;
procedure TCSTTimeDraw.DrawTimeBack;
Var
  nHour, nMin, nSec, nMSec: Word;
begin
  Timedecode (fSlider.MaxValue - fSlider.Position,nHour,nMin,nSec,nMsec);
     back_Hour := nHour;
     back_min  := nMin;
     back_sec  := nsec;
     back_msec := nmsec;
end;
procedure TCSTTimeDraw.DrawTime (back : Boolean);
begin
 If back = false then begin
  fmsec.Value := front_msec;
  fsec.Value := front_sec;
  fmin.Value := front_min;
  fhour.Value := front_hour;
end
else
 If back = true then begin
   fmsec.Value := back_msec;
   fsec.Value := back_sec;
   fmin.Value := back_min;
   fhour.Value := back_hour;
 end;
end;
procedure TCSTTimeDraw.Execute;
begin
 DrawTimeFront;
 DrawTimeBack;
end;
end.

----------------------------------------------------------
In the Application self

Code: [Select]

procedure TForm_Raum_1.pos_timer_1Timer(Sender: TObject);
begin
 if not Seeking_1  then pos_slider_1.Position := player1.Position;
   TimeDraw_1.Execute;
   SetRichtung(TimeDraw1,Image1);
end;

procedure SetRichtung (TimeDraw:TCSTTimeDraw;Image:TLabel);
begin
If Image.Caption = 'Remained' then
TimeDraw.DrawTime(false)
else
If Image.Caption  = 'Elapsed' then
TimeDraw.DrawTime(true);
end;



Greets Chris
« Last Edit: 28 Jun '03 - 04:39 by Chris »

DanaPaul

  • Posts: 335
Re: time elapsed / remaining problem
« Reply #5 on: 28 Jun '03 - 06:03 »
Quote
that does not seem to help. infact it adds (in alot of cases) a minute to the rmin value which is no good.


Hmmm, obvious oversight :) try this...

rmin := 60 - trunc(curtime / 60);
rsec := 60 - trunc((rtime mod 60) + 0.5);

Delete variable "rtime"


breakpoint

  • Guest
Re: time elapsed / remaining problem
« Reply #6 on: 28 Jun '03 - 09:28 »
@Creadig

Thx for the code but I would not know how to convert it to use with delphi.


@Chris
Thx to you as well but it seems that your component requires additional components for it to work properly. I tried to rip out only the parts that I might need and was unsuccessful in getting it to work but thanks again anyway.


@DanaPaul
Am kinda confused about your last post
Quote

rmin := 60 - trunc(curtime / 60);
rsec := 60 - trunc((rtime mod 60) + 0.5);

Delete variable "rtime"


you say to delete the rtime variable but in your example you are still using it in the rsec expression. Not exactly sure what you mean.

I tried to run the code as it was and it gave me compiling errors so I modified it abit so it would run and it returned 60:60 for the remaining time and surely that is not right so again I am at a loss.

Again I think I should point out that sometimes the time shows up correctly and at other times it's 1 second behind where it should be so whatever the problem is I can tell you it's sparatic. (sure that narrows it down eh)

Chris

  • Posts: 2132
Re: time elapsed / remaining problem
« Reply #7 on: 28 Jun '03 - 10:21 »
Here the code for an label

Code: [Select]


unit CSTTimeDraw;

interface

uses
Windows, Messages, SysUtils, Classes;

type
TCSTTimeDraw = class(TComponent)
private
fSlider : TSlider;
s_front : string;
s_back : string;
fLabel : TLabel

/// front LEDS;

procedure DrawTimeFront;
 procedure DrawTimeBack;
function TimeToString(Time: Longint): string;


  { Private-Deklarationen }
protected
  { Protected-Deklarationen }
public
  { Public-Deklarationen }

 procedure DrawTime (back : Boolean);
 procedure Execute;

published
property Slider : TSlider read fslider write    fslider;
property Label: TLabel read fLabel write FLabel;



  { Published-Deklarationen }
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('CST-Tools', [TCSTTimeDraw]);
end;

function TimeToString(Time: Longint): string;
begin
  if Time >= 3600000 then
     Result := Format('%d:%2.2d:%2.2d.%3.3d',[Time div 3600000,
                                             (Time mod 3600000) div 60000,
                                             (Time mod 60000) div 1000,
                                              Time mod 1000])
  else
     Result := Format('%d:%2.2d.%3.3d',[Time div 60000,
                                       (Time mod 60000) div 1000,
                                        Time mod 1000]);
end;  
end;

procedure TCSTTimeDraw.DrawTimeFront;
begin
  TimetoString(fslider.position,s_front);
end;
procedure TCSTTimeDraw.DrawTimeBack;
begin
timetostring((fslider.maxvalue- fslider.position),s_back);
end;
procedure TCSTTimeDraw.DrawTime (back : Boolean);
begin
If back = false then
 fLabel.caption := s_front;
else
If back = true then
 fLabel.caption := s_back
end;
procedure TCSTTimeDraw.Execute;
begin
DrawTimeFront;
DrawTimeBack;
end;
end.



Greets Chris
« Last Edit: 28 Jun '03 - 10:57 by Chris »

Ian @ un4seen

  • Administrator
  • Posts: 25063
Re: time elapsed / remaining problem
« Reply #8 on: 28 Jun '03 - 10:33 »
It's no great mystery :)

For example...
Code: [Select]
  total time = 1:31.1 ... 1:31 (truncated)
- elapsed    = 0:10.7 ... 0:10 (truncated)
= remaining  = 1:20.4 ... 1:20 (truncated)

If you're not interest in fractions of a second, the answer is to truncate the numbers (or at least the elapsed time) before doing the subtraction...
Code: [Select]
curtime := trunc(Bass_ChannelBytes2Seconds(song, Bass_ChannelGetPosition(song)));

breakpoint

  • Guest
Re: time elapsed / remaining problem
« Reply #9 on: 28 Jun '03 - 11:33 »
thx for the code chris I am sure I will find a use for it and thx to ian as well I should have figured it would have been something simple like that.