Hi
Ich will einen Sinus-Verlauf berechnen z.B.: 110Hz - 440Hz
Das Ergebnis ist leider nicht korrekt: autoit.de/wcf/attachment/21482/
Die ersten 4 Wellen sind richtig und zeigen eine Sinuskurve in 110, 220, 440 u 880Hz
Die letzten 3 sind Sweeps und sollten jeweils bis 440Hz gehen, allerdings ist die Wellenlänge am Ende deutlich kürzer als erwartet.
Weiß jemand, wie man solche Sweeps berechnet?
Ein möglicher Lösungsansatz wäre:
Immer eine ganze Schwingung mit gleicher Frequenz berechnen. Wellenlänge = Lambda = Samplerate / Frequenz.
Die nächste Schwingung beginnt wieder im Nulldurchgang (Step (in meinem Script "$j") beginnt jedesmal wieder bei 0)
Das ist dann aber kein linearer Verlauf mehr!
Es muss doch eine einfache Lösung geben?!
Vielen Dank!
Spoiler anzeigen
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)
Opt("MustDeclareVars", 1)
Global Const $cPI = ATan(1) * 4
Global Const $c2PI = $cPI * 2
_GDIPlus_Startup()
[/autoit] [autoit][/autoit] [autoit]Global $iWidth = 800
Global $iHeight = 600
Global $hGui = GUICreate("AutoIt GDI+", $iWidth, $iHeight)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
Global $hBmpBuffer = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
Global $hGfxBuffer = _GDIPlus_ImageGetGraphicsContext($hBmpBuffer)
_GDIPlus_GraphicsSetSmoothingMode($hGfxBuffer, 2)
_GDIPlus_GraphicsClear($hGfxBuffer, 0xFFFFFFFF)
Global $hPen = _GDIPlus_PenCreate(0xFFFF0000)
[/autoit] [autoit][/autoit] [autoit]GUIRegisterMsg($WM_PAINT, "_WM_PAINT")
GUISetState()
Global $tSine
[/autoit] [autoit][/autoit] [autoit]Global $aHz[3][2] = [[2]]
$aHz[1][0] = 110
$aHz[1][1] = 1
$aHz[2][0] = 110
$aHz[2][1] = 2000
$tSine = _SineSweep($aHz)
_DrawSine($aHz, $tSine, 80)
$aHz[1][0] = 220
$aHz[2][0] = 220
$tSine = _SineSweep($aHz)
_DrawSine($aHz, $tSine, 160)
$aHz[1][0] = 440
$aHz[2][0] = 440
$tSine = _SineSweep($aHz)
_DrawSine($aHz, $tSine, 240)
$aHz[1][0] = 880
$aHz[2][0] = 880
$tSine = _SineSweep($aHz)
_DrawSine($aHz, $tSine, 320)
$aHz[1][0] = 110
$aHz[2][0] = 440
$tSine = _SineSweep($aHz)
_DrawSine($aHz, $tSine, 400)
Global $aHz[4][2] = [[3]]
$aHz[1][0] = 110
$aHz[1][1] = 1
$aHz[2][0] = 220
$aHz[2][1] = 1000
$aHz[3][0] = 440
$aHz[3][1] = 2000
$tSine = _SineSweep($aHz)
_DrawSine($aHz, $tSine, 480)
$aHz[1][0] = 110
$aHz[2][0] = 110
$aHz[3][0] = 440
$tSine = _SineSweep($aHz)
_DrawSine($aHz, $tSine, 560)
While 1
Sleep(10)
WEnd
Func _DrawSine($aHz, $tSine, $iY, $fAmp = 16)
Local $iSamples = DllStructGetData($tSine, "Cnt")
Local $tCurve = DllStructCreate("float[" & $iSamples * 2 & "]")
Local $fTmp
For $i = 1 To $iSamples
$fTmp = DllStructGetData($tSine, "Sine", $i) * $fAmp
DllStructSetData($tCurve, 1, ($i - 1) / $iSamples * $iWidth, ($i - 1) * 2 + 1)
DllStructSetData($tCurve, 1, $fTmp + $iY, ($i - 1) * 2 + 2)
Next
DllCall($ghGDIPDll, "uint", "GdipDrawCurve2", "hwnd", $hGfxBuffer, "hwnd", $hPen, "ptr", DllStructGetPtr($tCurve), "int", $iSamples, "float", 0.5)
[/autoit] [autoit][/autoit] [autoit]For $i = 1 To $aHz[0][0]
_GDIPlus_GraphicsDrawString($hGfxBuffer, $aHz[$i][0] & "Hz", $aHz[$i][1] / $iSamples * ($iWidth - 40), $iY - $fAmp - 16)
Next
_GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
EndFunc ;==>_DrawSine
Func _SineSweep($aHz, $fRate = 44100.0)
Local $iCnt = $aHz[0][0]
Local $iSamples = $aHz[$iCnt][1]
Local $tSine = DllStructCreate("int Cnt; float Sine[" & $iSamples & "]")
DllStructSetData($tSine, "Cnt", $iSamples)
Local $fHZ_Start, $fHZ_End
Local $iSmp_Start, $iSmp_End
Local $fTmp, $fS
[/autoit] [autoit][/autoit] [autoit]For $i = 1 To $iCnt - 1
$fHZ_Start = $aHz[$i][0]
$fHZ_End = $aHz[$i + 1][0]
ConsoleWrite("> Sweep: " & $fHZ_Start & "Hz -> " & $fHZ_End & "Hz" & " | " & $aHz[$i][1] & " -> " & $aHz[$i + 1][1] & @CRLF)
For $j = $aHz[$i][1] To $aHz[$i + 1][1]
$fTmp = $fHZ_Start + (($fHZ_End - $fHZ_Start) * ($j - $aHz[$i][1]) / ($aHz[$i + 1][1] - $aHz[$i][1]))
ConsoleWrite("! Hz: " & $fTmp & @CRLF)
$fS = Sin($j * $c2PI / ($fRate / $fTmp))
DllStructSetData($tSine, "Sine", $fS, $j)
Next
Next
Return $tSine
EndFunc ;==>_SineSweep
Func _WM_PAINT($hWnd, $iMsg, $wParam, $lParam)
_GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
Return $GUI_RUNDEFMSG
EndFunc ;==>_WM_PAINT
Func _Exit()
_GDIPlus_PenDispose($hPen)
_GDIPlus_GraphicsDispose($hGfxBuffer)
_GDIPlus_BitmapDispose($hBmpBuffer)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_Shutdown()
GUIDelete($hGui)
Exit
EndFunc ;==>_Exit