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

📄 mmreverb.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
destructor TMMReverb.Destroy;
begin
   Close;
   FEchos.Free;

   inherited Destroy;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.PcmOverflow;
begin
   if assigned(FOnPcmOverflow) then FOnPcmOverflow(Self);
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.Change;
begin
   if assigned(FOnChange) then FOnChange(Self);
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.SetEchos(aValue: TMMEchoList);
begin
   if (aValue <> FEchos) then FEchos.Assign(aValue);
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.EchosChanged(Sender: TObject);
begin
   if not FUpdating then
   begin
      Update;
      Change;
   end;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.SetPWaveFormat(aValue: PWaveFormatEx);
begin
   if (aValue <> nil) then
   begin
      if not (csDesigning in ComponentState) then
         if not pcmIsValidFormat(aValue) then
            raise EMMReverbError.Create(LoadResStr(IDS_INVALIDFORMAT));
   end;
   inherited SetPWaveFormat(aValue);
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.SaveToIniFile(IniFile: TFileName; Section: string);
var
   i,j: integer;
begin
   if (IniFile <> '') then
   begin
      with TIniFile.Create(IniFile) do
      try
         if Pos('Reverb.',Section) = 0 then Section := 'Reverb.'+Section;
         WriteInteger(Section, 'MaxDelay', MaxDelay);
         WriteInteger(Section, 'InputGain', InputGain);
         WriteInteger(Section, 'InputPan', InputPan);
         WriteInteger(Section, 'OutputGain', OutputGain);
         WriteInteger(Section, 'FeedBack', FeedBack);
         WriteBool(Section, 'Filter', Filter);

         j := 0;
         for i := 0 to Echos.Count-1 do
         with Echos[i] do
         begin
            if (Gain <> 0) then
            begin
               WriteInteger(Section, 'Delay'+IntToStr(j), Delay);
               WriteInteger(Section, 'Gain'+IntToStr(j), Gain);
               inc(j);
            end;
         end;

      finally
         Free;
      end;
   end;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.ReadFromIniFile(IniFile: TFileName; Section: string);
var
   i,P: integer;
begin
   if (IniFile <> '') then
   begin
      with TIniFile.Create(IniFile) do
      try
         if Pos('Reverb.',Section) = 0 then Section := 'Reverb.'+Section;
         i := ReadInteger(Section, 'MaxDelay', -1);
         if (i > 0) then
         try
            FUpdating := True;
            MaxDelay    := ReadInteger(Section, 'MaxDelay', 1000);
            InputGain   := ReadInteger(Section, 'InputGain', 50);
            InputPan    := ReadInteger(Section, 'InputPan', 50);
            OutputGain  := ReadInteger(Section, 'OutputGain', 50);
            FeedBack    := ReadInteger(Section, 'FeedBack', 0);
            Filter      := ReadBool(Section, 'Filter', True);

            for i := 0 to MAXECHOS-1 do
            with Echos[i] do
            begin
               Delay := ReadInteger(Section, 'Delay'+IntToStr(i), 0);
               Gain  := ReadInteger(Section, 'Gain'+IntToStr(i), 0);
            end;

            P := Pos('.',Section);
            if (P <> 0) then Section := Copy(Section,P+1,MaxInt);
            Description := Section;

         finally
            FUpdating := False;
            Update;
            Change;
         end;

      finally
         Free;
      end;
   end;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.ReadIniSections(IniFile: TFileName; Strings: TStrings);
var
   i, P: integer;
   Sections: TStringList;
begin
   if (IniFile <> '') and (Strings <> nil) then
   begin
      with TIniFile.Create(IniFile) do
      try
         Sections := TStringList.Create;
         try
            ReadSections(Sections);
            Strings.BeginUpdate;
            try
               Strings.Clear;
               for i := 0 to Sections.Count-1 do
               begin
                  P := Pos('.',Sections[i]);
                  if (P <> 0) then Strings.Add(Copy(Sections[i],P+1,MaxInt));
               end;

            finally
               Strings.EndUpdate;
            end;

         finally
            Sections.Free;
         end;

      finally
         Free;
      end;
   end;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.DeleteSection(IniFile: TFileName; Section: string);
begin
   if (IniFile <> '') then
   begin
      with TIniFile.Create(IniFile) do
      try
         if Pos('Reverb.',Section) = 0 then Section := 'Reverb.'+Section;
         EraseSection(Section);

      finally
         Free;
      end;
   end;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.Assign(Source: TPersistent);
begin
   if (Source is TMMReverb) then
   begin
      if (Source <> nil) then
      begin
         Enabled    := TMMReverb(Source).Enabled;
         Description:= TMMReverb(Source).Description;
         MaxDelay   := TMMReverb(Source).MaxDelay;
         InputGain  := TMMReverb(Source).InputGain;
         InputPan   := TMMReverb(Source).InputPan;
         OutputGain := TMMReverb(Source).OutputGain;
         FeedBack   := TMMReverb(Source).FeedBack;
         Filter     := TMMReverb(Source).Filter;
         Echos      := TMMReverb(Source).Echos;
      end;
   end;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.SetDescription(aValue: String);
begin
   if (aValue <> FDescription) then
   begin
      FDescription := aValue;
      Change;
   end;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.SetMaxDelay(aValue: integer);
begin
   if (aValue <> FMaxDelay) then
   begin
      FMaxDelay := aValue;
   end;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.SetEnabled(aValue: Boolean);
begin
   if (aValue <> FEnabled) then
   begin
      FEnabled := aValue;
      if FEnabled then Update;
   end;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.SetGains(index: integer; aValue: TMMEffectVolume);
begin
   case index of
       0: if (aValue = FInputGain) then exit
          else
          begin
             FInputGain := aValue;
             if FOpen then FPReverb^.InputGain := MulDiv(aValue,256,100);
          end;
       1: if (aValue = FInputPan) then exit
          else
          begin
             FInputPan := aValue;
             if FOpen then FPReverb^.InputPan := MulDiv(aValue,256,100);
          end;
       2: if (aValue = FOutputGain) then exit
          else
          begin
             FOutputGain := aValue;
             if FOpen then FPReverb^.OutputGain := MulDiv(aValue,256,100);
          end;
   end;
   Change;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.SetFeedBack(aValue: TMMFeedBack);
begin
   if (aValue <> FFeedBack) then
   begin
      FFeedBack := aValue;
      if FOpen then FPReverb^.FeedBack := MulDiv(aValue,256,100);
      Change;
   end;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.SetFilter(aValue: Boolean);
begin
   if (aValue <> FFilter) then
   begin
      FFilter := aValue;
      if FOpen then FPReverb^.OutputFilter := FFilter;
      Change;
   end;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.Open;
begin
   if not FOpen then
   begin
      if pcmIsValidFormat(PWaveFormat) then
      begin
         FPReverb := InitReverb(PWaveFormat, FMaxDelay);
         if (FPReverb = nil) then OutOfMemoryError
         else
         begin
            FOpen := True;
            Update;
         end;
      end;
   end;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.Close;
begin
   if FOpen then
   begin
      FOpen := False;
      DoneReverb(FPReverb);
   end;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.Process(Buffer: PChar; Length: integer);
begin
   { process the buffer trough the reverb engine }
   if (FPReverb <> nil) then
      if DoReverb(FPReverb, Buffer, Length) then
         GlobalSynchronize(PcmOverflow);
end;

{-- TMMReverb -----------------------------------------------------------}
function TMMReverb.CleanUp(Buffer: PChar; Length: integer): Longint;
begin
   { process the remaining delayed bytes in the delay lines }
   if (FPReverb <> nil) and (FCleanup > 0) then
   begin
      FCleanup := Max(FCleanup - Length,0);
      FillChar(Buffer^, Length, 0);
      if DoReverb(FPReverb, Buffer, Length) then
         GlobalSynchronize(PcmOverflow);
   end;
   { return the remaining bytes to process }
   Result := FCleanup;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.Update;
var
   i: integer;
   _Echos: TEchoArray;
   NumEchos: integer;

begin
   { setup the reverb engine with the params }
   if FOpen then
   begin
      NumEchos := 0;
      FCleanup := 0;
      for i := 0 to Echos.Count-1 do
      begin
         if (Echos[i].Gain <> 0) then
         begin
            { copy in temp record }
            _Echos[NumEchos].Delay := Echos[i].Delay;
            _Echos[NumEchos].Gain := Echos[i].Gain;
            inc(NumEchos);
            if Echos[i].Delay > FCleanup then FCleanup := Echos[i].Delay;
         end;
      end;

      if (FCleanup > 0) then
      begin
         { convert cleanup time to bytes }
         FCleanup := wioTimeToSamples(PWaveFormat,FCleanup*abs(FFeedBack));
      end;
      { now update the reverb params }
      SetReverb(FPReverb, FFilter, FInputGain, FInputPan,
                FOutputGain, FFeedBack, NumEchos, @_Echos);
   end;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.Opened;
begin
   Open;

   inherited Opened;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.Closed;
begin
   Close;

   inherited Closed;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.Started;
begin
   Update;

   inherited Started;
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.BufferReady(lpwh: PWaveHdr);
begin
   if Enabled and FOpen then
   begin
      Process(lpwh^.lpData, lpwh^.dwBytesRecorded);
   end;

   inherited BufferReady(lpwh);
end;

{-- TMMReverb -----------------------------------------------------------}
procedure TMMReverb.BufferLoad(lpwh: PWaveHdr; var MoreBuffers: Boolean);
var
   aLength: Longint;
begin
   inherited BufferLoad(lpwh, MoreBuffers);

   if Enabled and FOpen then
   begin
      if not MoreBuffers then
      begin
         aLength := lpwh^.dwBufferLength;
         if Cleanup(lpwh^.lpData, aLength) > 0 then MoreBuffers := True;
         lpwh^.dwBytesRecorded := aLength;
      end
      else Process(lpwh^.lpData, lpwh^.dwBytesRecorded);
   end;
end;

Initialization
   { register echo class for streaming ! }
   DoRegisterClass(@TMMEcho.Load,
                   @TMMEcho.Store,
                   TMMEcho);
end.

⌨️ 快捷键说明

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