208 lines
5.1 KiB
ObjectPascal
208 lines
5.1 KiB
ObjectPascal
(*
|
|
this file is a part of audio components suite v 2.3.
|
|
copyright (c) 2002-2005 andrei borovsky. all rights reserved.
|
|
see the license file for more details.
|
|
you can contact me at mail@z0m3ie.de
|
|
*)
|
|
|
|
{
|
|
$Log: acs_indicator.pas,v $
|
|
Revision 1.2 2006/08/31 20:10:54 z0m3ie
|
|
*** empty log message ***
|
|
|
|
Revision 1.1 2005/12/19 18:34:35 z0m3ie
|
|
*** empty log message ***
|
|
|
|
Revision 1.4 2005/12/04 16:54:33 z0m3ie
|
|
All classes are renamed, Style TACS... than T... to avoid conflicts with other components (eg TMixer is TACSMixer now)
|
|
|
|
Revision 1.3 2005/10/02 16:51:46 z0m3ie
|
|
*** empty log message ***
|
|
|
|
Revision 1.2 2005/09/13 21:54:11 z0m3ie
|
|
acs is localizeable now (ACS_Strings)
|
|
|
|
Revision 1.1 2005/09/12 22:04:52 z0m3ie
|
|
modified structure again, fileformats are now in an sperat folder.
|
|
all File In/Out classes are capsulated from TFileIn and TFileOut
|
|
|
|
Revision 1.2 2005/08/22 20:17:01 z0m3ie
|
|
changed Headers to log
|
|
changed mail adress
|
|
|
|
}
|
|
|
|
|
|
unit acs_indicator;
|
|
|
|
{$ifdef fpc}
|
|
{$mode delphi}
|
|
{$endif}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, ACS_Types, ACS_Classes, ACS_Procs, ACS_Strings;
|
|
|
|
type
|
|
|
|
TACSSoundIndicator = class(TACSCustomConverter)
|
|
private
|
|
Lock : Boolean;
|
|
Window : array[0..1023] of Double;
|
|
FValues : array[0..31] of Double;
|
|
protected
|
|
function GetBPS : Integer; override;
|
|
function GetCh : Integer; override;
|
|
function GetSR : Integer; override;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
function GetData(Buffer : Pointer; BufferSize : Integer): Integer; override;
|
|
procedure GetValues(var Values : array of Double);
|
|
procedure Init; override;
|
|
procedure Flush; override;
|
|
end;
|
|
|
|
implementation
|
|
|
|
constructor TACSSoundIndicator.Create;
|
|
begin
|
|
inherited Create(AOwner);
|
|
HannWindow(@Window, 1024, True);
|
|
end;
|
|
|
|
destructor TACSSoundIndicator.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TACSSoundIndicator.GetBPS : Integer;
|
|
begin
|
|
if not Assigned(FInput) then
|
|
raise EACSException.Create(strInputnotassigned);
|
|
Result := FInput.BitsPerSample;
|
|
end;
|
|
|
|
function TACSSoundIndicator.GetCh : Integer;
|
|
begin
|
|
if not Assigned(FInput) then
|
|
raise EACSException.Create(strInputnotassigned);
|
|
Result := FInput.Channels;
|
|
end;
|
|
|
|
function TACSSoundIndicator.GetSR : Integer;
|
|
begin
|
|
if not Assigned(FInput) then
|
|
raise EACSException.Create(strInputnotassigned);
|
|
Result := FInput.SampleRate;
|
|
end;
|
|
|
|
procedure TACSSoundIndicator.Init;
|
|
begin
|
|
if not Assigned(FInput) then
|
|
raise EACSException.Create(strInputnotassigned);
|
|
FBusy := True;
|
|
FInput.Init;
|
|
FSize := FInput.Size;
|
|
FillChar(FValues[0], SizeOf(Double)*32, 0);
|
|
Lock := False;
|
|
FPosition := 0;
|
|
end;
|
|
|
|
procedure TACSSoundIndicator.Flush;
|
|
begin
|
|
FInput.Flush;
|
|
FBusy := False;
|
|
Lock := False;
|
|
end;
|
|
|
|
function TACSSoundIndicator.GetData(Buffer : Pointer; BufferSize : Integer): Integer;
|
|
var
|
|
i, j, k, NumSamples : Integer;
|
|
P : Pointer;
|
|
P8 : PACSBuffer8;
|
|
P16 : PACSBuffer16;
|
|
PS8 : PACSStereoBuffer8;
|
|
PS16 : PACSStereoBuffer16;
|
|
DA : array[0..63] of Double;
|
|
C1 : array[0..63] of TACSComplex;
|
|
begin
|
|
if not Busy then raise EACSException.Create(strStreamnotopen);
|
|
while InputLock do;
|
|
InputLock := True;
|
|
Result := FInput.GetData(Buffer, BufferSize);
|
|
InputLock := False;
|
|
FPosition := Finput.Position;
|
|
if Result = 0 then Exit;
|
|
if Lock then Exit;
|
|
Lock := True;
|
|
k := Result;
|
|
GetMem(P, k);
|
|
Move(Buffer^, P^, k);
|
|
if FInput.BitsPerSample = 8 then
|
|
begin
|
|
if FInput.Channels = 1 then NumSamples := k
|
|
else NumSamples := k shr 1;
|
|
end else
|
|
begin
|
|
if FInput.Channels = 1 then NumSamples := k shr 1
|
|
else NumSamples := k shr 2;
|
|
end;
|
|
for i := 0 to (NumSamples div 64) - 1 do
|
|
begin
|
|
if FInput.BitsPerSample = 8 then
|
|
begin
|
|
if FInput.Channels = 1 then
|
|
begin
|
|
P8 := P;
|
|
for j := 0 to 63 do DA[j] := P8[i*64+j];
|
|
end else
|
|
begin
|
|
PS8 := P;
|
|
for j := 0 to 63 do DA[j] := (PS8[i*64+j].Left+PS8[i*64+j].Right)/2;
|
|
end
|
|
end else
|
|
begin
|
|
if FInput.Channels = 1 then
|
|
begin
|
|
P16 := P;
|
|
for j := 0 to 63 do DA[j] := P16[i*64+j];
|
|
end else
|
|
begin
|
|
PS16 := P;
|
|
for j := 0 to 63 do DA[j] := (PS16[i*64+j].Left+PS16[i*64+j].Right)/2;
|
|
end
|
|
end;
|
|
MultDoubleArrays(@Window[0], @DA[0], 64);
|
|
for j := 0 to 63 do
|
|
begin
|
|
C1[j].Re := DA[j];
|
|
C1[j].Im := 0;
|
|
end;
|
|
ComplexFFT(@C1, 64, 1);
|
|
LgMagnitude(@C1[0], @DA[0], 64, 0);
|
|
try
|
|
for j := 0 to 31 do FValues[j]:=FValues[j]+DA[j];
|
|
except
|
|
for j := 0 to 31 do FValues[j] := 0;
|
|
end;
|
|
end;
|
|
for j := 0 to 31 do FValues[j]:=FValues[j]/(NumSamples div 64);
|
|
FreeMem(P);
|
|
Lock := False;
|
|
end;
|
|
|
|
procedure TACSSoundIndicator.GetValues;
|
|
var
|
|
i : Integer;
|
|
begin
|
|
while Lock do;
|
|
Lock := True;
|
|
for i := 0 to 31 do Values[i] := FValues[i]*0.4; //ValCount;
|
|
for i := 0 to 31 do FValues[i] := 0;
|
|
Lock := False;
|
|
end;
|
|
|
|
end.
|