用过DelphiX进行音频流传输的请进(200分)

  • 主题发起人 主题发起人 寻路
  • 开始时间 开始时间

寻路

Unregistered / Unconfirmed
GUEST, unregistred user!
请问怎样用DelphiX传输声音?
捕捉麦克风的声音,然后传到另外一台计算机,然后播放!
最好有源码!
 
请大家帮帮忙!!!!!
 
UP,大家都说说吧!
 
难到没有人会吗,DFW上面的高手都去哪里了!
如果分不够可以再加~!
 
晕,为什么不用ACM呢?
做《黑洞2000》时候的代码。。。

首先初始化Dirctx
procedure TForm1.Button1Click(Sender: TObject);
begin

try
Capture := TSoundCaptureStream.Create(nil);
capture.CaptureFormat := 8;
Capture.OnFilledBuffer := CaptureStreamEvent;
Capture.Start;
except
capture.Stop;
capture.Free;
capture := nil;
Application.MessageBox('对不起!您的声卡不支持DirectX录音!不能使用此功能!',
'警告信息', MB_OK + MB_ICONINFORMATION);
EXIT;
end;


SVoicesocket.Close;
// 打开自己的UDP协议,发送语音数据
SVoiceSocket.Proto := 'udp';
SVoiceSocket.Addr := '255.255.255.255';
SVoiceSocket.Port := '777';
SVoiceSocket.LocalPort := '0';
SVoiceSocket.Connect;
end;


然后响应相应事件
procedure TForm1.CaptureStreamEvent(Sender: TObject);
var
voice_buf: array[0..1023] of char;
fa_ci, fa_yu, voice_streamsize, i, j: integer;
voicestream: Tmemorystream;
novoice: char;
nosend: boolean;
begin

voicestream := Tmemorystream.Create;
voicestream.Clear;
voicestream.Position := 0;
voicestream.CopyFrom(capture, capture.filledSize);
voicestream.Position := 0;
nosend := false;
for j := 1 to voicestream.size div 2do
//静音检测
begin

novoice := chr($00);
voicestream.ReadBuffer(novoice, 1);
if (novoice <= chr($81)) and (novOice >= chr($7F)) then

nosend := true
else

begin

。。。。。。

接收的同理
procedure TForm1.RVoiceSocketDataAvailable(Sender: TObject;
Error: Word);
var
voice_recbuf: array[0..1023] of char;
len: integer;
begin

voice_recbuf := #0;
len := RVoicesocket.Receive(@voice_recbuf, 1024);
if len > 0 then

begin

//读入发来的长度数据
playvoice_stream.WriteBuffer(voice_recbuf, len);
if not audio.Playing then

begin

p_stream.Clear;
p_stream.LoadFromStream(playvoice_stream);
playvoice_stream.Clear;
Audio.WaveStream := pwav;
Audio.BufferLength := 500;
Audio.Play;
end;

end;


end;
 
to jingtao:
感谢的你回答,但是我还有一些问题没有搞清楚:
1、RVoiceSocket 是个什么控件?
2、pwav 是干什么用的?

我知道怎么发送声音流,但就是不知道怎么接收!
 
对你可以使用ACM控件,它有一个in和out控件,负责接收和播放声音。
代码如下:
unit ppVoice;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ACMWaveIn, ACMWaveOut, ExtCtrls, StdCtrls, Buttons, ScktComp,
Spin;
type
TGSM610=packed record
wFormatTag: Word;
{ format type }
nChannels: Word;
{ number of channels (i.e. mono, stereo, etc.) }
nSamplesPerSec: DWORD;
{ sample rate }
nAvgBytesPerSec: DWORD;
{ for buffer estimation }
nBlockAlign: Word;
{ block size of data }
wBitsPerSample: Word;
{ number of bits per sample of mono data }
cbSize: Word;
{ the count in bytes of the size of }
wSamplesPerBlock:word;
end;

type
TfrmPhone = class(TForm)
Image: TImage;
ACMWaveOut: TACMWaveOut;
ACMWaveIn: TACMWaveIn;
cmbWhoTo: TComboBox;
btnStop: TBitBtn;
btnStart: TBitBtn;
lblRecvPackets: TLabel;
lblErrPackets: TLabel;
ClientSocket: TClientSocket;
ServerSocket: TServerSocket;
lblPacketSize: TLabel;
Label1: TLabel;
Label2: TLabel;
lblSendPackets: TLabel;
Label3: TLabel;
Label4: TLabel;
edServer: TEdit;
sePort: TSpinEdit;
btnConnect: TSpeedButton;
procedure FormShow(Sender: TObject);
procedure ACMWaveInData(data: Pointer;
size: Integer);
procedure btnStartClick(Sender: TObject);
procedure btnStopClick(Sender: TObject);
procedure FormClose(Sender: TObject;
var Action: TCloseAction);
procedure ClientSocketRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure btnConnectMouseMove(Sender: TObject;
Shift: TShiftState;
X,
Y: Integer);
procedure btnConnectClick(Sender: TObject);
procedure ClientSocketConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocketError(Sender: TObject;
Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
protected
public
{ Public declarations }
end;


var
frmPhone: TfrmPhone;
format:Pointer;
gsm610:TGSM610;
PlayPackets,SentPackets,ErrorPackets:integer;


implementation

{$R *.dfm}

procedure TfrmPhone.FormShow(Sender: TObject);
begin

ACMWaveIn.Visible:=False;
ACMWaveOut.Visible:=False;
PlayPackets:=0;
ErrorPackets:=0;
SentPackets:=0;
end;


procedure TfrmPhone.ACMWaveInData(data: Pointer;
size: Integer);
var
mdata:array[1..10000] of char;
k:integer;
begin

for k:=1 to sizedo

mdata[k]:=pchar(dword(data)+dword(k-1))^;
for k:=0 to ServerSocket.Socket.ActiveConnections -1do

ServerSocket.Socket.Connections[k].SendBuf(mdata,size);
Inc(SentPackets);
lblSendPackets.Caption :='Packets:'+IntToStr(SentPackets);
end;




procedure TfrmPhone.btnStartClick(Sender: TObject);
begin

ServerSocket.Port:=8011;
ServerSocket.Active:=True;
ACMWaveIn.Open(format);
btnStart.Enabled:=false;
btnStop.Enabled:=true;
end;


procedure TfrmPhone.btnStopClick(Sender: TObject);
begin

ACMWaveIn.Close;
btnStart.Enabled:=true;
btnStop.Enabled:=false;
end;


procedure TfrmPhone.FormClose(Sender: TObject;
var Action: TCloseAction);
begin

ClientSocket.Close;
ServerSocket.Close;
ACMWaveIn.Close;
ACMWaveOut.Close;
end;


procedure TfrmPhone.ClientSocketRead(Sender: TObject;
Socket: TCustomWinSocket);
var
mdata:array[0..1625] of char;
data:Pchar;
i:integer;
begin

i:= Socket.ReceiveBuf(mdata,1625);
data:=pchar(dword(@mdata));
lblRecvPackets.caption:='Packets:'+inttostr(PlayPackets);
inc(PlayPackets);
if i=-1 then

begin

inc(ErrorPackets)
end
else

ACMWaveOut.PlayBack(data,i);
lblErrPackets.caption:='Errors:'+inttostr(ErrorPackets);
lblPacketSize.caption:='Size:'+inttostr(i);
end;


procedure TfrmPhone.btnConnectMouseMove(Sender: TObject;
Shift: TShiftState;
X, Y: Integer);
var
s:string;
begin

s:=Trim(edserver.Text);
if btnConnect.Down then

btnConnect.Hint:='断开与'+QuotedStr(s)+'的连接'
else
if s='' then

btnConnect.Hint:='请输入对方主机地址'
else

btnConnect.Hint:='与'+QuotedStr(s)+'连接';
end;


procedure TfrmPhone.btnConnectClick(Sender: TObject);
var
s:string;
begin

if not btnConnect.Down then

begin

if MessageBox(0,PChar('确认要断开与:'+edServer.Text+'的连接么?'),
'信息提示',MB_YESNO)=ID_YES then

begin

ClientSocket.Close;
ACMWaveOut.Close;
edServer.Enabled:=True;
sePort.Enabled:=True;
end;

end
else

begin

s:=Trim(edServer.Text);
if s='' then

btnConnect.Down:=False
else

begin

try
edServer.Enabled:=False;
sePort.Enabled:=False;
ClientSocket.Address:=edServer.Text;
ClientSocket.Port:=sePort.Value;
ClientSocket.Open;
except
ShowMessage('无法连接到服务提供方!');
btnConnect.Down:=False;
edServer.Enabled:=True;
sePort.Enabled:=True;
end;


end;

end
end;


procedure TfrmPhone.ClientSocketConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin

ACMWaveOut.Open(format);
end;


procedure TfrmPhone.ClientSocketError(Sender: TObject;
Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin

ClientSocket.Close;
ACMWaveOut.Close;
edServer.Enabled:=True;
sePort.Enabled:=True;
btnConnect.Down:=False;
end;


procedure TfrmPhone.FormCreate(Sender: TObject);
begin

with gsm610do

begin

wFormatTag:=$31;
nChannels:=1;
wBitsPerSample:=0;
nSamplesPerSec:=8000;
nBlockAlign:=65;
nAvgBytesPerSec:=1625;
cbSize:=2;
wSamplesPerBlock:=$140;
end;

format:=@gsm610;
end;


end.
 
大哥,ACM我用过,效果不是很好,所以才求助大家DS的解决方法!
如果能够解决,再加300分,决不食言!
 
到这里可以找到更多的关于语音的程序源码,可以找到ACM控件
http://61.132.118.185:8080/
 
up ,jingtao SOS
 
SVoiceSocket: TWSocket;
RVoiceSocket: TWSocket;
//ICS控件,可用类似控件代替
DXSound1: TDXSound;

public
Audio: TAudioStream;
testwav, pwav: Twavestream;
Capture: TSoundCaptureStream;
//语音录音流
{ Public declarations }
end;


var
frmVoice: TfrmVoice;

implementation

var
playvoice_stream, p_stream: Tmemorystream;
//语音传输流
{$R *.DFM}
 
非常感谢jingtao的回答!
 
后退
顶部