MMPCMSup.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:62k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {========================================================================}
  2. {=                (c) 1995-98 SwiftSoft Ronald Dittrich                 =}
  3. {========================================================================}
  4. {=                          All Rights Reserved                         =}
  5. {========================================================================}
  6. {=  D 01099 Dresden             = Fax.: +49(0)351-8037944               =}
  7. {=  Loewenstr.7a                = info@swiftsoft.de                     =}
  8. {========================================================================}
  9. {=  Actual versions on http://www.swiftsoft.de/index.html               =}
  10. {========================================================================}
  11. {=  This code is for reference purposes only and may not be copied or   =}
  12. {=  distributed in any format electronic or otherwise except one copy   =}
  13. {=  for backup purposes.                                                =}
  14. {=                                                                      =}
  15. {=  No Delphi Component Kit or Component individually or in a collection=}
  16. {=  subclassed or otherwise from the code in this unit, or associated   =}
  17. {=  .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed     =}
  18. {=  without express permission from SwiftSoft.                          =}
  19. {=                                                                      =}
  20. {=  For more licence informations please refer to the associated        =}
  21. {=  HelpFile.                                                           =}
  22. {========================================================================}
  23. {=  $Date: 12.11.98 - 20:57:03 $                                        =}
  24. {========================================================================}
  25. unit MMPCMSup;
  26. {$I COMPILER.INC}
  27. interface
  28. uses
  29. {$IFDEF WIN32}
  30.     Windows,
  31. {$ELSE}
  32.     WinTypes,
  33.     WinProcs,
  34. {$ENDIF}
  35.     SysUtils,
  36.     Forms,
  37.     MMSystem,
  38.     MMUtils,
  39.     MMMath,
  40.     MMRegs,
  41.     MMWaveIO,
  42.     MMAbout;
  43. type
  44.     {$IFDEF WIN32}
  45.     TDataSize = Longint;
  46.     {$ELSE}
  47.     {$IFDEF USEASM}
  48.     TDataSize = Longint;
  49.     {$ELSE}
  50.     TDataSize = integer;
  51.     {$ENDIF}
  52.     {$ENDIF}
  53. const
  54.     Overflow      : Boolean = False;
  55. type
  56.     PMMMixPool    = ^TMMMixPool;
  57.     TMMMixPool    = record
  58.         dwLeftVolume : Longint;  { master volumes                     }
  59.         dwRightVolume: Longint;
  60.         lpBuffers    : array[0..0] of PChar;
  61.     end;
  62. {------------------------------------------------------------------------}
  63. function  pcmSampleClip8(Sample: Smallint): Shortint;
  64. function  pcmSampleClip16(Sample: Longint): Smallint;
  65. {------------------------------------------------------------------------}
  66. function  pcmSampleVolume8(Sample: ShortInt; Volume: Longint): Shortint;
  67. function  pcmSampleVolume16(Sample: Smallint; Volume: Longint): Smallint;
  68. {------------------------------------------------------------------------}
  69. function  pcmVolume(pwfx: PWaveFormatEx; lpData: PChar; dwSrcLen: TDataSize;
  70.                     LeftVolume, RightVolume: Longint): Boolean;
  71. function  pcmVolume8M(lpData: PChar; dwSrcLen: TDataSize; Volume: Longint): Boolean;
  72.                       {$IFDEF WIN32}pascal;{$ENDIF}
  73. function  pcmVolume8S(lpData: PChar; dwSrcLen: TDataSize;
  74.                       LeftVolume, RightVolume: Longint): Boolean;
  75.                       {$IFDEF WIN32}pascal;{$ENDIF}
  76. function  pcmVolume16M(lpData: PChar; dwSrcLen: TDataSize; Volume: Longint): Boolean;
  77.                        {$IFDEF WIN32}pascal;{$ENDIF}
  78. function  pcmVolume16S(lpData: PChar; dwSrcLen: TDataSize;
  79.                        LeftVolume, RightVolume: Longint): Boolean;
  80.                        {$IFDEF WIN32}pascal;{$ENDIF}
  81. {------------------------------------------------------------------------}
  82. procedure pcmReverse(pwfx: PWaveFormatEx; lpData: PChar; dwSrcLen: TDataSize);
  83. {------------------------------------------------------------------------}
  84. function pcmPitchChange(pwfx: PWaveFormatEx; pSrc,pDst: PChar;
  85.                         var SrcLen,DstLen,IncValue: Longint; Factor: Longint): Longint;
  86. function pcmPitchChange8M(pSrc,pDst: PChar; var SrcLen,DstLen,IncValue: Longint;
  87.                           Factor: Longint): Longint; {$IFDEF WIN32}pascal;{$ENDIF}
  88. function pcmPitchChange8S(pSrc,pDst: PChar; var SrcLen,DstLen,IncValue: Longint;
  89.                           Factor: Longint): Longint; {$IFDEF WIN32}pascal;{$ENDIF}
  90. function pcmPitchChange16M(pSrc,pDst: PChar; var SrcLen,DstLen,IncValue: Longint;
  91.                            Factor: Longint): Longint; {$IFDEF WIN32}pascal;{$ENDIF}
  92. function pcmPitchChange16S(pSrc,pDst: PChar; var SrcLen,DstLen,IncValue: Longint;
  93.                            Factor: Longint): Longint; {$IFDEF WIN32}pascal;{$ENDIF}
  94. {------------------------------------------------------------------------}
  95. function  pcmAllocMixPool(NumTracks: integer): PMMMixPool;
  96. function  pcmMixIt(pwfx: PWaveFormatEx;
  97.                    pDst: PChar; pTemp: PChar;
  98.                    const pSrc: PMMMixPool; NumWaves: integer;
  99.                    dwSrcLen: Longint): Boolean;
  100. function  pcmMixIt8(pDst: PChar; pTemp: PSmallint;
  101.                     const pSrc: PMMMixPool; NumWaves: integer;
  102.                     dwSrcLen: Longint): Boolean;
  103.                     {$IFDEF WIN32}pascal;{$ENDIF}
  104. function  pcmMixIt16(pDst: PChar; pTemp: PLongint;
  105.                      const pSrc: PMMMixPool; NumWaves: integer;
  106.                      dwSrcLen: Longint): Boolean;
  107.                      {$IFDEF WIN32}pascal;{$ENDIF}
  108. {------------------------------------------------------------------------}
  109. function  pcmIsValidFormat(pwfx: PWaveFormatEx): Boolean;
  110. procedure pcmBuildWaveHeader(pwfx: PWaveFormatEx;wBitsPS,nChannels: Word;
  111.                              dwSampleRate: Longint);
  112. procedure pcmBuildWaveFormatExtensible(pwfxEx: PWaveFormatExtensible;
  113.                                        wBitsPS, nChannels: Word;
  114.                                        dwSampleRate: DWORD;
  115.                                        dwChannelMask: DWORD);
  116. procedure pcmFillSilence(pwfx: PWaveFormatEx; lpData: PChar; dwLength: Longint);
  117. function  pcmFindZeroCross(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: Cardinal;
  118.                            Channel, Flank, Level: Integer): Longint;
  119. procedure pcmCalcStatistics(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: TDataSize;
  120.                             var AvgL, AvgR, RmsL, RmsR: SmallInt);
  121. procedure pcmFindPeak(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: TDataSize;
  122.                       var PeakL, PeakR: SmallInt); {$IFDEF WIN32}pascal;{$ENDIF}
  123. procedure pcmFindMinMax(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: TDataSize;
  124.                       var MinL, MaxL, MinR, MaxR: SmallInt); {$IFDEF WIN32}pascal;{$ENDIF}
  125. procedure pcmFindSilenceEnd(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: TDataSize;
  126.                             Threshold: Longint; var SilenceEnd: Longint);
  127. procedure pcmFindSilenceStart(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: TDataSize;
  128.                               Threshold: Longint; var SilenceStart: Longint);
  129. function  pcmConvertSizeOutputData(pwfDst, pwfSrc: PPCMWaveFormat;
  130.                                    NumBytesSrc: Longint): Longint; {$IFDEF WIN32}pascal;{$ENDIF}
  131. function  pcmConvert(pwfDst: PPCMWaveFormat; pDst: PChar;
  132.                      pwfSrc: PPCMWaveFormat; pSrc: PChar;
  133.                      dwSrcLen: Cardinal): Cardinal; {$IFDEF WIN32}pascal;{$ENDIF}
  134. function  pcmBitsPerSampleAlign(nDstBitsPS: Word; pDst: PChar;
  135.                                 nSrcBitsPS: Word; pSrc: PChar;
  136.                                 dwSrcLen: Cardinal): Cardinal;
  137. function  pcmChannelAlign(nDstChannels: Word; pDst: PChar;
  138.                           nSrcChannels: Word; pSrc: PChar;
  139.                           nBitsPS: Word; dwSrcLen: Cardinal): Cardinal;
  140. procedure pcmAvgSample8(pDst, pSrc: PChar; nSkip, nChannels: Word);
  141. procedure pcmAvgSample16(pDst, pSrc: PChar; nSkip, nChannels: Word);
  142. procedure pcmRepSample8(pDst, pSrc: PChar; nRep, nChannels: Word);
  143. procedure pcmRepSample16(pDst, pSrc: PChar; nRep, nChannels: Word);
  144. function  pcmSamplesPerSecAlign(nDstSPS: Longint; pDst: PChar;
  145.                                nSrcSPS: Longint; pSrc: PChar;
  146.                                nBitsPS, nChannels: Word;
  147.                                dwSrcLen: Cardinal): Cardinal;
  148. implementation
  149. Uses MMMulDiv;
  150. {*************************************************************************}
  151. {* the code below provides 'support' routines for building/verifying     *}
  152. {* PCM wave headers                                                      *)
  153. {*************************************************************************}
  154. function pcmIsValidFormat(pwfx: PWaveFormatEx): Boolean;
  155. begin
  156.    Result := False;
  157.    if (pwfx = Nil) then exit;
  158.    if (pwfx^.wFormatTag <> WAVE_FORMAT_PCM) then exit;
  159.    if ((pwfx^.wBitsPerSample <> 8) and (pwfx^.wBitsPerSample <> 16)) then exit;
  160.    if ((pwfx^.nChannels <> 1) and (pwfx^.nChannels <> 2)) then exit;
  161.    if ((pwfx^.nSamplesPerSec < 4000) or (pwfx^.nSamplesPerSec > 100000)) then
  162.       exit;
  163.    Result := True;
  164. end;
  165. (*************************************************************************)
  166. procedure pcmBuildWaveHeader(pwfx: PWaveFormatEx; wBitsPS, nChannels: Word;
  167.                              dwSampleRate: Longint);
  168. begin
  169.      { fill in the info for our destination format... }
  170.      pwfx^.wFormatTag     := WAVE_FORMAT_PCM;
  171.      pwfx^.nChannels      := nChannels;
  172.      pwfx^.nSamplesPerSec := dwSampleRate;
  173.      pwfx^.wBitsPerSample := wBitsPS;
  174.      { set nAvgBytesPerSec and nBlockAlign }
  175.      pwfx^.nBlockAlign    := (wBitsPS * nChannels) div 8;
  176.      pwfx^.nAvgBytesPerSec:= pwfx^.nBlockAlign * pwfx^.nSamplesPerSec;
  177.      pwfx^.cbSize := 0;
  178. end;
  179. (*************************************************************************)
  180. procedure pcmBuildWaveFormatExtensible(pwfxEx: PWaveFormatExtensible;
  181.                                        wBitsPS, nChannels: Word;
  182.                                        dwSampleRate: DWORD;
  183.                                        dwChannelMask: DWORD);
  184. begin
  185.    pwfxEx^.Format.wFormatTag           := WAVE_FORMAT_EXTENSIBLE;
  186.    pwfxEx^.Format.nChannels            := nChannels;
  187.    pwfxEx^.Format.nSamplesPerSec       := dwSampleRate;
  188.    pwfxEx^.Format.wBitsPerSample       := wBitsPS;
  189.    pwfxEx^.Format.nBlockAlign          := (wBitsPS * nChannels) div 8;
  190.    pwfxEx^.Format.nAvgBytesPerSec      := dwSampleRate*pwfxex^.Format.nBlockAlign;
  191.    pwfxEx^.Format.cbSize               := sizeof(TWaveFormatExtensible) - sizeof(TWaveFormatEx);
  192.    pwfxEx^.Samples.wValidBitsPerSample := wBitsPS;
  193.    pwfxEx^.dwChannelMask               := dwChannelMask;
  194.    pwfxEx^.SubFormat                   := KSDATAFORMAT_SUBTYPE_PCM;
  195. end;
  196. (*************************************************************************)
  197. procedure pcmFillSilence(pwfx: PWaveFormatEx; lpData: PChar; dwLength: Longint);
  198. var
  199.    Silence: integer;
  200. begin
  201.    if (pwfx^.wBitsPerSample = 16) then
  202.        Silence := 0
  203.    else
  204.        Silence := 128;
  205.    GlobalFillMem(lpData^,dwLength,Silence);
  206. end;
  207. {*************************************************************************}
  208. {* find the zero cross point in pSrc: 8/16 bit, mono/stereo              *}
  209. {*************************************************************************}
  210. {* Channel: 0 = Both, 1 = Left, 2 = Right                                *}
  211. {* Flank  : 0 = None, 1 = Up, 2 = Down                                   *)
  212. (* Level  : LevelThreshold in %                                          *)                                             *}
  213. {*************************************************************************}
  214. function pcmFindZeroCross(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: Cardinal;
  215.                           Channel, Flank, Level: Integer): Longint;
  216. var
  217.    SrcNumBytes: Longint;
  218.    BytePos: Cardinal;
  219. begin
  220.    Result := -1;
  221.    if (Flank = 0) or (dwSrcLen = 0) then exit;
  222.    if (Flank = 2) then Level := -Level;
  223.    BytePos:= 0;
  224.    if pwfx^.wBitsperSample = 8 then
  225.    begin
  226.       Level := Trunc(Level*127/100)+128;
  227.       if pwfx^.nChannels = 2 then
  228.       begin
  229.          SrcNumBytes := dwSrcLen and not 1;
  230.          while (SrcNumBytes > 4) do
  231.          begin
  232.             case Channel of
  233.                 { both channels }
  234.                 0: begin
  235.                       { left }
  236.                       if (Flank=1)and(PByte(pSrc)^<Level)and(PByte(pSrc+2)^>=Level) then
  237.                       begin
  238.                          Result := BytePos+2;
  239.                          exit;
  240.                       end
  241.                       else if (Flank=2)and(PByte(pSrc)^>Level)and(PByte(pSrc+2)^<=Level) then
  242.                       begin
  243.                          Result := BytePos+2;
  244.                          exit;
  245.                       end;
  246.                       { right }
  247.                       if (Flank=1)and(PByte(pSrc+1)^<Level)and(PByte(pSrc+3)^>=Level) then
  248.                       begin
  249.                          Result := BytePos+3;
  250.                          exit;
  251.                       end
  252.                       else if (Flank=2)and(PByte(pSrc+1)^>Level)and(PByte(pSrc+3)^<=Level) then
  253.                       begin
  254.                          Result := BytePos+3;
  255.                          exit;
  256.                       end;
  257.                    end;
  258.                 { the left channel }
  259.                 1: if (Flank=1)and(PByte(pSrc)^<Level)and(PByte(pSrc+2)^>=Level) then
  260.                    begin
  261.                       Result := BytePos+2;
  262.                       exit;
  263.                    end
  264.                    else if (Flank=2)and(PByte(pSrc)^>Level)and(PByte(pSrc+2)^<=Level) then
  265.                    begin
  266.                       Result := BytePos+2;
  267.                       exit;
  268.                    end;
  269.                 { the right channel }
  270.                 2: if (Flank=1)and(PByte(pSrc+1)^<Level)and(PByte(pSrc+3)^>=Level) then
  271.                    begin
  272.                       Result := BytePos+3;
  273.                       exit;
  274.                    end
  275.                    else if (Flank=2)and(PByte(pSrc+1)^>Level)and(PByte(pSrc+3)^<=Level) then
  276.                    begin
  277.                       Result := BytePos+3;
  278.                       exit;
  279.                    end;
  280.             end;
  281.             inc(BytePos, 2*sizeOf(Byte));
  282.             inc(pSrc, 2*sizeOf(Byte));
  283.             dec(SrcNumBytes, 2*sizeOf(Byte));
  284.          end;
  285.       end
  286.       else
  287.       begin
  288.          SrcNumBytes := dwSrcLen;
  289.          while (SrcNumBytes > 2) do
  290.          begin
  291.             { we have only one channel }
  292.             if (Flank=1)and(PByte(pSrc)^<Level)and(PByte(pSrc+1)^>=Level) then
  293.             begin
  294.                Result := BytePos+1;
  295.                exit;
  296.             end
  297.             else if (Flank=2)and(PByte(pSrc)^>Level)and(PByte(pSrc+1)^<=Level) then
  298.             begin
  299.                Result := BytePos+1;
  300.                exit;
  301.             end;
  302.             inc(BytePos, sizeOf(Byte));
  303.             inc(pSrc, sizeOf(Byte));
  304.             dec(SrcNumBytes, sizeOf(Byte));
  305.          end;
  306.       end;
  307.    end
  308.    else
  309.    begin
  310.       Level := Level*327;
  311.       if pwfx^.nChannels = 2 then
  312.       begin
  313.          SrcNumBytes := dwSrcLen and not 3;
  314.          while (SrcNumBytes > 8) do
  315.          begin
  316.             case Channel of
  317.                 { both channels }
  318.                 0: begin
  319.                       { left }
  320.                       if (Flank=1)and(PSmallInt(pSrc)^<Level)and(PSmallInt(pSrc+4)^>=Level) then
  321.                       begin
  322.                          Result := BytePos+4;
  323.                          exit;
  324.                       end
  325.                       else if (Flank=2)and(PSmallInt(pSrc)^>Level)and(PSmallInt(pSrc+4)^<=Level) then
  326.                       begin
  327.                          Result := BytePos+4;
  328.                          exit;
  329.                       end;
  330.                       { right }
  331.                       if (Flank=1)and(PSmallInt(pSrc+4)^<Level)and(PSmallInt(pSrc+8)^>=Level) then
  332.                       begin
  333.                          Result := BytePos+8;
  334.                          exit;
  335.                       end
  336.                       else if (Flank=2)and(PSmallInt(pSrc+4)^>Level)and(PSmallInt(pSrc+8)^<=Level) then
  337.                       begin
  338.                          Result := BytePos+8;
  339.                          exit;
  340.                       end;
  341.                    end;
  342.                 { the left channel }
  343.                 1: if (Flank=1)and(PSmallInt(pSrc)^<Level)and(PSmallInt(pSrc+4)^>=Level) then
  344.                    begin
  345.                       Result := BytePos+4;
  346.                       exit;
  347.                    end
  348.                    else if (Flank=2)and(PSmallInt(pSrc)^>Level)and(PSmallInt(pSrc+4)^<=Level) then
  349.                    begin
  350.                       Result := BytePos+4;
  351.                       exit;
  352.                    end;
  353.                 { the right channel }
  354.                 2: if (Flank=1)and(PSmallInt(pSrc+4)^<Level)and(PSmallInt(pSrc+8)^>=Level) then
  355.                    begin
  356.                       Result := BytePos+8;
  357.                       exit;
  358.                    end
  359.                    else if (Flank=2)and(PSmallInt(pSrc+4)^>Level)and(PSmallInt(pSrc+8)^<=Level) then
  360.                    begin
  361.                       Result := BytePos+8;
  362.                       exit;
  363.                    end;
  364.             end;
  365.             inc(BytePos, 2*sizeOf(SmallInt));
  366.             inc(pSrc, 2*sizeOf(SmallInt));
  367.             dec(SrcNumBytes, 2*sizeOf(SmallInt));
  368.          end;
  369.       end
  370.       else
  371.       begin
  372.          SrcNumBytes := dwSrcLen and not 1;
  373.          while (SrcNumBytes > 4) do
  374.          begin
  375.             { we have only one channel }
  376.             if (Flank=1)and(PSmallInt(pSrc)^<Level)and(PSmallInt(pSrc+2)^>=Level) then
  377.             begin
  378.                Result := BytePos+2;
  379.                exit;
  380.             end
  381.             else if (Flank=2)and(PSmallInt(pSrc)^>Level)and(PSmallInt(pSrc+2)^<=Level) then
  382.             begin
  383.                Result := BytePos+2;
  384.                exit;
  385.             end;
  386.             inc(BytePos, sizeOf(SmallInt));
  387.             inc(pSrc, sizeOf(SmallInt));
  388.             dec(SrcNumBytes, sizeOf(SmallInt));
  389.          end;
  390.       end;
  391.    end;
  392. end;
  393. {*************************************************************************}
  394. { Computes the RMS amplitude in pSrc: 8/16 bit, mono/stereo              *}
  395. {*************************************************************************}
  396. procedure pcmCalcStatistics(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: TDataSize;
  397.                             var AvgL, AvgR, RmsL, RmsR: SmallInt);
  398. var
  399.    Samples,SrcBytes: Longint;
  400.    SumL, SumR,
  401.    SumL2,SumR2: Extended;
  402.    s: Smallint;
  403. begin
  404.    SumL := 0;
  405.    SumR := 0;
  406.    SumL2 := 0;
  407.    SumR2 := 0;
  408.    AvgL := 0;
  409.    AvgR := 0;
  410.    RmsL := 0;
  411.    RmsR := 0;
  412.    Samples := 0;
  413.    if pwfx^.wBitsperSample = 8 then
  414.    begin
  415.       if pwfx^.nChannels = 2 then
  416.       begin
  417.          SrcBytes := dwSrcLen and not 1;
  418.          while (SrcBytes > 0) do
  419.          begin
  420.             { the left channel }
  421.             s := (PByte(pSrc)^ - 128);
  422.             SumL := SumL + s;
  423.             SumL2:= SumL2 + Long(s)*s;
  424.             { the right channel }
  425.             s := (PByte(pSrc+1)^ - 128);
  426.             SumR := SumR + s;
  427.             SumR2:= SumR2 + Long(s)*s;
  428.             inc(Samples);
  429.             inc(pSrc, 2*sizeOf(Byte));
  430.             dec(SrcBytes, 2*sizeOf(Byte));
  431.          end;
  432.          if Samples > 0 then
  433.          begin
  434.             AvgL := Round(SumL/Samples);
  435.             if AvgL <> 0 then
  436.                RmsL := Round(Sqrt(SumL2/Samples-(Long(AvgL)*AvgL)));
  437.             AvgR := Round(SumR/Samples);
  438.             if AvgR <> 0 then
  439.                RmsR := Round(Sqrt(SumR2/Samples-(Long(AvgR)*AvgR)));
  440.          end;
  441.       end
  442.       else
  443.       begin
  444.          SrcBytes := dwSrcLen;
  445.          while (SrcBytes > 0) do
  446.          begin
  447.             { we have only one channel }
  448.             s := (PByte(pSrc)^ - 128);
  449.             SumL := SumL + s;
  450.             SumL2:= SumL2 + Long(s)*s;
  451.             inc(Samples);
  452.             inc(pSrc, sizeOf(Byte));
  453.             dec(SrcBytes, sizeOf(Byte));
  454.          end;
  455.          if Samples > 0 then
  456.          begin
  457.             AvgL := Round(SumL/Samples);
  458.             if AvgL <> 0 then
  459.                RmsL := Round(Sqrt(SumL2/Samples-(Long(AvgL)*AvgL)));
  460.          end;
  461.          AvgR := AvgL;
  462.          RmsR := RmsL;
  463.       end;
  464.    end
  465.    else
  466.    begin
  467.       if pwfx^.nChannels = 2 then
  468.       begin
  469.          SrcBytes := dwSrcLen and not 1;
  470.          while (SrcBytes > 0) do
  471.          begin
  472.             { the left channel }
  473.             s := PSmallint(pSrc)^;
  474.             SumL := SumL + s;
  475.             SumL2:= SumL2 + Long(s)*s;
  476.             { the right channel }
  477.             s := PSmallint(pSrc+2)^;
  478.             SumR := SumR + s;
  479.             SumR2:= SumR2 + Long(s)*s;
  480.             inc(Samples);
  481.             inc(pSrc, 2*sizeOf(SmallInt));
  482.             dec(SrcBytes, 2*sizeOf(Smallint));
  483.          end;
  484.          if Samples > 0 then
  485.          begin
  486.             AvgL := Round(SumL/Samples);
  487.             if AvgL <> 0 then
  488.                RmsL := Round(Sqrt(SumL2/Samples-(Long(AvgL)*AvgL)));
  489.             AvgR := Round(SumR/Samples);
  490.             if AvgR <> 0 then
  491.                RmsR := Round(Sqrt(SumR2/Samples-(Long(AvgR)*AvgR)));
  492.          end;
  493.       end
  494.       else
  495.       begin
  496.          SrcBytes := dwSrcLen and not 1;
  497.          while (SrcBytes > 0) do
  498.          begin
  499.             { we have only one channel }
  500.             s := PSmallint(pSrc)^;
  501.             SumL := SumL + s;
  502.             SumL2:= SumL2 + Long(s)*s;
  503.             inc(Samples);
  504.             inc(pSrc, sizeOf(SmallInt));
  505.             dec(SrcBytes, sizeOf(SmallInt));
  506.          end;
  507.          if Samples > 0 then
  508.          begin
  509.             AvgL := Round(SumL/Samples);
  510.             if AvgL <> 0 then
  511.                RmsL := Round(Sqrt(SumL2/Samples-(Long(AvgL)*AvgL)));
  512.          end;
  513.          AvgR := AvgL;
  514.          RmsR := RmsL;
  515.       end;
  516.    end;
  517. end;
  518. {*************************************************************************}
  519. function pcmVolume(pwfx: PWaveFormatEx; lpData: PChar; dwSrcLen: TDataSize;
  520.                    LeftVolume, RightVolume: Longint): Boolean;
  521. begin
  522.    Result := False;
  523.    if (pwfx = nil) or (pwfx^.wFormatTag <> WAVE_FORMAT_PCM) then exit;
  524.    if (pwfx^.wBitsPerSample = 8) then
  525.    begin
  526.       if (pwfx^.nChannels = 1) then
  527.           Result := pcmVolume8M(lpData, dwSrcLen, LeftVolume)
  528.       else
  529.           Result := pcmVolume8S(lpData, dwSrcLen, LeftVolume, RightVolume);
  530.    end
  531.    else
  532.    begin
  533.       if (pwfx^.nChannels = 1) then
  534.           Result := pcmVolume16M(lpData, dwSrcLen, LeftVolume)
  535.       else
  536.           Result := pcmVolume16S(lpData, dwSrcLen, LeftVolume, RightVolume);
  537.    end;
  538. end;
  539. {*************************************************************************}
  540. procedure pcmReverse(pwfx: PWaveFormatEx; lpData: PChar; dwSrcLen: TDataSize);
  541. var
  542.    Temp: Longint;
  543.    lpSource,pTemp: PChar;
  544. begin
  545.    if (pwfx = nil) or (pwfx^.wFormatTag <> WAVE_FORMAT_PCM) then exit;
  546.    pTemp := @Temp;
  547.    if (pwfx^.wBitsPerSample = 8) then
  548.    begin
  549.       if (pwfx^.nChannels = 1) then
  550.       begin
  551.          lpSource := (lpData+dwSrcLen-sizeOf(Byte));
  552.          dwSrcLen := dwSrcLen div 2;
  553.          while (dwSrcLen > 0) do
  554.          begin
  555.             PByte(pTemp)^   := PByte(lpData)^;
  556.             PByte(lpData)^  := PByte(lpSource)^;
  557.             PByte(lpSource)^:= PByte(pTemp)^;
  558.             inc(lpData,sizeOf(Byte));
  559.             dec(lpSource,sizeOf(Byte));
  560.             dec(dwSrcLen,sizeOf(Byte));
  561.          end;
  562.       end
  563.       else
  564.       begin
  565.          lpSource := (lpData+dwSrcLen-sizeOf(Word));
  566.          dwSrcLen := dwSrcLen div 2;
  567.          while (dwSrcLen > 0) do
  568.          begin
  569.             PWord(pTemp)^   := PWord(lpData)^;
  570.             PWord(lpData)^  := PWord(lpSource)^;
  571.             PWord(lpSource)^:= PWord(pTemp)^;
  572.             inc(lpData,sizeOf(Word));
  573.             dec(lpSource,sizeOf(Word));
  574.             dec(dwSrcLen,sizeOf(Word));
  575.          end;
  576.       end;
  577.    end
  578.    else
  579.    begin
  580.       if (pwfx^.nChannels = 1) then
  581.       begin
  582.          lpSource := (lpData+dwSrcLen-sizeOf(Smallint));
  583.          dwSrcLen := dwSrcLen div 2;
  584.          while (dwSrcLen > 0) do
  585.          begin
  586.             PSmallint(pTemp)^   := PSmallint(lpData)^;
  587.             PSmallint(lpData)^  := PSmallint(lpSource)^;
  588.             PSmallint(lpSource)^:= PSmallint(pTemp)^;
  589.             inc(lpData,sizeOf(Smallint));
  590.             dec(lpSource,sizeOf(Smallint));
  591.             dec(dwSrcLen,sizeOf(Smallint));
  592.          end;
  593.       end
  594.       else
  595.       begin
  596.          lpSource := (lpData+dwSrcLen-sizeOf(Longint));
  597.          dwSrcLen := dwSrcLen div 2;
  598.          while (dwSrcLen > 0) do
  599.          begin
  600.             PLongint(pTemp)^   := PLongint(lpData)^;
  601.             PLongint(lpData)^  := PLongint(lpSource)^;
  602.             PLongint(lpSource)^:= PLongint(pTemp)^;
  603.             inc(lpData,sizeOf(Longint));
  604.             dec(lpSource,sizeOf(Longint));
  605.             dec(dwSrcLen,sizeOf(Longint));
  606.          end;
  607.       end;
  608.    end;
  609. end;
  610. {*************************************************************************}
  611. function pcmPitchChange(pwfx: PWaveFormatEx; pSrc,pDst: PChar;
  612.                         var SrcLen,DstLen,IncValue: Longint; Factor: Longint): Longint;
  613. begin
  614.    Result := 0;
  615.    if (pwfx = nil) or (pwfx^.wFormatTag <> WAVE_FORMAT_PCM) then exit;
  616.    if (pwfx^.wBitsPerSample = 8) then
  617.    begin
  618.       if (pwfx^.nChannels = 1) then
  619.           Result := pcmPitchChange8M(pSrc, pDst, SrcLen, DstLen, IncValue, Factor)
  620.       else
  621.           Result := pcmPitchChange8S(pSrc, pDst, SrcLen, DstLen, IncValue, Factor);
  622.    end
  623.    else
  624.    begin
  625.       if (pwfx^.nChannels = 1) then
  626.           Result := pcmPitchChange16M(pSrc, pDst, SrcLen, DstLen, IncValue, Factor)
  627.       else
  628.           Result := pcmPitchChange16S(pSrc, pDst, SrcLen, DstLen, IncValue, Factor);
  629.    end;
  630. end;
  631. {*************************************************************************}
  632. procedure pcmFindSilenceEnd(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: TDataSize;
  633.                             Threshold: Longint; var SilenceEnd: Longint);
  634. var
  635.    SrcNumBytes: Longint;
  636. begin
  637.    SilenceEnd := -1;
  638.    if (Threshold < 0) then Threshold := 0;
  639.    if pwfx^.wBitsperSample = 8 then
  640.    begin
  641.       if pwfx^.nChannels = 2 then
  642.       begin
  643.          SrcNumBytes := dwSrcLen and not 1;
  644.          while (SrcNumBytes > 0) do
  645.          begin
  646.             if (abs(PByte(pSrc)^ - 128) > Threshold) or      { the left channel }
  647.                (abs(PByte(pSrc+1)^ - 128) > Threshold) then  { the right channel }
  648.             begin
  649.                SilenceEnd := dwSrcLen-SrcNumBytes;
  650.                exit;
  651.             end;
  652.             inc(pSrc, 2*sizeOf(Byte));
  653.             dec(SrcNumBytes, 2*sizeOf(Byte));
  654.          end;
  655.       end
  656.       else
  657.       begin
  658.          SrcNumBytes := dwSrcLen;
  659.          while (SrcNumBytes > 0) do
  660.          begin
  661.             { we have only one channel }
  662.             if (abs(PByte(pSrc)^ -128) > Threshold) then
  663.             begin
  664.                SilenceEnd := dwSrcLen-SrcNumBytes;
  665.                exit;
  666.             end;
  667.             inc(pSrc, sizeOf(Byte));
  668.             dec(SrcNumBytes, sizeOf(Byte));
  669.          end;
  670.       end;
  671.    end
  672.    else
  673.    begin
  674.       if pwfx^.nChannels = 2 then
  675.       begin
  676.          SrcNumBytes := dwSrcLen and not 3;
  677.          while (SrcNumBytes > 0) do
  678.          begin
  679.             if (abs(PSmallint(pSrc)^) > Threshold) or      { the left channel }
  680.                (abs(PSmallint(pSrc+2)^) > Threshold) then  { the right channel }
  681.             begin
  682.                SilenceEnd := dwSrcLen-SrcNumBytes;
  683.                exit;
  684.             end;
  685.             inc(pSrc, 2*sizeOf(SmallInt));
  686.             dec(SrcNumBytes, 2*sizeOf(SmallInt));
  687.          end;
  688.       end
  689.       else
  690.       begin
  691.          SrcNumBytes := dwSrcLen and not 1;
  692.          while (SrcNumBytes > 0) do
  693.          begin
  694.             { we have only one channel }
  695.             if (abs(PSmallint(pSrc)^) > Threshold) then
  696.             begin
  697.                SilenceEnd := dwSrcLen-SrcNumBytes;
  698.                exit;
  699.             end;
  700.             inc(pSrc, sizeOf(SmallInt));
  701.             dec(SrcNumBytes, sizeOf(SmallInt));
  702.          end;
  703.       end;
  704.    end;
  705. end;
  706. {*************************************************************************}
  707. procedure pcmFindSilenceStart(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: TDataSize;
  708.                               Threshold: Longint; var SilenceStart: Longint);
  709. var
  710.    SrcNumBytes: Longint;
  711. begin
  712.    SilenceStart := -1;
  713.    if (Threshold < 0) then Threshold := 0;
  714.    if pwfx^.wBitsperSample = 8 then
  715.    begin
  716.       if pwfx^.nChannels = 2 then
  717.       begin
  718.          SrcNumBytes := dwSrcLen and not 1;
  719.          while (SrcNumBytes > 0) do
  720.          begin
  721.             if (abs(PByte(pSrc)^ - 128) <= Threshold) and     { the left channel }
  722.                (abs(PByte(pSrc+1)^ - 128) <= Threshold) then  { the right channel }
  723.             begin
  724.                if (SilenceStart = -1) then
  725.                    SilenceStart := dwSrcLen-SrcNumBytes;
  726.             end
  727.             else
  728.             begin
  729.                SilenceStart := -1;
  730.             end;
  731.             inc(pSrc, 2*sizeOf(Byte));
  732.             dec(SrcNumBytes, 2*sizeOf(Byte));
  733.          end;
  734.       end
  735.       else
  736.       begin
  737.          SrcNumBytes := dwSrcLen;
  738.          while (SrcNumBytes > 0) do
  739.          begin
  740.             { we have only one channel }
  741.             if (abs(PByte(pSrc)^ -128) <= Threshold) then
  742.             begin
  743.                if (SilenceStart = -1) then
  744.                    SilenceStart := dwSrcLen-SrcNumBytes;
  745.             end
  746.             else
  747.             begin
  748.                SilenceStart := -1;
  749.             end;
  750.             inc(pSrc, sizeOf(Byte));
  751.             dec(SrcNumBytes, sizeOf(Byte));
  752.          end;
  753.       end;
  754.    end
  755.    else
  756.    begin
  757.       if pwfx^.nChannels = 2 then
  758.       begin
  759.          SrcNumBytes := dwSrcLen and not 3;
  760.          while (SrcNumBytes > 0) do
  761.          begin
  762.             if (abs(PSmallint(pSrc)^) <= Threshold) and     { the left channel }
  763.                (abs(PSmallint(pSrc+2)^) <= Threshold) then  { the right channel }
  764.             begin
  765.                if (SilenceStart = -1) then
  766.                    SilenceStart := dwSrcLen-SrcNumBytes;
  767.             end
  768.             else
  769.             begin
  770.                SilenceStart := -1;
  771.             end;
  772.             inc(pSrc, 2*sizeOf(SmallInt));
  773.             dec(SrcNumBytes, 2*sizeOf(SmallInt));
  774.          end;
  775.       end
  776.       else
  777.       begin
  778.          SrcNumBytes := dwSrcLen and not 1;
  779.          while (SrcNumBytes > 0) do
  780.          begin
  781.             { we have only one channel }
  782.             if (abs(PSmallint(pSrc)^) <= Threshold) then
  783.             begin
  784.                if (SilenceStart = -1) then
  785.                    SilenceStart := dwSrcLen-SrcNumBytes;
  786.             end
  787.             else
  788.             begin
  789.                SilenceStart := -1;
  790.             end;
  791.             inc(pSrc, sizeOf(SmallInt));
  792.             dec(SrcNumBytes, sizeOf(SmallInt));
  793.          end;
  794.       end;
  795.    end;
  796. end;
  797. {*************************************************************************}
  798. {$IFDEF USEASM}
  799. {$IFDEF WIN32}{$L MMPCM32.OBJ}{$ELSE}{$L MMPCM16.OBJ}{$ENDIF}
  800. {$F+}
  801. function  pcmSampleClip8(Sample: SmallInt): ShortInt; external;
  802. function  pcmSampleClip16(Sample: Longint): SmallInt; external;
  803. function  pcmSampleVolume8(Sample: Shortint; Volume: Longint): ShortInt; external;
  804. function  pcmSampleVolume16(Sample: Smallint; Volume: Longint): SmallInt; external;
  805. function  pcmVolume8M(lpData: PChar; dwSrcLen, Volume: Longint): Boolean; external;
  806. function  pcmVolume8S(lpData: PChar; dwSrcLen, LeftVolume, RightVolume: Longint): Boolean; external;
  807. function  pcmVolume16M(lpData: PChar; dwSrcLen, Volume: Longint): Boolean; external;
  808. function  pcmVolume16S(lpData: PChar; dwSrcLen, LeftVolume, RightVolume: Longint): Boolean; external;
  809. procedure pcmFindPeak(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: TDataSize;
  810.                       var PeakL, PeakR: SmallInt); external;
  811. procedure pcmFindMinMax(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: TDataSize;
  812.                       var MinL, MaxL, MinR, MaxR: SmallInt); external;
  813. function  pcmConvertSizeOutputData(pwfDst, pwfSrc: PPCMWaveFormat;
  814.                                    NumBytesSrc: Longint): Longint; external;
  815. function  pcmConvert(pwfDst: PPCMWaveFormat; pDst: PChar;
  816.                      pwfSrc: PPCMWaveFormat; pSrc: PChar;
  817.                      dwSrcLen: Cardinal): Cardinal; external;
  818. {$F-}
  819. {$ELSE}
  820. (*************************************************************************)
  821. function pcmSampleClip8(Sample: SmallInt): ShortInt;
  822. const
  823.      ClipValue = 127;
  824. begin
  825.    if (Sample < -ClipValue) then
  826.    begin
  827.       Result := -ClipValue;
  828.       Overflow := True;
  829.    end
  830.    else if (Sample > ClipValue) then
  831.    begin
  832.       Result := ClipValue;
  833.       Overflow := True;
  834.    end
  835.    else
  836.        Result := Sample;
  837. end;
  838. (*************************************************************************)
  839. function pcmSampleClip16(Sample: Longint): SmallInt;
  840. const
  841.      ClipValue = 32767;
  842. begin
  843.    if (Sample < -ClipValue) then
  844.    begin
  845.       Result := -ClipValue;
  846.       Overflow := True;
  847.    end
  848.    else if (Sample > ClipValue) then
  849.    begin
  850.       Result := ClipValue;
  851.       Overflow := True;
  852.    end
  853.    else
  854.        Result := Sample;
  855. end;
  856. (*************************************************************************)
  857. function pcmSampleVolume8(Sample: ShortInt; Volume: Longint): ShortInt;
  858. begin
  859.    Result := 128 + ((Sample-128) * Volume) div VOLUMEBASE;
  860. end;
  861. (*************************************************************************)
  862. function pcmSampleVolume16(Sample: Smallint; Volume: Longint): Smallint;
  863. begin
  864.    Result := (Sample * Volume) div VOLUMEBASE;
  865. end;
  866. (*************************************************************************)
  867. function pcmVolume8M(lpData: PChar; dwSrcLen: TDataSize; Volume: Longint): Boolean;
  868. var
  869.    s: Smallint;
  870. begin
  871.    Overflow := False;
  872.    while (dwSrcLen > 0) do
  873.    begin
  874.       s := 128+((PByte(lpData)^-128) * Volume) div VOLUMEBASE;
  875.       PByte(lpData)^ := pcmSampleClip8(s);
  876.       inc(lpData, sizeOf(Byte));
  877.       dec(dwSrcLen, sizeOf(Byte));
  878.    end;
  879.    Result := Overflow;
  880. end;
  881. (*************************************************************************)
  882. function pcmVolume8S(lpData: PChar; dwSrcLen: TDataSize; LeftVolume, RightVolume: Longint): Boolean;
  883. var
  884.    s: Smallint;
  885. begin
  886.    Overflow := False;
  887.    dwSrcLen := dwSrcLen and not 1;
  888.    while (dwSrcLen > 0) do
  889.    begin
  890.       s := 128+((PByte(lpData)^-128) * LeftVolume) div VOLUMEBASE;
  891.       PByte(lpData)^ := pcmSampleClip8(s);
  892.       inc(lpData, sizeOf(Byte));
  893.       s := 128+((PByte(lpData)^-128) * RightVolume) div VOLUMEBASE;
  894.       PByte(lpData)^ := pcmSampleClip8(s);
  895.       inc(lpData, sizeOf(Byte));
  896.       dec(dwSrcLen, 2*sizeOf(Byte));
  897.    end;
  898.    Result := Overflow;
  899. end;
  900. (*************************************************************************)
  901. function pcmVolume16M(lpData: PChar; dwSrcLen: TDataSize; Volume: Longint): Boolean;
  902. var
  903.    s: Longint;
  904. begin
  905.    Overflow := False;
  906.    dwSrcLen := dwSrcLen and not 1;
  907.    while (dwSrcLen > 0) do
  908.    begin
  909.       s := (PSmallint(lpData)^ * Volume) div VOLUMEBASE;
  910.       PSmallint(lpData)^ := pcmSampleClip16(s);
  911.       inc(lpData, sizeOf(Smallint));
  912.       dec(dwSrcLen, sizeOf(Smallint));
  913.    end;
  914.    Result := Overflow;
  915. end;
  916. (*************************************************************************)
  917. function pcmVolume16S(lpData: PChar; dwSrcLen: TDataSize; LeftVolume, RightVolume: Longint): Boolean;
  918. var
  919.    s: Longint;
  920. begin
  921.    Overflow := False;
  922.    dwSrcLen := dwSrcLen and not 3;
  923.    while (dwSrcLen > 0) do
  924.    begin
  925.       s := (PSmallint(lpData)^ * LeftVolume) div VOLUMEBASE;
  926.       PSmallint(lpData)^ := pcmSampleClip16(s);
  927.       inc(lpData, sizeOf(Smallint));
  928.       s := (PSmallint(lpData)^ * RightVolume) div VOLUMEBASE;
  929.       PSmallint(lpData)^ := pcmSampleClip16(s);
  930.       inc(lpData, sizeOf(Smallint));
  931.       dec(dwSrcLen, 2*sizeOf(Smallint));
  932.    end;
  933.    Result := Overflow;
  934. end;
  935. {*************************************************************************}
  936. {* find the peak value in pSrc: 8/16 bit, mono/stereo                    *}
  937. {*************************************************************************}
  938. procedure pcmFindPeak(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: TDataSize;
  939.                       var PeakL, PeakR: SmallInt);
  940. var
  941.    SrcNumBytes,sd: Longint;
  942.    pL,pR,sw: Smallint;
  943. begin
  944.    PeakL := 0;
  945.    PeakR := 0;
  946.    pR    := 0;
  947.    pL    := 0;
  948.    if pwfx^.wBitsperSample = 8 then
  949.    begin
  950.       if pwfx^.nChannels = 2 then
  951.       begin
  952.          SrcNumBytes := dwSrcLen and not 1;
  953.          while (SrcNumBytes > 0) do
  954.          begin
  955.             { the left channel }
  956.             sw := PByte(pSrc)^ - 128;
  957.             if abs(sw) > pL then
  958.             begin
  959.                PeakL := sw;
  960.                pL := Min(abs(sw),127);
  961.             end;
  962.             { the right channel }
  963.             sw := PByte(pSrc+1)^ - 128;
  964.             if abs(sw) > pR then
  965.             begin
  966.                PeakR := sw;
  967.                pR := Min(abs(sw),127);
  968.             end;
  969.             inc(pSrc, 2*sizeOf(Byte));
  970.             dec(SrcNumBytes, 2*sizeOf(Byte));
  971.          end;
  972.          PeakL := PeakL + 128;
  973.          PeakR := PeakR + 128;
  974.       end
  975.       else
  976.       begin
  977.          SrcNumBytes := dwSrcLen;
  978.          while (SrcNumBytes > 0) do
  979.          begin
  980.             { we have only one channel }
  981.             sw := PByte(pSrc)^ -128;
  982.             if abs(sw) > pL then
  983.             begin
  984.                PeakL := sw;
  985.                pL := Min(abs(sw),127);
  986.             end;
  987.             inc(pSrc, sizeOf(Byte));
  988.             dec(SrcNumBytes, sizeOf(Byte));
  989.          end;
  990.          PeakL := PeakL + 128;
  991.          PeakR := PeakL;
  992.       end;
  993.    end
  994.    else
  995.    begin
  996.       if pwfx^.nChannels = 2 then
  997.       begin
  998.          SrcNumBytes := dwSrcLen and not 3;
  999.          while (SrcNumBytes > 0) do
  1000.          begin
  1001.             { the left channel }
  1002.             sd := PSmallint(pSrc)^;
  1003.             if abs(sd) > pL then
  1004.             begin
  1005.                PeakL := sd;
  1006.                pL := Min(abs(sd),32767);
  1007.             end;
  1008.             { the right channel }
  1009.             sd := PSmallint(pSrc+2)^;
  1010.             if abs(sd) > pR then
  1011.             begin
  1012.                PeakR := sd;
  1013.                pR := Min(abs(sd),32767);
  1014.             end;
  1015.             inc(pSrc, 2*sizeOf(SmallInt));
  1016.             dec(SrcNumBytes, 2*sizeOf(SmallInt));
  1017.          end;
  1018.       end
  1019.       else
  1020.       begin
  1021.          SrcNumBytes := dwSrcLen and not 1;
  1022.          while (SrcNumBytes > 0) do
  1023.          begin
  1024.             { we have only one channel }
  1025.             sd := PSmallint(pSrc)^;
  1026.             if abs(sd) > pL then
  1027.             begin
  1028.                PeakL := sd;
  1029.                pL := Min(abs(sd),32767);
  1030.             end;
  1031.             inc(pSrc, sizeOf(SmallInt));
  1032.             dec(SrcNumBytes, sizeOf(SmallInt));
  1033.          end;
  1034.          PeakR := PeakL;
  1035.       end;
  1036.    end;
  1037. end;
  1038. {*************************************************************************}
  1039. {* find the signed Min/Max value in pSrc: 8/16 bit, mono/stereo                *}
  1040. {*************************************************************************}
  1041. procedure pcmFindMinMax(pwfx: PWaveFormatEx; pSrc: PChar; dwSrcLen: TDataSize;
  1042.                       var MinL, MaxL, MinR, MaxR: SmallInt);
  1043. var
  1044.    SrcNumBytes: Longint;
  1045.    i, MinIdx_L, MaxIdx_L, MinIdx_R, MaxIdx_R: integer;
  1046. begin
  1047.    MinIdx_L := 0;
  1048.    MaxIdx_L := 0;
  1049.    MinIdx_R := 0;
  1050.    MaxIdx_R := 0;
  1051.    i := 0;
  1052.    if pwfx^.wBitsperSample = 8 then
  1053.    begin
  1054.       MinL := 128;
  1055.       MaxL := 128;
  1056.       MinR := 128;
  1057.       MaxR := 128;
  1058.       if pwfx^.nChannels = 2 then
  1059.       begin
  1060.          SrcNumBytes := dwSrcLen and not 1;
  1061.          if (SrcNumBytes > 0) then
  1062.          begin
  1063.             MinL := 127;
  1064.             MaxL := -128;
  1065.             MinR := 127;
  1066.             MaxR := -128;
  1067.             while (SrcNumBytes > 0) do
  1068.             begin
  1069.                { the left channel }
  1070.                if PByte(pSrc)^ -128 < MinL then
  1071.                begin
  1072.                   MinL := PByte(pSrc)^ -128;
  1073.                   MinIdx_L := i;
  1074.                end;
  1075.                if PByte(pSrc)^ -128 > MaxL then
  1076.                begin
  1077.                   MaxL := PByte(pSrc)^ -128;
  1078.                   MaxIdx_L := i;
  1079.                end;
  1080.                { the right channel }
  1081.                if PByte(pSrc+1)^ -128 < MinR then
  1082.                begin
  1083.                   MinR := PByte(pSrc+1)^ -128;
  1084.                   MinIdx_R := i;
  1085.                end;
  1086.                if PByte(pSrc+1)^ -128 > MaxR then
  1087.                begin
  1088.                   MaxR := PByte(pSrc+1)^ -128;
  1089.                   MaxIdx_R := i;
  1090.                end;
  1091.                inc(pSrc, 2*sizeOf(Byte));
  1092.                dec(SrcNumBytes, 2*sizeOf(Byte));
  1093.                inc(i);
  1094.             end;
  1095.             if MaxIdx_L < MinIdx_L then SwapSmall(MinL, MaxL);
  1096.             if MaxIdx_R < MinIdx_R then SwapSmall(MinR, MaxR);
  1097.             MinL := MinL + 128;
  1098.             MaxL := MaxL + 128;
  1099.             MinR := MinR + 128;
  1100.             MaxR := MaxR + 128;
  1101.          end;
  1102.       end
  1103.       else
  1104.       begin
  1105.          SrcNumBytes := dwSrcLen;
  1106.          if (SrcNumBytes > 0) then
  1107.          begin
  1108.             MinL := 127;
  1109.             MaxL := -128;
  1110.             while (SrcNumBytes > 0) do
  1111.             begin
  1112.                { we have only one channel }
  1113.                if PByte(pSrc)^ -128 < MinL then
  1114.                begin
  1115.                   MinL := PByte(pSrc)^ -128;
  1116.                   MinIdx_L := i;
  1117.                end;
  1118.                if PByte(pSrc)^ -128 > MaxL then
  1119.                begin
  1120.                   MaxL := PByte(pSrc)^ -128;
  1121.                   MaxIdx_L := i;
  1122.                end;
  1123.                inc(pSrc, sizeOf(Byte));
  1124.                dec(SrcNumBytes, sizeOf(Byte));
  1125.                inc(i);
  1126.             end;
  1127.             if MaxIdx_L < MinIdx_L then SwapSmall(MinL, MaxL);
  1128.             MinL := MinL + 128;
  1129.             MaxL := MaxL + 128;
  1130.             MinR := MinL;
  1131.             MaxR := MaxL;
  1132.          end;
  1133.       end;
  1134.    end
  1135.    else
  1136.    begin
  1137.       MinL := 0;
  1138.       MaxL := 0;
  1139.       MinR := 0;
  1140.       MaxR := 0;
  1141.       if pwfx^.nChannels = 2 then
  1142.       begin
  1143.          SrcNumBytes := dwSrcLen and not 3;
  1144.          if (SrcNumBytes > 0) then
  1145.          begin
  1146.             MinL := 32767;
  1147.             MaxL := -32768;
  1148.             MinR := 32767;
  1149.             MaxR := -32768;
  1150.             while (SrcNumBytes > 0) do
  1151.             begin
  1152.                { the left channel }
  1153.                if PSmallInt(pSrc)^ < MinL then
  1154.                begin
  1155.                   MinL := PSmallint(pSrc)^;
  1156.                   MinIdx_L := i;
  1157.                end;
  1158.                if PSmallInt(pSrc)^ > MaxL then
  1159.                begin
  1160.                   MaxL := PSmallint(pSrc)^;
  1161.                   MaxIdx_L := i;
  1162.                end;
  1163.                { the right channel }
  1164.                if PSmallint(pSrc+2)^ < MinR then
  1165.                begin
  1166.                   MinR := PSmallint(pSrc+2)^;
  1167.                   MinIdx_R := i;
  1168.                end;
  1169.                if PSmallint(pSrc+2)^ > MaxR then
  1170.                begin
  1171.                   MaxR := PSmallint(pSrc+2)^;
  1172.                   MaxIdx_R := i;
  1173.                end;
  1174.                inc(pSrc, 2*sizeOf(SmallInt));
  1175.                dec(SrcNumBytes, 2*sizeOf(SmallInt));
  1176.                inc(i);
  1177.             end;
  1178.             if MaxIdx_L < MinIdx_L then SwapSmall(MinL, MaxL);
  1179.             if MaxIdx_R < MinIdx_R then SwapSmall(MinR, MaxR);
  1180.          end;
  1181.       end
  1182.       else
  1183.       begin
  1184.          { we have only one channel }
  1185.          SrcNumBytes := dwSrcLen and not 1;
  1186.          if (SrcNumBytes > 0) then
  1187.          begin
  1188.             MinL := 32767;
  1189.             MaxL := -32768;
  1190.             while (SrcNumBytes > 0) do
  1191.             begin
  1192.                { we have only one channel }
  1193.                if PSmallInt(pSrc)^ < MinL then
  1194.                begin
  1195.                   MinL := PSmallint(pSrc)^;
  1196.                   MinIdx_L := i;
  1197.                end;
  1198.                if PSmallInt(pSrc)^ > MaxL then
  1199.                begin
  1200.                   MaxL := PSmallint(pSrc)^;
  1201.                   MaxIdx_L := i;
  1202.                end;
  1203.                inc(pSrc, sizeOf(SmallInt));
  1204.                dec(SrcNumBytes, sizeOf(SmallInt));
  1205.                inc(i);
  1206.             end;
  1207.             if MaxIdx_L < MinIdx_L then SwapSmall(MinL, MaxL);
  1208.             MinR := MinL;
  1209.             MaxR := MaxL;
  1210.          end;
  1211.       end;
  1212.    end;
  1213. end;
  1214. {*************************************************************************}
  1215. {* all formats: 8/16 bit, Mono/Stereo, frequency: 1..$FFFFFF             *}
  1216. {*************************************************************************}
  1217. function pcmConvertSizeOutputData(pwfDst, pwfSrc: PPCMWaveFormat;
  1218.                                   NumBytesSrc: Longint): Longint;
  1219. Var
  1220.    nSamples: Longint;
  1221. begin
  1222.    (* OutSamples := (SrcSamples * DstSampleRate) div SrcSampleRate *)
  1223.    nSamples := wioBytesToSamples(PWaveFormatEx(pwfSrc), NumBytesSrc);
  1224.    nSamples := muldiv32(nSamples, pwfDst^.wf.nSamplesPerSec, pwfSrc^.wf.nSamplesPerSec);
  1225.    Result := wioSamplesToBytes(PWaveFormatEx(pwfDst), nSamples);
  1226. end;
  1227. {*************************************************************************}
  1228. {* convert all: 8/16 bit, Mono/Stereo, frequency: 1..$FFFFFF             *}
  1229. {*************************************************************************}
  1230. function pcmConvert(pwfDst: PPCMWaveFormat; pDst: PChar;
  1231.                     pwfSrc: PPCMWaveFormat; pSrc: PChar;
  1232.                     dwSrcLen: Cardinal): Cardinal;
  1233. Var
  1234.    newSample16: array[0..1] of SmallInt;
  1235.    newSample8: array[0..1] of Byte;
  1236.    dwSrcSampleRate, dwDstSampleRate: Longint;
  1237.    wSrcChannels, wDstChannels: Word;
  1238.    wSrcBytesPS, wDstBytesPS: Word;                     { Bytes per Sample }
  1239.    dwNumSamples, dwSum: Longint;
  1240.    dwTotalDst: integer;
  1241.    fBPSUp: Boolean; { convert BPS up }
  1242.    fBPSDown: Boolean; { convert BPS down }
  1243.    i: integer;
  1244. {-------------------}
  1245. Procedure ReadSample;
  1246. Var
  1247.    ch: integer;
  1248. begin
  1249.    { get the source sample(s) }
  1250.    for ch := 0 to wSrcChannels-1 do
  1251.    begin
  1252.       if fBPSUp then
  1253.       begin
  1254.          newSample16[ch] := (PByte(pSrc)^ shl 8) xor $8000;
  1255.          inc(pSrc);
  1256.       end
  1257.       else if fBPSDown then
  1258.       begin
  1259.          newSample8[ch] := ((PSmallInt(pSrc)^ xor $8000) + $0080) shr 8;
  1260.          inc(pSrc,2);
  1261.       end
  1262.       else if (wSrcBytesPS <= 1) then
  1263.       begin
  1264.          newSample8[ch] := PByte(pSrc)^;
  1265.          inc(pSrc);
  1266.       end
  1267.       else
  1268.       begin
  1269.          newSample16[ch] := PSmallint(pSrc)^;
  1270.          inc(pSrc,2);
  1271.       end;
  1272.    end;
  1273. end;
  1274. {--------------------}
  1275. procedure WriteSample;
  1276. Var
  1277.    ch: integer;
  1278. begin
  1279.    for ch := 0 to wDstChannels-1 do
  1280.    begin
  1281.       if fBPSDown or (wDstBytesPS <= 1) then
  1282.       begin
  1283.          if (wSrcChannels = wDstChannels) then
  1284.             PByte(pDst)^ := newSample8[ch]
  1285.          else if (wSrcChannels < wDstChannels) then
  1286.             PByte(pDst)^ := newSample8[0]
  1287.          else { mix the two channels }
  1288.             PByte(pDst)^ := MinMax(Word(newSample8[0]) + newSample8[1],0,255);
  1289.          inc(pDst);
  1290.  inc(dwTotalDst);
  1291.       end
  1292.       else
  1293.       begin
  1294.          if (wSrcChannels = wDstChannels) then
  1295.             PSmallInt(pDst)^ := newSample16[ch]
  1296.          else if (wSrcChannels < wDstChannels) then
  1297.             PSmallInt(pDst)^ := newSample16[0]
  1298.          else { mix the two channels }
  1299.             PSmallInt(pDst)^ := MinMax(Longint(newSample16[0]) + newSample16[1],-32768,32765);
  1300.          inc(pDst,2);
  1301.  inc(dwTotalDst, 2);
  1302.       end;
  1303.    end;
  1304. end;
  1305. {-- MAIN --}
  1306. begin
  1307.    fBPSup := False;
  1308.    fBPSDown := False;
  1309.    wSrcBytesPS := pwfSrc^.wBitsPerSample shr 3;
  1310.    wDstBytesPS := pwfDst^.wBitsPerSample shr 3;
  1311.    wSrcChannels := pwfSrc^.wf.nChannels;
  1312.    wDstChannels := pwfDst^.wf.nChannels;
  1313.    dwSrcSampleRate := pwfSrc^.wf.nSamplesPerSec;
  1314.    dwDstSampleRate := pwfDst^.wf.nSamplesPerSec;
  1315.    { if wave formats are the same just return the input buffer }
  1316.    if ((wSrcChannels = wDstChannels) and
  1317.        (dwSrcSampleRate = dwDstSampleRate) and
  1318.        (wSrcBytesPS = wDstBytesPS)) then
  1319.    begin
  1320.       move(pSrc^, pDst^, dwSrcLen);
  1321.       Result := dwSrcLen;
  1322.       exit;
  1323.    end;
  1324.    dwNumSamples := dwSrcLen div wSrcBytesPS div wSrcChannels;
  1325.    if (wSrcBytesPS <= 1) and (wDstBytesPS >  1) then fBPSUp := True;
  1326.    if (wSrcBytesPS >  1) and (wDstBytesPS <= 1) then fBPSDown := True;
  1327.    dwTotalDst := 0;
  1328.    { PCM format (8 or 16 bit, mono/stereo, and sample rate). }
  1329.    if (dwSrcSampleRate > dwDstSampleRate) then
  1330.    begin
  1331.        { down sampling, skip samples }
  1332.        dwSum := dwSrcSampleRate div 2;
  1333.        for i := 0 to dwNumSamples-1 do
  1334.        begin
  1335.           ReadSample;
  1336.           dwSum := dwSum - dwDstSampleRate;
  1337.           if dwSum < 0 then
  1338.           begin
  1339.              WriteSample;
  1340.              dwSum := dwSum + dwSrcSampleRate;
  1341.           end;
  1342.        end;
  1343.    end
  1344.    else
  1345.    begin
  1346.        { up sampling, repeat samples }
  1347.        dwSum := dwDstSampleRate div 2;
  1348.        for i := 0 to dwNumSamples-1 do
  1349.        begin
  1350.           ReadSample;
  1351.           while dwSum >= 0 do
  1352.           begin
  1353.              WriteSample;
  1354.              dwSum := dwSum - dwSrcSampleRate;
  1355.           end;
  1356.           dwSum := dwSum + dwDstSampleRate;
  1357.        end;
  1358.    end;
  1359.    Result := dwTotalDst;
  1360. end;
  1361. {$ENDIF}
  1362. {*************************************************************************}
  1363. {* only standard: 8/16 bit PCM                                           *}
  1364. {*************************************************************************}
  1365. function pcmBitsPerSampleAlign(nDstBitsPS: Word; pDst: PChar;
  1366.                                nSrcBitsPS: Word; pSrc: PChar;
  1367.                                dwSrcLen: Cardinal): Cardinal;
  1368. Var
  1369.    i: integer;
  1370.    dwNumSamples: Longint;
  1371.    dwTotalDst: Longint;
  1372. begin
  1373.    if (nSrcBitsPS = nDstBitsPS) then
  1374.    begin
  1375.       move(pSrc^, pDst^, dwSrcLen);
  1376.       Result := dwSrcLen;
  1377.       exit;
  1378.    end;
  1379.    dwNumSamples := dwSrcLen div (nSrcBitsPS shr 3);
  1380.    dwTotalDst := 0;
  1381.    if (nSrcBitsPS > nDstBitsPS) then
  1382.    begin                                   { convert from 16 bit to 8 bit }
  1383.       for i := 0 to dwNumSamples-1 do
  1384.       begin
  1385.        PByte(pDst)^ := (PSmallInt(pSrc)^ div 256) + 128;
  1386.         inc(pSrc, 2);
  1387.         inc(pDst);
  1388.         inc(dwTotalDst);
  1389.       end;
  1390.    end
  1391.    else
  1392.    begin                                   { convert from 8 bit to 16 bit }
  1393.       for i := 0 to dwNumSamples-1 do
  1394.       begin
  1395.          PSmallInt(pDst)^ := Smallint(PByte(pSrc)^-128) * 256;
  1396.          inc(pSrc);
  1397.          inc(pDst, 2);
  1398.          inc(dwTotalDst, 2);
  1399.       end;
  1400.    end;
  1401.    Result := dwTotalDst;
  1402. end;
  1403. {*************************************************************************}
  1404. {* only standard: Mono/Stereo PCM                                        *}
  1405. {*************************************************************************}
  1406. function pcmChannelAlign(nDstChannels: Word; pDst: PChar;
  1407.                          nSrcChannels: Word; pSrc: PChar;
  1408.                          nBitsPS: Word; dwSrcLen: Cardinal): Cardinal;
  1409. Var
  1410.    i: integer;
  1411.    dwNumSamples: Longint;
  1412.    dwTotalDst: Longint;
  1413. begin
  1414.    if (nSrcChannels = nDstChannels) then
  1415.    begin
  1416.       move(pSrc^, pDst^, dwSrcLen);
  1417.       Result := dwSrcLen;
  1418.       exit;
  1419.    end;
  1420.    dwNumSamples := dwSrcLen div (nBitsPS shr 3) div nSrcChannels;
  1421.    dwTotalDst := 0;
  1422.    if (nSrcChannels < nDstChannels) then     { convert from mono to stereo }
  1423.    begin
  1424.       if (nBitsPS = 8) then                                       { 8 bit }
  1425.       begin
  1426.  for i := 0 to dwNumSamples-1 do
  1427.  begin
  1428.     PByte(pDst)^ := PByte(pSrc)^;
  1429.             PByte(pDst+1)^ := PByte(pSrc)^;
  1430.             inc(pSrc);
  1431.             inc(pDst, 2);
  1432.             inc(dwTotalDst, 2);
  1433.          end;
  1434.       end
  1435.       else                                                       { 16 bit }
  1436.       begin
  1437.  for i := 0 to dwNumSamples-1 do
  1438.  begin
  1439.     PSmallInt(pDst)^ := PSmallInt(pSrc)^;
  1440.             PSmallInt(pDst+2)^ := PSmallInt(pSrc)^;
  1441.             inc(pSrc, 2);
  1442.             inc(pDst, 4);
  1443.             inc(dwTotalDst, 4);
  1444.          end;
  1445.       end;
  1446.    end
  1447.    else                                     { convert from stereo to mono }
  1448.    begin
  1449.       if (nBitsPS = 8) then                                       { 8 bit }
  1450.       begin
  1451.  for i := 0 to dwNumSamples-1 do
  1452.  begin
  1453.             { mix the two channels }
  1454.             PByte(pDst)^ := MinMax(Word(PByte(pSrc)^)+Word(PByte(pSrc+1)^),0, 255);
  1455.             inc(pSrc, 2);
  1456.             inc(pDst);
  1457.             inc(dwTotalDst);
  1458.          end;
  1459.       end
  1460.       else                                                       { 16 bit }
  1461.       begin
  1462.          for i := 0 to dwNumSamples-1 do
  1463.  begin
  1464.     PSmallInt(pDst)^ := MinMax(Longint(PSmallInt(pSrc)^) + Longint(PSmallInt(pSrc+2)^),-32765, 32765);
  1465.             inc(pSrc, 4);
  1466.             inc(pDst, 2);
  1467.             inc(dwTotalDst, 2);
  1468.          end;
  1469.       end;
  1470.    end;
  1471.    Result := dwTotalDst;
  1472. end;
  1473. (*************************************************************************)
  1474. (* this routine averages the 8 bit samples along the different channels  *)
  1475. (*************************************************************************)
  1476. procedure pcmAvgSample8(pDst, pSrc: PChar; nSkip, nChannels: Word);
  1477. Var
  1478.    lpB: PByte;
  1479.    sum, i,j: integer;
  1480. begin
  1481.      for i := 0 to nChannels-1 do
  1482.      begin
  1483.         lpB := PByte(pSrc);
  1484.         inc(pSrc);
  1485. sum := 0;
  1486. for j := 0 to nSkip-1 do
  1487.         begin
  1488.    sum := sum + (lpB^ - 128);
  1489.            inc(lpB, nChannels);
  1490.         end;
  1491.         PByte(pDst)^ := (sum div nSkip) + 128;
  1492.         inc(pDst);
  1493.      end;
  1494. end;
  1495. (*************************************************************************)
  1496. (* this routine averages the 16 bit samples along the different channels *)
  1497. (*************************************************************************)
  1498. procedure pcmAvgSample16(pDst, pSrc: PChar; nSkip, nChannels: Word);
  1499. Var
  1500.    lpW: PSmallInt;
  1501.    sum: Longint;
  1502.    i,j: integer;
  1503. begin
  1504.      for i := 0 to nChannels-1 do
  1505.      begin
  1506.         lpW := PSmallInt(pSrc);
  1507.         inc(PSmallInt(pSrc));
  1508. sum := 0;
  1509.         for j := 0 to nSkip-1 do
  1510.         begin
  1511.    sum := sum + lpW^;
  1512.    inc(lpW, nChannels);
  1513.         end;
  1514. PSmallInt(pDst)^ := sum div nSkip;
  1515.         inc(PSmallInt(pDst));
  1516.      end;
  1517. end;
  1518. (*************************************************************************)
  1519. (* this routine interpolates the 8 Bit samples along the diff. channels  *)
  1520. (*************************************************************************)
  1521. procedure pcmRepSample8(pDst, pSrc: PChar; nRep, nChannels: Word);
  1522. Var
  1523.    lpB: PByte;
  1524.    diff, val: integer;
  1525.    i, j: integer;
  1526. begin
  1527.      if (nRep > 1) then
  1528.      begin
  1529.         lpB := PByte(pDst);
  1530.         for i := 0 to nChannels-1 do
  1531.         begin
  1532.    PByte(pDst) := lpB;
  1533.            inc(lpB);
  1534.            diff := (PByte(pSrc+nChannels)^ - PByte(pSrc)^) div nRep;
  1535.            PByte(pDst)^ := pByte(pSrc)^;
  1536.    val := PByte(pSrc)^;
  1537.    inc(pDst, nChannels);
  1538.            {diff := 0; remove interpolation }
  1539.            for j := 1 to nRep-1 do
  1540.            begin
  1541.               inc(val, diff);
  1542.               PByte(pDst)^ := val;
  1543.               inc(pDst, nChannels);
  1544.            end;
  1545.    inc(pSrc);
  1546.         end;
  1547.      end;
  1548. end;
  1549. (*************************************************************************)
  1550. (* this routine interpolates the 8 Bit samples along the diff. channels  *)
  1551. (*************************************************************************)
  1552. procedure pcmRepSample16(pDst, pSrc: PChar; nRep, nChannels: Word);
  1553. Var
  1554.    lpW: PSmallInt;
  1555.    diff, val: integer;
  1556.    i, j: integer;
  1557. begin
  1558.      if (nRep > 1) then
  1559.      begin
  1560.         lpW := PSmallInt(pDst);
  1561.         for i := 0 to nChannels-1 do
  1562.         begin
  1563.            PSmallInt(pDst) := lpW;
  1564.            inc(lpW);
  1565.            diff := (PSmallInt(pSrc+2*nChannels)^ - PSmallInt(pSrc)^) div nRep;
  1566.            PSmallInt(pDst)^ := PSmallInt(pSrc)^;
  1567.            val := PSmallInt(pSrc)^;
  1568.    inc(PSmallInt(pDst), nChannels);
  1569.            { diff := 0; remove interpolation }
  1570.            for j := 1 to nRep-1 do
  1571.            begin
  1572.       inc(val,diff);
  1573.       PSmallInt(pDst)^ := val;
  1574.               inc(PSmallInt(pDst), nChannels);
  1575.            end;
  1576.            inc(PSmallInt(pSrc));
  1577.         end;
  1578.      end;
  1579. end;
  1580. {*************************************************************************}
  1581. {* only standard: 11025Khz, 22050Khz, 44100Khz PCM !!!                   *}
  1582. {*************************************************************************}
  1583. function pcmSamplesPerSecAlign(nDstSPS: Longint; pDst: PChar;
  1584.                                nSrcSPS: Longint; pSrc: PChar;
  1585.                                nBitsPS, nChannels: Word;
  1586.                                dwSrcLen: Cardinal): Cardinal;
  1587. Var
  1588.    i,j: integer;
  1589.    SampleSize: DWORD;
  1590.    nRep,nSkip: DWORD;
  1591.    dwNumSamples,dwNewNumSamples: DWORD;
  1592.    dwTotalDst: Longint;
  1593.    pTmp: PChar;
  1594. begin
  1595.    if (nSrcSPS = nDstSPS) then
  1596.    begin
  1597.       move(pSrc^, pDst^, dwSrcLen);
  1598.       Result := dwSrcLen;
  1599.       exit;
  1600.    end;
  1601.    SampleSize := (nBitsPS shr 3) * nChannels;
  1602.    dwNumSamples := dwSrcLen div SampleSize;
  1603.    nSkip := 0;
  1604.    nRep := 0;
  1605.    dwTotalDst := 0;
  1606.    if (nDstSPS > nSrcSPS) then
  1607.    begin      
  1608.       { then need to add in extra samples }
  1609.       nRep := nDstSPS div nSrcSPS;
  1610.       dwNewNumSamples := dwNumSamples * nRep;
  1611.    end
  1612.    else
  1613.    begin
  1614.       { replace the sample with the average of nSkip samples }
  1615.       nSkip :=  nSrcSPS div nDstSPS;
  1616.       dwNewNumSamples := dwNumSamples div DWORD(Max(nSkip,1));
  1617.    end;
  1618.    if (nRep > 0) then
  1619.    begin
  1620.       if nBitsPS = 8 then
  1621.       begin
  1622.          for i := 1 to dwNumSamples-1 do
  1623.          begin
  1624.     { this routine should interpolate the 8 Bit samples }
  1625.     pcmRepSample8(pDst, pSrc, nRep, nChannels);
  1626.     inc(pSrc, SampleSize);
  1627.             inc(pDst, nRep * SampleSize);
  1628.             inc(dwTotalDst, nRep * SampleSize);
  1629.          end;
  1630.       end
  1631.       else
  1632.       begin
  1633.          for i := 1 to dwNumSamples-1 do
  1634.          begin
  1635.     { this routine should interpolate the 16 Bit samples }
  1636.     pcmRepSample16(pDst, pSrc, nRep, nChannels);
  1637.     inc(pSrc, SampleSize);
  1638.             inc(pDst, nRep * SampleSize);
  1639.             inc(dwTotalDst, nRep * SampleSize);
  1640.          end;
  1641.       end;
  1642.       { up sample last sample without filtering }
  1643.       for i := 0 to nRep-1 do
  1644.       begin
  1645.          pTmp := pSrc;
  1646.          for j := 0 to SampleSize-1 do
  1647.          begin
  1648.             pDst^ := pTmp^;
  1649.             inc(pTmp);
  1650.             inc(pDst);
  1651.             inc(dwTotalDst);
  1652.          end;
  1653.       end;
  1654.    end
  1655.    else
  1656.    begin
  1657.       if nBitsPS = 8 then
  1658.       begin
  1659.          for i := 1 to dwNewNumSamples-1 do
  1660.          begin
  1661.             { this routine should average the 8 Bit samples }
  1662.     pcmAvgSample8(pDst, pSrc, nSkip, nChannels);
  1663.     inc(pSrc, nSkip * SampleSize);
  1664.     inc(pDst, SampleSize);
  1665.     inc(dwTotalDst, SampleSize);
  1666.          end;
  1667.       end
  1668.       else
  1669.       begin
  1670.          for i := 1 to dwNewNumSamples-1 do
  1671.          begin
  1672.             { this routine should average the 16 Bit samples }
  1673.     pcmAvgSample16(pDst, pSrc, nSkip, nChannels);
  1674.     inc(pSrc, nSkip * SampleSize);
  1675.     inc(pDst, SampleSize);
  1676.     inc(dwTotalDst, SampleSize);
  1677.          end;
  1678.       end;
  1679.       { just copy the last sample }
  1680.       for i := 0 to SampleSize-1 do
  1681.       begin
  1682.         pDst^:= pSrc^;
  1683.          inc(pSrc);
  1684.          inc(pDst);
  1685.          inc(dwTotalDst);
  1686.       end;
  1687.    end;
  1688.    Result := dwTotalDst;
  1689. end;
  1690. (*************************************************************************)
  1691. function pcmAllocMixPool(NumTracks: integer): PMMMixPool;
  1692. begin
  1693.    Result := GlobalAllocMem(sizeOf(TMMMixPool)+NumTracks*sizeOf(PChar));
  1694.    if Result = nil then OutOfMemoryError;
  1695. end;
  1696. {*************************************************************************}
  1697. function pcmMixIt(pwfx: PWaveFormatEx;
  1698.                   pDst: PChar; pTemp: PChar;
  1699.                   const pSrc: PMMMixPool; NumWaves: integer;
  1700.                   dwSrcLen: Longint): Boolean;
  1701. begin
  1702.    Result := False;
  1703.    if (pwfx = nil) or (pwfx^.wFormatTag <> WAVE_FORMAT_PCM) then exit;
  1704.    if (pwfx^.wBitsPerSample = 8) then
  1705.    begin
  1706.       Result := pcmMixIt8(pDst,Pointer(pTemp),pSrc,NumWaves,dwSrcLen);
  1707.    end
  1708.    else
  1709.    begin
  1710.       Result := pcmMixIt16(pDst,Pointer(pTemp),pSrc,NumWaves,dwSrcLen);
  1711.    end;
  1712. end;
  1713. {*************************************************************************}
  1714. {$IFDEF WIN32}{$L MMMIX32.OBJ}{$ELSE}{$L MMMIX16.OBJ}{$ENDIF}
  1715. {$F+}
  1716. function pcmMixIt8(pDst: PChar; pTemp: PSmallint;
  1717.                    const pSrc: PMMMixPool; NumWaves: integer;
  1718.                    dwSrcLen: Longint): Boolean; external;
  1719. function pcmMixIt16(pDst: PChar; pTemp: PLongint;
  1720.                     const pSrc: PMMMixPool; NumWaves: integer;
  1721.                     dwSrcLen: Longint): Boolean; external;
  1722. {$F-}
  1723. {*************************************************************************}
  1724. {$IFDEF WIN32}{$L MMPITC32.OBJ}{$ELSE}{$L MMPITC16.OBJ}{$ENDIF}
  1725. {$F+}
  1726. function pcmPitchChange8M(pSrc,pDst: PChar; var SrcLen,DstLen,IncValue: Longint;
  1727.                           Factor: Longint): Longint; external;
  1728. function pcmPitchChange8S(pSrc,pDst: PChar; var SrcLen,DstLen,IncValue: Longint;
  1729.                           Factor: Longint): Longint; external;
  1730. function pcmPitchChange16M(pSrc,pDst: PChar; var SrcLen,DstLen,IncValue: Longint;
  1731.                            Factor: Longint): Longint; external;
  1732. function pcmPitchChange16S(pSrc,pDst: PChar; var SrcLen,DstLen,IncValue: Longint;
  1733.                            Factor: Longint): Longint; external;
  1734. {$F-}
  1735. end.