delphi实现音频传输

2018-10-30

语音聊天在今天是一个很普通的话题,小厮写了一段音频采集、网络传输和播放的程序,实现和简单的语音聊天,但是语音信息没有经过很好的压缩,所以,在局域网外,由于网速问题,效果可能不会很理想
下面我们切入正题。小厮使用的是ACM组件,ACMWaveOut——播放ACMWaveIn——采集ACMDialog——音频格式设置
客户端:定义一个开始按钮,设置音频格式procedure TForm1.Button1Click(Sender: TObject);
var
format:pointer;
beginidudpclient1.Host :='127.0.0.1';
idudpclient1.Port :=8000;
format:=ACMDialog1.OpenDialog;
if format=nil then exit; idudpclient1.Active :=true;
ACMWaveIn1.Open(format);
end;
有声音输入时,触发ACMWaveIn1Data事件,在此事件中,发送音频数据。因为在ACMWaveIn、ACMWaveOut组件中data均类型为pchar,所以在发送和接受过程中要适当的进行类型转换,以确保类型正确。
procedure TForm1.ACMWaveIn1Data(data: Pointer; size: Integer);
var
pchData:pChar;
memStream:TMemoryStream;
begin
pchData:=pchar(data);
if pchData[1]='' then exit;
memStream:=TMemoryStream.Create;
try
memStream.Write(pchData^,size); idudpclient1.SendBuffer(memStream.Memory^,memStream.Size); finally
memStream.Free;
end;end; 服务器端:设定UDPServer监听8000端口,同时设置音频格式 procedure TForm1.Button1Click(Sender: TObject);var
format:pointer;
beginidudpserver1.DefaultPort :=8000;
idudpserver1.Active :=true;
format:=ACMDialog1.OpenDialog;
if format=nil then exit;
ACMWaveOut1.Open(format);
end;UDPServer受到数据时,触发事件UDPRead,在此事件中,调用ACMWaveOut,播放语音数据。
procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
var
a:array of char;
s:string;
pcharplaystr:pchar;
begin
SetLength(a,AData.Size);
AData.ReadBuffer(A[0],AData.Size);
s:=PChar(@A[0]);
pcharplaystr:=pchar(s);
ACMWaveOut1.PlayBack(pcharplaystr,AData.Size); //播放接收到的数据
end; 其实,数据类型转换的代码有很多种写法,但结果应该是相同的,还有这一段,也可以实现var
recData:string;
pcharplaystr:pchar;
myStream:TMemoryStream;
begin
myStream:=TMemoryStream.create;
try mystream.LoadFromStream(AData); Setlength(recdata,myStream.Size);
myStream.Position :=0;
myStream.Read(recdata[1],myStream.Size); //数据流转换成字符串
pcharplaystr:=pchar(recData);
ACMWaveOut1.PlayBack(pcharplaystr,AData.Size); //播放接收到的数据 finally myStream.free; end;end;
我们只要在家一个交互式设计,就可以完成两人的聊天了。

但是,这个简单的音频设计,还有很多问题:一、音频数据未经压缩而传输, 数据量大,难以适应低速网络;二、没有经过特殊处理,网络回声会有影响,但如果使用较好的耳机, 效果还是不错。
阅读54