Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Problem Trackbar bass.dll (https://www.delphipraxis.net/119581-problem-trackbar-bass-dll.html)

Ducksoul 28. Aug 2008 16:03


Problem Trackbar bass.dll
 
Da meine alte Trackbar nicht flüssig gelaufen ist, bzw. es Störgeräusche gab wenn ich die Frequenz des Timers erhöht habe, habe ich nun den Code angepasst.
Dabei habe ich mich auf den Code von Gausis mp3-Player gestützt (http://www.gausi.de/delphi/memp/5.php).

Das Problem ist jetzt, dass wenn ich unten angegebenen Code nutze, es einige Probleme gibt.

Der Code für den Timer verursacht, dass der Stream immer von vorne beginnt wenn ich pausiere.
Der Code beim Changen der Trackbar verursacht ebenfalls, dass immer von vorne abgespielt wird und nicht von der Position die gewollt ist.
Wenn ich beide Codes gleichzeitig anhabe, dann beginnt der Track immer wieder alle 100ms in einer Endlosschleife.

Woran liegt das?

Delphi-Quellcode:
  (* Update der Progressbar *)
  procedure TRecordForm.RecordTimerTimer(Sender: TObject);
    var t: integer;
    begin
      ProgressBar.Position := Round((BASS_ChannelGetPosition(chan, BASS_POS_BYTE) / BASS_ChannelGetLength(chan, BASS_POS_BYTE)) * 100);
    end; // procedure RecordTimerTimer

  (* Position via ProgressBar ändern *)
  procedure TRecordForm.ProgressBarChange(Sender: TObject);
  begin
    if BASS_ChannelIsActive(chan) = BASS_ACTIVE_Playing
      then begin
        BASS_ChannelPause(chan);
        BASS_ChannelSetPosition(chan, Round(ProgressBar.Position / 100), BASS_POS_BYTE);
        BASS_ChannelPlay(chan, False);
      end
    else
      BASS_ChannelSetPosition(chan, Round(ProgressBar.Position / 100) * BASS_ChannelGetLength(chan, BASS_POS_BYTE), BASS_POS_BYTE);
  end; // procedure ProgressBarChange

  (* PlayButtonClick || Wiedergabe der Aufnahme *)
  procedure TRecordForm.PlayExecute(Sender: TObject);
    begin
          case BASS_ChannelIsActive(chan) of
            BASS_Active_Stopped:
              begin
                BASS_ChannelPlay(chan, True);
                EndSync := Bass_ChannelSetSync(chan, Bass_SYNC_END, 0, @SyncProc, nil);
                ToggleStatus(1);
              end;
            BASS_Active_Playing:
              begin
                BASS_ChannelPause(chan);
                ToggleStatus(2);
              end;
            BASS_Active_Paused:
              begin
                BASS_ChannelPlay(chan, False);
                ToggleStatus(1);
              end;
          end; // case
    end; //  procedure PlayExecute

Danke schonmal im Voraus,
Duck

himitsu 28. Aug 2008 16:23

Re: Problem Trackbar bass.dll
 
Erstmal das Problem mit dem Timer:

Wenn über den die Position geändert wird, ruft dieses wiederum OnChange auf, was also die Position im BASS ändert und bei gerundeten Werten, sowie einer weiterlaufenden Zeit im BASS, zu netten nebenwirkungen führt.

Du mußt einfach nur irgendwie verhinden, daß OnChange nicht ausgeführt wird, wenn dieses vom Programm verursacht wurde.
Delphi-Quellcode:
(* Update der Progressbar *)
procedure TRecordForm.RecordTimerTimer(Sender: TObject);
  // var t: integer;  = wo wird T verwendet?
  begin
    ProgressBar.OnChange := nil;
    ProgressBar.Position := Round((BASS_ChannelGetPosition(chan, BASS_POS_BYTE)
      / BASS_ChannelGetLength(chan, BASS_POS_BYTE)) * 100);
    ProgressBar.OnChange := ProgressBarChange;
  end; // procedure RecordTimerTimer
oder
Delphi-Quellcode:
(* Update der Progressbar *)
// irgendwo irgendeine Variable definieren
var OnChangeGesperrt: Boolean;

procedure TRecordForm.RecordTimerTimer(Sender: TObject);
  // var t: integer;  = wo wird T verwendet?
  begin
    OnChangeGesperrt := true;
    ProgressBar.Position := BASS_ChannelGetPosition(chan, BASS_POS_BYTE) * 100
      div BASS_ChannelGetLength(chan, BASS_POS_BYTE));
    OnChangeGesperrt := false;
  end; // procedure RecordTimerTimer

(* Position via ProgressBar ändern *)
procedure TRecordForm.ProgressBarChange(Sender: TObject);
begin
  if OnChangeGesperrt then Exit;
  ...
[add]
mal 'ne Frage: Warum wird in .RecordTimerTimer die Position für BASS_ChannelGetPosition anders berechnet (bei wenn Pause und wenn nicht)


[add2]
Vorschlag:
Delphi-Quellcode:
(* Position via ProgressBar ändern *)
procedure TRecordForm.ProgressBarChange(Sender: TObject);
var B: Boolean;
begin
  B := BASS_ChannelIsActive(chan) = BASS_ACTIVE_Playing;
  if B then BASS_ChannelPause(chan);
  BASS_ChannelSetPosition(chan, ProgressBar.Position
    * BASS_ChannelGetLength(chan, BASS_POS_BYTE) div 100, BASS_POS_BYTE);
  if B then BASS_ChannelPlay(chan, False);
end; // procedure ProgressBarChange
PS: das langsame Round und die zugehörigen Fließkommarechenoperationen kannst'e getrost weglassen, wenn du mit den rechenoperationen bei Intergerrechenoperationen bleibst :zwinker:

Ducksoul 28. Aug 2008 17:13

Re: Problem Trackbar bass.dll
 
Hi, danke für deine Antwort. Das Problem mit dem Timer hat sich dadurch schonmal erledigt. Einfach aber funktioniert :)

Beim Verstehen des Codes habe ich allerdings noch ein kleines Problem (Funktionieren tut es, aber ich komm mit dem Verständnis nicht ganz hinterher).


Delphi-Quellcode:
  B := BASS_ChannelIsActive(chan) = BASS_ACTIVE_Playing;
  if B then BASS_ChannelPause(chan);
  BASS_ChannelSetPosition(chan, ProgressBar.Position
    * BASS_ChannelGetLength(chan, BASS_POS_BYTE) div 100, BASS_POS_BYTE);
  if B then BASS_ChannelPlay(chan, False);
Angenommen ändere die Posi der Trackbar, wenn der Stream pausiert ist, dann macht er bei der ersten if-Schleife nichts, führt den Befehl aus und bei der 2. if-Schleife wird auch nichts gemacht. Fertig. Soweit hab isses mir klar.
Wenn allerdings die Posi geändert wird, solange der Stream läuft, dann ergibt die erste if true und der Chan wird pausiert. Danach wird die Position gesetzt. Aber müsste dann nicht die 2. if-Schleife ein False ergeben? Denn dann sollte BASS_ChannelIsActive(chan) ja den Wert BASS_ACTIVE_Paused zurückgeben und somit B false ergeben und die Wiedergabe des Streams daher nicht gestartet werden. Allerdings macht er das trotzem? Wo is mein Verständnisfehler?

Viele Grüße,
Duck

[PS] Und vielen Dank nochmal :)

himitsu 28. Aug 2008 18:35

Re: Problem Trackbar bass.dll
 
Das B ist eine Variable, welche vor Aufurf der beiden IFs mit einem Wert belegt wird und dieser Wert wird sonst nirgends geändert, also bleibt er auch gleich.
es wird also als erstes der Vergleich mit BASS_ACTIVE_Playing ausgefühert und dessen Ergebnis später nur noch von B abgefragt.

Ducksoul 28. Aug 2008 18:45

Re: Problem Trackbar bass.dll
 
Ah ja klar. Danke für die Antwort :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:36 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz