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

📄 mmpcmsup.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 5 页
字号:
                      if (Flank=1)and(PSmallInt(pSrc+4)^<Level)and(PSmallInt(pSrc+8)^>=Level) then
                      begin
                         Result := BytePos+8;
                         exit;
                      end
                      else if (Flank=2)and(PSmallInt(pSrc+4)^>Level)and(PSmallInt(pSrc+8)^<=Level) then
                      begin
                         Result := BytePos+8;
                         exit;
                      end;
                   end;
                { the left channel }
                1: if (Flank=1)and(PSmallInt(pSrc)^<Level)and(PSmallInt(pSrc+4)^>=Level) then
                   begin
                      Result := BytePos+4;
                      exit;
                   end
                   else if (Flank=2)and(PSmallInt(pSrc)^>Level)and(PSmallInt(pSrc+4)^<=Level) then
                   begin
                      Result := BytePos+4;
                      exit;
                   end;
                { the right channel }
                2: if (Flank=1)and(PSmallInt(pSrc+4)^<Level)and(PSmallInt(pSrc+8)^>=Level) then
                   begin
                      Result := BytePos+8;
                      exit;
                   end
                   else if (Flank=2)and(PSmallInt(pSrc+4)^>Level)and(PSmallInt(pSrc+8)^<=Level) then
                   begin
                      Result := BytePos+8;
                      exit;
                   end;
            end;
            inc(BytePos, 2*sizeOf(SmallInt));
            inc(pSrc, 2*sizeOf(SmallInt));
            dec(SrcNumBytes, 2*sizeOf(SmallInt));
         end;
      end
      else
      begin
         SrcNumBytes := dwSrcLen and not 1;
         while (SrcNumBytes > 4) do
         begin
            { we have only one channel }
            if (Flank=1)and(PSmallInt(pSrc)^<Level)and(PSmallInt(pSrc+2)^>=Level) then
            begin
               Result := BytePos+2;
               exit;
            end
            else if (Flank=2)and(PSmallInt(pSrc)^>Level)and(PSmallInt(pSrc+2)^<=Level) then
            begin
               Result := BytePos+2;
               exit;
            end;
            inc(BytePos, sizeOf(SmallInt));
            inc(pSrc, sizeOf(SmallInt));
            dec(SrcNumBytes, sizeOf(SmallInt));
         end;
      end;
   end;
end;

{*************************************************************************}
{ Computes the RMS amplitude in pSrc: 8/16 bit, mono/stereo              *}
{*************************************************************************}
procedure pcmCalcStatistics(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: TDataSize;
                            var AvgL, AvgR, RmsL, RmsR: SmallInt);
var
   Samples,SrcBytes: Longint;
   SumL, SumR,
   SumL2,SumR2: Extended;
   s: Smallint;

begin
   SumL := 0;
   SumR := 0;
   SumL2 := 0;
   SumR2 := 0;

   AvgL := 0;
   AvgR := 0;
   RmsL := 0;
   RmsR := 0;

   Samples := 0;

   if pwfx^.wBitsperSample = 8 then
   begin
      if pwfx^.nChannels = 2 then
      begin
         SrcBytes := dwSrcLen and not 1;
         while (SrcBytes > 0) do
         begin
            { the left channel }
            s := (PByte(pSrc)^ - 128);
            SumL := SumL + s;
            SumL2:= SumL2 + Long(s)*s;

            { the right channel }
            s := (PByte(pSrc+1)^ - 128);
            SumR := SumR + s;
            SumR2:= SumR2 + Long(s)*s;

            inc(Samples);

            inc(pSrc, 2*sizeOf(Byte));
            dec(SrcBytes, 2*sizeOf(Byte));
         end;

         if Samples > 0 then
         begin
            AvgL := Round(SumL/Samples);
            if AvgL <> 0 then
               RmsL := Round(Sqrt(SumL2/Samples-(Long(AvgL)*AvgL)));

            AvgR := Round(SumR/Samples);
            if AvgR <> 0 then
               RmsR := Round(Sqrt(SumR2/Samples-(Long(AvgR)*AvgR)));
         end;
      end
      else
      begin
         SrcBytes := dwSrcLen;
         while (SrcBytes > 0) do
         begin
            { we have only one channel }
            s := (PByte(pSrc)^ - 128);
            SumL := SumL + s;
            SumL2:= SumL2 + Long(s)*s;

            inc(Samples);

            inc(pSrc, sizeOf(Byte));
            dec(SrcBytes, sizeOf(Byte));
         end;

         if Samples > 0 then
         begin
            AvgL := Round(SumL/Samples);
            if AvgL <> 0 then
               RmsL := Round(Sqrt(SumL2/Samples-(Long(AvgL)*AvgL)));
         end;
         AvgR := AvgL;
         RmsR := RmsL;
      end;
   end
   else
   begin
      if pwfx^.nChannels = 2 then
      begin
         SrcBytes := dwSrcLen and not 1;
         while (SrcBytes > 0) do
         begin
            { the left channel }
            s := PSmallint(pSrc)^;
            SumL := SumL + s;
            SumL2:= SumL2 + Long(s)*s;

            { the right channel }
            s := PSmallint(pSrc+2)^;
            SumR := SumR + s;
            SumR2:= SumR2 + Long(s)*s;

            inc(Samples);

            inc(pSrc, 2*sizeOf(SmallInt));
            dec(SrcBytes, 2*sizeOf(Smallint));
         end;

         if Samples > 0 then
         begin
            AvgL := Round(SumL/Samples);
            if AvgL <> 0 then
               RmsL := Round(Sqrt(SumL2/Samples-(Long(AvgL)*AvgL)));

            AvgR := Round(SumR/Samples);
            if AvgR <> 0 then
               RmsR := Round(Sqrt(SumR2/Samples-(Long(AvgR)*AvgR)));
         end;
      end
      else
      begin
         SrcBytes := dwSrcLen and not 1;
         while (SrcBytes > 0) do
         begin
            { we have only one channel }
            s := PSmallint(pSrc)^;
            SumL := SumL + s;
            SumL2:= SumL2 + Long(s)*s;

            inc(Samples);

            inc(pSrc, sizeOf(SmallInt));
            dec(SrcBytes, sizeOf(SmallInt));
         end;

         if Samples > 0 then
         begin
            AvgL := Round(SumL/Samples);
            if AvgL <> 0 then
               RmsL := Round(Sqrt(SumL2/Samples-(Long(AvgL)*AvgL)));
         end;

         AvgR := AvgL;
         RmsR := RmsL;
      end;
   end;
end;

{*************************************************************************}
function pcmVolume(pwfx: PWaveFormatEx; lpData: PChar; dwSrcLen: TDataSize;
                   LeftVolume, RightVolume: Longint): Boolean;
begin
   Result := False;

   if (pwfx = nil) or (pwfx^.wFormatTag <> WAVE_FORMAT_PCM) then exit;

   if (pwfx^.wBitsPerSample = 8) then
   begin
      if (pwfx^.nChannels = 1) then
          Result := pcmVolume8M(lpData, dwSrcLen, LeftVolume)
      else
          Result := pcmVolume8S(lpData, dwSrcLen, LeftVolume, RightVolume);
   end
   else
   begin
      if (pwfx^.nChannels = 1) then
          Result := pcmVolume16M(lpData, dwSrcLen, LeftVolume)
      else
          Result := pcmVolume16S(lpData, dwSrcLen, LeftVolume, RightVolume);
   end;
end;

{*************************************************************************}
procedure pcmReverse(pwfx: PWaveFormatEx; lpData: PChar; dwSrcLen: TDataSize);
var
   Temp: Longint;
   lpSource,pTemp: PChar;
begin
   if (pwfx = nil) or (pwfx^.wFormatTag <> WAVE_FORMAT_PCM) then exit;

   pTemp := @Temp;

   if (pwfx^.wBitsPerSample = 8) then
   begin
      if (pwfx^.nChannels = 1) then
      begin
         lpSource := (lpData+dwSrcLen-sizeOf(Byte));
         dwSrcLen := dwSrcLen div 2;
         while (dwSrcLen > 0) do
         begin
            PByte(pTemp)^   := PByte(lpData)^;
            PByte(lpData)^  := PByte(lpSource)^;
            PByte(lpSource)^:= PByte(pTemp)^;
            inc(lpData,sizeOf(Byte));
            dec(lpSource,sizeOf(Byte));
            dec(dwSrcLen,sizeOf(Byte));
         end;
      end
      else
      begin
         lpSource := (lpData+dwSrcLen-sizeOf(Word));
         dwSrcLen := dwSrcLen div 2;
         while (dwSrcLen > 0) do
         begin
            PWord(pTemp)^   := PWord(lpData)^;
            PWord(lpData)^  := PWord(lpSource)^;
            PWord(lpSource)^:= PWord(pTemp)^;
            inc(lpData,sizeOf(Word));
            dec(lpSource,sizeOf(Word));
            dec(dwSrcLen,sizeOf(Word));
         end;
      end;
   end
   else
   begin
      if (pwfx^.nChannels = 1) then
      begin
         lpSource := (lpData+dwSrcLen-sizeOf(Smallint));
         dwSrcLen := dwSrcLen div 2;
         while (dwSrcLen > 0) do
         begin
            PSmallint(pTemp)^   := PSmallint(lpData)^;
            PSmallint(lpData)^  := PSmallint(lpSource)^;
            PSmallint(lpSource)^:= PSmallint(pTemp)^;
            inc(lpData,sizeOf(Smallint));
            dec(lpSource,sizeOf(Smallint));
            dec(dwSrcLen,sizeOf(Smallint));
         end;
      end
      else
      begin
         lpSource := (lpData+dwSrcLen-sizeOf(Longint));
         dwSrcLen := dwSrcLen div 2;
         while (dwSrcLen > 0) do
         begin
            PLongint(pTemp)^   := PLongint(lpData)^;
            PLongint(lpData)^  := PLongint(lpSource)^;
            PLongint(lpSource)^:= PLongint(pTemp)^;
            inc(lpData,sizeOf(Longint));
            dec(lpSource,sizeOf(Longint));
            dec(dwSrcLen,sizeOf(Longint));
         end;
      end;
   end;
end;

{*************************************************************************}
function pcmPitchChange(pwfx: PWaveFormatEx; pSrc,pDst: PChar;
                        var SrcLen,DstLen,IncValue: Longint; Factor: Longint): Longint;
begin
   Result := 0;

   if (pwfx = nil) or (pwfx^.wFormatTag <> WAVE_FORMAT_PCM) then exit;

   if (pwfx^.wBitsPerSample = 8) then
   begin
      if (pwfx^.nChannels = 1) then
          Result := pcmPitchChange8M(pSrc, pDst, SrcLen, DstLen, IncValue, Factor)
      else
          Result := pcmPitchChange8S(pSrc, pDst, SrcLen, DstLen, IncValue, Factor);
   end
   else
   begin
      if (pwfx^.nChannels = 1) then
          Result := pcmPitchChange16M(pSrc, pDst, SrcLen, DstLen, IncValue, Factor)
      else
          Result := pcmPitchChange16S(pSrc, pDst, SrcLen, DstLen, IncValue, Factor);
   end;
end;

{*************************************************************************}
procedure pcmFindSilenceEnd(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: TDataSize;
                            Threshold: Longint; var SilenceEnd: Longint);
var
   SrcNumBytes: Longint;
begin
   SilenceEnd := -1;
   if (Threshold < 0) then Threshold := 0;
   if pwfx^.wBitsperSample = 8 then
   begin
      if pwfx^.nChannels = 2 then
      begin
         SrcNumBytes := dwSrcLen and not 1;
         while (SrcNumBytes > 0) do
         begin
            if (abs(PByte(pSrc)^ - 128) > Threshold) or      { the left channel }
               (abs(PByte(pSrc+1)^ - 128) > Threshold) then  { the right channel }
            begin
               SilenceEnd := dwSrcLen-SrcNumBytes;
               exit;
            end;
            inc(pSrc, 2*sizeOf(Byte));
            dec(SrcNumBytes, 2*sizeOf(Byte));
         end;
      end
      else
      begin
         SrcNumBytes := dwSrcLen;
         while (SrcNumBytes > 0) do
         begin
            { we have only one channel }
            if (abs(PByte(pSrc)^ -128) > Threshold) then
            begin
               SilenceEnd := dwSrcLen-SrcNumBytes;
               exit;
            end;
            inc(pSrc, sizeOf(Byte));
            dec(SrcNumBytes, sizeOf(Byte));
         end;
      end;
   end
   else
   begin
      if pwfx^.nChannels = 2 then
      begin
         SrcNumBytes := dwSrcLen and not 3;
         while (SrcNumBytes > 0) do
         begin
            if (abs(PSmallint(pSrc)^) > Threshold) or      { the left channel }
               (abs(PSmallint(pSrc+2)^) > Threshold) then  { the right channel }
            begin
               SilenceEnd := dwSrcLen-SrcNumBytes;
               exit;
            end;

⌨️ 快捷键说明

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