AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Optimierung von Pixel

Ein Thema von EWeiss · begonnen am 7. Apr 2016 · letzter Beitrag vom 12. Apr 2016
Antwort Antwort
Seite 8 von 11   « Erste     678 910     Letzte »    
EWeiss
(Gast)

n/a Beiträge
 
#71

AW: Optimierung von Pixel

  Alt 9. Apr 2016, 14:49
Ich werde deine Ausführung nochmal genau durchgehen.
So das ich genau verstehe warum und wieso.. Danke!

Zitat:
Wenn man sich solche Schnitzer eingefangen hat, kann man in größeren Programmen Tage bis Wochen damit verbringen sie zu finden.
Was muss ich denn nun genau machen damit hier kein Fehler auftritt?
Den Buffer auf 256 einstellen und anschließend nur 160 Pixel daraus lesen also abhängig von der höhe der Bitmap?
Dann ist der Speicher mit 256 Bytes gefüllt verwende dann aber nur 160 davon.
Wenn es das ist was ihr meint.
Dann wird aber genau wie vorher nicht der gesamte Bereich des Spectrums gezeichnet weil das Bitmap halt kleiner ist.
Der Speicher hingegen ist dann aber korrekt gefüllt.

Zitat:
Leider hast du alle Anhänge gelöscht (wieso!?!?), so dass ich das nicht testweise bauen kann. Schade.
Kein Problem hänge es nochmal an.
Habe noch etwas geändert bzg. dem Fehler mit ScanLine prüfe jetzt auf <> NIL.
Damit bei der Rückgabe der Farben kein ZeilenFehler auftritt.

Hoffe nur du bekommst jetzt einen Channel

gruss

Geändert von EWeiss ( 9. Apr 2016 um 18:15 Uhr)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#72

AW: Optimierung von Pixel

  Alt 9. Apr 2016, 17:52
Den Buffer auf 256 einstellen und anschließend nur 160 Pixel daraus lesen also abhängig von der höhe der Bitmap?
Dann ist der Speicher mit 256 Bytes gefüllt verwende dann aber nur 160 davon. Wenn es das ist was ihr meint.
Exakt das, ja.
Zitat:
Dann wird aber genau wie vorher nicht der gesamte Bereich des Spectrums gezeichnet weil das Bitmap halt kleiner ist.
Ist ja erstmal nicht schlimm, das ist ja gewollt, wenn ich das richtig verstanden habe.
Zitat:
Der Speicher hingegen ist dann aber korrekt gefüllt.
Und das ist wichtig! Was du bisher hattest, war einer der klassischsten Bugs überhaupt, und ganz klar ein echter Fehler im Code. Solche Dinger sind keine Kleinigkeiten, weil die potenziellen Effekte von gar nichts bis Bluescreen reichen, und sowohl zeitlich als auch örtlich (lies: Codestelle) augenscheinlich völlig unabhängig von dem eigentlichen Fehler auftreten können. Richtig eklig.
Zitat:
Kein Problem hänge es nochmal an.
Danke. Leider jetzt zu spät, das Abendprogramm geht gleich los. (Informatiker mit Sozialleben, wo gibs denn sowas?) Mal schauen dass ich morgen noch Mal dran gehe. Interessant isses ja
Zitat:
Hoffe nur du bekommst jetzt einen Channel
Das war im Büro in einer VM. Ich hoffe, dass es zu Hause direkt auf dem PC besser geht. Aber leider nur Lazarus, wo es kein TBitmap.Scanline gibt. Mal gucken wie ich das deichsel.

Schönes sonniges Wochenende!
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#73

AW: Optimierung von Pixel

  Alt 9. Apr 2016, 17:59
Zitat:
Exakt das, ja.
Ok habe die Korrekturen vorgenommen.
In dem Beispiel funktioniert jetzt auch das weiterschalten der Seiten.

Zitat:
Schönes sonniges Wochenende!
Dir auch

gruss

Geändert von EWeiss (11. Jul 2019 um 16:07 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#74

AW: Optimierung von Pixel

  Alt 10. Apr 2016, 08:43
Um das mit dem Buffer nochmal zu veranschaulichen: Stell dir vor, du hast einen Kaffeeautomaten (die BASS-Funktion), der dir immer genau eine Tasse Kaffee ausspuckt, wenn du auf den Knopf drückst. Wenn du jetzt Lust auf wenig Kaffee hast und nur eine Espresso-Tasse (zu kleiner Puffer) drunterstellst, dann gibt es eine Sauerei
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#75

AW: Optimierung von Pixel

  Alt 10. Apr 2016, 12:04
Um das mit dem Buffer nochmal zu veranschaulichen: Stell dir vor, du hast einen Kaffeeautomaten (die BASS-Funktion), der dir immer genau eine Tasse Kaffee ausspuckt, wenn du auf den Knopf drückst. Wenn du jetzt Lust auf wenig Kaffee hast und nur eine Espresso-Tasse (zu kleiner Puffer) drunterstellst, dann gibt es eine Sauerei
Jo dann gibt's ärger mit der Frau

gruss
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#76

AW: Optimierung von Pixel

  Alt 10. Apr 2016, 22:32
Ich habe das Ganze mal unter Lazarus ans Laufen bekommen, und auch gefunden warum ich keinen gültigen Channel bekam: Du übergibst das Flag BASS_UNICODE ohne Wenn und Aber, aber ich habe nur Delphi 2007 im Büro. Daher war der Dateiname bei mir nicht in Unicode. Da wäre ggf. eine Fallunterscheidung nicht übel, die du zum Abspielen weiter unten sogar schon drin hast.

Die Ergebnisse sind zwischen Delphi und FPC sicherlich kaum zu vergleichen. Ich habe jetzt z.B. mit der 64Bit Variante der Bass.dll gearbeitet, weil Lazarus offenbar keinen Win32 Compiler installiert hat (und ich keine Lust hatte zu suchen wie ich das zurechtstückeln muss).
Ich habe ein fast genau 2min langes MP3 geladen, und brauchte trotz Verwendung von TCanvas.Pixels[] nur 2 Sekunden. Allerdings arbeitet TCanvas.Pixels[] in FPC auch komplett anders als unter Delphi, und Scanline gibt es erst gar nicht. Von daher praktisch keine Chance da für dich brauchbare Zeiten zu messen.

Was ich aber gemacht habe, ist zu messen wie lange die gesamte Prozedur dauerte, und wie viel davon auf das reine Malen entfielen. Bei 2sek gesamt wurden 1,25sek zum Zeichnen gebraucht. Der Rest war Bass-Daten abfragen, die Schleifen und Farbumrechnungen. (Was übrigens zumindest unter Lazarus sehr viel gefressen hat, war das immer wieder Abfragen von Radiobutton1.Checked!)

Hier mal, wie du ähnlich messen kannst. (Erheblich präziser als mit GetTickCount!) Die entsprechenden Zeilen habe ich mal via Kommentar markiert, damit sie besser auffallen.
Delphi-Quellcode:
procedure TForm1.SampleAudioStream(FileName: String);
Const
  BUFFER_SIZE = 256;
var
  Buffer: array of Single;
  Info: BASS_CHANNELINFO;
  i: integer;
  Progress: integer;
  H, S, L: double;
  Value: double;
  StreamLength: Int64;
  ScanLines: TArray<PRGBTriple>;
  P: PRGBTriple;
  R, G, B: Byte;
  pcFrequency: Int64; // <--------------------- Zeitmessung
  timeAll0, timeAll1, timeAll: Int64; // <----- Zeitmessung
  timeDraw0, timeDraw1, timeDraw: Int64; // <-- Zeitmessung
begin
  Channel := BASS_MusicLoad(false, PChar(FileName), 0, 0,
    BASS_MUSIC_DECODE OR BASS_MUSIC_STOPBACK OR BASS_MUSIC_CALCLEN {$IFDEF UNICODE} OR BASS_UNICODE {$ENDIF} OR BASS_SAMPLE_FLOAT, 0);
  if Channel = 0 then
  begin
    Channel := BASS_StreamCreateFile(false, PChar(FileName), 0, 0,
      BASS_STREAM_DECODE OR BASS_MP3_SETPOS OR BASS_SAMPLE_FLOAT {$IFDEF UNICODE} OR BASS_UNICODE {$ENDIF});
  end;

  if Channel = 0 then
  begin
    Exit;
  end;

  Form2.ProgressBar1.position := 0;
  Form2.Show;

  BASS_ChannelGetInfo(Channel, Info);
  StreamLength := BASS_ChannelGetLength(Channel, BASS_POS_BYTE);
  Bitmap.Height := 256;
  Bitmap.Width := (StreamLength div 512 div 4) div Info.chans;

  PB.Width := Bitmap.Width;
  PB.Height := Bitmap.Height;
  PB.Parent.DoubleBuffered := true;

  S := 0.9;

  SetLength(Buffer, BUFFER_SIZE);
  ColumnCounter := 0;

  QueryPerformanceFrequency(pcFrequency); // <------ Zeitmessung
  QueryPerformanceCounter(timeAll0); // <----------- Zeitmessung
  timeDraw := 0; // <------------------------------- Zeitmessung

  if RadioButton1.Checked then
  begin
    SetLength(ScanLines, Bitmap.Height);
    for i := 0 to Length(ScanLines) - 1 do
      ScanLines[i] := Bitmap.Scanline[i];
  end;

  while BASS_ChannelIsActive(Channel) <> BASS_ACTIVE_STOPPED do
  begin
    BASS_ChannelGetData(Channel, Pointer(Buffer), BASS_DATA_FFT512);
    for i := 0 to BUFFER_SIZE - 1 do
    begin
      Value := SQRT(SQRT(Buffer[i]));
      H := 0 + Value / 1.5;
      L := Value;

      if RadioButton1.Checked then
      begin
        QueryPerformanceCounter(timeDraw0); // <-------------------- Zeitmessung
        P := ScanLines[BUFFER_SIZE - i];
        if Assigned(P) then
          HSLtoRGB(H, S, L, P^.rgbtRed, P^.rgbtGreen, P^.rgbtBlue);
        QueryPerformanceCounter(timeDraw1); // <------------------- Zeitmessung
        timeDraw := timeDraw + (timeDraw1-timeDraw0); // <--------- Zeitmessung
      end
      else
      begin
        QueryPerformanceCounter(timeDraw0); // <------------------- Zeitmessung
        HSLtoRGB(H, S, L, R, G, B);
        Bitmap.Canvas.Pixels[ColumnCounter, BUFFER_SIZE - i] := RGB(R, G, B)
        QueryPerformanceCounter(timeDraw1); // <------------------- Zeitmessung
        timeDraw := timeDraw + (timeDraw1-timeDraw0); // <--------- Zeitmessung
      end;
    end;

    if RadioButton1.Checked then
    begin
      for i := 0 to Length(ScanLines) - 1 do
        Inc(ScanLines[i]);
    end
    else
      Inc(ColumnCounter);

    Progress := trunc(100 * (Bass_ChannelGetPosition(Channel, BASS_POS_BYTE) / BASS_ChannelGetLength
          (Channel, BASS_POS_BYTE)));

    if (Form2.ProgressBar1.position <> Progress) then
    begin
      Form2.ProgressBar1.position := Progress;
      PB.Refresh;
    end;
  end;

  QueryPerformanceCounter(timeAll1); // <-------------------------------------------------- Zeitmessung
  timeAll := timeAll1-timeAll0; // <------------------------------------------------------- Zeitmessung

  Label1.Caption := 'Gesamtzeit: '+FloatToStrF(timeAll/pcFrequency, ffFixed, 8, 3); // <--- Zeitmessung
  Label2.Caption := 'Draw-Zeit: '+FloatToStrF(timeDraw/pcFrequency, ffFixed, 8, 3); // <--- Zeitmessung

  Form2.Hide;
  Bass_StreamFree(Channel);

  Channel := BASS_StreamCreateFile(false, PChar(FileName), 0, 0, 0 {$IFDEF UNICODE} or BASS_UNICODE {$ENDIF});
  if Channel = 0 then
  begin
    Channel := BASS_MusicLoad(false, PChar(FileName), 0, 0,
      BASS_MUSIC_RAMPS or BASS_MUSIC_POSRESET or BASS_MUSIC_PRESCAN {$IFDEF UNICODE} or BASS_UNICODE {$ENDIF}, 0);
    if (Channel = 0) then
      Exit;
  end;

  DestBitmap.Width := PB.Width;
  DestBitmap.Height := PB.Height;
  BitBlt(DestBitmap.Canvas.handle, 0, 0, PB.Width, PB.Height, Bitmap.Canvas.handle, 0, 0, SrcCopy);
  bpp := BASS_ChannelGetLength(Channel, BASS_POS_BYTE) div PB.Width;
  BASS_ChannelSetSync(Channel, BASS_SYNC_END or BASS_SYNC_MIXTIME, 0, LoopSyncProc, nil);
  BASS_ChannelPlay(Channel, false);
  Timer1.Enabled := true;
end;
Die Zeit wird hierbei in Sekunden angegeben. (Deshalb die 3 Nachkommastellen um die Anzeige bis auf Millisekunden genau zu haben.)
Das könnte gut dabei helfen zu ermitteln, ob das eigentliche Zeichnen wirklich der Flaschenhals ist, und ob es sich lohnt in dessen Optimierung überhaupt noch viel Zeit zu stecken. (Ich kann mir gut vorstellen, dass das Berechnen des Fortschritts wegen der vielen Calls zur Bass.dll auch ganz schön zu Buche schlägt. Tut's zumindest unter Lazarus nicht. Der Unterschied ist im normalen Schwankungsbereich.)
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)

Geändert von Medium (10. Apr 2016 um 22:38 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#77

AW: Optimierung von Pixel

  Alt 11. Apr 2016, 00:59
(Ich kann mir gut vorstellen, dass das Berechnen des Fortschritts wegen der vielen Calls zur Bass.dll auch ganz schön zu Buche schlägt. Tut's zumindest unter Lazarus nicht. Der Unterschied ist im normalen Schwankungsbereich.)
Ganz normale Calls sind in der Regel zu vernachlässigen. Hat man natürlich bisschen Overhead durch das Pushen der Rücksprungadresse und je nach Aufrufkonvention der Parameter, aber Performance-kritisch wird das nicht.
Frequente Aufrufe bestimmter Windows APIs können allerdings durch den Kontext-Switch in Kernel-Mode und wieder zurück (SYSENTER) extrem teuer sein.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#78

AW: Optimierung von Pixel

  Alt 11. Apr 2016, 06:16
Zitat:
Du übergibst das Flag BASS_UNICODE ohne Wenn und Aber, aber ich habe nur Delphi 2007 im Büro. Daher war der Dateiname bei mir nicht in Unicode. Da wäre ggf. eine Fallunterscheidung nicht übel, die du zum Abspielen weiter unten sogar schon drin hast.
Oh.. ja habe ich im ersten BASS_StreamCreateFile Call vergessen.
Man schaut immer zu sehr auf seine eigene Developer Umgebung.

Zitat:
Von daher praktisch keine Chance da für dich brauchbare Zeiten zu messen.
Würde auch nicht viel sinn machen mit unterschiedlichen Sprachen.

Zitat:
Was übrigens zumindest unter Lazarus sehr viel gefressen hat, war das immer wieder Abfragen von Radiobutton1.Checked
Sollte das kleinste Problem sein
Werde da mal eine Variable für anlegen um den zugriff auf das Control zu verhindern.

QueryPerformanceCounter ist natürlich etwas genauer als GeTickCount.. wird umgebaut.

Danke für das Testen wenn auch unter Lazarus.

Anbei vergleich von Pixel/ScanLine als Bilder und neue Version mit deiner Zeitmessung incl. Variable anstelle von Radiobutton1.Checked.
BASS_UNICODE ist abgesichert..

gruss

Geändert von EWeiss (11. Jul 2019 um 16:07 Uhr)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#79

AW: Optimierung von Pixel

  Alt 11. Apr 2016, 08:22
Man schaut immer zu sehr auf seine eigene Developer Umgebung.
Kenn ich was von *schäm*

Zitat:
Würde auch nicht viel sinn machen mit unterschiedlichen Sprachen.
Hab jetzt leider einen Aussentermin, aber heute Nachmittag mal schauen wie es hier im Büro aussieht. Jetzt weiss ich ja wie ich an einen gültigen Kanal komme

Zitat:
QueryPerformanceCounter ist natürlich etwas genauer als GeTickCount.. wird umgebaut.
Ich finde an dem so praktisch, dass es damit tatsächlich aussagekräftige Ergebnisse gibt, selbst wenn man nur eine kleine Zeile misst. Ohne das wäre das Aufsummieren der Zeichenaufrufe kaum drin. Hab mir den mittlerweile angewöhnt.

Zitat:
Anbei vergleich von Pixel/ScanLine als Bilder und neue Version mit deiner Zeitmessung incl. Variable anstelle von Radiobutton1.Checked.
Das sind SEHR ähnliche Werte wie bei mir (Bei Nutzung von Pixel[])
300ms zum Zeichnen sind schon gar nicht so übel. Vor allem weil es ja nur ca. 30% der Gesamtzeit ausmacht. So ganz so viel ist da dann gar nicht mehr herauszuholen.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#80

AW: Optimierung von Pixel

  Alt 11. Apr 2016, 08:29
Zitat:
Das sind SEHR ähnliche Werte wie bei mir (Bei Nutzung von Pixel[])
300ms zum Zeichnen sind schon gar nicht so übel. Vor allem weil es ja nur ca. 30% der Gesamtzeit ausmacht. So ganz so viel ist da dann gar nicht mehr herauszuholen.
Denke ich auch..
Die Ergebnisse sind schon mal nicht schlecht
Danke für deine Zeit die du geopfert hast.
Vielleicht ist es ja auch etwas für andere die so was schon immer mal realisieren wollten.

gruss
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 8 von 11   « Erste     678 910     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:59 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