对你可以使用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
ointer;
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
char;
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.