Sprach-Streaming mit bass.dll

  • Hallo Leute,

    ich bin heute morgen zufällig über Mikrofon gestolpert.
    Dort geht es über Sprach-Streaming, auch bekannt als VoIP.
    Das fand ich interessant und hab mich deswegen ein bisschen damit beschäftigt.

    Das Beispiel von Eukalyptus und ein anderes Beispiel und mein Wissen :D hab ich dann zusammengeschmissen:
    Jetzt hab ich zwei Skripte:

    stream.au3
    [autoit]

    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_UseUpx=n
    #AutoIt3Wrapper_Res_Description=Stream senden
    #AutoIt3Wrapper_Res_Fileversion=0.1.0.0
    #AutoIt3Wrapper_Res_LegalCopyright=Copyright (C) 2010 by Jan Kirsten
    #AutoIt3Wrapper_Res_Language=1031
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

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

    #include <BassEnc.au3>
    #include <GUIConstantsEx.au3>
    #include <ProgressConstants.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    #include <GuiComboBox.au3>

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

    ;Bass Variablen
    Global $device, $input, $EncHandle, $RecHandle, $Bitrate = 128, $KHZ = 44100, $levels, $levelL = 0, $levelR = 0, $temp, $EncState = False
    ;TCP Variablen
    Global $ConnectedSocket, $szData
    Global $szIPADDRESS = InputBox("IP", "IP-Adresse eingeben:")
    Global $nPORT = 3344

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

    _BASS_STARTUP()
    _BASS_Encode_STARTUP()
    $basscb_dll = DllOpen("BASSCB.dll")

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

    ;Gui
    #Region ### START Koda GUI section ###
    $hGui = GUICreate("Jan-Sprachchat", 322, 281, 347, 158)
    GUICtrlCreateLabel("Audiogerät ausählen:", 10, 20, 172, 12)
    $hDevice = GUICtrlCreateCombo("", 10, 38, 300, 25, BitOR($CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL, $WS_VSCROLL))
    GUICtrlCreateLabel("Eingabetyp auswählen:", 11, 69, 172, 12)
    $hInput = GUICtrlCreateCombo("", 10, 88, 300, 25, BitOR($CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL, $WS_VSCROLL))
    $hPeakL = GUICtrlCreateProgress(10, 136, 300, 10)
    $hPeakR = GUICtrlCreateProgress(10, 151, 300, 10)
    GUICtrlCreateLabel("An Encoder gesendete Daten:", 11, 175, 172, 12)
    $hEncCount = GUICtrlCreateLabel("", 11, 198, 200, 12)
    $hStart = GUICtrlCreateButton("Start", 20, 226, 130, 28, $WS_GROUP)
    $hStop = GUICtrlCreateButton("Stop", 170, 226, 130, 28, $WS_GROUP)
    GUICtrlCreateLabel("Copyright (C) 2010 by Jan Kirsten", 11, 260, 172, 12)
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###

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

    ;Tcp initialisieren
    TCPStartup()

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

    ;Verbindungsversuch
    $ConnectedSocket = TCPConnect($szIPADDRESS, $nPORT)
    ;Bei Fehler
    If @error Then
    MsgBox(4112, "Fehler", "TCP-Connect schlug mit folgendem WSA-Fehler fehl: " & @error)
    Exit
    EndIf

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

    ;Bass Einstellungen
    _BASS_SetConfig($BASS_CONFIG_REC_BUFFER, 1000)

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

    ;Initialisieren
    $device = _GetDevices()
    _BASS_RecordInit($device)
    $input = _GetInputs()
    $RecHandle = _BASS_RecordStart($KHZ, 2, _makelong($BASS_SAMPLE_FX, 500), "_RecCallBack")
    $temp = DllCall($basscb_dll, "dword", "RecordStart", "dword", $KHZ, "dword", 2, "dword", _makelong($BASS_SAMPLE_FX, 10))

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

    $timer = TimerInit()
    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $hDevice
    _SelectDevice()
    Case $hInput
    _SelectInput()
    Case $hStart
    _Start()
    Case $hStop
    _Stop()
    GUICtrlSetState($hGui, $GUI_DISABLE)
    EndSwitch
    Sleep(5)
    $peak = _BASS_ChannelGetLevel($RecHandle)
    If Not @error Then
    $temp = (_LoWord($peak) / 32768) * 100
    If $temp > $levelL Then $levelL = $temp
    $temp = (_HiWord($peak) / 32768) * 100
    If $temp > $levelR Then $levelR = $temp
    GUICtrlSetData($hPeakL, $levelL)
    GUICtrlSetData($hPeakR, $levelR)
    $levelL -= 1
    $levelR -= 1
    EndIf
    If TimerDiff($timer) > 200 Then
    $timer = TimerInit()
    If $EncState Then
    GUICtrlSetData($hEncCount, _BASS_Encode_GetCount( $EncHandle, $BASS_ENCODE_COUNT_IN))
    EndIf
    EndIf
    WEnd

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

    Func _Start()
    GUICtrlSetState($hDevice, $GUI_DISABLE)
    GUICtrlSetState($hInput, $GUI_DISABLE)
    GUICtrlSetState($hStart, $GUI_DISABLE)
    GUICtrlSetState($hStop, $GUI_ENABLE)
    $EncHandle = _BASS_Encode_Start( $RecHandle, 'lame -r -x -b 128 -h - -', 0, "_Callback_Enc")
    $EncState = True
    EndFunc ;==>_Start

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

    Func _Stop()
    GUICtrlSetState($hDevice, $GUI_ENABLE)
    GUICtrlSetState($hInput, $GUI_ENABLE)
    GUICtrlSetState($hStart, $GUI_ENABLE)
    GUICtrlSetState($hStop, $GUI_DISABLE)
    _BASS_Encode_Stop( $EncHandle)
    $EncState = False
    EndFunc ;==>_Stop

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

    Func _RecCallBack($handle, $buffer, $length, $user)
    Return 1
    EndFunc ;==>_RecCallBack

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

    Func _SelectDevice()
    Local $new = _GUICtrlComboBox_GetCurSel($hDevice)
    If $new = $device Then Return
    _BASS_RecordFree()
    _BASS_RecordSetDevice($new)
    _BASS_Recordinit($new)
    GUICtrlSetData($hInput, "", "")
    _GetInputs()
    $RecHandle = _BASS_RecordStart($KHZ, 2, _makelong($BASS_SAMPLE_FX, 500), "_RecCallBack")
    $device = $new
    EndFunc ;==>_SelectDevice

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

    Func _SelectInput()
    Local $new = _GUICtrlComboBox_GetCurSel($hInput)
    If $new = $input Then Return
    _BASS_RecordSetInput($new, $BASS_INPUT_ON, -1)
    $input = $new
    EndFunc ;==>_SelectInput

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

    Func _GetDevices()
    Local $count = 0, $info, $name = "", $sdef = "", $idef = 0
    While 1
    $info = _BASS_RecordGetDeviceInfo($count)
    If @error Then ExitLoop
    $count += 1
    If BitAND($info[2], $BASS_DEVICE_ENABLED) Then $name &= $info[0] & "|"
    If BitAND($info[2], $BASS_DEVICE_DEFAULT) Then
    $sdef = $info[0]
    $idef = $count
    EndIf
    WEnd
    GUICtrlSetData($hDevice, $name, $sdef)
    Return $idef - 1
    EndFunc ;==>_GetDevices

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

    Func _GetInputs()
    Local $count = 0, $info, $name = "", $flags, $sdef = "", $idef = 0
    $info = _BASS_RecordGetInputName($count)
    While $info <> ""
    $flags = _BASS_RecordGetInput($count)
    $count += 1
    $name &= $info & "|"
    If BitAND($flags[0], $BASS_INPUT_OFF) = 0 Then
    $sdef = $info
    $idef = $count
    EndIf
    $info = _BASS_RecordGetInputName($count)
    WEnd
    GUICtrlSetData($hInput, $name, $sdef)
    Return $idef - 1
    EndFunc ;==>_GetInputs

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

    Func _exit()
    ;Bass beenden
    If _BASS_Encode_IsActive( $EncHandle) Then _BASS_Encode_Stop( $EncHandle)
    _BASS_RecordFree()
    ;Tcp beenden
    TCPShutdown()
    Exit
    EndFunc ;==>_Exit

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

    Func _Callback_Enc($handle, $channel, $buffer, $length, $user)
    If Not $length Then
    $length = 4012
    Else
    $length = Dec(StringReplace($length, "0x", ""))
    EndIf
    Local $tempbuffer = DllStructCreate("byte[" & $length & "]", $buffer) ;???
    TCPSend($ConnectedSocket, DllStructGetData($tempbuffer, 1) & @CRLF)
    EndFunc ;==>Bass_Callback_Enc

    [/autoit]


    und

    hear.au3
    [autoit]

    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_UseUpx=n
    #AutoIt3Wrapper_Res_Description=Stream empfangen
    #AutoIt3Wrapper_Res_Fileversion=0.1.0.0
    #AutoIt3Wrapper_Res_LegalCopyright=Copyright (C) 2010 by Jan Kirsten
    #AutoIt3Wrapper_Res_Language=1031
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

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

    ;Includes
    #include <BassEnc.au3>
    #include <GUIConstantsEx.au3>

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

    ;Dlls laden
    _BASS_STARTUP()
    _BASS_Encode_STARTUP()
    $basscb_dll = DllOpen("BASSCB.dll")

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

    ;Variablen
    Global $szIPADDRESS = @IPAddress1
    Global $nPORT = 3344
    Global $MainSocket, $GOOEY, $edit, $ConnectedSocket, $szIP_Accepted
    Global $msg, $recv

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

    ;Bass initialisieren
    _BASS_Init(0, -1, 44100, 0, "")
    Global $stream = _BASS_StreamCreate(44100, 2, 0, $STREAMPROC_PUSH, "")

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

    ;Tcp starten
    TCPStartup()

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

    ;Socket erstellen
    $MainSocket = TCPListen($szIPADDRESS, $nPORT)

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

    ;Bei Fehler
    If $MainSocket = -1 Then Exit

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

    ;Gui
    $GOOEY = GUICreate("Server (IP: " & $szIPADDRESS & ")", 300, 200)
    $edit = GUICtrlCreateEdit("", 10, 10, 280, 180)
    GUISetState()

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

    ;Auf Verbindung warten
    $ConnectedSocket = -1

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

    Do
    $ConnectedSocket = TCPAccept($MainSocket)
    Until $ConnectedSocket <> -1

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

    ;Ip herausfinden
    $szIP_Accepted = SocketToIP($ConnectedSocket)

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

    ;Stream abspielen
    _Bass_ChannelPlay($stream, 1)

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

    While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
    ;Empfangen
    $recv = TCPRecv($ConnectedSocket, 4012)
    If $recv <> "" Then
    ;Abspielen
    $tempbuffer = DllStructCreate("byte[4096]")
    DllStructSetData($tempbuffer, 1, $recv)
    _BASS_StreamPutData($stream, DllStructGetPtr($tempbuffer), 4096)
    ;Daten in Input schreiben
    GUICtrlSetData($edit, _
    $recv & @CRLF & GUICtrlRead($edit))
    EndIf
    WEnd

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

    If $ConnectedSocket <> -1 Then TCPCloseSocket($ConnectedSocket)

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

    Func SocketToIP($SHOCKET)
    Global $sockaddr, $aRet

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

    $sockaddr = DllStructCreate("short;ushort;uint;char[8]")

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

    $aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _
    "ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
    If Not @error And $aRet[0] = 0 Then
    $aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
    If Not @error Then $aRet = $aRet[0]
    Else
    $aRet = 0
    EndIf

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

    $sockaddr = 0

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

    Return $aRet
    EndFunc ;==>SocketToIP

    [/autoit]

    Das Problem ist, dass man nur in Abständen ein Rauschen hört.
    Es kann sein, dass die Übertragung zu langsam ist oder oder oder....
    Kann mir da jemand helfen?

    Im Anhang findet ihr alle Dateien. (Konnte nur 7z, zip war zu groß)
    autoit.de/wcf/attachment/8804/

  • Ich will ja nicht pushen, aber weiß wirklich niemand was?? ;( ;(
    Es wurde schon 55 mal angesehen..
    Please help me

    o
    L_/
    | ||

    This ist janaiky. Copy janaiky into your signature to help him on the war to the Weltherrschaft.

  • Ein normaler Stream muß mit Sampledaten gefüllt werden und nicht mit MP3-Daten - deshalb das Rauschen

    Du kannst entweder richtige Sampledaten versenden (das werden jedoch zu große Datenmengen sein)
    Oder StreamCreateFileUser verwenden; dieser kann auch mit MP3-Daten befüllt werden

    Hab das mal kurz probiert:

    Sender

    Spoiler anzeigen
    [autoit]

    #include <BassEnc.au3>

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

    Global $bMp3Data

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

    Global $ConnectedSocket, $szData
    Global $szIPADDRESS = InputBox("IP", "IP-Adresse eingeben:", "192.168.0.100")
    Global $nPORT = 3344

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

    TCPStartup()

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

    $ConnectedSocket = TCPConnect($szIPADDRESS, $nPORT)
    If @error Then
    MsgBox(4112, "Fehler", "TCP-Connect schlug mit folgendem WSA-Fehler fehl: " & @error)
    Exit
    EndIf

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

    Global $hRecHandle, $hEncHandle

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

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

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

    _BASS_STARTUP()
    _BASS_Encode_STARTUP()
    _BASS_SetConfig($BASS_CONFIG_REC_BUFFER, 1000)

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

    _BASS_RecordInit(-1)
    $hRecHandle = _BASS_RecordStart(44100, 2, _makelong($BASS_SAMPLE_FX, 500), "_Bass_Callback_Rec")
    $hEncHandle = _BASS_Encode_Start($hRecHandle, 'lame -r -x -b128 -h - -', 0, "_Bass_Callback_Enc")

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

    While 1
    If BinaryLen($bMp3Data) Then
    TCPSend($ConnectedSocket, $bMp3Data)
    $bMp3Data = ""
    EndIf
    WEnd

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

    Func _Bass_Callback_Rec($handle, $buffer, $length, $user)
    Return 1
    EndFunc ;==>_Bass_Callback_Rec

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

    Func _Exit()
    If _BASS_Encode_IsActive($hEncHandle) Then _BASS_Encode_Stop($hEncHandle)
    _BASS_RecordFree()
    TCPShutdown()
    Exit
    EndFunc ;==>_EXIT

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

    Func _Bass_Callback_Enc($handle, $channel, $buffer, $length, $user)
    Local $tempbuffer = DllStructCreate("byte[" & $length & "]", $buffer) ;???
    $bMp3Data = Binary($bMp3Data & DllStructGetData($tempbuffer, 1))
    EndFunc ;==>_Bass_Callback_Enc

    [/autoit]

    Empfänger

    Spoiler anzeigen
    [autoit]

    #include <Bass.au3>
    #include <GUIConstantsEx.au3>

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

    _BASS_STARTUP()

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

    Global $bMp3Data

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

    $proc = DllStructCreate("ptr;ptr;ptr;ptr")
    $cb_close = DllCallbackRegister("Bass_Callback_Close", "none", "ptr")
    $cb_length = DllCallbackRegister("Bass_Callback_Length", "uint64", "ptr")
    $cb_read = DllCallbackRegister("Bass_Callback_Read", "dword", "ptr;dword;ptr")
    $cb_seek = DllCallbackRegister("Bass_Callback_Seek", "int", "uint64;ptr")
    DllStructSetData($proc, 1, DllCallbackGetPtr($cb_close))
    DllStructSetData($proc, 2, DllCallbackGetPtr($cb_length))
    DllStructSetData($proc, 3, DllCallbackGetPtr($cb_read))
    DllStructSetData($proc, 4, DllCallbackGetPtr($cb_seek))

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

    Global $szIPADDRESS = @IPAddress1
    Global $nPORT = 3344
    Global $MainSocket, $GOOEY, $edit, $ConnectedSocket, $szIP_Accepted
    Global $msg, $recv, $hStream

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

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

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

    TCPStartup()

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

    $MainSocket = TCPListen($szIPADDRESS, $nPORT)
    If $MainSocket = -1 Then Exit

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

    $GOOEY = GUICreate("Server (IP: " & $szIPADDRESS & ")", 300, 200)
    $edit = GUICtrlCreateEdit("", 10, 10, 280, 180)
    GUISetState()

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

    ;Auf Verbindung warten
    $ConnectedSocket = -1

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

    Do
    $ConnectedSocket = TCPAccept($MainSocket)
    Until $ConnectedSocket <> -1

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

    While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
    $bMp3Data = Binary($bMp3Data & TCPRecv($ConnectedSocket, 4096, 1))
    $iSize = BinaryLen($bMp3Data)
    If $iSize >= 4096 And Not $hStream Then
    $hStream = _BASS_StreamCreateFileUser($STREAMFILE_BUFFERPUSH, BitOR($BASS_STREAM_RESTRATE, $BASS_STREAM_BLOCK), DllStructGetPtr($proc), 0)
    _BASS_ChannelPlay($hStream, False)
    EndIf
    If $iSize And $hStream Then
    $tempbuffer = DllStructCreate("byte[" & $iSize & "]")
    DllStructSetData($tempbuffer, 1, BinaryMid($bMp3Data, 1, $iSize))
    $bMp3Data = BinaryMid($bMp3Data, $iSize)
    _BASS_StreamPutFileData($hStream, DllStructGetPtr($tempbuffer), DllStructGetSize($tempbuffer))
    EndIf
    WEnd

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

    If $ConnectedSocket <> -1 Then TCPCloseSocket($ConnectedSocket)

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

    Func Bass_Callback_Close($pUser)
    ConsoleWrite("Bass wants to close the file." & @CRLF)
    EndFunc ;==>Bass_Callback_Close

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

    Func Bass_Callback_Length($pUser)
    ConsoleWrite("Bass wants the length of the file." & @CRLF)
    ; Returning 0 means Bass will get the data when bass gets it.
    Return 0
    EndFunc ;==>Bass_Callback_Length

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

    Func Bass_Callback_Read($pBuffer, $iSize, $pUser)
    ;ConsoleWrite($iSize & @LF)
    ; Write data to the buffer pointer Bass supplied us with.
    ; Hopefully bass don't want more than 8 kB (the amount of data guarantied to be in the buffer)
    $tBuffer = DllStructCreate("byte[" & $iSize & "]", $pBuffer)
    DllStructSetData($tBuffer, 1, BinaryMid($bMp3Data, 1, $iSize))
    $bMp3Data = BinaryMid($bMp3Data, $iSize)
    ConsoleWrite("Bass wants to read " & $iSize & " bytes. " & BinaryLen($bMp3Data) & " left" & @CRLF)
    Return $iSize
    EndFunc ;==>Bass_Callback_Read

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

    Func Bass_Callback_Seek($iOffset, $pUser)
    ConsoleWrite("Bass wants to seek the file." & @CRLF)
    EndFunc ;==>Bass_Callback_Seek

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

    Func _BASS_StreamCreateFileUser($system, $flags, $procs, $user)
    Local $BASS_ret_ = DllCall($_ghBassDll, "hwnd", "BASS_StreamCreateFileUser", "dword", $system, "dword", $flags, "ptr", $procs, "ptr", $user)
    If @error Then Return SetError(1, 1, 0)
    If $BASS_ret_[0] = 0 Then Return SetError(_BASS_ErrorGetCode(), 0, 0)
    Return $BASS_ret_[0]
    EndFunc ;==>_BASS_StreamCreateFileUser

    [/autoit]


    (Siehe auch http://www.autoitscript.com/forum/index.php?showtopic=98861&view=findpost&p=710665)

    Das Problem ist allerdings, daß Autoit hierfür zu langsam ist und das Senderscript nach einiger Zeit abstürzt
    Das lässt sich beheben indem man die Callback-Funktionen in eine DLL auslagert - Das kann ich aber erst morgen probieren


    mfgE

  • DANKE :thumbup: :thumbup:
    jetzt gehts und dem Programm steht nichts im wege

    bei mir ist es noch nicht abgestürzt.
    edit: ja jetzt ist es mal abgestürzt

    o
    L_/
    | ||

    This ist janaiky. Copy janaiky into your signature to help him on the war to the Weltherrschaft.

    Einmal editiert, zuletzt von janaiky (15. April 2010 um 19:55)