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

📄 mmpcmsup.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 5 页
字号:
            inc(pSrc, 2*sizeOf(SmallInt));
            dec(SrcNumBytes, 2*sizeOf(SmallInt));
         end;
      end
      else
      begin
         SrcNumBytes := dwSrcLen and not 1;
         while (SrcNumBytes > 0) do
         begin
            { we have only one channel }
            if (abs(PSmallint(pSrc)^) > Threshold) then
            begin
               SilenceEnd := dwSrcLen-SrcNumBytes;
               exit;
            end;
            inc(pSrc, sizeOf(SmallInt));
            dec(SrcNumBytes, sizeOf(SmallInt));
         end;
      end;
   end;
end;

{*************************************************************************}
procedure pcmFindSilenceStart(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: TDataSize;
                              Threshold: Longint; var SilenceStart: Longint);
var
   SrcNumBytes: Longint;
begin
   SilenceStart := -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) and     { the left channel }
               (abs(PByte(pSrc+1)^ - 128) <= Threshold) then  { the right channel }
            begin
               if (SilenceStart = -1) then
                   SilenceStart := dwSrcLen-SrcNumBytes;
            end
            else
            begin
               SilenceStart := -1;
            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
               if (SilenceStart = -1) then
                   SilenceStart := dwSrcLen-SrcNumBytes;
            end
            else
            begin
               SilenceStart := -1;
            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) and     { the left channel }
               (abs(PSmallint(pSrc+2)^) <= Threshold) then  { the right channel }
            begin
               if (SilenceStart = -1) then
                   SilenceStart := dwSrcLen-SrcNumBytes;
            end
            else
            begin
               SilenceStart := -1;
            end;
            inc(pSrc, 2*sizeOf(SmallInt));
            dec(SrcNumBytes, 2*sizeOf(SmallInt));
         end;
      end
      else
      begin
         SrcNumBytes := dwSrcLen and not 1;
         while (SrcNumBytes > 0) do
         begin
            { we have only one channel }
            if (abs(PSmallint(pSrc)^) <= Threshold) then
            begin
               if (SilenceStart = -1) then
                   SilenceStart := dwSrcLen-SrcNumBytes;
            end
            else
            begin
               SilenceStart := -1;
            end;
            inc(pSrc, sizeOf(SmallInt));
            dec(SrcNumBytes, sizeOf(SmallInt));
         end;
      end;
   end;
end;

{*************************************************************************}
{$IFDEF USEASM}
{$IFDEF WIN32}{$L MMPCM32.OBJ}{$ELSE}{$L MMPCM16.OBJ}{$ENDIF}
{$F+}
function  pcmSampleClip8(Sample: SmallInt): ShortInt; external;
function  pcmSampleClip16(Sample: Longint): SmallInt; external;

function  pcmSampleVolume8(Sample: Shortint; Volume: Longint): ShortInt; external;
function  pcmSampleVolume16(Sample: Smallint; Volume: Longint): SmallInt; external;

function  pcmVolume8M(lpData: PChar; dwSrcLen, Volume: Longint): Boolean; external;
function  pcmVolume8S(lpData: PChar; dwSrcLen, LeftVolume, RightVolume: Longint): Boolean; external;
function  pcmVolume16M(lpData: PChar; dwSrcLen, Volume: Longint): Boolean; external;
function  pcmVolume16S(lpData: PChar; dwSrcLen, LeftVolume, RightVolume: Longint): Boolean; external;

procedure pcmFindPeak(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: TDataSize;
                      var PeakL, PeakR: SmallInt); external;
procedure pcmFindMinMax(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: TDataSize;
                      var MinL, MaxL, MinR, MaxR: SmallInt); external;
function  pcmConvertSizeOutputData(pwfDst, pwfSrc: PPCMWaveFormat;
                                   NumBytesSrc: Longint): Longint; external;

function  pcmConvert(pwfDst: PPCMWaveFormat; pDst: PChar;
                     pwfSrc: PPCMWaveFormat; pSrc: PChar;
                     dwSrcLen: Cardinal): Cardinal; external;
{$F-}
{$ELSE}
(*************************************************************************)
function pcmSampleClip8(Sample: SmallInt): ShortInt;
const
     ClipValue = 127;
begin
   if (Sample < -ClipValue) then
   begin
      Result := -ClipValue;
      Overflow := True;
   end
   else if (Sample > ClipValue) then
   begin
      Result := ClipValue;
      Overflow := True;
   end
   else
       Result := Sample;
end;

(*************************************************************************)
function pcmSampleClip16(Sample: Longint): SmallInt;
const
     ClipValue = 32767;
begin
   if (Sample < -ClipValue) then
   begin
      Result := -ClipValue;
      Overflow := True;
   end
   else if (Sample > ClipValue) then
   begin
      Result := ClipValue;
      Overflow := True;
   end
   else
       Result := Sample;
end;

(*************************************************************************)
function pcmSampleVolume8(Sample: ShortInt; Volume: Longint): ShortInt;
begin
   Result := 128 + ((Sample-128) * Volume) div VOLUMEBASE;
end;

(*************************************************************************)
function pcmSampleVolume16(Sample: Smallint; Volume: Longint): Smallint;
begin
   Result := (Sample * Volume) div VOLUMEBASE;
end;

(*************************************************************************)
function pcmVolume8M(lpData: PChar; dwSrcLen: TDataSize; Volume: Longint): Boolean;
var
   s: Smallint;
begin
   Overflow := False;
   while (dwSrcLen > 0) do
   begin
      s := 128+((PByte(lpData)^-128) * Volume) div VOLUMEBASE;
      PByte(lpData)^ := pcmSampleClip8(s);
      inc(lpData, sizeOf(Byte));
      dec(dwSrcLen, sizeOf(Byte));
   end;
   Result := Overflow;
end;

(*************************************************************************)
function pcmVolume8S(lpData: PChar; dwSrcLen: TDataSize; LeftVolume, RightVolume: Longint): Boolean;
var
   s: Smallint;
begin
   Overflow := False;
   dwSrcLen := dwSrcLen and not 1;
   while (dwSrcLen > 0) do
   begin
      s := 128+((PByte(lpData)^-128) * LeftVolume) div VOLUMEBASE;
      PByte(lpData)^ := pcmSampleClip8(s);
      inc(lpData, sizeOf(Byte));

      s := 128+((PByte(lpData)^-128) * RightVolume) div VOLUMEBASE;
      PByte(lpData)^ := pcmSampleClip8(s);
      inc(lpData, sizeOf(Byte));

      dec(dwSrcLen, 2*sizeOf(Byte));
   end;
   Result := Overflow;
end;

(*************************************************************************)
function pcmVolume16M(lpData: PChar; dwSrcLen: TDataSize; Volume: Longint): Boolean;
var
   s: Longint;
begin
   Overflow := False;
   dwSrcLen := dwSrcLen and not 1;
   while (dwSrcLen > 0) do
   begin
      s := (PSmallint(lpData)^ * Volume) div VOLUMEBASE;
      PSmallint(lpData)^ := pcmSampleClip16(s);
      inc(lpData, sizeOf(Smallint));
      dec(dwSrcLen, sizeOf(Smallint));
   end;
   Result := Overflow;
end;

(*************************************************************************)
function pcmVolume16S(lpData: PChar; dwSrcLen: TDataSize; LeftVolume, RightVolume: Longint): Boolean;
var
   s: Longint;
begin
   Overflow := False;
   dwSrcLen := dwSrcLen and not 3;
   while (dwSrcLen > 0) do
   begin
      s := (PSmallint(lpData)^ * LeftVolume) div VOLUMEBASE;
      PSmallint(lpData)^ := pcmSampleClip16(s);
      inc(lpData, sizeOf(Smallint));

      s := (PSmallint(lpData)^ * RightVolume) div VOLUMEBASE;
      PSmallint(lpData)^ := pcmSampleClip16(s);
      inc(lpData, sizeOf(Smallint));

      dec(dwSrcLen, 2*sizeOf(Smallint));
   end;
   Result := Overflow;
end;

{*************************************************************************}
{* find the peak value in pSrc: 8/16 bit, mono/stereo                    *}
{*************************************************************************}
procedure pcmFindPeak(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: TDataSize;
                      var PeakL, PeakR: SmallInt);
var
   SrcNumBytes,sd: Longint;
   pL,pR,sw: Smallint;

begin
   PeakL := 0;
   PeakR := 0;
   pR    := 0;
   pL    := 0;
   if pwfx^.wBitsperSample = 8 then
   begin
      if pwfx^.nChannels = 2 then
      begin
         SrcNumBytes := dwSrcLen and not 1;
         while (SrcNumBytes > 0) do
         begin
            { the left channel }
            sw := PByte(pSrc)^ - 128;
            if abs(sw) > pL then
            begin
               PeakL := sw;
               pL := Min(abs(sw),127);
            end;

            { the right channel }
            sw := PByte(pSrc+1)^ - 128;
            if abs(sw) > pR then
            begin
               PeakR := sw;
               pR := Min(abs(sw),127);
            end;

            inc(pSrc, 2*sizeOf(Byte));
            dec(SrcNumBytes, 2*sizeOf(Byte));
         end;
         PeakL := PeakL + 128;
         PeakR := PeakR + 128;
      end
      else
      begin
         SrcNumBytes := dwSrcLen;
         while (SrcNumBytes > 0) do
         begin
            { we have only one channel }
            sw := PByte(pSrc)^ -128;
            if abs(sw) > pL then
            begin
               PeakL := sw;
               pL := Min(abs(sw),127);
            end;

            inc(pSrc, sizeOf(Byte));
            dec(SrcNumBytes, sizeOf(Byte));
         end;
         PeakL := PeakL + 128;
         PeakR := PeakL;
      end;
   end
   else
   begin
      if pwfx^.nChannels = 2 then
      begin
         SrcNumBytes := dwSrcLen and not 3;
         while (SrcNumBytes > 0) do
         begin
            { the left channel }
            sd := PSmallint(pSrc)^;
            if abs(sd) > pL then
            begin
               PeakL := sd;
               pL := Min(abs(sd),32767);
            end;

            { the right channel }
            sd := PSmallint(pSrc+2)^;
            if abs(sd) > pR then
            begin
               PeakR := sd;
               pR := Min(abs(sd),32767);
            end;

            inc(pSrc, 2*sizeOf(SmallInt));
            dec(SrcNumBytes, 2*sizeOf(SmallInt));
         end;
      end
      else
      begin
         SrcNumBytes := dwSrcLen and not 1;
         while (SrcNumBytes > 0) do
         begin
            { we have only one channel }
            sd := PSmallint(pSrc)^;
            if abs(sd) > pL then
            begin
               PeakL := sd;
               pL := Min(abs(sd),32767);
            end;

            inc(pSrc, sizeOf(SmallInt));
            dec(SrcNumBytes, sizeOf(SmallInt));
         end;
         PeakR := PeakL;
      end;
   end;
end;

{*************************************************************************}
{* find the signed Min/Max value in pSrc: 8/16 bit, mono/stereo                *}
{*************************************************************************}
procedure pcmFindMinMax(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: TDataSize;
                      var MinL, MaxL, MinR, MaxR: SmallInt);
var

⌨️ 快捷键说明

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