Autor Beitrag
Killmag10
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 297

Suse Linux / DOS / Windows All In One ;)
D4 / D2005
BeitragVerfasst: So 08.07.07 16:00 
Hi

ich versuche mit einen TServerSocket und TClientSocket raw audiodaten zu senden, jedoch kommt dabei nur schrott an.

weis jehmand worans liegen könnte ?

mfg. Killmag10

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
procedure TForm1.ServerClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  i,l   :integer;
  data  :Pointer;
  n     :integer;
  value :TMemoryStream;
  wert  :smallint;
begin


l:=socket.ReceiveLength;
getmem(data,l);

try
Socket.ReceiveBuf(data^,l-1);
except
ListBox1.Items.Add('Fehler !');
AudioIn1.StopGracefully;
end;


pb1.Position:=0;

N := l Div 2;

value:=TMemoryStream.Create;
value.SetSize(l);
value.Seek(0,soFromBeginning);
value.Write(data,l);
value.Seek(0,soFromBeginning);

for i:=0 to N-2 do
    begin

    value.Read(wert,2);

    if pb1.Position<trunc(wert/(32767/100)) then pb1.Position:=trunc(wert/(32767/100));

    end;

freemem(data);

end;


function TForm1.AudioIn1BufferFilled(Buffer: PChar;
  var Size: Integer): Boolean;
var
  n,i   :integer;
  p     :^smallint;
  value :smallint;
begin

balken1.Position:=0;
client.Address:='127.0.0.1';
client.Port:=portnummer;
client.Open;
Application.ProcessMessages;
balken1.Position:=30;
Client.Socket.SendBuf(Buffer,size);
Application.ProcessMessages;
client.Close;
balken1.Position:=90;



pb2.Position:=0;

N := Size Div 2;
p := Pointer(Buffer);

for i:=0 to N-1 do
    begin
    value:=p^;
    inc(p);

    if pb2.Position<trunc(value/(32767/100)) then begin
       pb2.Position:=trunc(value/(32767/100));
       Label1.Caption:=inttostr(trunc(value/(32767/100)));
    end;

end;

Result:=true;
end;

_________________
Mega-inkompetente Computer-ruinierende Organisation spioniert ohne funktionierende Technik
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: So 08.07.07 16:21 
Moin!

Dein Code kann so nicht funktionieren, du wertest z.B. gar nicht die Anzahl der gelesenen Bytes aus. :mahn: Siehe FAQ-Beitrag

Schau dir mal diese Kompos an, damit ist das sicher einfacher, wenn es ereignisorientiert sein soll. :idea:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Killmag10 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 297

Suse Linux / DOS / Windows All In One ;)
D4 / D2005
BeitragVerfasst: Mo 09.07.07 01:08 
Zitat:
Dein Code kann so nicht funktionieren, du wertest z.B. gar nicht die Anzahl der gelesenen Bytes aus. Siehe FAQ-Beitrag


doch kann aber nur unter gewissen umständen, habs aber natürlich geändert

der eigendliche fehler wahr jedoch

ausblenden Delphi-Quelltext
1:
Client.Socket.SendBuf(Buffer,size);					


muss in

ausblenden Delphi-Quelltext
1:
Client.Socket.SendBuf(Buffer^,size);					


geändert werden, weil ein pointer allein nütz den andern nicht viel ^^

_________________
Mega-inkompetente Computer-ruinierende Organisation spioniert ohne funktionierende Technik
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mo 09.07.07 14:41 
Moin!

BTW:
user profile iconKillmag10 hat folgendes geschrieben:
ausblenden Delphi-Quelltext
1:
AudioIn1.StopGracefully;					

Was´n das für eine spannende Kompo? ;)

user profile iconKillmag10 hat folgendes geschrieben:
doch kann

Schon klar, eigener unsauberer Code ist immer ein ganz kleines bischen sauberer, als fremder... :zwinker:

user profile iconKillmag10 hat folgendes geschrieben:
aber nur unter gewissen umständen,

Yip, unter anderem, weil du raw stream open end data sendest. :mahn: Allerdings, wenn die Samples nicht genau 1 Byte groß sind, produzierst du durch einen Versatz von einem Byte beim Senden/Empfangen wieder Schrott... :?

user profile iconKillmag10 hat folgendes geschrieben:
habs aber natürlich geändert

Wenn du schon dabei bist, dann hätte ich auch noch diese Vorschläge zu machen: ;)

Du erzeugst einen MemoryStream:
ausblenden Delphi-Quelltext
1:
value :TMemoryStream;					

aber gibst ihn nicht wieder frei! :shock:

Hier holst du Speicher, den du zwar wenigstens wieder freigibst, aber das ganze machst du viel zu oft:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
l:=socket.ReceiveLength;  
getmem(data,l);  
//...
freemem(data);

Bei jedem Ereignis wird wieder Speicher angefordert und freigegeben, das zerstückelt dir auf Dauer auch den Heap! :mahn: Anstatt auch noch einen Memorystream anzulegen, bietet es sich an, einen globalen Empfangspuffer zu verwenden (mehr als 8kb kommen ja nie auf einmal an!) und die Werte daraus direkt zu verarbeiten. Das darf dann auch gerne ein Stream sein, dann hast du auch die Möglichkeit, die Daten zu queuen. :idea:

Du liest immer ein Byte zu wenig: :nixweiss:
ausblenden Delphi-Quelltext
1:
Socket.ReceiveBuf(data^,l-1);					


Das hier ist potenziell defekter Code: :hair:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
client.Open;
Application.ProcessMessages;
Client.Socket.SendBuf(Buffer,size);
Application.ProcessMessages;
client.Close;

Grund: Niemand garantiert, dass der Socket nach dem Open und ("nur") dem folgenden MessageLoopCall tatsächlich schon connected ist, damit der Send-Call erfolgreich ist (besonders nicht über´s Internet; lokal mag das ja noch gehen... ist aber trotzdem ein übler Hack)! Du musst (im non-blocking-mode) auf das OnClientConnect-Ereignis warten, wenn du nicht mit "zufällig" auftretenden Exceptions kämpfen willst! :mahn: Das gleiche nach dem Senden: "nur" ein MessageLoopCall mag bei lokalen Transfers (also nicht zu einem anderen System per Netzwerk, sondern zu localhost) ja gerade so noch laufen, der folgende .Close auf den Socket wird dir aber bei einem Internetransfer sicher mal einen solchen kaputt machen... :| Fazit: du behandelst den Socket im non-blocking-mode wie einen im blocking-mode, aber das macht man dann bitte auch in diesem Mode und in einem Thread; alles andere ist kaputt. :roll: :?

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Killmag10 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 297

Suse Linux / DOS / Windows All In One ;)
D4 / D2005
BeitragVerfasst: Mo 09.07.07 18:41 
Das war blos ein stück test code :wink:

türlich pass ich auf das der speicher auch wieder freigegeben wird blos hatte ich gerade getestet woran es liegen könnte und hatte beim posten vergessen das wieder rein zu nehmen. :oops:

_________________
Mega-inkompetente Computer-ruinierende Organisation spioniert ohne funktionierende Technik