procedure TAudioUser.RecAudioData(RecvBuff: array of byte; RecvBytes: Integer);
var
 Buf: array [0..2048] of Byte;
begin
  CopyMemory(@Buf[0], @RecvBuff[0], RecvBytes);//RecvBuff是接收到的音频数据,RecvBytes是接收的数据长度
  FACMWaveOut.PlayBack(@Buf,P2PSendAudioDataPack.head.Len);
end;ACMWaveOut是一个控件,PlayBack的代码如下procedure TACMWaveOut.PlayBack(data:pointer;size:longint);
var
  Header:PWaveHdr;
  memblock:pointer;
  i:integer;
begin
  if HWaveOut1<>nil then
  begin
   header:=new(PWaveHdr);
   memblock:=new(pointer);
   getmem(memblock,size);
   move(data^,memBlock^,size);
   header.lpdata:=memBlock;
   header.dwbufferlength:=size;
   header.dwbytesrecorded:=size;
   header.dwUser:=0;
   header.dwflags:=0;
   header.dwloops:=0;
   i:=WaveOutPrepareHeader(HWaveOut1^,header,sizeof(TWaveHdr));
   if i<> 0 then showmessage('WaveOutPrepareHeader error');
   i:=WaveOutWrite(HWaveOut1^,header,sizeof(TWaveHdr));
   if i<> 0 then showmessage('WaveOutWrite error');
  end;
end;现在的问题是:
如果只接收一个客户端的音频是没有问题的,如果有多个客户端发送多份音频数据就会出现问题(当然我也尝试多创建多个ACMWaveOut分别接收对应的客户端数据)。
现象是播放声音随着时间的的增加,成倍的延迟,到最后声音完全找不到同步点。我从网上查了一下,原因是Wave数据在Wave设备上输出使用的是WaveOutWrite函数,但是该函数不支持多路Wave数据的同时播放,为了能达到多路Wave数据的
效果,需要用到混音技术。搜到一个函数,但搞不明白怎么用mixit(LPSAMPLE   lpDest,LPSAMPLE   rgWaveSrc〔〕,int   iNumWaves,WORD   wLen)   
  {   
          int,,iSum;   
          WORD   ctr;   
          ctr=0   
          While(wLen)   
          {   
                iSum=128;/*静音时数值为128*/   
                for(I=0;I<iNumWaves;I++=   
                iSum=iSum+*(rgWaveSrc〔I〕+ctr)-128;   
                PEG((int)0,iSum,(int)225);/*对转换结果处理*/   
                *lpDest++=iSum;   
                ctr++;   
                wLen--;   
            }   
  }   
哪位兄弟会的话帮帮忙,指点一下,多谢了(本人的结贴率是100%)。

解决方案 »

  1.   

    盒子上有个组件不知道对你有没有用
    http://www.2ccc.com/article.asp?articleid=631
      

  2.   

    找了一段代码,合成后的效果根本不能听,但合成后也能听到正确的声音,但附带的有很难听的杂音,很刺耳。  TBuffer8 = array[0..0] of Byte;//注我的是单声道所以用MixChannels8
      PBuffer8 = ^TBuffer8;procedure MixChannels8(Buf1, Buf2 : PBuffer8; Vol1, Vol2, InSize : Integer);
    var
      i : Integer;
    begin
      for i := 0 to (Insize shr 1) - 1 do
      Buf2[i] := (Round(Buf1[i]*(Vol1/255)) + Round(Buf2[i]*(Vol2/255))) div 2;
    end;  //调用代码。其中InBuf1, InBuf2分别从输入端取到的两路音频数据 CopyMemory(@InBuf2[1], @RecvBuff[0], RecvBytes);
      MixChannels161(@InBuf1[1], @InBuf2[1], 255, 255, RecvBytes);
      CopyMemory(@Buf[0], @InBuf2[1], RecvBytes);
      FACMWaveOut.PlayBack(@Buf,RecvBytes);
    有没有懂语音合成的朋友,指点一下啊,急......
      

  3.   


    procedure MixChannels8(Buf1, Buf2 : PBuffer8; Vol1, Vol2, InSize : Integer);
    var      // optimized by leozhang
      i, tmp : Integer;
      V1,V2: Real;
    begin
      V1 := Vol1 / 127;
      V2 := Vol2 / 127;
      for i := 0 to (Insize shr 1) - 1 do
      begin
        if Buf2[i] = 0 then
        begin
           Buf2[i] := Round(Buf1[i] * V1);
        end
        else if Buf1[i] = 0 then
        begin
           Buf2[i] := Round(Buf2[i] * V2);
        end
        else
           Buf2[i] :=Round(Buf1[i] * V1) + Round(Buf2[i] * V2);
      end;
    end;换了个函数,发现燥音总是出现在最后一句Buf2[i] :=Round(Buf1[i] * V1) + Round(Buf2[i] * V2)
    如果把最后一句换成Buf2[i] :=0;则完全没有燥音,但也丢失了一下声音数据。
    如果把最后一句改成Buf2[i] :=Round(Buf2[i] * V2)或Round(Buf1[i] * V1)同样会有燥音。真是郁闷!
      

  4.   

    问题已解决,但不是用的混音,用的是COM技术。
    下午结贴,兄弟们过来接分吧。
      

  5.   

    找一下DirectX里面的DirectSound看看,里面或许有
      

  6.   

    找到了一段DirectSound代码,不过没搞成。因为时间来不及,后来就换思路了。
      

  7.   

    兄弟,com技术昨整整,我也碰到这个问题