File: QuickAvg.pas

package info (click to toggle)
morserunner 0.9%2Blinux-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,384 kB
  • sloc: pascal: 5,344; makefile: 4
file content (158 lines) | stat: -rw-r--r-- 3,690 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//------------------------------------------------------------------------------
//This Source Code Form is subject to the terms of the Mozilla Public
//License, v. 2.0. If a copy of the MPL was not distributed with this
//file, You can obtain one at http://mozilla.org/MPL/2.0/.
//------------------------------------------------------------------------------
unit QuickAvg;

{$MODE Delphi}

interface

uses
  LCLIntf, LCLType, LMessages, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Math, SndTypes;

type
  TDoubleArray2D = array of array of Double;

  TQuickAverage = class(TComponent)
  private
    FPasses: integer;
    FPoints: integer;
    FScale: Single;

    ReBufs, ImBufs: TDoubleArray2D;
    Idx, PrevIdx: integer;

    procedure SetPasses(const Value: integer);
    procedure SetPoints(const Value: integer);
    function DoFilter(V: Single; Bufs: TDoubleArray2D): Single;
  protected
    { Protected declarations }
  public
    constructor Create(AOwner: TComponent); override;
    procedure Reset;
    function Filter(V: Single): Single; overload;
    function Filter(ARe, AIm: Single): TComplex; overload;
    function Filter(V: TComplex): TComplex; overload;
    function FilteredModule(ARe, AIm: Single): Single;
  published
    property Passes: integer read FPasses write SetPasses;
    property Points: integer read FPoints write SetPoints;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Snd', [TQuickAverage]);
end;

{ TQuickAverage }

//------------------------------------------------------------------------------
//                                 init
//------------------------------------------------------------------------------
constructor TQuickAverage.Create(AOwner: TComponent);
begin
  inherited;
  FPoints := 128;
  FPasses := 4;
  Reset;
end;


procedure TQuickAverage.SetPasses(const Value: integer);
begin
  FPasses := Max(1, Min(8, Value));
  Reset;
end;


procedure TQuickAverage.SetPoints(const Value: integer);
begin
  FPoints := Max(1, Value);
  Reset;
end;


procedure TQuickAverage.Reset;
begin
  ReBufs := nil;
  SetLength(ReBufs, FPasses+1, FPoints);

  ImBufs := nil;
  SetLength(ImBufs, FPasses+1, FPoints);

  FScale := IntPower(FPoints, -FPasses);
  Idx := 0;
  PrevIdx := FPoints-1;
end;







//------------------------------------------------------------------------------
//                                 filter
//------------------------------------------------------------------------------
function TQuickAverage.Filter(V: Single): Single;
begin
  Result := DoFilter(V, ReBufs);
  PrevIdx := Idx;

  Idx := (Idx + 1) mod FPoints;
end;


function TQuickAverage.Filter(ARe, AIm: Single): TComplex;
begin
  Result.Re := DoFilter(ARe, ReBufs);
  Result.Im := DoFilter(AIm, ImBufs);

  PrevIdx := Idx;
  Idx := (Idx + 1) mod FPoints;
end;


function TQuickAverage.Filter(V: TComplex): TComplex;
begin
  Result.Re := DoFilter(V.Re, ReBufs);
  Result.Im := DoFilter(V.Im, ImBufs);

  PrevIdx := Idx;
  Idx := (Idx + 1) mod FPoints;
end;


function TQuickAverage.FilteredModule(ARe, AIm: Single): Single;
begin
  with Filter(ARe, AIm) do
    Result := Sqrt(Sqr(Re) + Sqr(Im));
end;

function TQuickAverage.DoFilter(V: Single; Bufs: TDoubleArray2D): Single;
var
  p: integer;
begin
  Result := V;
  for p:=1 to FPasses do
    begin
    V := Result;
    Result := Bufs[p][PrevIdx] - Bufs[p-1][Idx] + V;
    Bufs[p-1][Idx] := V;
    end;
  Bufs[FPasses,Idx] := Result;
  Result := Result * FScale;
end;




end.