如何利用声卡采集声音信号,而PCM的文件如何做FFT转换,就是频谱处理QQ:65466700(200分)

  • 主题发起人 Alongsun
  • 开始时间
我建议把这个问题提到日程上来,,,要求版主把它 加重!!!!!
 
我这里有个vc的例子..要的话说一声.
 
xwings:
您好,mmtools我没有收到,能否在发一边,谢谢。
yaoyg@cmmail.com
 
我以前做过一个FFT函数,但是速度不太快,1024点要70ms,麻烦。。。
还是mmtools好,但是我没有源码,xwings能否发给我?或者上传到:
ftp://delphi:delphi@ftp.xxtax.gov.cn/
大家共享。
 
已经上传到ftp上了. 大家可以去下载.里面还有samples,和我写的一点简单用法.
 
只有for D5的吗? [:(]
 
NowCan,
ce 你能不能来点真的呀,,,,我真的想搞定它!

不知道能不能把你的见解也分布这里点点,,,,

我去了FTP,只看到了MMTOOLS这个东西,,,
我想知道有没有 人真的对WAV做过处理,,,,,
我没有别的意思,只是想知道个明白,,

我看了傅立叶 变换的几个算法,,,很烦,
还没有编程实现,,,

大家如果真搞过,请多指点!!
QQ: 65466700
MAIL : alongsun@sina.com
 
fhw 真心请教大侠们给点指点!
 
我真的是忘了具体算法了,而且手头还没有相应的书籍可查。FFT的算法就我印象不是很烦,
用几次复数运算就可以搞定。可是现在就是想不起来。你说已经找到了算法,能不能说出来呀。
 
q 我是找到了高数书,那里面讲了傅立叶变换,但它有好多种算法,FFT用的多点
还有离散的等等!

真是烦呀,那么多公式,还有什么SGM(求合)
怎么样做程式呀!大家多指点吧!
 
HIHIHI,,,

大侠们快点出手吧,
QQ: 65466700
 
codeguru上有非常详细的VC例子,声卡输入并显示波形。改变成delphi就可以了。
搜索mix会找到那个fft的例子。混音几个wave波形。
 
想要那个例子吗?我可以给你。但是这个例子很复杂,估计还不如把算法看明白然后自己写。
nowcan@163.com
 
aseng大佬,请明示,能不能SHOW出你的 连接网址!多谢

我的QQ: 65466700多指教!
 
听说可以用控件搞定这个东西,,,,但听说你不喜欢用控件,那只好,,自己搞了
 
unit DSXFastFourier;

interface

uses
Windows, Messages, SysUtils, Classes,math;

procedure Register;

type
TComplex = Record
Real :do
uble;
imag :do
uble;
end;


TOnGetDataEvent = procedure(index : integer;
var Value : TComplex) of Object;

TComplexArray = array [0..0] of TComplex;
PComplexArray = ^TComplexArray;

EFastFourierError = class(Exception);

TDSXFastFourier = Class(TComponent)

private
FNumSamples : integer;
FInBuffer : PComplexArray;
FOutBuffer : PComplexArray;
FOnGetData : TOnGetDataEvent;

function IsPowerOfTwo ( x: word ): boolean;
function NumberOfBitsNeeded ( PowerOfTwo: word ): word;
function ReverseBits ( index, NumBits: word ): word;
procedure FourierTransform ( AngleNumerator: do
uble );
procedure SetNumSamples(value : integer);
function GetTransformedData(idx : integer) : TComplex;

constructor
create(AOwner : TComponent);
destructor
destroy;

public
procedure fft;
procedure ifft;
procedure CalcFrequency (FrequencyIndex: word);

published
property OnGetData : TOnGetDataEvent read FOnGetData write FOnGetData;
property NumSamples : integer read FNumSamples write SetNumSamples;
property SampleCount : Integer read FNumSamples;
property TransformedData[idx : integer] : TComplex read GetTransformedData;
end;


implementation

constructor TDSXFastFourier.Create(AOwner : TComponent);
begin

inherited create(AOwner);
end;


destructor TDSXFastFourier.Destroy;
begin

if Assigned(FInBuffer) then

FreeMem(FinBuffer);
if Assigned(FOutBuffer) then

FreeMem(FOutBuffer);
end;



procedure TDSXFastFourier.SetNumSamples(value : integer);
begin


FNumSamples := value;

if Assigned(FInBuffer) then

FreeMem(FinBuffer);

if Assigned(FOutBuffer) then

FreeMem(FOutBuffer);

try
getMem(FInBuffer, sizeof(TComplex)*FNumSamples);
getMem(FOutBuffer, sizeof(TComplex)*FNumSamples);
except on EOutOfMemorydo

raise EFastFourierError.Create('Could not allocate memory for complex arrays');
end;


end;


function TDSXFastFourier.GetTransformedData(idx : integer) : TComplex;
begin

Result := FOutBuffer[idx];
end;


function TDSXFastFourier.IsPowerOfTwo ( x: word ): boolean;
var i, y: word;
begin

y := 2;
for i := 1 to 31do
begin

if x = y then
begin

IsPowerOfTwo := TRUE;
exit;
end;

y := y SHL 1;
end;


IsPowerOfTwo := FALSE;
end;



function TDSXFastFourier.NumberOfBitsNeeded ( PowerOfTwo: word ): word;
var i: word;
begin

for i := 0 to 16do
begin

if (PowerOfTwo AND (1 SHL i)) <> 0 then
begin

NumberOfBitsNeeded := i;
exit;
end;

end;

end;



function TDSXFastFourier.ReverseBits ( index, NumBits: word ): word;
var i, rev: word;
begin

rev := 0;
for i := 0 to NumBits-1do
begin

rev := (rev SHL 1) OR (index AND 1);
index := index SHR 1;
end;


ReverseBits := rev;
end;



procedure TDSXFastFourier.FourierTransform ( AngleNumerator: do
uble);
var
NumBits, i, j, k, n, BlockSize, BlockEnd: word;
delta_angle, delta_ar:do
uble;
alpha, beta:do
uble;
tr, ti, ar, ai:do
uble;
begin

if not IsPowerOfTwo(FNumSamples) or (FNumSamples<2) then

raise EFastFourierError.Create('NumSamples is not a positive integer power of 2');

if not assigned(FOnGetData) then

raise EFastFourierError.Create('You must specify an OnGetData handler');

NumBits := NumberOfBitsNeeded (FNumSamples);
for i := 0 to FNumSamples-1do
begin

j := ReverseBits ( i, NumBits );
FOnGetData(i,FInBuffer);
FOutBuffer[j] := FInBuffer;
end;

BlockEnd := 1;
BlockSize := 2;
while BlockSize <= FNumSamplesdo
begin

delta_angle := AngleNumerator / BlockSize;
alpha := sin ( 0.5 * delta_angle );
alpha := 2.0 * alpha * alpha;
beta := sin ( delta_angle );

i := 0;
while i < FNumSamplesdo
begin

ar := 1.0;
(* cos(0) *)
ai := 0.0;
(* sin(0) *)

j := i;
for n := 0 to BlockEnd-1do
begin

k := j + Blockend;

tr := ar*FOutBuffer[k].Real - ai*FOutBuffer[k].Imag;
ti := ar*FOutBuffer[k].Imag + ai*FOutBuffer[k].Real;
FOutBuffer[k].Real := FOutBuffer[j].Real - tr;
FOutBuffer[k].Imag := FOutBuffer[j].Imag - ti;
FOutBuffer[j].Real := FOutBuffer[j].Real + tr;
FOutBuffer[j].Imag := FOutBuffer[j].Imag + ti;
delta_ar := alpha*ar + beta*ai;
ai := ai - (alpha*ai - beta*ar);
ar := ar - delta_ar;
INC(j);
end;

i := i + BlockSize;
end;

BlockEnd := BlockSize;
BlockSize := BlockSize SHL 1;
end;

end;



procedure TDSXFastFourier.fft;
begin

FourierTransform ( 2*PI);
end;



procedure TDSXFastFourier.ifft;
var
i: word;
begin

FourierTransform ( -2*PI);

(* Normalize the resulting time samples... *)
for i := 0 to FNumSamples-1do
begin

FOutBuffer.Real := FOutBuffer.Real / FNumSamples;
FOutBuffer.Imag := FOutBuffer.Imag / FNumSamples;
end;

end;



procedure TDSXFastFourier.CalcFrequency (FrequencyIndex: word);
var
k: word;
cos1, cos2, cos3, theta, beta:do
uble;
sin1, sin2, sin3:do
uble;
begin

FOutBuffer[0].Real := 0.0;
FOutBuffer[0].Imag := 0.0;
theta := 2*PI * FrequencyIndex / FNumSamples;
sin1 := sin ( -2 * theta );
sin2 := sin ( -theta );
cos1 := cos ( -2 * theta );
cos2 := cos ( -theta );
beta := 2 * cos2;
for k := 0 to FNumSamples-1do
begin

sin3 := beta*sin2 - sin1;
sin1 := sin2;
sin2 := sin3;
cos3 := beta*cos2 - cos1;
cos1 := cos2;
cos2 := cos3;
FOutBuffer[0].Real := FOutBuffer[0].Real + FInBuffer[k].Real*cos3 - FInBuffer[k].Imag*sin3;
FOutBuffer[0].Imag := FOutBuffer[0].Imag + FInBuffer[k].Imag*cos3 + FInBuffer[k].Real*sin3;
end;

end;


procedure Register;
begin

RegisterComponents('Free', [TDSXFastFourier]);
end;


end.
 
顶部