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

📄 mmpcmsup.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 5 页
字号:
   begin                                   { convert from 8 bit to 16 bit }
      for i := 0 to dwNumSamples-1 do
      begin
         PSmallInt(pDst)^ := Smallint(PByte(pSrc)^-128) * 256;
         inc(pSrc);
         inc(pDst, 2);
         inc(dwTotalDst, 2);
      end;
   end;

   Result := dwTotalDst;
end;

{*************************************************************************}
{* only standard: Mono/Stereo PCM                                        *}
{*************************************************************************}
function pcmChannelAlign(nDstChannels: Word; pDst: PChar;
                         nSrcChannels: Word; pSrc: PChar;
                         nBitsPS: Word; dwSrcLen: Cardinal): Cardinal;
Var
   i: integer;
   dwNumSamples: Longint;
   dwTotalDst: Longint;

begin
   if (nSrcChannels = nDstChannels) then
   begin
      move(pSrc^, pDst^, dwSrcLen);
      Result := dwSrcLen;
      exit;
   end;

   dwNumSamples := dwSrcLen div (nBitsPS shr 3) div nSrcChannels;
   dwTotalDst := 0;

   if (nSrcChannels < nDstChannels) then     { convert from mono to stereo }
   begin
      if (nBitsPS = 8) then                                       { 8 bit }
      begin
	 for i := 0 to dwNumSamples-1 do
	 begin
	    PByte(pDst)^ := PByte(pSrc)^;
            PByte(pDst+1)^ := PByte(pSrc)^;
            inc(pSrc);
            inc(pDst, 2);
            inc(dwTotalDst, 2);
         end;
      end
      else                                                       { 16 bit }
      begin
	 for i := 0 to dwNumSamples-1 do
	 begin
	    PSmallInt(pDst)^ := PSmallInt(pSrc)^;
            PSmallInt(pDst+2)^ := PSmallInt(pSrc)^;
            inc(pSrc, 2);
            inc(pDst, 4);
            inc(dwTotalDst, 4);
         end;
      end;
   end
   else                                     { convert from stereo to mono }
   begin
      if (nBitsPS = 8) then                                       { 8 bit }
      begin
	 for i := 0 to dwNumSamples-1 do
	 begin
            { mix the two channels }
            PByte(pDst)^ := MinMax(Word(PByte(pSrc)^)+Word(PByte(pSrc+1)^),0, 255);
            inc(pSrc, 2);
            inc(pDst);
            inc(dwTotalDst);
         end;
      end
      else                                                       { 16 bit }
      begin
         for i := 0 to dwNumSamples-1 do
	 begin
	    PSmallInt(pDst)^ := MinMax(Longint(PSmallInt(pSrc)^) + Longint(PSmallInt(pSrc+2)^),-32765, 32765);
            inc(pSrc, 4);
            inc(pDst, 2);
            inc(dwTotalDst, 2);
         end;
      end;
   end;

   Result := dwTotalDst;
end;

(*************************************************************************)
(* this routine averages the 8 bit samples along the different channels  *)
(*************************************************************************)
procedure pcmAvgSample8(pDst, pSrc: PChar; nSkip, nChannels: Word);
Var
   lpB: PByte;
   sum, i,j: integer;

begin
     for i := 0 to nChannels-1 do
     begin
        lpB := PByte(pSrc);
        inc(pSrc);
	sum := 0;
	for j := 0 to nSkip-1 do
        begin
	   sum := sum + (lpB^ - 128);
           inc(lpB, nChannels);
        end;
        PByte(pDst)^ := (sum div nSkip) + 128;
        inc(pDst);
     end;
end;

(*************************************************************************)
(* this routine averages the 16 bit samples along the different channels *)
(*************************************************************************)
procedure pcmAvgSample16(pDst, pSrc: PChar; nSkip, nChannels: Word);
Var
   lpW: PSmallInt;
   sum: Longint;
   i,j: integer;

begin
     for i := 0 to nChannels-1 do
     begin
        lpW := PSmallInt(pSrc);
        inc(PSmallInt(pSrc));
	sum := 0;
        for j := 0 to nSkip-1 do
        begin
	   sum := sum + lpW^;
	   inc(lpW, nChannels);
        end;
	PSmallInt(pDst)^ := sum div nSkip;
        inc(PSmallInt(pDst));
     end;
end;

(*************************************************************************)
(* this routine interpolates the 8 Bit samples along the diff. channels  *)
(*************************************************************************)
procedure pcmRepSample8(pDst, pSrc: PChar; nRep, nChannels: Word);
Var
   lpB: PByte;
   diff, val: integer;
   i, j: integer;

begin
     if (nRep > 1) then
     begin
        lpB := PByte(pDst);
        for i := 0 to nChannels-1 do
        begin
	   PByte(pDst) := lpB;
           inc(lpB);
           diff := (PByte(pSrc+nChannels)^ - PByte(pSrc)^) div nRep;
           PByte(pDst)^ := pByte(pSrc)^;
	   val := PByte(pSrc)^;
	   inc(pDst, nChannels);

           {diff := 0; remove interpolation }

           for j := 1 to nRep-1 do
           begin
              inc(val, diff);
              PByte(pDst)^ := val;
              inc(pDst, nChannels);
           end;

	   inc(pSrc);
        end;
     end;
end;

(*************************************************************************)
(* this routine interpolates the 8 Bit samples along the diff. channels  *)
(*************************************************************************)
procedure pcmRepSample16(pDst, pSrc: PChar; nRep, nChannels: Word);
Var
   lpW: PSmallInt;
   diff, val: integer;
   i, j: integer;

begin
     if (nRep > 1) then
     begin
        lpW := PSmallInt(pDst);
        for i := 0 to nChannels-1 do
        begin
           PSmallInt(pDst) := lpW;
           inc(lpW);
           diff := (PSmallInt(pSrc+2*nChannels)^ - PSmallInt(pSrc)^) div nRep;
           PSmallInt(pDst)^ := PSmallInt(pSrc)^;
           val := PSmallInt(pSrc)^;
	   inc(PSmallInt(pDst), nChannels);

           { diff := 0; remove interpolation }

           for j := 1 to nRep-1 do
           begin
	      inc(val,diff);
	      PSmallInt(pDst)^ := val;
              inc(PSmallInt(pDst), nChannels);
           end;

           inc(PSmallInt(pSrc));
        end;
     end;
end;

{*************************************************************************}
{* only standard: 11025Khz, 22050Khz, 44100Khz PCM !!!                   *}
{*************************************************************************}
function pcmSamplesPerSecAlign(nDstSPS: Longint; pDst: PChar;
                               nSrcSPS: Longint; pSrc: PChar;
                               nBitsPS, nChannels: Word;
                               dwSrcLen: Cardinal): Cardinal;
Var
   i,j: integer;
   SampleSize: DWORD;
   nRep,nSkip: DWORD;
   dwNumSamples,dwNewNumSamples: DWORD;
   dwTotalDst: Longint;
   pTmp: PChar;

begin
   if (nSrcSPS = nDstSPS) then
   begin
      move(pSrc^, pDst^, dwSrcLen);
      Result := dwSrcLen;
      exit;
   end;

   SampleSize := (nBitsPS shr 3) * nChannels;
   dwNumSamples := dwSrcLen div SampleSize;

   nSkip := 0;
   nRep := 0;
   dwTotalDst := 0;

   if (nDstSPS > nSrcSPS) then
   begin      
      { then need to add in extra samples }
      nRep := nDstSPS div nSrcSPS;
      dwNewNumSamples := dwNumSamples * nRep;
   end
   else
   begin
      { replace the sample with the average of nSkip samples }
      nSkip :=  nSrcSPS div nDstSPS;
      dwNewNumSamples := dwNumSamples div DWORD(Max(nSkip,1));
   end;

   if (nRep > 0) then
   begin
      if nBitsPS = 8 then
      begin
         for i := 1 to dwNumSamples-1 do
         begin
	    { this routine should interpolate the 8 Bit samples }
	    pcmRepSample8(pDst, pSrc, nRep, nChannels);
	    inc(pSrc, SampleSize);
            inc(pDst, nRep * SampleSize);
            inc(dwTotalDst, nRep * SampleSize);
         end;
      end
      else
      begin
         for i := 1 to dwNumSamples-1 do
         begin
	    { this routine should interpolate the 16 Bit samples }
	    pcmRepSample16(pDst, pSrc, nRep, nChannels);
	    inc(pSrc, SampleSize);
            inc(pDst, nRep * SampleSize);
            inc(dwTotalDst, nRep * SampleSize);
         end;
      end;

      { up sample last sample without filtering }
      for i := 0 to nRep-1 do
      begin
         pTmp := pSrc;
         for j := 0 to SampleSize-1 do
         begin
            pDst^ := pTmp^;
            inc(pTmp);
            inc(pDst);
            inc(dwTotalDst);
         end;
      end;
   end
   else
   begin
      if nBitsPS = 8 then
      begin
         for i := 1 to dwNewNumSamples-1 do
         begin
            { this routine should average the 8 Bit samples }
	    pcmAvgSample8(pDst, pSrc, nSkip, nChannels);
	    inc(pSrc, nSkip * SampleSize);
	    inc(pDst, SampleSize);
	    inc(dwTotalDst, SampleSize);
         end;
      end
      else
      begin
         for i := 1 to dwNewNumSamples-1 do
         begin
            { this routine should average the 16 Bit samples }
	    pcmAvgSample16(pDst, pSrc, nSkip, nChannels);
	    inc(pSrc, nSkip * SampleSize);
	    inc(pDst, SampleSize);
	    inc(dwTotalDst, SampleSize);
         end;
      end;

      { just copy the last sample }
      for i := 0 to SampleSize-1 do
      begin
      	 pDst^:= pSrc^;
         inc(pSrc);
         inc(pDst);
         inc(dwTotalDst);
      end;
   end;

   Result := dwTotalDst;
end;

(*************************************************************************)
function pcmAllocMixPool(NumTracks: integer): PMMMixPool;
begin
   Result := GlobalAllocMem(sizeOf(TMMMixPool)+NumTracks*sizeOf(PChar));
   if Result = nil then OutOfMemoryError;
end;

{*************************************************************************}
function pcmMixIt(pwfx: PWaveFormatEx;
                  pDst: PChar; pTemp: PChar;
                  const pSrc: PMMMixPool; NumWaves: integer;
                  dwSrcLen: Longint): Boolean;
begin
   Result := False;
   if (pwfx = nil) or (pwfx^.wFormatTag <> WAVE_FORMAT_PCM) then exit;

   if (pwfx^.wBitsPerSample = 8) then
   begin
      Result := pcmMixIt8(pDst,Pointer(pTemp),pSrc,NumWaves,dwSrcLen);
   end
   else
   begin
      Result := pcmMixIt16(pDst,Pointer(pTemp),pSrc,NumWaves,dwSrcLen);
   end;
end;

{*************************************************************************}
{$IFDEF WIN32}{$L MMMIX32.OBJ}{$ELSE}{$L MMMIX16.OBJ}{$ENDIF}
{$F+}
function pcmMixIt8(pDst: PChar; pTemp: PSmallint;
                   const pSrc: PMMMixPool; NumWaves: integer;
                   dwSrcLen: Longint): Boolean; external;
function pcmMixIt16(pDst: PChar; pTemp: PLongint;
                    const pSrc: PMMMixPool; NumWaves: integer;
                    dwSrcLen: Longint): Boolean; external;
{$F-}

{*************************************************************************}
{$IFDEF WIN32}{$L MMPITC32.OBJ}{$ELSE}{$L MMPITC16.OBJ}{$ENDIF}
{$F+}
function pcmPitchChange8M(pSrc,pDst: PChar; var SrcLen,DstLen,IncValue: Longint;
                          Factor: Longint): Longint; external;

function pcmPitchChange8S(pSrc,pDst: PChar; var SrcLen,DstLen,IncValue: Longint;
                          Factor: Longint): Longint; external;

function pcmPitchChange16M(pSrc,pDst: PChar; var SrcLen,DstLen,IncValue: Longint;
                           Factor: Longint): Longint; external;

function pcmPitchChange16S(pSrc,pDst: PChar; var SrcLen,DstLen,IncValue: Longint;
                           Factor: Longint): Longint; external;
{$F-}

end.


⌨️ 快捷键说明

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