Sinuswellen-Generator

  • Hi,
    aufgrund einer Nachfrage habe ich mal in meinen halbfertigen Asservaten gewühlt. Der Generator erstellt bisher nur Sinuswellen, die Parameter sollte man einstellen können, bzw. wissen, was man wozu braucht. Die WAV-Datei wird im Speicher abgespielt, kann aber auch als Datei abgelegt werden.
    Naja, ich setz mich dran um den Code mal zu entwursteln und den Rest einzubauen^^

    Spoiler anzeigen
    [autoit]

    #include <EditConstants.au3>
    #include <WindowsConstants.au3>
    #include <GUIConstantsEx.au3>

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

    ;Das Script erstellt eine WAV-Datei im Speicher, spielt diese ab und speichert anschließend in eine Datei

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

    ;Opt("GUIOnEventMode", 1)

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

    Global Const $pi = 4 * ATan(1) ;pi=3,1415926....
    Global $struct, $wavstruct, $sekunden, $samplingrate, $Channels, $samplefaktor
    Global $freq_sliderold = 440, $volm_sliderold = 50

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

    $gui = GUICreate("Wave Generator ", 450, 450, -1, -1)
    ;label
    $freq_lbl = GUICtrlCreateLabel("Frequenz Hz", 16, 16, 64, 17)
    $grph_lbl = GUICtrlCreateLabel("Wave Form", 16, 184, 59, 17)
    $samp_lbl = GUICtrlCreateLabel("Sampling Bits/Sec", 16, 48, 90, 17)
    $bits_lbl = GUICtrlCreateLabel("Bits per Sample", 16, 120, 90, 17)
    $chan_lbl = GUICtrlCreateLabel("Channels", 16, 152, 48, 17)
    $show_lbl = GUICtrlCreateLabel("Show Samples ", 16, 216, 77, 17)
    $volm_lbl = GUICtrlCreateLabel("Volume", 16, 80, 39, 17)

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

    ;input
    Global $freq_inp = GUICtrlCreateInput("440.0", 120, 16, 81, 21, $ES_NUMBER)
    Global $volm_inp = GUICtrlCreateInput("50", 120, 80, 81, 21, $ES_NUMBER)
    ;combo
    $bits_cbo = GUICtrlCreateCombo("", 120, 120, 81, 25)
    GUICtrlSetData(-1, "8|16|24", "16")
    $samp_cbo = GUICtrlCreateCombo("", 120, 48, 81, 21)
    GUICtrlSetData(-1, "8000|11025|12000|16000|22050|24000|32000|44100|48000", "22050")
    $chan_cbo = GUICtrlCreateCombo("", 120, 152, 81, 25)
    GUICtrlSetData(-1, "1|2|4", "1")
    $form_cbo = GUICtrlCreateCombo("", 120, 184, 81, 25)
    GUICtrlSetData(-1, "Sinus|Dreieck|Rechteck", "Sinus")
    ;slider
    $freq_sld = GUICtrlCreateSlider(216, 16, 217, 25)
    GUICtrlSetLimit($freq_sld, 20000, 1)
    GUICtrlSetData($freq_sld, 441)
    $volm_sld = GUICtrlCreateSlider(216, 80, 217, 25)
    GUICtrlSetData($volm_sld, 100, 50)
    GUICtrlSetData($volm_sld, 50)
    ;button
    $test_btn = GUICtrlCreateButton("Test Channels", 224, 152, 105, 25, $WS_GROUP)
    $play_btn = GUICtrlCreateButton("Play Wave", 16, 400, 129, 25, $WS_GROUP)
    $save_btn = GUICtrlCreateButton("Save Wave to File", 160, 400, 129, 25, $WS_GROUP)
    $exit_btn = GUICtrlCreateButton("Exit", 304, 400, 129, 25, $WS_GROUP)
    ;graphic
    $graphic_line = GUICtrlCreateGraphic(16, 235, 420, 150)

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

    GUISetState(@SW_SHOW)

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

    While Sleep(20)
    $nMsg = GUIGetMsg(1)
    Switch $nMsg[0]
    Case $GUI_EVENT_CLOSE
    Exit
    Case $play_btn
    If GUICtrlRead($play_btn) = "Stop playing" Then
    GUICtrlSetData($play_btn, "Play Wave")
    _playsound("") ;sound stoppen
    Else
    GUICtrlSetData($play_btn, "Stop playing")
    _playwave(0) ;sound abspielen
    EndIf
    Case $GUI_EVENT_MOUSEMOVE
    $mpos=GUIGetCursorInfo()
    if $mpos[4]=$freq_sld and $mpos[2] then _freq_sld() ;nur wenn maus über slider und mausbutton down, dann neue frequenz holen
    if $mpos[4]=$volm_sld and $mpos[2] then _volm_sld()
    Case $save_btn
    _playwave(1) ;sound speichern
    EndSwitch
    WEnd

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

    Func _playwave($save = 0) ;bei save=1 datei speichern

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

    $sekunden = 5 ;so lange soll der ton inb der abgespeicherten Datei abgespielt werden
    $samplingrate = GUICtrlRead($samp_cbo) ;abtastungen pro sekunde
    $BitsPerSample = GUICtrlRead($bits_cbo);guictrlread( ;8,16,24 äquivalent die "Farbtiefe bei einem Bild",
    $Channels = GUICtrlRead($chan_cbo) ;1,2,4, Kanäle, mono, stereo usw

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

    $block = Int($Channels * $BitsPerSample / 8) ;1
    $bytes = $samplingrate * $block
    $samplefaktor = $BitsPerSample / 8 ;lokale hilfsvariable
    $filesize = $samplefaktor * $sekunden * $samplingrate * $Channels + 44 - 8

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

    ;struktur mit dem Header einer WAV-Datei erstellen
    Local $struct = DllStructCreate("byte[" & $samplefaktor * $sekunden * $samplingrate * $Channels + 44 & "]") ;platz für unser sampling

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

    Local $s = "char RIFF [4];" & _ ;RIFF
    "uint FileSize;" & _ ;Dateigröße-8 Bytes
    "char WAVE [4];" & _ ;WAVE
    "char fmt [4];" & _ ;fmt Header Signatur
    "uint fmt_len;" & _ ;länge restl. fmt
    "word Format;" & _ ;Datenformat s. Tabelle z.B. Wikipedia 1=PCM
    "word Channels;" & _ ;Anzahl Kanäle 1=MONO
    "uint Samplerate;" & _ ;Abtastrate pro Sekunde (22050)
    "uint Bytes;" & _ ;Abtastrate * Block (22050)
    "word Block;" & _ ;Channels * BitsPerSample / 8 (1)
    "word BitsPerSample;" & _ ;8, 16, oder 24 (8)
    "char DATA [4];" & _ ;DATA Header Signatur
    "uint Len;" ;Länge des folgenden Datenblocks

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

    Switch $samplefaktor ;je nach einstellungen platz für die wav-Daten reservieren
    Case 1
    $s &= "byte WAVDATA[" & $sekunden * $samplefaktor * $samplingrate * $Channels & "]"
    Case 2
    $s &= "word WAVDATA[" & $sekunden * $samplefaktor * $samplingrate * $Channels & "]"
    Case 4
    $s &= "dword WAVDATA[" & $sekunden * $samplefaktor * $samplingrate * $Channels & "]"
    EndSwitch

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

    Local $wavstruct = DllStructCreate($s, DllStructGetPtr($struct)) ;struct "überlagern" damit alle Daten byteweise in eine Datei geschrieben werden können

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

    ;Unsere Daten für die Sinuswelle
    $f = GUICtrlRead($freq_inp) ;frequenz in hertz
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $f = ' & $f & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $w = 2 * $pi * $f ;omega=2*pi*f für Maschinenbauer gilt: OMEGA das weiß ich, Pi mal N durch dreißig!!! :o)
    $Amplitude = (GUICtrlRead($volm_inp) * 1.81019) ^ $samplefaktor ;Lautstärke, bei 8 bit maximal 2^8, bei 16 bit maximal 2^16
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Amplitude = ' & $Amplitude & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $i = 0 ;anzahl der geschriebenen bytes (funktionswerte)
    If $save = 1 Then
    $f = 1 / $sekunden ;falls gespeichert werden soll, anzahl Sekunden festlegen
    Else
    GUICtrlDelete($graphic_line) ;grafik kurven-linien löschen
    GUICtrlSetColor($graphic_line, 0)
    $graphic_line = GUICtrlCreateGraphic(16, 235, 420, 150) ;kurven-linien
    GUICtrlSetGraphic(-1, $GUI_GR_MOVE, 0, 75)
    GUICtrlSetGraphic($graphic_line, $GUI_GR_LINE, 420, 75)

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

    GUICtrlSetColor($graphic_line, 0xFF0000)
    GUICtrlSetBkColor($graphic_line, 0xFFFFFF)
    GUICtrlSetGraphic($graphic_line, $GUI_GR_COLOR, 0xFF0000, 0xFFFFF0)
    ;GUICtrlSetGraphic($graphic_line, $GUI_GR_RECT, 0, 0, 20, 150)

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

    EndIf
    ;hier gehts los, wir erstellen eine komplette sinuswelle, diese wird so lange wiederholt, bis die Abspieldauer in sekunden erreicht ist
    For $t = 0 To 1 / $f Step 1 / $samplingrate ;samplingrate y(t)-Werte ()Amplituden) ermitteln
    $i += 1 ;anzahl der samples
    $yt = Int($Amplitude * Sin($w * $t)) ;unsere altbekannte formel
    If $i < 210 Then ConsoleWrite($i & " " & $yt & @CRLF)
    DllStructSetData($wavstruct, "WAVDATA", $yt, $i) ;schreiben von y(t) in die struct
    If $save = 0 Then ;wenn speichern gewählt, keine welle zeichnen
    GUICtrlSetGraphic($graphic_line, $GUI_GR_MOVE, Int(420 * $f * $t), 75) ;punkt auf x-achse
    GUICtrlSetGraphic($graphic_line, $GUI_GR_LINE, Int($t * 420 * $f), Int(75 - ($yt / $Amplitude * 75 * GUICtrlRead($volm_inp) / 100))) ;linie zeichnen (hoehe y(t))
    EndIf

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

    If $Channels = 2 Then ;wenn 2 kanäle (stereo), dann das byte für den 2. Kanal hinzufügen
    $i += 1
    DllStructSetData($wavstruct, "WAVDATA", $yt, $i)
    EndIf
    Next
    GUICtrlSetGraphic($graphic_line, $GUI_GR_REFRESH)
    ;jetzt werden die Daten in die struct geschrieben, es entsteht eine WAV-Datei im Speicher
    DllStructSetData($wavstruct, "RIFF", "RIFF")
    DllStructSetData($wavstruct, "FileSize", $filesize)
    DllStructSetData($wavstruct, "WAVE", "WAVE")
    DllStructSetData($wavstruct, "fmt", "fmt ")
    DllStructSetData($wavstruct, "fmt_len", 16)
    DllStructSetData($wavstruct, "Format", 1) ;PCM
    DllStructSetData($wavstruct, "Channels", $Channels)
    DllStructSetData($wavstruct, "Samplerate", $samplingrate)
    DllStructSetData($wavstruct, "Bytes", $bytes) ;samplerate*block
    DllStructSetData($wavstruct, "Block", $block)
    DllStructSetData($wavstruct, "BitsPerSample", $BitsPerSample)
    DllStructSetData($wavstruct, "DATA", "data")
    DllStructSetData($wavstruct, "Len", ($samplingrate / $f * $Channels * $samplefaktor));hier wird NUR DIE LÄNGE DER ERSTEN SINUSWELLE eingetragen, um den Sound im speicher abzuspielen
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : ($samplingrate / $f * $Channels * $samplefaktor) = ' & ($samplingrate / $f * $Channels * $samplefaktor) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

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

    ;~ $data = ""
    ;~ For $i = 1 To 14 ;anzeigen des WAV-Headers
    ;~ $data &= DllStructGetData($wavstruct, $i) & @CRLF
    ;~ Next
    ;MsgBox(0, "Daten WAV-Header", StringLeft($data, 100))

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

    If $save = 0 Then
    _playsound("") ;aktuellen sound beenden
    _Playsound(DllStructGetPtr($wavstruct), 1) ;abspielen des sounds aus dem speicher, Ton wird immer wiederholt
    Else
    $sdat = DllStructGetData($struct, 1) ;struktur in eine Datei schreiben
    $wavdata = StringLeft(BinaryToString($sdat), $sekunden * $samplingrate * $Channels * $samplefaktor + 44)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $wavdata = ' & StringLen($wavdata) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $wav = FileOpen("test1.wav", 18)
    $bindata = FileWrite($wav, $wavdata)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $bindata = ' & $bindata & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    FileClose($wav)
    ShellExecute("test1.wav") ;wavedatei abspielen
    EndIf
    ;Msgbox(0,"Ton mit Frequenz "&$f&" Hz","Spieldauer "&$sekunden&" Sekunden",$sekunden)
    EndFunc ;==>_playwave

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

    Func _freq_sld()
    If GUICtrlRead($freq_sld) = $freq_sliderold Then Return
    $freq_sliderold = GUICtrlRead($freq_sld)
    GUICtrlSetData($freq_inp, GUICtrlRead($freq_sld))
    If GUICtrlRead($play_btn) = "Stop playing" Then _playwave()
    EndFunc ;==>_freq_sld

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

    Func _volm_sld()
    If GUICtrlRead($volm_sld) = $volm_sliderold Then Return
    $volm_sliderold = GUICtrlRead($freq_sld)
    GUICtrlSetData($volm_inp, GUICtrlRead($volm_sld))
    If GUICtrlRead($play_btn) = "Stop playing" Then _playwave()
    EndFunc ;==>_volm_sld

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

    Func _PlaySound($sSoundFile, $mem = 0) ;mem=1 spielt sound aus dem speicher, dann muss $sSoundfile der pointer zum anfang der struct sein
    Local Const $SND_ALIAS = 0x10000
    Local Const $SND_ALIAS_ID = 0x110000
    Local Const $SND_APPLICATION = 0x80
    Local Const $SND_ASYNC = 0x1
    Local Const $SND_FILENAME = 0x20000
    Local Const $SND_LOOP = 0x8
    Local Const $SND_MEMORY = 0x4
    Local Const $SND_NODEFAULT = 0x2
    Local Const $SND_NOSTOP = 0x10
    Local Const $SND_NOWAIT = 0x2000
    Local Const $SND_PURGE = 0x40
    Local Const $SND_RESOURCE = 0x40004
    Local Const $SND_SYNC = 0x0
    If $sSoundFile = "" Then
    DllCall('winmm.dll', 'int', 'PlaySoundA', 'ptr', 0, 'int', 0, 'int', 0)
    Return
    EndIf
    If $mem = 1 Then
    $a = DllCall('winmm.dll', 'int', 'PlaySoundA', 'ptr', $sSoundFile, 'int', 0, 'int', BitOR(4, 1, 8))

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

    Else
    $a = DllCall('winmm.dll', 'int', 'PlaySoundA', 'str', $sSoundFile, 'int', 0, 'int', BitOR(1, 2, 0x10))
    EndIf
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $a = ' & $a[0] & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    EndFunc ;==>_PlaySound

    [/autoit]
  • Hab mich mal an weiteren Waveformen versucht...

    Spoiler anzeigen
    [autoit]

    #include <EditConstants.au3>
    #include <GuiComboBoxEx.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>

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

    ;Das Script erstellt eine WAV-Datei im Speicher, spielt diese ab und speichert anschließend in eine Datei

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

    ;Opt("GUIOnEventMode", 1)

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

    Global Const $pi = 4 * ATan(1) ;pi=3,1415926....
    Global $struct, $wavstruct, $sekunden, $samplingrate, $Channels, $samplefaktor
    Global $freq_sliderold = 440, $volm_sliderold = 50

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

    $gui = GUICreate("Wave Generator ", 450, 450, -1, -1)
    ;label
    $freq_lbl = GUICtrlCreateLabel("Frequenz Hz", 16, 16, 64, 17)
    $grph_lbl = GUICtrlCreateLabel("Wave Form", 16, 184, 59, 17)
    $samp_lbl = GUICtrlCreateLabel("Sampling Bits/Sec", 16, 48, 90, 17)
    $bits_lbl = GUICtrlCreateLabel("Bits per Sample", 16, 120, 90, 17)
    $chan_lbl = GUICtrlCreateLabel("Channels", 16, 152, 48, 17)
    $show_lbl = GUICtrlCreateLabel("Show Samples ", 16, 216, 77, 17)
    $volm_lbl = GUICtrlCreateLabel("Volume", 16, 80, 39, 17)

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

    ;input
    Global $freq_inp = GUICtrlCreateInput("440.0", 120, 16, 81, 21, $ES_NUMBER)
    Global $volm_inp = GUICtrlCreateInput("50", 120, 80, 81, 21, $ES_NUMBER)
    ;combo
    $bits_cbo = GUICtrlCreateCombo("", 120, 120, 81, 25)
    GUICtrlSetData(-1, "8|16|24", "16")
    $samp_cbo = GUICtrlCreateCombo("", 120, 48, 81, 21)
    GUICtrlSetData(-1, "8000|11025|12000|16000|22050|24000|32000|44100|48000", "44100")
    $chan_cbo = GUICtrlCreateCombo("", 120, 152, 81, 25)
    GUICtrlSetData(-1, "1|2|4", "1")
    $form_cbo = GUICtrlCreateCombo("", 120, 184, 81, 25)
    GUICtrlSetData(-1, "Sinus|Dreieck|Rechteck|Sägezahn aufsteigend|Sägezahn absteigend", "Sinus")
    ;slider
    $freq_sld = GUICtrlCreateSlider(216, 16, 217, 25)
    GUICtrlSetLimit($freq_sld, 20000, 1)
    GUICtrlSetData($freq_sld, 441)
    $volm_sld = GUICtrlCreateSlider(216, 80, 217, 25)
    GUICtrlSetData($volm_sld, 100, 50)
    GUICtrlSetData($volm_sld, 50)
    ;button
    $test_btn = GUICtrlCreateButton("Test Channels", 224, 152, 105, 25, $WS_GROUP)
    $play_btn = GUICtrlCreateButton("Play Wave", 16, 400, 129, 25, $WS_GROUP)
    $save_btn = GUICtrlCreateButton("Save Wave to File", 160, 400, 129, 25, $WS_GROUP)
    $exit_btn = GUICtrlCreateButton("Exit", 304, 400, 129, 25, $WS_GROUP)
    ;graphic
    $graphic_line = GUICtrlCreateGraphic(16, 235, 420, 150)

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

    GUISetState(@SW_SHOW)

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

    While Sleep(20)
    $nMsg = GUIGetMsg(1)
    Switch $nMsg[0]
    Case $GUI_EVENT_CLOSE, $exit_btn
    Exit
    Case $play_btn
    If GUICtrlRead($play_btn) = "Stop playing" Then
    GUICtrlSetData($play_btn, "Play Wave")
    _playsound("") ;sound stoppen
    Else
    GUICtrlSetData($play_btn, "Stop playing")
    _playwave(0) ;sound abspielen
    EndIf
    Case $GUI_EVENT_MOUSEMOVE
    $mpos = GUIGetCursorInfo()
    If $mpos[4] = $freq_sld And $mpos[2] Then _freq_sld() ;nur wenn maus über slider und mausbutton down, dann neue frequenz holen
    If $mpos[4] = $volm_sld And $mpos[2] Then _volm_sld()
    Case $save_btn
    _playwave(1) ;sound speichern
    EndSwitch
    WEnd

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

    Func _playwave($save = 0) ;bei save=1 datei speichern

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

    $sekunden = 5 ;so lange soll der ton inb der abgespeicherten Datei abgespielt werden
    $samplingrate = GUICtrlRead($samp_cbo) ;abtastungen pro sekunde
    $BitsPerSample = GUICtrlRead($bits_cbo);guictrlread( ;8,16,24 äquivalent die "Farbtiefe bei einem Bild",
    $Channels = GUICtrlRead($chan_cbo) ;1,2,4, Kanäle, mono, stereo usw
    Local $iType, $nTemp
    Switch GUICtrlRead($form_cbo)
    Case "Square", "Rechteck"
    $iType = 1
    Case "Triangle", "Dreieck"
    $iType = 2
    Case "Sawtooth ascending", "Sägezahn aufsteigend"
    $iType = 3
    Case "Sawtooth descending", "Sägezahn absteigend"
    $iType = 4
    Case Else
    $iType = 0
    EndSwitch
    ConsoleWrite("iType: " & $iType & @LF)

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

    $block = Int($Channels * $BitsPerSample / 8) ;1
    $bytes = $samplingrate * $block
    $samplefaktor = $BitsPerSample / 8 ;lokale hilfsvariable
    $filesize = $samplefaktor * $sekunden * $samplingrate * $Channels + 44 - 8

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

    ;struktur mit dem Header einer WAV-Datei erstellen
    Local $struct = DllStructCreate("byte[" & $samplefaktor * $sekunden * $samplingrate * $Channels + 44 & "]") ;platz für unser sampling

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

    Local $s = "char RIFF [4];" & _ ;RIFF
    "uint FileSize;" & _ ;Dateigröße-8 Bytes
    "char WAVE [4];" & _ ;WAVE
    "char fmt [4];" & _ ;fmt Header Signatur
    "uint fmt_len;" & _ ;länge restl. fmt
    "word Format;" & _ ;Datenformat s. Tabelle z.B. Wikipedia 1=PCM
    "word Channels;" & _ ;Anzahl Kanäle 1=MONO
    "uint Samplerate;" & _ ;Abtastrate pro Sekunde (22050)
    "uint Bytes;" & _ ;Abtastrate * Block (22050)
    "word Block;" & _ ;Channels * BitsPerSample / 8 (1)
    "word BitsPerSample;" & _ ;8, 16, oder 24 (8)
    "char DATA [4];" & _ ;DATA Header Signatur
    "uint Len;" ;Länge des folgenden Datenblocks

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

    Switch $samplefaktor ;je nach einstellungen platz für die wav-Daten reservieren
    Case 1
    $s &= "byte WAVDATA[" & $sekunden * $samplefaktor * $samplingrate * $Channels & "]"
    Case 2
    $s &= "word WAVDATA[" & $sekunden * $samplefaktor * $samplingrate * $Channels & "]"
    Case 4
    $s &= "dword WAVDATA[" & $sekunden * $samplefaktor * $samplingrate * $Channels & "]"
    EndSwitch

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

    Local $wavstruct = DllStructCreate($s, DllStructGetPtr($struct)) ;struct "überlagern" damit alle Daten byteweise in eine Datei geschrieben werden können

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

    ;Unsere Daten für die Sinuswelle
    $f = GUICtrlRead($freq_inp) ;frequenz in hertz
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $f = ' & $f & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $w = 2 * $pi * $f ;omega=2*pi*f für Maschinenbauer gilt: OMEGA das weiß ich, Pi mal N durch dreißig!!! :o)
    ConsoleWrite("!W: " & $w & @LF)
    $Amplitude = (GUICtrlRead($volm_inp) * 1.81019) ^ $samplefaktor ;Lautstärke, bei 8 bit maximal 2^8, bei 16 bit maximal 2^16
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Amplitude = ' & $Amplitude & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $i = 0 ;anzahl der geschriebenen bytes (funktionswerte)
    If $save = 1 Then
    $f = 1 / $sekunden ;falls gespeichert werden soll, anzahl Sekunden festlegen
    Else
    GUICtrlDelete($graphic_line) ;grafik kurven-linien löschen
    GUICtrlSetColor($graphic_line, 0)
    $graphic_line = GUICtrlCreateGraphic(16, 235, 420, 150) ;kurven-linien
    GUICtrlSetGraphic(-1, $GUI_GR_MOVE, 0, 75)
    GUICtrlSetGraphic($graphic_line, $GUI_GR_LINE, 420, 75)

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

    GUICtrlSetColor($graphic_line, 0xFF0000)
    GUICtrlSetBkColor($graphic_line, 0xFFFFFF)
    GUICtrlSetGraphic($graphic_line, $GUI_GR_COLOR, 0xFF0000, 0xFFFFF0)
    ;GUICtrlSetGraphic($graphic_line, $GUI_GR_RECT, 0, 0, 20, 150)

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

    EndIf
    ;hier gehts los, wir erstellen eine komplette sinuswelle, diese wird so lange wiederholt, bis die Abspieldauer in sekunden erreicht ist
    For $t = 0 To 1 / $f Step 1 / $samplingrate ;samplingrate y(t)-Werte ()Amplituden) ermitteln
    $i += 1 ;anzahl der samples
    $yt = Int($Amplitude * Sin($w * $t)) ;unsere altbekannte formel
    Switch $iType
    Case 0 ; Sine
    Case 1 ; Square
    Switch $yt
    Case 0 To $Amplitude
    $yt = $Amplitude
    Case Else
    $yt = -$Amplitude
    EndSwitch
    Case 2 ; Triangle
    $nTemp = Mod($w * $t, $pi) / $pi
    Switch $nTemp
    Case 0 To 0.5
    $nTemp = $Amplitude * $nTemp * 2
    Case Else
    $nTemp = $Amplitude * (1 - $nTemp) * 2
    EndSwitch
    Switch $yt
    Case 0 To $Amplitude
    $yt = $nTemp
    Case Else
    $yt = -$nTemp
    EndSwitch
    Case 3 ; Sawtooth ascending
    $nTemp = Mod($w * $t, $pi * 2) / ($pi * 2)
    $yt = $Amplitude * (-1 + $nTemp * 2)
    Case 4 ; Sawtooth descending
    $nTemp = Mod($w * $t, $pi * 2) / ($pi * 2)
    $yt = $Amplitude * (1 - $nTemp * 2)
    EndSwitch
    If $i < 210 Then ConsoleWrite($i & " " & $yt & @CRLF)
    DllStructSetData($wavstruct, "WAVDATA", $yt, $i) ;schreiben von y(t) in die struct
    If $save = 0 Then ;wenn speichern gewählt, keine welle zeichnen
    GUICtrlSetGraphic($graphic_line, $GUI_GR_MOVE, Int(420 * $f * $t), 75) ;punkt auf x-achse
    GUICtrlSetGraphic($graphic_line, $GUI_GR_LINE, Int($t * 420 * $f), Int(75 - ($yt / $Amplitude * 75 * GUICtrlRead($volm_inp) / 100))) ;linie zeichnen (hoehe y(t))
    EndIf

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

    If $Channels = 2 Then ;wenn 2 kanäle (stereo), dann das byte für den 2. Kanal hinzufügen
    $i += 1
    DllStructSetData($wavstruct, "WAVDATA", $yt, $i)
    EndIf
    Next
    GUICtrlSetGraphic($graphic_line, $GUI_GR_REFRESH)
    ;jetzt werden die Daten in die struct geschrieben, es entsteht eine WAV-Datei im Speicher
    DllStructSetData($wavstruct, "RIFF", "RIFF")
    DllStructSetData($wavstruct, "FileSize", $filesize)
    DllStructSetData($wavstruct, "WAVE", "WAVE")
    DllStructSetData($wavstruct, "fmt", "fmt ")
    DllStructSetData($wavstruct, "fmt_len", 16)
    DllStructSetData($wavstruct, "Format", 1) ;PCM
    DllStructSetData($wavstruct, "Channels", $Channels)
    DllStructSetData($wavstruct, "Samplerate", $samplingrate)
    DllStructSetData($wavstruct, "Bytes", $bytes) ;samplerate*block
    DllStructSetData($wavstruct, "Block", $block)
    DllStructSetData($wavstruct, "BitsPerSample", $BitsPerSample)
    DllStructSetData($wavstruct, "DATA", "data")
    DllStructSetData($wavstruct, "Len", ($samplingrate / $f * $Channels * $samplefaktor));hier wird NUR DIE LÄNGE DER ERSTEN SINUSWELLE eingetragen, um den Sound im speicher abzuspielen
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : ($samplingrate / $f * $Channels * $samplefaktor) = ' & ($samplingrate / $f * $Channels * $samplefaktor) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

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

    ;~ $data = ""
    ;~ For $i = 1 To 14 ;anzeigen des WAV-Headers
    ;~ $data &= DllStructGetData($wavstruct, $i) & @CRLF
    ;~ Next
    ;MsgBox(0, "Daten WAV-Header", StringLeft($data, 100))

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

    If $save = 0 Then
    _playsound("") ;aktuellen sound beenden
    _Playsound(DllStructGetPtr($wavstruct), 1) ;abspielen des sounds aus dem speicher, Ton wird immer wiederholt
    Else
    $sdat = DllStructGetData($struct, 1) ;struktur in eine Datei schreiben
    $wavdata = StringLeft(BinaryToString($sdat), $sekunden * $samplingrate * $Channels * $samplefaktor + 44)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $wavdata = ' & StringLen($wavdata) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $wav = FileOpen("test1.wav", 18)
    $bindata = FileWrite($wav, $wavdata)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $bindata = ' & $bindata & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    FileClose($wav)
    ShellExecute("test1.wav") ;wavedatei abspielen
    EndIf
    ;Msgbox(0,"Ton mit Frequenz "&$f&" Hz","Spieldauer "&$sekunden&" Sekunden",$sekunden)
    EndFunc ;==>_playwave

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

    Func _freq_sld()
    If GUICtrlRead($freq_sld) = $freq_sliderold Then Return
    $freq_sliderold = GUICtrlRead($freq_sld)
    GUICtrlSetData($freq_inp, GUICtrlRead($freq_sld))
    If GUICtrlRead($play_btn) = "Stop playing" Then _playwave()
    EndFunc ;==>_freq_sld

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

    Func _volm_sld()
    If GUICtrlRead($volm_sld) = $volm_sliderold Then Return
    $volm_sliderold = GUICtrlRead($freq_sld)
    GUICtrlSetData($volm_inp, GUICtrlRead($volm_sld))
    If GUICtrlRead($play_btn) = "Stop playing" Then _playwave()
    EndFunc ;==>_volm_sld

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

    Func _PlaySound($sSoundFile, $mem = 0) ;mem=1 spielt sound aus dem speicher, dann muss $sSoundfile der pointer zum anfang der struct sein
    Local Const $SND_ALIAS = 0x10000
    Local Const $SND_ALIAS_ID = 0x110000
    Local Const $SND_APPLICATION = 0x80
    Local Const $SND_ASYNC = 0x1
    Local Const $SND_FILENAME = 0x20000
    Local Const $SND_LOOP = 0x8
    Local Const $SND_MEMORY = 0x4
    Local Const $SND_NODEFAULT = 0x2
    Local Const $SND_NOSTOP = 0x10
    Local Const $SND_NOWAIT = 0x2000
    Local Const $SND_PURGE = 0x40
    Local Const $SND_RESOURCE = 0x40004
    Local Const $SND_SYNC = 0x0
    If $sSoundFile = "" Then
    DllCall('winmm.dll', 'int', 'PlaySoundA', 'ptr', 0, 'int', 0, 'int', 0)
    Return
    EndIf
    If $mem = 1 Then
    $a = DllCall('winmm.dll', 'int', 'PlaySoundA', 'ptr', $sSoundFile, 'int', 0, 'int', BitOR(4, 1, 8))

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

    Else
    $a = DllCall('winmm.dll', 'int', 'PlaySoundA', 'str', $sSoundFile, 'int', 0, 'int', BitOR(1, 2, 0x10))
    EndIf
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $a = ' & $a[0] & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    EndFunc ;==>_PlaySound

    [/autoit]
  • jaaa...so sollte es werden :thumbup:

    Das Script ist noch ziemlich buggy, aber das Gröbste klappt schon mal. Ab und zu hängt es sich beim ändern der Frequenz während des Abspielens auf....

    Eigentlich hatte ich es als "Steuermodul" für die Ausgabe einer elektrischen Spannung über den LineOUT für Bastelkram vorgesehen. Gewissermaßen als Ersatz für die weggefallenen RS232 und parallelen Schnittstellen....