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. veronesi

Beiträge von veronesi

  • 2. GUI lässt sich nicht schliessen.

    • veronesi
    • 21. April 2010 um 11:04

    Hey, vielen Dank!

    Nun funktioniert alles!
    Das Problem scheint wirklich das folgende zu sein:
    OnEvent scheint nur in der Hauptschleife zu funktionieren.

    Vorher war ich dauernd in der Sub-Funktion und OnEvent funktionierte deshalb vermutlich nicht!

    Nun habe ich eine Funktion "ShowGUI2" und "HideGUI2" und alles läuft!

    Vielen Dank
    Gruss
    Veronesi

  • 2. GUI lässt sich nicht schliessen.

    • veronesi
    • 21. April 2010 um 10:43

    Die Idee ist gut. Das werde ich mal testen.
    Doch grundsätzlich sollte das Andere doch auch funktionieren?!

  • 2. GUI lässt sich nicht schliessen.

    • veronesi
    • 21. April 2010 um 09:58

    Hallo SEuBo,

    nein, das Script kommt wirklich nicht in die Close Funktion!
    Der Komplette Code hat inzwischen 2790 Zeilen, dazu 9 Include Dateien und 12 FileInstall Dateien (2 davon ebenfalls AutoIt EXE Files).

    Das ganze zu analysieren ist viel zu viel.
    Vielleicht schaffe ich es, das Problem auf wenige Zeilen Testcode zusammenzukürzen. Aber das kann eine Weile dauern, bis ich das Problem dann wieder reproduzieren kann.

    Gibt es bei zwei GUIs etwas zu beachten (ausser dem GUISwitch) ?

    Mein WorkAround ist im Moment, dass ich in der Unterfunktion die OnEvent ausschalte und danach wieder einschalte. Das funktioniert, doch finde ich unschön!

    Gruss
    Veronesi

  • 2. GUI lässt sich nicht schliessen.

    • veronesi
    • 21. April 2010 um 09:43

    Hallo zusammen,

    ja, ich weiss, das wurde schon mal behandelt und gefragt. Trotzdem kriege ich es nicht hin.
    Ich habe eine GUI. Irgendwann wird dann mal ein Button eingeblendet der in einer 2. GUI ein "Hilfe"-Bild anzeigen soll.

    Das zweite GUI kommt auch, aber es lässt sich nicht schliessen. Auch das erste lässt sich dann nicht mehr schliessen.
    Ich arbeite mit GUISetOnEvent.

    Für das 1. GUI funktioniert das wunderbar, solange das 2. nicht geöffnet ist.
    Das 2. GUI habe ich aber nur vom 1. kopiert und wenig geändert:

    Spoiler anzeigen
    [autoit]

    Dim $CloseGUI2 = False, $hGUI
    opt("GUIOnEventMode", 1) ;Enable events on GUI

    [/autoit] [autoit][/autoit] [autoit]

    Func SecondGUI()
    Local $hGUI2, $msg
    $hGUI2 = GUICreate("Umbauhilfe", 700, 700, 10, 10) ;Create GUI
    GUICtrlCreatePic("Testbild.jpg",0,0,700,700)
    GUISwitch($hGUI2)
    GUISetState() ; Display the GUI
    GUISetOnEvent(-3,"CloseSecondGUI",$hGUI2)

    [/autoit] [autoit][/autoit] [autoit]

    While Not $CloseGUI2
    Sleep(100)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    GUIDelete($hGUI2)
    GUISwitch($hGUI)
    $CloseGUI2 = False
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func CloseSecondGUI()
    $CloseGUI2 = True
    EndFunc

    [/autoit]

    Leider kann ich nicht das ganze Programm hier mitgeben, da es viel zu gross zum analysieren wäre...
    Vielleicht findet ja jemand einen Denkfehler oder kann mir Tipps geben, wonach ich suchen könnte!

    Wenn ich in der Funktion SecondGUI() die Option Event auf 0 stelle (opt("GUIOnEventMode", 0))
    dann kann ich ganz normal mit GUIGetMsg() das schliessen abfragen. Dann geht es!
    Am Schluss stelle ich natürlich dann die Events wieder ein.

    Aber das müsste doch auch mit den Event klappen?

    Grüsse
    Veronesi

  • Aufnahme mit _BASS_Record

    • veronesi
    • 19. April 2010 um 09:30

    So, für den Moment konnte ich das Problem lösen.
    Viele von meinen Prüfungen sind automatisiert. Dort habe ich den Interrupt nun abgeschaltet, da der Benutzer sowieso nichts machen muss (ausser Sekundenbruchteile zu warten).

    In den Prüfungen, in welchen der Benutzer etwas machen muss, schalte ich den Interrupt kurz ein und am Ende wieder aus.

    Trotzdem wäre es schön, wenn man solche Hard-Crashes irgendwie abfangen und behandeln könnte!

    Grüsse
    Veronesi

  • Aufnahme mit _BASS_Record

    • veronesi
    • 19. April 2010 um 08:56

    Nein, leider reicht das nicht.
    An diesen (Prüfcomputer) werden im laufenden Betrieb (zum testen von Produkten) Monitore angeschlossen und wieder abgehängt.
    Da der PC 4 Grafikkarten hat, aber (aus Platzgründen) nur zwei Monitore, sind immer zwei Grafikkarten Ausgänge zur Zeit nicht belegt.

    Zuerst muss der Benutzer 2x Digital mit dem Produkt prüfen, dann 2x Analog. Wenn er die Monitore an die anderen Grafikkarten anschliesst, dann sieht er logischerweise das erste Bild nicht mehr.
    Dann sieht er auch das GUI mit den weiteren Anweisungen nicht mehr. Deshalb kann er dann nur die Maus verschieben und dann kommt automatisch das GUI.

    (blind mit Tastenkombinationen das Fenster in den sichtbaren Bereich schieben kann ich den Benutzern nicht zumuten.)

    Aber es muss nicht zwingend 500ms sein. 1000ms oder notfalls 2000ms gehen auch. Trotzdem tritt der Effekt auf!

    Gruss
    Veronesi

  • Aufnahme mit _BASS_Record

    • veronesi
    • 19. April 2010 um 08:39

    Nun konnte ich den Fehler etwas weiter eingrenzen:

    Er tritt nur auf, wenn ich in meinem "grossen" Programm folgendes aktiviere:

    [autoit]

    AdlibRegister("GetMousePosition",500) ;Create Interrupt for GUI Moving

    [/autoit]

    Dieser Befehl überprüft, auf welchem Bildschirm die Maus ist und verschiebt das GUI automatisch auf den richtigen Monitor.
    Hier die Funktionen dahinter:

    Func GetMousePosition()

    Spoiler anzeigen
    [autoit]

    Func GetMousePosition() ;Interrupt Timer: Check Mouse Position and moves the GUI to this screen
    Local $aTmp[32], $ResX, $ResY, $PosX, $PosY, $Tmp

    $Tmp = _GetMouseInfo()
    If $Tmp <> $MouseScreenNumber Then
    $MouseScreenNumber = $Tmp
    $aTmp = _GetMonitorInfo()
    $ResX = $aTmp[$Tmp][0]
    $ResY = $aTmp[$Tmp][1]
    $PosX = $aTmp[$Tmp][2]
    $PosY = $aTmp[$Tmp][3]
    $aTmp = WinGetPos($hGUI)

    WinMove($hGUI,"",$PosX + ($ResX/2) - ($aTmp[2]/2),$PosY + ($ResY/2) - ($aTmp[3]/2),$aTmp[2],$aTmp[3],2)
    EndIf
    EndFunc ;=> GetMousePosition

    [/autoit]

    Func _GetMouseInfo()

    Spoiler anzeigen
    [autoit]

    #include-once
    #include "Func_GetMonitorInfo.au3"
    Func _GetMouseInfo()
    ;Returns the screen number on which the actual mouse cursor is
    ;Call: _GetMouseInfo()

    Local $aTmp[32][32], $MousePos, $NrOfScreens, $i
    $MousePos = MouseGetPos()
    $aTmp = _GetMonitorInfo()
    $NrOfScreens = $aTmp[0][0]
    For $i = 1 To $NrOfScreens
    If $MousePos[0] >= $aTmp[$i][2] AND ($MousePos[0] <= $aTmp[$i][2] + $aTmp[$i][0]) AND $MousePos[1] >= $aTmp[$i][3] AND ($MousePos[1] <= $aTmp[$i][3] + $aTmp[$i][1]) Then Return $i
    ;Checks on which Screen the Mousecursor is
    Next
    EndFunc

    [/autoit]

    Func _GetMonitorInfo()

    Spoiler anzeigen
    [autoit]

    #include-once

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetMonitorInfo()
    ;Returns some informations about your screens
    ;Call: _GetMonitorInfo()
    ;Return: Array With
    ;[0][0] Nr of Monitors
    ;[1][0] X Resolution of Monitor 1
    ;[1][1] Y Resolution of Monitor 1
    ;[1][2] X Position of Monitor 1
    ;[1][3] Y Position of Monitor 1

    [/autoit] [autoit][/autoit] [autoit]

    ;[2][0] X Resolution of Monitor 2
    ;[2][1] Y Resolution of Monitor 2
    ;[2][2] X Position of Monitor 2
    ;[2][3] Y Position of Monitor 2
    ;......

    Local $NrOfMonitors, $ResolutionX[32], $ResolutionY[32], $PositionX[32], $PositionY[32], $Ret
    Local $cbMonitorEnumProc = DllCallbackRegister("MonitorEnumProc", "ubyte", "ptr;ptr;ptr;int")

    [/autoit] [autoit][/autoit] [autoit]

    If @error Then Return SetError(1, 0, False)
    Local $strctCount = DllStructCreate("uint Count;uint Width[12];uint Height[12];int left[12];int top[12]")
    If @error Then Return SetError(2, @error, False)
    Local $iCount

    DllStructSetData($strctCount, "Count", 0)

    $Ret = DllCall("User32.dll", "ubyte","EnumDisplayMonitors","ptr", 0,"ptr", 0, "ptr", DllCallbackGetPtr($cbMonitorEnumProc), "ptr", DllStructGetPtr($strctCount))
    If @error Or $Ret[0] = 0 Then Return SetError(3, @error, False)

    DllCallbackFree($cbMonitorEnumProc)

    $iCount = Int(DllStructGetData($strctCount, "Count"))

    Local $aMonitors[$iCount+1][4] = [[$iCount]]

    For $i = 1 To $iCount
    $aMonitors[$i][0] = Int(DllStructGetData($strctCount, "Width",$i))
    $aMonitors[$i][1] = Int(DllStructGetData($strctCount, "Height",$i))
    $aMonitors[$i][2] = Int(DllStructGetData($strctCount, "left",$i))
    $aMonitors[$i][3] = Int(DllStructGetData($strctCount, "top",$i))
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ;~ If Not @error Then
    ;~ $NrOfMonitors = $aMonitors[0][0]
    ;~ For $i = 1 To $NrOfMonitors
    ;~ $ResolutionX[$i] = $aMonitors[$i][0]
    ;~ $ResolutionY[$i] = $aMonitors[$i][1]
    ;~ $PositionX[$i] = $aMonitors[$i][2]
    ;~ $PositionY[$i] = $aMonitors[$i][3]
    ;~ Next
    ;~ EndIf
    Return $aMonitors
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func MonitorEnumProc($hMonitor, $hdcMonitor, $lprcMonitor, $dwData)
    Local $strctRECT = DllStructCreate("long left;long top;long right;long bottom", $lprcMonitor)
    Local $strctCount = DllStructCreate("uint Count;uint Width[12];uint Height[12];int left[12];int top[12]", $dwData)
    Local $iNumber = DllStructGetData($strctCount, "Count")
    Local $Height = Int(DllStructGetData($strctRECT, "bottom"))-Int(DllStructGetData($strctRECT, "top"))
    Local $Width = Int(DllStructGetData($strctRECT, "right"))-Int(DllStructGetData($strctRECT, "left"))

    DllStructSetData($strctCount, "Width", $Width, $iNumber+1)
    DllStructSetData($strctCount, "Height", $Height, $iNumber+1)
    DllStructSetData($strctCount, "left", Int(DllStructGetData($strctRECT, "left")), $iNumber+1)
    DllStructSetData($strctCount, "top", Int(DllStructGetData($strctRECT, "top")), $iNumber+1)
    DllStructSetData($strctCount, "Count", $iNumber+1)
    Return True
    EndFunc

    [/autoit]

    Diese Funktionen alleine stürzen nicht ab. Doch zusammen mit irgendwelchen anderen Dingen von mir dann schon.....
    Das Problem ist vermutlich, dass diese Funktion alle 500ms ausgeführt wird (Interrupt). Wenn dann das Programm genau in einer "kritischen" Phase ist....

    Sieht jemand etwas kritisches an diesen Programmteilen?
    Gruss
    Veronesi

  • Aufnahme mit _BASS_Record

    • veronesi
    • 19. April 2010 um 07:47

    So, ich hoffe, ihr lest hier noch mit!

    Inzwischen habe ich aus dem Skript eine Funktion gemacht und in mein ganzes Projekt eingefügt.
    Die Funktion sieht so aus:

    Spoiler anzeigen
    [autoit]

    #include "Include\Bass.au3"
    #include "Include\BassConstants.au3"
    #include "Include\BassEnc.au3"

    [/autoit] [autoit][/autoit] [autoit]

    Dim $File = @TempDir & "\1kHz.wav"

    [/autoit] [autoit][/autoit] [autoit]

    CheckAudio(50)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func CheckAudio($Tolerance) ;Check for Audio
    Local $hRecord, $hMusic, $iFreqOut, $iFreqIn, $TimerAudio

    [/autoit] [autoit][/autoit] [autoit]

    ;~ GUICtrlSetBkColor($CheckBoxNr,$LightGray)
    ;~ IESetText($Text, $LightGreen, $Size)

    [/autoit] [autoit][/autoit] [autoit]

    FileInstall("Include\1kHz.wav",@TempDir & "\1kHz.wav",1)
    FileInstall("Include\bass.dll",@TempDir & "\bass.dll",1)
    FileInstall("Include\basscb.dll",@TempDir & "\basscb.dll",1)
    FileInstall("Include\bassenc.dll",@TempDir & "\bassenc.dll",1)

    _BASS_STARTUP(@TempDir & "\BASS.dll") ;Open Bass.DLL.
    _BASS_Init(0, 1, 44100, 0, "") ;Initalize bass.
    If @error Then
    ;~ MsgBox(0,"ERROR","ERROR Audio Out")
    ;~ GUICtrlSetBkColor($CheckBoxNr,$LightRed) ;Set color for Checkbox Background
    ;~ GUICtrlSetState($CheckBoxNr,1) ;Set Checkbox checked
    Return 0
    EndIf

    _BASS_RecordInit(0)
    If @error Or _BASS_RecordGetDevice() > 10 Or _BASS_RecordGetDevice() < 0 Then
    ;~ MsgBox(0,"ERROR","ERROR Audio In")
    ;~ GUICtrlSetBkColor($CheckBoxNr,$LightRed) ;Set color for Checkbox Background
    ;~ GUICtrlSetState($CheckBoxNr,1) ;Set Checkbox checked
    Return 0
    EndIf

    _BASS_RecordSetInput(0, $BASS_INPUT_ON,-1)

    $hRecord = _BASS_RecordStart(44100, 2, 0)

    $hMusic = _BASS_StreamCreateFile(False, $File, 0, 0, 0) ;Set handle for 1kHz. Music File

    _BASS_ChannelPlay($hMusic, 1) ;Play 1kHz. Music-File
    $TimerAudio = TimerInit()

    [/autoit] [autoit][/autoit] [autoit]

    While _BASS_ChannelIsActive($hMusic) = $BASS_ACTIVE_PLAYING ;While playing get frequency of Line-Out and Line-In
    $iFreqOut = GetFreq($hMusic)
    $iFreqIn = GetFreq($hRecord)
    ;~ ToolTip("Frequenz Out: " & $iFreqOut & @LF & "Frequenz In: " & $iFreqIn)
    If TimerDiff($TimerAudio) > 1500 Then ExitLoop
    Sleep(50)
    WEnd
    ToolTip(@error)
    Sleep(5000)

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_Free()
    _BASS_RecordFree()

    If $iFreqOut + $Tolerance > $iFreqIn AND $iFreqOut - $Tolerance < $iFreqIn AND $iFreqOut < 1100 and $iFreqOut > 900 Then ;If both frequencies are +/- the same and the Output frequency is +/- 1kHz. then it's OK!
    ;~ MsgBox(0,"Erfolg","Signal wurde erfolgreich empfangen!" & @LF & "Ausgangsfrequenz: " & $iFreq1 & @lF & "Eingangsfrequenz: " & $iFreq2)
    ;~ GUICtrlSetBkColor($CheckBoxNr,$GUIBackgroundColor) ;Set color for Checkbox Background
    ;~ GUICtrlSetColor($CheckBoxNr,$LightGreen) ;Set color for Checkbox Text
    ;~ GUICtrlSetState($CheckBoxNr,1) ;Set Checkbox checked
    Return 1
    ElseIf $iFreqOut > 1100 OR $iFreqOut < 900 Then
    ;~ MsgBox(0,"Fehler","Fehler! Vermutlich wurde das Kabel nicht korrekt am Line-Out Anschluss angeschlossen" & $ifreq1 & $ifreq2)
    ;~ GUICtrlSetBkColor($CheckBoxNr,$LightRed) ;Set color for Checkbox Background
    ;~ GUICtrlSetState($CheckBoxNr,1) ;Set Checkbox checked
    Return -1
    Else
    ;~ MsgBox(0,"Fehler","Fehler! Vielleicht wurde das Kabel nicht korrekt am Line-In Anschluss angeschlossen, oder das Produkt hat einen defekt!")
    ;~ GUICtrlSetBkColor($CheckBoxNr,$LightRed) ;Set color for Checkbox Background
    ;~ GUICtrlSetState($CheckBoxNr,1) ;Set Checkbox checked
    Return 0
    EndIf
    EndFunc ;=> CheckAudio

    [/autoit] [autoit][/autoit] [autoit]

    Func GetFreq($hHandle)
    Local $TmpData = 0, $TmpNr = 0, $fft = 0
    Local $fftstruct = DllStructCreate("float[4096]")
    _BASS_ChannelGetData($hHandle, DllStructGetPtr($fftstruct), $BASS_DATA_FFT8192)
    For $i = 0 To 4095
    $TmpData = Round(DllStructGetData($fftstruct, 1, $i + 1) * 100)
    If $TmpData > 0.2 And $fft < $TmpData Then ;Bestimme den Ort des Maximalwerts der FFT Analyse
    $fft = $TmpData
    $TmpNr = $i + 1
    EndIf
    Next
    Return Round(22000 / 4096 * $TmpNr) ;Max 22kHz.
    EndFunc ;=> GetFreq

    [/autoit]

    Man beachte die Line mit dem ToolTip(@error) und danach die Sleep(5000). Irgendwo vom _BASS_ChannelPlay(....) bis zu der erwähnten Zeile passiert ein Fehler.
    Zwar wird alles ausgeführt, doch wenn ich das ganze Programm dann beende, dann bekomme ich einen Exit Code: -1073741819. (Fehlermeldung: Der Inhalt kann nicht angezeigt werden, da er nicht mehr verfügbar ist. )
    Dies sei ein Hard-Crash. Doch wie bringe ich den weg? Denn mit diesem Fehler ist mein ganzes Programm ziemlich wertlos und unprofessionell!
    Ich verwende die aktuellste AutoIT Version 3.3.6.1

    Leider kann ich das meistens nur reproduzieren, wenn ich den Code-Schnippsel im meinem ganzen Programm verwende! Doch das ist zu gross um von Euch analysiert zu werden....
    Gibt es generelle Anregungen?

    Vielen Dank für Eure Anregungen!
    Gruss
    Veronesi

    PS: Includes: Der Inhalt kann nicht angezeigt werden, da er nicht mehr verfügbar ist.

    Bilder

    • Error.jpg
      • 21,11 kB
      • 485 × 149

    Dateien

    Include.zip 168,53 kB – 265 Downloads
  • _GUICtrlRichEdit_Create ohne blinkender Cursor

    • veronesi
    • 17. April 2010 um 16:22

    Ja, ich kenne mich mit HTML genügend aus, damit ich das verwirklichen kann, was ich möchte.

    Ich habe Dein UDF angeschaut und dann auch gesehen, dass Du ja ein eingebetteter IE nimmst. Wusste gar nicht, dass es das gibt!
    Aber das ist natürlich wunderbar!

    Vielen Dank!
    Gruss
    Veronesi

  • _GUICtrlRichEdit_Create ohne blinkender Cursor

    • veronesi
    • 17. April 2010 um 10:30

    Ja, ich benötige kein Eingabefeld. Aber der Text kann varieren und wird von einer Textdatei automatisch eingelesen.
    Manchmal habe ich kein Wort, das Fett sein muss. Und dann wieder 15 oder 20 Wörter, die Fett sein müssen. Insgesamt werden manchmal nur eine Zeile Text angezeigt, und dann wieder 30 Zeilen..
    Da müsste ich ja dutzende von Labels erstellen. Das ist mir der Aufwand dann nicht wert!

    Die Chatbox-UDF schaue ich mir heute abend mal an!

    Ich vermute mal, dass die "normalen" Labels bei den GUI's keine Tags wie <b> und </b> oder ähnlich interpretieren!

    Gruss
    Veronesi

  • _GUICtrlRichEdit_Create ohne blinkender Cursor

    • veronesi
    • 17. April 2010 um 07:21

    Hallo zusammen,

    ist es möglich mit einer _GUICtrlRichEdit_Create den blinkenden Cursor (caret) zu entfernen?
    Einfach so, dass man ihn nicht sieht?

    Grundsätzlich möchte ich eigentlich nur ein GUI mit einem Label drin gestalten. Doch beim Text des Labels muss ich auch einzelne Wörter Fett markieren können. Deshalb bin ich auch die RichEdit Funktionen gestossen.

    Also, geht das? Wer hat eine Idee?

    Edit: Ach ja, ist es möglich bei den RichEdit's die Default Schriftgrösse / Farbe zu setzen?
    Gruss
    Veronesi

  • Aufnahme mit _BASS_Record

    • veronesi
    • 15. April 2010 um 10:51

    HEY EUKALYPTUS, Du bist genial! :rock:

    das Script scheint nun auf XP und Windows 7 zu laufen!
    Einzig die Zeile

    [autoit]

    _BASS_Init(0, 2, 44100, 0, "") ;Initalize bass.

    [/autoit]


    musste ich abändern. Aus der 2 eine 1 machen!

    Nun läuft es einwandfrei! 8)

    Nun muss ich das ganze natürlich noch ein klein wenig umbauen, damit es in mein gesamtes Skript passt. (Es muss eben noch mehr geprüft werden).
    Und statt MsgBox'es mache ich natürlich mit Return Fehlerauswertungen!

    Vielen herzlichen Dank!!
    Sobald ich das geschafft habe, werde ich das natürlich noch auf verschiedenen PCs mit verschiedenen Soundkarten testen!

    Beste Grüsse
    Veronesi

  • Aufnahme mit _BASS_Record

    • veronesi
    • 15. April 2010 um 10:08

    So, nun konnte ich das endlich testen.
    Hier die Ergebnisse:

    Ganz ohne Kabel:
    -Default Device: 4294967295

    Kabel nur am Line-Out:
    -Default Device: 4294967295

    Kabel nur am Line-In:
    -Default Device: 0
    !Eingang (High Definition Audio- Hauptlautstärke: Device 0 / Input 0 / Level 1%

    Kabel in beide eingesteckt:
    -Default Device: 0
    +Eingang (High Definition Audio-Gerät) Hauptlautstärke: Device 0 / Input 0 / Level 100%

  • Aufnahme mit _BASS_Record

    • veronesi
    • 15. April 2010 um 08:27

    Nun wieder ein Script von mir:

    Spoiler anzeigen
    [autoit]

    #include <BassEnc.au3>
    #include "Bass.au3"
    #include "BassConstants.au3"

    [/autoit] [autoit][/autoit] [autoit]

    FileInstall("bass.dll",@ScriptDir & "\bass.dll")
    FileInstall("basscb.dll",@ScriptDir & "\basscb.dll")
    FileInstall("bassenc.dll",@ScriptDir & "\bassenc.dll")

    [/autoit] [autoit][/autoit] [autoit]

    Dim $File1 = @ScriptDir & "\1kHz.wav", $File2 = @ScriptDir & "\test.wav"
    Local $hMusic, $iFreq, $iFreq1, $iFreq2, $basscb_dll, $RecordDevice, $temp ,$hRecord, $EncHandle

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_STARTUP("BASS.dll") ;Open Bass.DLL.
    _BASS_Init(0, -1, 44100, 0, "") ;Initalize bass.
    _BASS_Encode_STARTUP("BassEnc.dll")
    $basscb_dll = DllOpen("BASSCB.dll")
    $RecordDevice = _BASS_RecordInit(-1)
    $temp = DllCall($basscb_dll, "dword", "RecordStart", "dword", 44100, "dword", 2, "dword", _makelong($BASS_SAMPLE_FX, 10))
    $hRecord = $temp[0]

    [/autoit] [autoit][/autoit] [autoit]

    $iFreq1 = Play($File1) ;Play 1kHz. testfile
    Record() ;Record
    $iFreq2 = Play($File2) ;Play recorded file

    [/autoit] [autoit][/autoit] [autoit]

    MsgBox(0,"Ausgabe","Ausgangsfrequenz: " & $iFreq1 & @lF & "Eingangsfrequenz: " & $iFreq2)

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_Free()
    _BASS_RecordFree()
    Exit ;=>Main

    [/autoit] [autoit][/autoit] [autoit]

    Func Play($File)
    $hMusic = _BASS_StreamCreateFile(False, $File, 0, 0, 0) ;Create Play Handle
    _BASS_ChannelPlay($hMusic, 1) ;Play File
    Sleep(100) ;Ignore silence at the beginning of file
    $iFreq = GetFreq($hMusic)
    Return $iFreq
    EndFunc ;=>Play

    [/autoit] [autoit][/autoit] [autoit]

    Func Record()
    $EncHandle = _BASS_Encode_Start($hRecord,$File2, $BASS_ENCODE_PCM)
    Sleep(1000)
    _BASS_Encode_Stop($hRecord)
    EndFunc ;=>Record

    [/autoit] [autoit][/autoit] [autoit]

    Func GetFreq($hHandle)
    Local $TmpData = 0, $TmpNr = 0, $fft = 0
    Local $fftstruct = DllStructCreate("float[4096]")
    _BASS_ChannelGetData($hHandle, DllStructGetPtr($fftstruct), $BASS_DATA_FFT8192)
    For $i = 0 To 4095
    $TmpData = Round(DllStructGetData($fftstruct, 1, $i + 1) * 100)
    If $fft < $TmpData Then ;Bestimme den Ort des Maximalwerts der FFT Analyse
    $fft = $TmpData
    $TmpNr = $i + 1
    EndIf
    Next
    Return Round(22000 / 4096 * $TmpNr) ;Max 22kHz.
    EndFunc ;=>GetFreq

    [/autoit]

    Es wird folgendes gemacht:
    1. Testfile wiedergeben und Frequenz messen.
    2. (Fast) gleichzeitig Testfile wieder aufnehmen
    3. Aufgenommenes File wiedergeben und Frequenz messen.

    Testergebnisse unter XP
    - Kabel von Line-In zu Line-Out eingesteckt: Out = 1004Hz / In = 1004Hz.
    - Kabel ausgesteckt (oder nur an einem Ein-/Ausgang): Out = 1004Hz. / In = 0Hz.
    => Funktioniert!

    Testergebnisse unter Win7
    - Kabel von Line-In zu Line-Out eingesteckt: Out = 1004Hz / In = 1004Hz.
    (Aber manchmal erkennt Win7 gar nicht, dass am Line-In was eingesteckt ist. Dann muss man den Stecker wieder rausziehen und langsam (!!) wieder einstecken. Dann gehts.
    - Kabel ganz ausgesteckt: Out = 0Hz. / In = 0Hz. (vermutlich weil der Line-Out auch ausgesteckt ist! Aber das kann man abfangen, Wenn Out = 0 dann.... Meldung: Kabel vergessen!)
    - Kabel NUR am Line-Out eingesteckt: Out = 1004Hz. / In = 1004Hz. (Fehler!)

    => Windows 7 macht einfach irgendwie zicken.....
    Gruss
    Veronesi

  • Aufnahme mit _BASS_Record

    • veronesi
    • 15. April 2010 um 07:38

    Ok, ich habe nun alle (war nur 1) Audioaufnahmegerät unter Windows 7 aktiviert. Trotzdem messe ich bei der Frequenzanalyse im besten Fall 5Hz. (Vielleicht eine Schwankung des Netzes).
    Dann habe ich Deinen Recorder verwendet.

    Der funktioniert einwandfrei. Natürlich nur mit lokalen Admin-Rechten. Und er gibt beim "FileEncoding" einen Error aus, aber das File ist trotzdem da und tönt +/- nach einem 1kHz. Sinus!

    Bloss ist die Source von Deinem Recorder zu kompliziert für mich. Ich blick da momentan einfach nicht durch.
    Denn ich möchte das ja so einfach wie möglich (muss ja nicht zu genau sein) programmieren, damit ich dann auch irgendwann drauskomme! (Bin eigentlich kein Programmierer und bei AutoIt auch erst seit ca 2 Wochen...)

    Kannst Du mir nochmals einen Denkanstoss geben? Grundsätzlich möchte ich "bloss" auf dem Line-In Eingang kontrollieren ob +/- das reinkommt (Frequenz / Pegel) was auch rausgeht!
    Danke!
    Grüsse
    Veronesi

  • Aufnahme mit _BASS_Record

    • veronesi
    • 14. April 2010 um 21:02

    Ich muss morgen mal noch schauen, ob ich irgendwelche deaktivierten Geräte (Aufnahmegeräte) finde.

    Aber irgendwie stehe ich gerade etwas auf dem Schlauch (ist schon spät :) ). Welchen Recorder meinst Du genau? Sorry...

    Zudem: aufnehmen kann ich ja (sofern das Kabel eingesteckt ist). Aber ich messe die falsche Frequenz!

    Gruss
    Veronesi

  • Aufnahme mit _BASS_Record

    • veronesi
    • 14. April 2010 um 14:30

    Hallo Eukalyptus,

    ich habe Dein Script noch etwas angepasst:

    Spoiler anzeigen
    [autoit]

    #include "Bass.au3"
    #include "BassConstants.au3"

    [/autoit] [autoit][/autoit] [autoit]

    Global $File = "1kHz.wav"
    Local $aRecordInfo
    _BASS_STARTUP("BASS.dll") ;Open Bass.DLL.
    _BASS_Init(0, -1, 44100, 0, "") ;Initalize bass.
    _BASS_RecordInit(-1)

    [/autoit] [autoit][/autoit] [autoit]

    $aRecordInfo = _BASS_RecordGetInfo() ;Number of available input sources ([2])

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 0 to $aRecordInfo[2] ;Disable all input sources
    _BASS_RecordSetInput($i, $BASS_INPUT_OFF, -1)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 0 to $aRecordInfo[2]
    If StringLeft(_BASS_RecordGetInputName($i),4) = "Line" OR StringLeft(_BASS_RecordGetInputName($i),5) = "Haupt" OR StringLeft(_BASS_RecordGetInputName($i),6) = "Master" Then ExitLoop
    Next

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_RecordSetInput($i, $BASS_INPUT_ON, -1) ;Enable Line Input

    [/autoit] [autoit][/autoit] [autoit]

    $hRecord = _BASS_RecordStart(44100, 1, 0, "", 0)

    [/autoit] [autoit][/autoit] [autoit]

    $hMusic = _BASS_StreamCreateFile(False, $File, 0, 0, 0)
    _BASS_ChannelPlay($hMusic, 1)
    While _BASS_ChannelIsActive($hMusic) = $BASS_ACTIVE_PLAYING
    $iFreqOut = _GetFreq($hMusic)
    $iFreqIn = _GetFreq($hRecord)
    ToolTip("Frequenz Out: " & $iFreqOut & @LF & "Frequenz In: " & $iFreqIn & " / " & _BASS_RecordGetInputName($i))
    Sleep(100)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_Free()
    _BASS_RecordFree()

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetFreq($hHandle)
    Local $TmpData = 0, $TmpNr = 0, $fft = 0
    Local $fftstruct = DllStructCreate("float[4096]")
    _BASS_ChannelGetData($hHandle, DllStructGetPtr($fftstruct), $BASS_DATA_FFT8192)
    For $i = 0 To 4095
    $TmpData = Round(DllStructGetData($fftstruct, 1, $i + 1) * 100)
    If $fft < $TmpData Then ;Bestimme den Ort des Maximalwerts der FFT Analyse
    $fft = $TmpData
    $TmpNr = $i + 1
    EndIf
    Next
    Return Round(22000 / 4096 * $TmpNr) ;Max 22kHz.
    EndFunc ;==>_GetFreq

    [/autoit]

    Es fragt nun auch noch die Anzahl der Inputs ab, deaktiviert alle und aktiviert dann den, der mit Line, Haupt oder Master anfängt.
    (Unter deutschem XP heisst es Line, unter deutschem Win7 Haupt...)

    Das Ganze funktioniert nun auf meinem deutschen XP.
    Da wir aber bald auf Win7 wechseln testete ich es auch dort. Und dort bekomme ich bei eingestecktem Kabel nur 5Hz.
    Bei ausgestecktem Kabel erhalte ich gar eine Fehlermeldung und das Programm stürzt ab.

    Any idea?

    Grüsse + DANKE!
    Veronesi

  • Aufnahme mit _BASS_Record

    • veronesi
    • 14. April 2010 um 13:25

    So, hier ist der Output der Konsole:

    (Line-In Eingang war nicht verbunden und trotzdem bekam ich jeweils 1004Hz. angezeigt...)

    -Output 0: <No sound> <> <1>
    +Output 1: <Realtek HD Audio output> <RtkHDAud.sys> <7>

    +Input 0: <Realtek HD Audio Input> <RtkHDAud.sys> <7>
    + CD-Lautstärke
    + Mikrofon
    + Line-Lautstärke
    + Aux-Lautstärke
    + Stereomix

    Gruss
    Veronesi

  • Aufnahme mit _BASS_Record

    • veronesi
    • 14. April 2010 um 12:50

    Nun habe ich Dein Script noch auf einem anderen PC (ohne Mikrofon nur mit Line-In) getestet.
    Es läuft (fast) einwandfrei!

    Aber warum auf meinem Rechner nicht?

    Sind auf dem anderen PC keine Audio Kabel verbunden, so messe ich als Out 1004Hz und als In 0Hz. völlig korrekt.
    Nun stecke ich aber das Kabel (Line-Out zu Line-In) ein und messe nochmals. Dann bekomme ich als Out 1004Hz und als In 5Hz.

    Gibt es eine bessere Methode um die Frequenz eines TONES über die Soundkarte zu bestimmen?
    Ich brauche die Frequenz auch nicht wahnsinnig genau. Denn ich muss bloss wissen, ob das Signal am Line-In ankommt und ob es in sehr grob die richtige Frequenz / Pegel hat.

    Bei der Frequenz reichen mir +/- 50Hz. locker!

    Hast Du noch weitere Ideen?
    Grüsse
    Veronesi

  • Aufnahme mit _BASS_Record

    • veronesi
    • 14. April 2010 um 12:08

    Mit 0.2 funktioniert das leider nicht.
    Ich bin deshalb mal hoch gegangen auf 100!

    [autoit]

    If $TmpData > 100 AND $fft < $TmpData Then

    [/autoit]


    Und da passiert das unfassbare: Nun ist plötzlich Frequenz Out = 0 und Frequenz In = 1004.
    Also genau verdreht.

    Dann habe ich das wieder rückgängig gemacht:

    [autoit]

    If $fft < $TmpData Then

    [/autoit]


    und dafür das Sleep in der While Schlaufe verlängert. (Auf Sleep(1000))
    Nun zeigt er zwar für IN 1004 und für Out 0 an, doch auch wenn ich das Kabel an Line-In wieder einstecke, bleibt das so!

    Mir scheint das fast zufällig zu sein!

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™