Aufzeichnen -> TCP -> Abspielen (BassUDF)

  • Hallo Forum,

    ist es möglich mit der BassUDF Sound auf zu zeichnen und das aufgezeichnete über TCP (oder anderes Protokoll) direkt an einen anderen PC zu schicken welcher es dann sofort wieder abspielt? Also anders gefragt. Wie stelle ich es am besten an einen Stream mit der BassUDF zu erstellen?

    Danke schonmal ;)

  • ja,

    Also: bei den ganzen bass udf beispielen ist eine "TCP_SEND.au3" und eine "TCP_RECEIVE.au3".
    du musst die TCP_RECEIVE.au3 kompilieren und die TCP_SEND.au3 starten, dann hörste alles was du sagst kurz später nochmal ;D

    übers internet musste dann die ip in den scripten ändern, und warscheinlich den port freigeben.

    2 Mal editiert, zuletzt von Alizame (7. August 2012 um 13:13)


  • Wozu denn?
    Nimm doch gratissoftware die sowas schon kann.

    Na warum programmiert man was selber? Weil das vorhandene nicht den eigenen Ansprüchen gerecht wird ;)

    Ich möchte alle meine Sounds von Notebook auf meinen Rechner übertragen, wo sie dann abgespielt werden sollen. Funktioniert auch super mit VLC nur leider mit fast 3 Sekunden Verzögerung. Deswegen hab ich mir gedacht mach ich einfach selber was um die Verzögerung so gering wie möglich zu halten.


    ja,

    Also: bei den ganzen bass udf beispielen ist eine "TCP_SEND.au3" und eine "TCP_RECEIVE.au3".
    du musst die TCP_RECEIVE.au3 kompilieren und die TCP_SEND.au3 starten, dann hörste alles was du sagst kurz später nochmal ;D

    übers internet musste dann die ip in den scripten ändern, und warscheinlich den port freigeben.

    Super! Ziemlich genau das was ich gesucht habe! Hast du noch eine Idee wie man die Verzögerung so weit wie möglich verringern kann? Bitraten umstellen oder so? Befinde mich daheim in einem Gigabitnetzwerk, sollte also eigentlich kein Problem sein oder? ;)
    PS: Momentan hab ich so circa 1 Sekunde verzögerung

  • Um Zeit bei der Recording Funktion zu sparen, kannst du die Größe des RecordingBuffers verkleinern via _Bass_SetConfig.
    Am schnellsten ist Recording via BassASIO.dll

    Aber der Knackpunkt ist glaub ich TCP_Send.
    Kann man da nicht auch die Buffergröße verkleinern, oder sonst die Übertragungsgeschwindigkeit erhöhen?!?...

    E

  • [autoit]

    While 1
    If $iAcceptSocket = -1 Then
    $iAcceptSocket = TCPAccept($iSocket)
    $iSize = _BASS_EXT_MemoryBufferGetSize($aBuffer)
    _BASS_EXT_MemoryBufferGetData($aBuffer, $iSize) ; while not connected -> empty buffer
    ContinueLoop
    EndIf

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

    $iSize = _BASS_EXT_MemoryBufferGetSize($aBuffer)
    If $iSize Then
    $bMp3Data = _BASS_EXT_MemoryBufferGetData($aBuffer, $iSize)
    $iSent = TCPSend($iAcceptSocket, $bMp3Data)
    ConsoleWrite("Bytes: " & BinaryLen($bMp3Data) & " / gesendet: " & $iSent & @CRLF)
    EndIf

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

    Sleep(50)
    WEnd

    [/autoit]

    Bei TCPSend hab ich auch schon nach einem Buffer gesucht, finde aber keinen! Was ich auch noch nicht so ganz verstehe: Laut dem Scriptschnippsel direkt aus der TCP_SEND.au3 hält er solange den Speicher/Buffer leer, bis eine Verbindung besteht (erstes if) - Das versteh ich noch. ABER sobald nur 1 Byte in dem Buffer vorhanden ist sollte er eigentlich in den 2. if-baum gehen und dann auch schon die Daten senden. In die Console schreibt er aber immer dass er 4096 Bytes sendet und ich finde auch irgendwie keinen Grund raus warum er immer bis 4096 bytes wartet. Liefert _BASS_EXT_MemoryBufferGetSize() erst einen Success zurück wenn er voll ist oder wie darf ich das verstehen? Die Hilfe gibt da leider nicht ganz so viele infos :(

  • Naja alles schön und gut was die da schreiben aber soweit komme ich praktisch garnicht, denn ich finde gar keine Einstellugen/Parameter bei denen ich die Buffergröße bestimmen kann.

  • schau mal bei TCPListen() auf den 3. Parameter....
    /EDIT/ sry, MaxPendingConnection gibt nicht den Puffer sondern die Anzahl der maximal möglichen Verbindungen an

    Der Puffer ist uninteressant, die Paketgröße bei TCP ist idR. 1460 (1452) Bytes. Allerdings ist auch das völlig egal, da sowohl 1 Byte Nutzdaten als auch 1MB Nutzdaten versendet werden. Das unterschiedlich schnelle Füllen und Leeren der Eingangs- bzw. Empfangsbuffer übernimmt das Protokoll, AutoIt hat da keine Einflussnahme.

    Sorge dafür, dass der TCPSend() Befehl möglichst große Brocken erhält, in kleinere Pakete aufteilen wird er das von selbst.
    Allerdings steigt dann natürlich auch die Latenz, also ist es die Aufgabe des Programmierers, anhand der vorhandenen Übertragungsgeschwindigkeit die optimale Größe der gesendeten "Brocken" zu bestimmen. Solange mehr Daten gesendet als vom Empfänger verarbeitet werden können, wird der "stream" ohne Unterbrechungen laufen (von der Latenz abgesehen).

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    Einmal editiert, zuletzt von Andy (8. August 2012 um 18:30)

  • Das erklärt natürlich einiges! Brauch ich denn unbedingt encodierte Daten? Kann ich nicht auch einfach den puren Datenstrom schicken und den sofort wieder wiedergeben? Ich mein 1Gbit sollte auch das schaffen oder? ;)

    Ein zweiter Gedanke währe: Wie währe es einfach beim encodieren eine höhere Qualität zu nehmen? Das sollte ja dann die 4096 Bytes schneller füllen, schneller ausgeben und dadurch schneller verschicken oder hab ich da einen mächtigen Denkfehler? ;)

  • Eine neuere Lame Version hilft: http://sourceforge.net/tracker/index.php?func=detail&aid=1588283&group_id=290&atid=350290
    Der Parameter "--flush" bewirkt, dass die Mp3-Daten sofort ausgegeben werden.
    Evtl. muss der Parameter "-X" weggelassen werden!

    Dann kannst du mit den Werten etwas experimentieren.
    z.B. Sleep(10) statt Sleep(50)
    If $hStream And $iSize > 0 Then _BASS_EXT_StreamPutFileBufferData($hStream, $aBuffer, $iSize)
    usw...

    Um den Filestream überhaupt zu erzeugen benötigt Bass.dll allerdings eine gewisse Mindestmenge an Mp3-Daten.
    Der Wert in Zeile 34 darf also nicht zu niedrig sein...

    Natürlich kannst du auch die rohen PCM-Daten verschicken
    Das geht dann in etwa so:

    Spoiler anzeigen
    [autoit]

    #AutoIt3Wrapper_UseX64=n
    #include "Bass.au3"
    #include "BassExt.au3"

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

    If Not FileExists(@ScriptDir & "\TCP_RECEIVE.exe") Then
    MsgBox(0, "ERROR", @ScriptDir & "\TCP_RECEIVE.exe not found" & @CRLF & "please compile TCP_RECEIVE.au3 first")
    Exit
    EndIf

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

    $sIPADDRESS = "127.0.0.1"
    $iPORT = 1234

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

    OnAutoItExitRegister("_FreeBass")

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

    HotKeySet("{ESC}", "_Exit")

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

    _BASS_Startup()
    _BASS_EXT_STARTUP()

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

    _BASS_SetConfig($BASS_CONFIG_REC_BUFFER, 1000)

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

    _BASS_RecordInit(-1)
    $aBuffer = _BASS_EXT_MemoryBufferCreate()
    $hRecord = _BASS_RecordStart(44100, 2, 0, $BASS_EXT_RecordProc, $aBuffer[0])

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

    TCPStartup()
    $iSocket = TCPListen($sIPADDRESS, $iPORT)

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

    $iPid = Run('"' & @ScriptDir & '\TCP_RECEIVE.exe"')

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

    $iAcceptSocket = -1
    While 1
    If $iAcceptSocket = -1 Then
    $iAcceptSocket = TCPAccept($iSocket)
    $iSize = _BASS_EXT_MemoryBufferGetSize($aBuffer)
    _BASS_EXT_MemoryBufferGetData($aBuffer, $iSize) ; while not connected -> empty buffer
    ContinueLoop
    EndIf

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

    $iSize = _BASS_EXT_MemoryBufferGetSize($aBuffer)
    If $iSize Then
    $bMp3Data = _BASS_EXT_MemoryBufferGetData($aBuffer, $iSize)
    $iSent = TCPSend($iAcceptSocket, $bMp3Data)
    ConsoleWrite("Bytes: " & BinaryLen($bMp3Data) & " / gesendet: " & $iSent & @CRLF)
    EndIf

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

    Sleep(10)
    WEnd

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

    Func _Exit()
    Exit
    EndFunc ;==>_Exit

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

    Func _FreeBass()
    ProcessClose($iPid)
    TCPCloseSocket($iAcceptSocket)
    TCPShutdown()
    _BASS_RecordFree()
    _BASS_Free()
    EndFunc ;==>_FreeBass

    [/autoit]
    Spoiler anzeigen
    [autoit]

    #AutoIt3Wrapper_UseX64=n
    #include "Bass.au3"
    #include "BassExt.au3"

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

    $sIPADDRESS = "127.0.0.1"
    $iPORT = 1234

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

    OnAutoItExitRegister("_FreeBass")

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

    _BASS_Startup()
    _BASS_EXT_STARTUP()

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

    _BASS_SetConfig($BASS_CONFIG_UPDATEPERIOD, 80)
    _BASS_SetConfig($BASS_CONFIG_BUFFER, 100)

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

    _BASS_Init(0, -1, 44100, 0, "")

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

    $aBuffer = _BASS_EXT_MemoryBufferCreate()

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

    TCPStartup()
    $ConnectedSocket = TCPConnect($sIPADDRESS, $iPORT)
    If $ConnectedSocket = -1 Then
    MsgBox(0, "", @error)
    Exit
    EndIf

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

    $hStream = _BASS_StreamCreate(44100, 2, 0, $STREAMPROC_PUSH, 0)
    _BASS_ChannelPlay($hStream, 1)

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

    While 1

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

    $bMp3Data = TCPRecv($ConnectedSocket, 88200)
    If BinaryLen($bMp3Data) > 0 Then _BASS_EXT_MemoryBufferAddData($aBuffer, $bMp3Data)

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

    $iSize = _BASS_EXT_MemoryBufferGetSize($aBuffer)
    ToolTip("TCP_REICIVE Buffer size: " & $iSize)
    If $hStream And $iSize > 0 Then _BASS_EXT_StreamPutBufferData($hStream, $aBuffer, $iSize)

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

    Sleep(10)
    WEnd

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

    Func _Exit()
    Exit
    EndFunc ;==>_Exit

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

    Func _FreeBass()
    TCPCloseSocket($ConnectedSocket)
    TCPShutdown()
    _BASS_Free()
    EndFunc ;==>_FreeBass

    [/autoit]

    Die Werte für den Playbackbuffer sind schon fast zu niedrig bei mir.
    Am besten du probierst es auch mal mit BassASIO: _BASS_ASIO_ChannelEnable(True, 0, $BASS_EXT_AsioProc, $aBuffer[0])

    E