熟悉语音聊天的请进,音频传送 帮顶有分,在线等(200分)

  • 主题发起人 主题发起人 wuchunhua
  • 开始时间 开始时间
W

wuchunhua

Unregistered / Unconfirmed
GUEST, unregistred user!
音频捕捉部分已经完成。采用pcm 16-bit,44100H,单通道采集。
问题:以下代码如果采用udp发送方式,有吱吱的噪音,如果采用直接播放,没有噪音,
希望有经验的高手能指点迷经。
部分代码
procedure MMInDone(var msg:Tmessage);message MM_WIM_DATA;
...
procedure MMInDone(var msg:Tmessage);
var
Header:PWaveHdr;
memBlock:PmemBlock;
i:integer;
inLength : integer;
sBuf : array of smallint ;
begin

dec(in_count);
{得到已经接收的数据块}
Header:=PWaveHdr(msg.lparam);
i:=waveInUnPrepareHeader(HWaveIn^,Header,sizeof(TWavehdr));
if i<>0 then

application.messagebox('In Un Prepare error','error',mb_ok);
if not(close_invoked) then

begin

inc(out_count);
//udp发送音频数据
InLength := header.dwBytesRecorded ;
setLength(sbuf,inlength) ;
Move(header.lpdata,sbuf[0],inlength);
UdpServer.SendBuffer(IpStr,1000,sbuf[0],InLength) ;
//udp音频发送数据结束

{不采用upd发送,直接播放,
i:=WaveOutPrepareHeader(HWaveOut^,header,sizeof(TWaveHdr));
if i<> 0 then

showmessage('WaveOutPrepareHeader error');
i:=WaveOutWrite(HWaveOut^,header,sizeof(TWaveHdr));
if i<> 0 then

showmessage('WaveOutWrite error');
//定义一个新的缓存块
Header:=new(PWaveHdr);
memBlock:=new(PmemBlock);
直接播放部分结束,}
with header^do

begin

//lpdata:=pointer(memBlock);{选udp传送时注销,直接播放是必须使用}
dwbufferlength:=500;
dwbytesrecorded:=0;
dwUser:=0;
dwflags:=0;
dwloops:=0;
end;

{准备波形装入块}
i:=waveInPrepareHeader(HWaveIn^,Header,sizeof(TWavehdr));
if i<>0 then
application.messagebox('In Prepare error','error',mb_ok);
{将缓存区发送给波形输入设备}
i:=waveInAddBuffer(HWaveIn^,Header,sizeof(TWaveHdr));
if i<>0 then
application.messagebox('Add buffer error','error',mb_ok);
inc(in_count);
end;

{队列已经为空}
if (in_count=0) then

begin

WaveInClose(HWaveIn^);
HwaveIn:=nil;
CloseStream ;
end;

{判断是否已经处理完输入和输出队列}
if (in_count=0) and (out_count=0) then

begin

close_complete:=true;
close;
end;

end;


//----------------------------------------------
//udp接收到数据,播放声音
//----------------------------------------------
procedure TForm1.UdpServerUDPRead(Sender: TObject;
AData: TStream;
ABinding: TIdSocketHandle);
var
sBuf:array of smallint ;
Header:PWaveHdr;
i : integer;
memblock : PmemBlock ;
size : integer;
begin

size := adata.Size ;
setLength(rBuf,size);
setLength(sBuf,size);
adata.ReadBuffer(sBuf[0],size);

Header:=new(PWaveHdr);
memblock:=new(pointer);
getmem(memblock,size);
move(sBuf[0],memBlock^,size);
Header.lpdata:=Pointer(memBlock);
Header.dwbufferlength:=size;
Header.dwbytesrecorded:=size;
Header.dwUser:=0;
Header.dwflags:=0;
Header.dwloops:=0;
i:=WaveOutPrepareHeader(HWaveOut^,Header,sizeof(TWaveHdr));
if i<> 0 then

showmessage('WaveOutPrepareHeader error');
i:=WaveOutWrite(HWaveOut^,Header,sizeof(TWaveHdr));
if i<> 0 then

showmessage('WaveOutWrite error');
end;
 
网上有现成的控件,开源的,有udp实例,不过我也没搞懂在网络上怎么传输
 
C#中数组类型的强制转换,在delphi中怎么实现?

ManagementBaseObject[] objArray1 = (ManagementBaseObject[]) obj3.Properties[&quot;Dacl&quot;].Value;
 
自己翻译,不知道有没有错误,希望高手指点
unit uG729;

interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

const
L_FRAME_COMPRESSED = 10 ;
L_FRAME = 80 ;
SIZE_AUDIO_FRAME = 960 ;
SIZE_AUDIO_PACKED = 60 ;
procedure g729a_init_encoder();stdcall external 'G729.dll';
procedure g729a_encoder(speech: Psmallint;
bitstream: PshortInt);stdcall external 'G729.dll';
procedure g729a_init_decoder();stdcall external 'G729.dll';
procedure g729a_decoder(bitstream: PshortInt;
synth_short: Psmallint;
bfi:integer);stdcall external 'G729.dll';
procedure initCoder ;
function EncodeAudioData(pin: PshortInt;
len: integer;
pout: PshortInt;
lenr: Pinteger):boolean;
function DecodeAudioData(pin: pshortint;
len:integer;
pout: PshortInt;
lenr: Pinteger): boolean;
implementation

procedure initCoder ;
begin

g729a_init_encoder ;
g729a_init_decoder ;
end;


function EncodeAudioData(pin: PshortInt;
len: integer;
pout: PshortInt;
lenr: Pinteger):boolean;
var
bRet: boolean;
fbuf : array[1..60] of shortint ;
label RET;
begin

bRet := false ;
if ((not Pin^) or Len) <> (SIZE_AUDIO_FRAME or (not pout^)) then

// if(!pin||len!=SIZE_AUDIO_FRAME||!pout)
goto RET;

g729a_encoder( Psmallint(pin),PshortInt(pout));
inc(pin, 160);
inc(pout, 10);
g729a_encoder( Psmallint(pin), PshortInt(pout));
inc(pin, 160);
inc(pout, 10);
g729a_encoder( Psmallint(pin), PshortInt(pout));
inc(pin, 160);
inc(pout, 10);
g729a_encoder( Psmallint(pin), PshortInt(pout));
inc(pin, 160);
inc(pout, 10);
g729a_encoder( Psmallint(pin), PshortInt(pout));
inc(pin, 160);
inc(pout, 10);
g729a_encoder( Psmallint(pin), PshortInt(pout));

if lenr <> nil then

lenr^ := SIZE_AUDIO_PACKED;

bRet :=TRUE;
RET:
result := bRet;
end;


function DecodeAudioData(pin: pshortint;
len:integer;
pout: PshortInt;
lenr: Pinteger): boolean;
var
bRet: Boolean;
label RET;
begin

bRet := FALSE ;
if(not(pin^) or len <> SIZE_AUDIO_PACKED or not(pout^)) then

goto RET;
g729a_decoder(pshortInt(pin^),psmallInt(pout^),0);
inc(pin, 10) ;
inc(pout, 160);
g729a_decoder(pshortInt(pin^),psmallInt(pout^),0);
inc(pin, 10) ;
inc(pout, 160);
g729a_decoder(pshortInt(pin^),psmallInt(pout^),0);
inc(pin, 10) ;
inc(pout, 160);
g729a_decoder(pshortInt(pin^),psmallInt(pout^),0);
inc(pin, 10) ;
inc(pout, 160);
g729a_decoder(pshortInt(pin^),psmallInt(pout^),0);
inc(pin, 10) ;
inc(pout, 160);
g729a_decoder(pshortInt(pin^),psmallInt(pout^),0);

if lenr <> nil then

lenr^ := SIZE_AUDIO_FRAME;
bRet := TRUE;
RET:
result := bRet;
end;

end.
 
有什么翻译的,c动态库在D中调用嘛
函数原型弄清楚然后参考下贴
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3438484
顺手加俩吧,至于显式隐式调用,自己查一下了
type
PSmallint = ^Smallint;
PShortint = ^Shortint;
end;


extern &quot;C&quot;
void va_g729a_encoder(short *speech, unsigned char *bitstream);
// 转换
procedure va_g729a_encoder(PSmallint pSpeech;
PShortint pBitstream);
stdcall;

extern &quot;C&quot;
void va_g729a_decoder(unsigned char *bitstream, short *synth_short, int bfi);
// 转换
procedure va_g729a_decoder(PShortint pBitstream;
PSmallint pSynth_short;
Integer bfi);
 
自己解决了,不知道分能不能给自己 哈哈
 
给点分吧 呵呵
 
这可是力气活啊.
 
其实只要几个主要的地方翻译一下就可以了,比如fread,fwrite
你如果可以,分不是问题,可以再加
 
不会写delphi的控制台程序,没法帮你
 
楼上的,这不是控制台程序,是两个函数。很高兴你能顶 帮顶+10
解决另开帖+200
 
stderr,stdout,stdin 这些我怎么翻译?要是让我全翻译,真的跟duhai_lee说的一样,力气活
 
纯粹顶一下。
 
大富翁是提供咨询的地方,不是帮人免费打工的地方,要是那一句不懂可以问,做事还是要自己来。要是楼主不伤心,以后我们公司都不用招人了,把项目贴到大富翁上就行了。
 
俺更伤心!
楼主太强了!
把题目、内容全改了......
弄得俺的回答好像牛头不对马嘴......
分不重要,哪怕俺不要
弄得俺答案和题目不对,这问题俺认为比较严重了
本想回答,怕你过段日子再改题目,还是取消订阅了(此贴本是一直订阅中的).....
 
我说怎么看着前几位的回答这么奇怪,还以为是自己水平太菜
 
to :uiit;
首先很抱歉,没有想到uiit会这么生气,本人前面的问题因为自己解决了,所以在贴了一个问题,而且我也会把分给uiit一部分,其实这样的问题在dfw里面还是很多的
 
多人接受答案了。
 
后退
顶部