1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. alpines

Beiträge von alpines

  • FileInstall Funktion funktioniert nicht (immer) auf Windows 7 32 Bit?

    • alpines
    • 6. Februar 2018 um 16:03
    Zitat von Bitnugger

    Doch genauso wie in der resources.au3 funktioniert auch hier das Speichern von Bitmaps nicht... und bin noch nicht dahinter gekommen, woran es liegt.

    Vielleicht bringt der FileHeader der Bitmap das Ausleseverfahren durcheinander?

  • ASM-Code optimierbar und kann ich Dll-Funktionen aus dem ASM-Code aufrufen?

    • alpines
    • 5. Februar 2018 um 08:21

    Ich sollte noch dazu sagen, dass ich ursprünglich x0.7 der Höhe genommen hatte (weil ich noch ID3-Tags anzeigen wollte) und das Testen ohne x0.7 gemacht habe.

    Wenn wir das noch in Betracht ziehen sind wir bei knapp 1000 Zyklen pro Sekunde!

    Falls hier jemand das gerne mal ausprobieren möchte (AutoIt-Berechnung mit ASM-Code zu substituieren) soll er das auf jeden Fall machen.

    Wenn man ständig auf seinen x86-Befehlssatzspicker schaut, ist das gar nicht mal so schwierig. Zumindest habe ich kaum mehr Fehler gehabt als normal mit AutoIt zu scripten.

    Und mit ein paar Bytes Code kann man seinem Script einen unfassbaren Boost verpassen!

  • ASM-Code optimierbar und kann ich Dll-Funktionen aus dem ASM-Code aufrufen?

    • alpines
    • 5. Februar 2018 um 00:40
    Zitat von Andy

    Das wären dann ca. 300-400 Zyklen

    300-400 Zyklen? Nix da! Ich kriege 800 Zyklen pro Sekunde jetzt raus!! :D ASSEMBLER ROCKT!!!

    Der ASM-Code berechnet die Amplituden und die Koordinaten der Frequenzen und fügt diese mit GdipAddPathLine2 hinzu.

    In der AutoIt-Hauptschleife wird nur noch der Gdi+Buffer gecleared, der fftBuffer gelesen, der ASM-Code gecalled und anschließend der Pfad und der Double-Buffer gezeichnet.

    Kein unnötiges Hin und Her mit DllStructs sondern alles zeitkritische in ASM!

    Das tolle obendrein ist ja, dass ich 100 Zwischenfrequenzen (_SubdivideFrequencies) statt 10 nehmen kann

    und die Performance bricht bei weitem nicht so heftig zusammen wie vorher.

    Man kann sicherlich noch bisschen was rauskitzeln aber das ist schon mal ne Wucht! Kein Vergleich zu reinem AutoIt!

    Dateien

    package optimiert.zip 335,72 kB – 396 Downloads
  • ASM-Code optimierbar und kann ich Dll-Funktionen aus dem ASM-Code aufrufen?

    • alpines
    • 4. Februar 2018 um 21:17
    Zitat von Andy

    Beim Aufrufen einer jedwegen Funktion steht die Rücksprungadresse immer auf [esp+0]

    Ich dachte es mir fast schon! Danke für die Bestätigung! :)

    Wenn ich nach unten hin schiebe werden diese dann auch anschließend überschrieben, kein Wunder, dass die Rücksprungsadresse dann nicht mehr stimmt.

    Ich werde mich mal jetzt dranmachen die Berechnung der Punkte und das Hinzufügen mittels _GDIPlus_PathAddLine2 in ASM zu packen und berichte dann wieder.

  • ASM-Code optimierbar und kann ich Dll-Funktionen aus dem ASM-Code aufrufen?

    • alpines
    • 4. Februar 2018 um 20:35

    Ich hab mir mal aus der GDIPLus.au3 angeguckt in welchem Format das ganze sein muss und habe gesehen, dass dort einfach nur ein DllStruct mit floats erstellt wird.
    Das wollte ich jetzt auch machen und habe das ganze mehr oder weniger übersetzt und versuche es in ASM zu callen.

    Den Pointer zur Funktion, das Handle des Pfads, den Pointer zur Struct und die Anzahl der Punkte übergebe ich aber es crasht leider:

    Die Funktion wird auf jeden Fall ausgeführt, da der Stack aufgeräumt wird aber das Skript crasht anschließend.

    EAX wird auch auf 0 gesetzt. Das ist der GdiStatus 0 = OK.

    Wenn ich das ganze so wie du erstmal in die Register schiebe und dann neu auf den Stack pushe dann klappt das ganze (2. Script) aber wenn ich alles schon vorher richtig auf dem Stack platziere und dann nur den Call ausführe klappt das komischerweise nicht. Wieso?

    AutoIt
    #include <WinAPI.au3>
    #include <Array.au3>
    #include <GDIPlus.au3>
    #include <assembleit2_64.au3>
    
    #cs _addToPath
        use32
    
        start:
            add esp, 4
            pop eax
            _ASMDBG_()
            call eax
            _ASMDBG_()
            sub esp, 4
    
            ret
    
    #ce
    
    _GDIPlus_Startup()
    $hKERNEL32 = DllOpen("kernel32.dll")
    ;~ $hGDIPLUS = dllopen("gdiplus.dll")
    
    $handle= _WinAPI_GetModuleHandle("gdiplus.dll")
    
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $handle = ' & $handle & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $pointer= DllCall($hKERNEL32, "ptr", "GetProcAddress", "ptr", $handle, "str", "GdipAddPathLine2")
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $pointer[0] = ' & $pointer[0] & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    
    $hGUI = GUICreate("")
    GUISetState()
    
    $tPoints = DllStructCreate("float [4]")
    DllStructSetData($tPoints, 1, 10.0, 1)
    DllStructSetData($tPoints, 1, 10.0, 2)
    DllStructSetData($tPoints, 1, 150.0, 3)
    DllStructSetData($tPoints, 1, 150.0, 4)
    
    $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    $hPath = _GDIPlus_PathCreate()
    
    ;~ _GDIPlus_PathAddLine($hPath, 10, 10, 150, 150)
    
    $ret = _AssembleIt2("int", "_addToPath", "ptr", $pointer[0], "ptr", $hPath, "ptr", DllStructGetPtr($tPoints), "int", 2)
    ConsoleWrite($ret & @CRLF)
    
    _GDIPlus_GraphicsDrawPath($hGraphics, $hPath)
    
    While GUIGetMsg() <> -3
    WEnd
    Alles anzeigen
    AutoIt
    #include <WinAPI.au3>
    #include <Array.au3>
    #include <GDIPlus.au3>
    #include <assembleit2_64.au3>
    
    #cs _addToPath
        use32
    
        start:
            mov eax, [esp+8]
            mov ebx, [esp+12]
            mov ecx, [esp+16]
            mov esi, [esp+4]
    _ASMDBG_()
            push ecx
            push ebx
            push eax
    _ASMDBG_()
    
            call esi
    _ASMDBG_()
            ret
    
    #ce
    
    _GDIPlus_Startup()
    $hKERNEL32 = DllOpen("kernel32.dll")
    ;~ $hGDIPLUS = dllopen("gdiplus.dll")
    
    $handle= _WinAPI_GetModuleHandle("gdiplus.dll")
    
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $handle = ' & $handle & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $pointer= DllCall($hKERNEL32, "ptr", "GetProcAddress", "ptr", $handle, "str", "GdipAddPathLine2")
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $pointer[0] = ' & $pointer[0] & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    
    $hGUI = GUICreate("")
    GUISetState()
    
    $tPoints = DllStructCreate("float [4]")
    DllStructSetData($tPoints, 1, 10.0, 1)
    DllStructSetData($tPoints, 1, 10.0, 2)
    DllStructSetData($tPoints, 1, 150.0, 3)
    DllStructSetData($tPoints, 1, 150.0, 4)
    
    $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    $hPath = _GDIPlus_PathCreate()
    
    ;~ _GDIPlus_PathAddLine($hPath, 10, 10, 150, 150)
    ;~ _GDIPlus_PathAddLine($hPath, 150, 150, 150, 150)
    
    $ret = _AssembleIt2("uint", "_addToPath", "ptr", $pointer[0], "hwnd", $hPath, "struct*", DllStructGetPtr($tPoints), "uint", 2)
    ;~ ConsoleWrite($ret & @CRLF)
    
    _GDIPlus_GraphicsDrawPath($hGraphics, $hPath)
    
    While GUIGetMsg() <> -3
    WEnd
    Alles anzeigen
  • ASM-Code optimierbar und kann ich Dll-Funktionen aus dem ASM-Code aufrufen?

    • alpines
    • 4. Februar 2018 um 13:40

    Ich saß gestern den gesamten Abend dran endlich meine Berechnung in ASM zu machen statt purem AutoIt und es hat sich rausgestellt,

    dass meine Implementation gerade mal einen Vorteil von x1.28 bringt.

    Natürlich bin ich kein ASM-Profi und der Code ist sicherlich noch weiter optimierbar, also tobt euch mal bitte aus und hilft mir, den Code zu optimieren! :)

    Ich habe keine Funktion zum Berechnen der dritten Wurzel gefunden, also habe ich mir eine Approximation geschrieben.

    Idee der Approximation

    Approximation von einem Dezimalbruch N

    durch Addition von 1/(2^x), x in Natürlichen Zahlen

    Im x86-Befehlssatz habe ich zum Potenzieren keine wirklichen Funktionen gefunden bis auf F2XM1.

    F2XM1 berechnet (2^x)-1 und da ich x^(1/3) rechnen musste bietet sich da die Umrechnungsformel x^y = 2^(y * log2(x)) an,

    allerdings darf beim F2XM1 Befehl der Exponent x nur zwischen -1.0 und +1.0 liegen.

    Damit konnte ich leider nicht den gesamten Wertebereich von 0.0 bis 1.0 hoch 1/3 abdecken -> 2^(1/3 * log2(0.0 bis 1.0)) da bei einem x von 0.125 (wird zu -1) und 1.0 (wird zu 0) abdecken.

    Das reichte mir leider immer noch nicht, da ich gerne eine Abdeckung von 0.0 (wird zu -unendlich) bis 1.0 wollte.

    Dann kam mir die Idee, einfach den Exponenten mittels der Wurzelfunktion zu approximieren.

    Es gibt im x86-Befehlssatz die Funktion FSQRT und diese berechnet die Quadratwurzel von ST(0) (oberster Wert auf dem FPU-Stack).

    Die Potenzgesetze erlauben es einem den Exponent zu addieren, wenn man Potenzen gleicher Basen multiplziert.

    Beispiel: 2^(1/2) * 2^(1/4) = 2^(1/2 + 1/4) = 2^(3/4)

    Jetzt kann man sich immer näher an den gewünschten Wert mittels Quadratwurzeln rantasten:

    Beispiel: 1/6 = 0.166666666

    Approximationsanfang = 0

    1/2^0 = 1/1 = 1 1 + Approximation <= 1/6 ? Nein!

    1/2^1 = 1/2 = 0.5 0.5 + Approximation <= 1/6 ? Nein!

    1/2^2 = 1/4 = 0.25 0.25 + Approximation <= 1/6 ? Nein!

    1/2^3 = 1/8 = 0.125 0.125 + Approximation <= 1/6 ? Ja! 0.125 + 0 = 0.0125 => Neue Approximation = 0.125

    1/2^4 = 1/16 = 0.0625 0.0625 + Approximation <= 1/6 ? Nein!

    1/2^5 = 1/32 = 0.03125 0.03125 + Approximation <= 1/6 ? Ja! 0.03125 + 0.125 = 0.15625 => Neue Approximation = 0.15625

    1/2^6 = 1/64 = 0.015625 0.015625 + Approximation <= 1/6 ? Nein!

    1/2^7 = 1/128 = 0.0078125 0.0078125 + Approximation <= 1/6 ? Ja! 0.15625 + 0.0078125 = 0.1640625 => Neue Approximation = 0.1640625

    Wenn wir nun 0.1640625 als Approximation nutzen wollen müssen wir lediglich folgende Rechnung durchführen:

    x^(1/8) * x^(1/32) * x^(1/128)

    Als ASM-Code ungefähr so zu implementieren:

    x -> ST0 | ST0 = x

    SQRT(ST0) -> ST0 | ST0 = x^(1/2)

    SQRT(ST0) -> ST0 | ST0 = (x^(1/2))^(1/2) = x^((1/2) * (1/2)) = x^(1/4)

    SQRT(ST0) -> ST0 | ST0 = x^(1/8)

    Wir haben nun einen Wert den wir für die Approximation brauchen also kopieren wir ST0 nach ST1

    FST(ST1) | ST0 = ST0, ST1 = ST0

    SQRT(ST0) -> ST0 | ST0 = x^(1/16)

    SQRT(ST0) -> ST0 | ST0 = x^(1/32)

    Neuer benötigter Wert!

    FST(ST2) | ST0 = x^(1/32), ST1 = x^(1/8)

    SQRT(ST0) -> ST0 | ST0 = x^(1/64)

    SQRT(ST0) -> ST0 | ST0 = x^(1/128)

    Neuer benötigter Wert steht in ST0.

    Wir haben die Approximatino nun ausgerechnet und müssen nur noch die Ergebnisse multiplizieren:

    FMULP | ST0 = x^(1/128) * x^(1/32), ST1 = x^(1/8) FMULP popt nämlich das Register nach der Multiplikation

    FMULP | ST0 = x^(1/128) * x^(1/32) * x^(1/8)

    Fertig gerechnet, das Ergebnis steht in ST0!

    Man kann das ganze natürlich in ASM so programmieren, dann man beliebig nah an die Approximation kommt (wie das AutoIt-Äquivalent unten)

    aber in meinem Code haben vier Faktoren als Genauigkeit ausgereicht also habe ich es hardgecodet und nicht dymanisch.

    Momentan übergebe ich fast alle Daten mittels DllStructs an den ASM-Code und lese diese auch so wieder aus (DllStructGetData).

    Gibt es da eine schnellere Möglichkeit als jeden Index einzeln aus dem Struct zu lesen?

    Die "Zyklen pro Sekunde"-Messung schwankt sehr stark je nach Bildschirmauflösung und Visualizergröße.

    Das Script liest aus dem fftBuffer aus der aktuellen .mp3-Datei und berechnet einen Visualizer welcher mittels GDI+ angezeigt wird.

    Das Script zieht bei mir rund 15-20% CPU-Last (Intel Core i7 4790) und berechnet 260 Zyklen die Sekunde.

    Am Ende soll ein Sleep in die Schleife eingebaut werden, damit nur noch 40-50 Zyklen pro Sekunde berechnet werden (sieht immer noch flüssig aus) und die CPU-Last dann auf <1% sinkt.

    Das klappt auch bei mir schon fast mit einem Sleep(15) (42-44 Zyklen): CPU-Last: ~2% (mit anderen Prozessen im Hintergrund die nichts berechnen).

    Dann wäre noch die Frage:

    Ist es möglich die _GDIPlus_PathAddLine2 aus dem ASM-Code aufzurufen? Dann könnte ich nämlich die gesamte Berechnung der Punkte auf den ASM-Code auslagern und hätte dann nochmal einen Geschwindigkeitsboost! Wäre nett, wenn mir jemand zeigen könnte (wenn es möglich ist) wie es geht, die Implementierung würde ich gerne selber ausprobieren!!

    Angehangen ist AssembleIt2_64, Approximation.au3, BASS.au3, BASSconstants.au3, bass.dll, visualizer.au3

    Tobt euch aus!

    Dateien

    package.zip 336,99 kB – 425 Downloads
  • Diskussion zum Thema GOTO in der Shoutbox - Zusammenfassung

    • alpines
    • 3. Februar 2018 um 13:20
    Zitat von Andy

    Damals hatte man noch irre Angst vor Headcrashes der Festplatte, ich hab also den Rechner gekauft und einen Kumpel gebeten mein Auto (Käfer BJ1965) zu fahren von Wiesbaden nach Mainz, ich auf dem Rücksitz und den Rechner freischwebend in den Händen gehalten um ja die kleinste Erschütterung abzufangen.

    :rofl:

  • ja woher kommen sie denn ??? ...die Parameter für _crypt_DecryptData?

    • alpines
    • 2. Februar 2018 um 19:48

    Mit dem Release der 3.3.14.3 wurde auch endlich eine Tabelle in die Hilfe mitaufgenommen. Siehe hier.

  • Diskussion zum Thema GOTO in der Shoutbox - Zusammenfassung

    • alpines
    • 2. Februar 2018 um 18:31
    Zitat von Peter S. Taler

    Zur GOTO Diskussion fällt mir noch ein - gab es nicht sogar programierbare Taschenrechner mit GOTO Befelssatz?

    Diese haben meistens eine Implementation eines Akzentes von BASIC. Mein alter Schultaschenrechner (TI-84+) unterstützt Goto und Labels.

  • Jüngste Datei löschen

    • alpines
    • 2. Februar 2018 um 13:12

    Wenn du den Pfad anpasst wird das aber nicht mehr funktionieren.

  • Jüngste Datei löschen

    • alpines
    • 2. Februar 2018 um 12:42
    Zitat von Musashi

    Und falls man doch das Bedürfnis verspürt es mit Stringoperationen selbst zu machen, geht z.B. auch

    Zitat von Musashi

    Das wäre aber nun wirklich mal eine einfache Aufgabe für Dich

    :(

  • Diskussion zum Thema GOTO in der Shoutbox - Zusammenfassung

    • alpines
    • 2. Februar 2018 um 11:45
    Zitat von chesstiger

    Func drawRedRect($hGfx)

    Local $hBrush

    $hBrush = _GDIPlus_BrushCreate(0xffff0000)

    If $hBrush = Null Then Goto CleanUp

    _GDIPlus_GraphicsFillRect($hGfx, 0, 0, 100, 100, $hBrush)


    CleanUp:


    _GDIPlus_BrushDispose($hBrush)

    Return


    EndFunc

    Alles anzeigen

    Stehst du heute wieder auf dem Schlauch oder übersehe ich da etwas? Wenn $hBrush = Null ist, dann existiert das Objekt doch offenbar nicht und muss nicht extra disposed werden.

  • Text in iFrame schreiben

    • alpines
    • 2. Februar 2018 um 11:44

    Alle Globalen-Variablendefinitionen sollten auf jeden Fall aus den Funktionen raus, das ist sehr -- wirklich -- sehr schlechter Stil und führt nur zu Unmengen an Warnungen.

    Die GUIs solltest du ebenfalls überarbeiten, denn du rufst sie rekursiv auf. Das bedeutet, dass du von GUI1 zu GUI2 springst und dann von GUI2 GUI1 neu erstellst.

    Den Befehl Call solltest du komplett aus deinem Code streichen, der ist unnötig. Rufe deine Funktionen einfach direkt auf wie du MsgBoxen z.B. aufrufst.

  • Text in iFrame schreiben

    • alpines
    • 2. Februar 2018 um 11:35

    Poste ihn doch auf pastebin.com und verlink ihn dann hier.

  • Diskussion zum Thema GOTO in der Shoutbox - Zusammenfassung

    • alpines
    • 2. Februar 2018 um 11:35
    Zitat von BananaJoe

    BTW, weiß noch jemand wie die Commodore-Computer vor dem VC20 hießen?

    Meinst du die Commodore PET Serie?

  • Text in iFrame schreiben

    • alpines
    • 2. Februar 2018 um 11:34
    Zitat von AlphavibeZ

    Wollte ihn gerade hier posten aber irgendwie will das nicht so recht.

    Du hast es doch bisjetzt auch hinbekommen, woran scheiterts?

  • Jüngste Datei löschen

    • alpines
    • 2. Februar 2018 um 11:33

    Du kannst den Dateinamen mit Stringfunktionen zurechtschneiden.

    StringTrimLeft schneidet alles links ab der angegebenen Position zurück.

    StringInStr sucht in einem String ein Zeichen (du kannst auch angeben ab welchem x.ten Auftreten des Zeichens er die Position zurückgeben soll, auch von hinten)

    Die beiden Befehle brauchst du zum löschen des Teils davor. Jetzt liegt es an dir sie vernünftig mit Hilfe der Dokumentation zusammenzusetzen.

  • Text in iFrame schreiben

    • alpines
    • 2. Februar 2018 um 11:31
    Zitat von Oscar

    Falls Du SciTE als Editor benutzt, rufe einfach Tidy (STRG & T) auf. Das formatiert den Code.

    Psscht! Das soll beim Coden automatisch von der Hand gemacht werden!

  • Text in iFrame schreiben

    • alpines
    • 2. Februar 2018 um 11:26

    Schön, dass es funktioniert. Ich würde dir aber sehr ans Herz legen, dass du deinen Code von der Struktur/Formatierung nochmal überarbeitest.

    Die Klammern bei der $sArtikeltext-Definition sind nicht nötig und du verwendest keine Tabs zum Einrücken von Code.

    Funktional hat das alles keinen Wert aber erhöht die Leserlichkeit des Codes und du blickst auch nach ein paar Jahren schnell wieder durch.

  • Jüngste Datei löschen

    • alpines
    • 2. Februar 2018 um 10:23

    Kann höchstens daran liegen, dass dein Script schon bei dem 1. If sich beendet.

    Du findest im Editor den "</>"-Button für Code, wähle als Sprache AutoIt aus und paste ihn dann rein.

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™