⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmfftflt.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
   with pflt^,pflt^.Params[channel] do
   begin
      EnterCriticalSection(DataSection);
      try
         {-- ZApolnenie dlya fft --}
         for i := 0 to FFTLen_2-1 do
         begin
            fx[i].re := pIn[i];
            fx[i].im := pIn[FFTLen_2+i];
            fx[FFTLen_2+i].re :=0;
            fx[FFTLen_2+i].im :=0;
         end;

         {-- DIRECT FFT SIGNAL --}
         DoCplxFFTb(pfft,@fx,1);

         {-- PEREMNOSENIE Na Impl. Reaction --}
         fvecMul2(@fh, @fx, FFTLen);

         {-- IFFT ---------------}
         DoCplxFFTb(pfft,@fx,-1);

         {-- SUMMIR s Hvostom IMPuls reactsi --}
         for i := 0 to FFTLen_2-1 do
         begin
            pOut[i] := Trunc(fx[i].re+old_r[i]);

            pOut[FFTLen_2+i] := Trunc(fx[FFTLen_2+i].re+fx[i].im);
            old_r[i] := fx[FFTLen_2+i].im;
         end;

      finally
         LeaveCriticalSection(DataSection);
      end;
   end;
end;

{== GetSignal =================================================================}
procedure GetSignal(pflt: PFFTFilter; pIn: PSmallint; pOut: PIntArray);
{$IFNDEF USEASM}
var
   i: integer;
begin
   with pflt^ do
   for i := 0 to FFTlen-1 do
   begin
      pOut[i] := pIn^;
      inc(pIn,Channels);
   end;
{$ELSE}
const
   ParmSize = sizeOf(TFilterParams);
asm
   // EAX = pflt
   // EDX = pIn
   // ECX = pOut
   push  ebx
   push  esi
   push  edi

   mov   esi, TFFTFilter(eax).Channels

   mov   edi, TFFTFilter(eax).FFTLen

   shl   esi, 1

   xor   ebx, ebx

@@loop:

   movsx eax, word ptr [edx]
   add   edx, esi
   mov   [ecx+4*ebx], eax

   movsx eax, word ptr [edx]
   add   edx, esi
   mov   [ecx+4*ebx+4], eax

   movsx eax, word ptr [edx]
   add   edx, esi
   mov   [ecx+4*ebx+8], eax

   movsx eax, word ptr [edx]
   add   edx, esi
   mov   [ecx+4*ebx+12], eax

   add   ebx, 4
   cmp   ebx, edi
   jl    @@loop

@@exit:

   pop   edi
   pop   esi
   pop   ebx
{$ENDIF}
end;

{== Clip Output ===============================================================}
function ClipOutput(pflt: PFFTFilter; pOut: PSmallArray; channel: integer): Boolean;
{$IFNDEF USEASM}
var
   i: integer;
   outval: Longint;
   pS: PSmallint;

begin
   Result := False;
   with pflt^,pflt^.Params[channel] do
   begin
      pS := Pointer(pOut);
      for i := 0 to FFTLen-1 do
      begin
         outval := Out_Buf[i];

         if outval > 32767 then
         begin
            Result := True;
            pS^ := 32767;
         end
         else if outval < -32767 then
         begin
            Result := True;
            pS^ := -32767;
         end
         else
            pS^ := outval;

         inc(pS,Channels);
      end;
   end;
{$ELSE}
const
   ParmSize = sizeOf(TFilterParams);
asm
   // EAX = pflt
   // EDX = pOut
   // ECX = channel
   push  ebx
   push  edi
   push  esi
   push  ebp

   imul  ecx, ParmSize/8
   lea   esi, TFFTFilter(eax).Params+8*ecx

   mov   ebx, TFFTFilter(eax).Channels
   shl   ebx, 1

   mov   ebp, TFFTFilter(eax).FFTLen

   xor   eax, eax
   xor   ecx, ecx

@@loop:

   {--- 1. sample ---}
   mov   edi, dword ptr TFilterParams(esi).Out_Buf[4*ecx]

   cmp   edi, 32767
   jle   @@skip1

   mov   di, 32767
   mov   eax, True
   jmp   @@set1

@@skip1:

   cmp   edi, -32768
   jge   @@set1

   mov   di, -32768
   mov   eax, True

@@set1:

   mov   word ptr [edx], di
   add   edx, ebx

   {--- 2. sample ---}
   mov   edi, dword ptr TFilterParams(esi).Out_Buf[4*ecx+4]

   cmp   edi, 32767
   jle   @@skip2

   mov   di, 32767
   mov   eax, True
   jmp   @@set2

@@skip2:

   cmp   edi, -32768
   jge   @@set2

   mov   di, -32768
   mov   eax, True

@@set2:

   mov   word ptr [edx], di
   add   edx, ebx

   {--- 3. sample ---}
   mov   edi, dword ptr TFilterParams(esi).Out_Buf[4*ecx+8]

   cmp   edi, 32767
   jle   @@skip3

   mov   di, 32767
   mov   eax, True
   jmp   @@set3

@@skip3:

   cmp   edi, -32768
   jge   @@set3

   mov   di, -32768
   mov   eax, True

@@set3:

   mov   word ptr [edx], di
   add   edx, ebx

   {--- 4. sample ---}
   mov   edi, dword ptr TFilterParams(esi).Out_Buf[4*ecx+12]

   cmp   edi, 32767
   jle   @@skip4

   mov   di, 32767
   mov   eax, True
   jmp   @@set4

@@skip4:

   cmp   edi, -32768
   jge   @@set4

   mov   di, -32768
   mov   eax, True

@@set4:

   mov   word ptr [edx], di
   add   edx, ebx

   add   ecx, 4
   cmp   ecx, ebp
   jl    @@loop

   pop   ebp
   pop   esi
   pop   edi
   pop   ebx
{$ENDIF}
end;

var
   p: PFFTFilter;

{== FFT Filter ================================================================}
function DoFFTFilter(pflt: PFFTFilter; Channel: TMMChannel; pIn: PChar; Len: Cardinal): Boolean;
var
   i,ch,KOL,Count,chMin,chMax,BytesDone,nBytes: integer;
   pW,pS: PSmallArray;

begin
   Result := False;
   if (pflt <> nil) then
   with pflt^ do
   begin
      p := pflt;

      GlobalMoveMem(pIn^,(BufIn+BufIn_Bytes)^,Len);
      inc(BufIn_Bytes,Len);

      KOL := BufIn_Bytes div (Channels*sizeOf(Smallint)) div FFTlen;

      chMax := Channels;
      if (Channel = chLeft) then chMax := 1;

      chMin := 0;
      if (Channels = 2) and (Channel = chRight) then chMin := 1;

      for ch := chMin to chMax-1 do
      with Params[ch] do
      begin
         Count := 0;

         while (Count < KOL) do
         begin
            pW := @PSmallArray(BufIn)^[FFTLen*Count*Channels+ch];

            {-- get signal -------------------------------------------------}
            GetSignal(pflt,PSmallint(pW),@Out_Buf);

            {-- filter ---}
            FFT_Filter(pflt,@Out_Buf,@Out_Buf,ch);

            pW := @PSmallArray(PChar(BufOut+BufOut_Bytes))^[FFTLen*Count*Channels+ch];

            {-- formirov vixod signala -------------------------------------}
            if ClipOutput(pflt,pW,ch) then Result := True;

            inc(count);
         end;
      end;

      // TODO: Alles nochmal pr黤en

      BytesDone := KOL * (Channels*sizeOf(Smallint)) * FFTlen;
      if (BytesDone > 0) then
      begin
         inc(BufOut_Bytes,BytesDone);
         dec(BufIn_Bytes,BytesDone);
         GlobalMoveMem((BufIn+BytesDone)^,BufIn^,BufIn_Bytes);
      end;

      nBytes := Min(Len,BufOut_Bytes);
      GlobalFillMem(pIn^,Len-nBytes,0);

      if (Channels = 2) and (Channel <> chBoth) then
      begin
         pS := Pointer(BufOut+(Len-nBytes)+2*chMin);
         pW := Pointer(pIn+(Len-nBytes)+2*chMin);
         i := 0;
         while i < nBytes div 2 do
         begin
            pW^[i] := pS^[i];
            inc(i,2);
         end;
      end
      else GlobalMoveMem((BufOut+(Len-nBytes))^,(pIn+(Len-nBytes))^,nBytes);

      dec(BufOut_Bytes,nBytes);
      GlobalMoveMem((BufOut+nBytes)^,BufOut^,BufOut_Bytes);
   end;
end;

initialization
   Allocator := TMMAllocator.Create;
finalization
   Allocator.Free;
end.


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -