Witam,
Mam parę pytań odnośnie fft, pisze program który odnajduje częstotliwość dźwięku, używam biblioteki bass, najpierw mały schemat http://img51.imageshack.us/i/freqw.jpg/ , dobrze to rozumiem? (zignorujcie "cut off", wystarczy zmniejszyć samplerate o ile się nie mylę)
http://img718.imageshack.us/i/freq2.jpg/ - otrzymuje takie wyniki, db<0 czyli szukam najmniejszej wartości?
Główny problem jest taki, że po odpaleniu programu dostaje randomowe wartości mimo ze nic nie jest podłączone do mikrofonu, mikrofon jest wyciszony itd. Otrzymuje częstotliwości typu 5000 hz, gdy podłączam mikrofon nie robi to wielkiej różnicy, próbowałem na innym pc jest to samo. Livespec example dołączony do biblioteki bass działa normalnie tzn. Wyświetla napis „make some noise” gdy nic nie gra.
kod źródłowy (ważna część pod ////////////)
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, bass, Math;
type
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
ComboBox1: TComboBox;
TrackBar1: TTrackBar;
Button2: TButton;
ListBox2: TListBox;
ListBox3: TListBox;
ListBox4: TListBox;
procedure FormCreate(Sender: TObject);
procedure ComboBox1Change(Sender: TObject);
procedure TrackBar1Change(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
function RecordingCallBack(Handle: HRECORD; buffer: Pointer; length, user: DWord): boolean; stdcall;
var
Form1: TForm1;
RChannel : HRECORD;
fft: array[0..8191] of float;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
i,j: integer;
dName: PAnsiChar;
level: Single;
begin
Set8087CW($133f);
if (HIWORD(BASS_GetVersion) <> BASSVERSION) then
begin
MessageBox(0,'An incorrect version of BASS.DLL was loaded', nil,MB_ICONERROR);
Halt;
end;
if (not BASS_RecordInit(-1)) or (not BASS_Init(-1, 44100, 0, Handle, nil)) then
begin
BASS_RecordFree;
BASS_Free();
MessageDlg('Cannot start default recording device!', mtError, [mbOk], 0);
Halt;
end;
i := 0;
dName:= BASS_RecordGetInputName(i);
while dName <> nil do
begin
ComboBox1.Items.Add(StrPas(dName));
if (BASS_RecordGetInput(i,level) and BASS_INPUT_OFF) = 0 then
ComboBox1.ItemIndex := i;
Inc(i);
dName := BASS_RecordGetInputName(i);
end;
ComboBox1Change(self);
for j:=0 to 8191 do
fft[j]:=0;
end;
procedure TForm1.ComboBox1Change(Sender: TObject);
var
i: Integer;
r: Boolean;
begin
r:= True;
i:= 0;
while r do
begin
r:= BASS_RecordSetInput(i, BASS_INPUT_OFF,-1);
Inc(i);
end;
BASS_RecordSetInput(ComboBox1.ItemIndex, BASS_INPUT_ON,-1);
end;
procedure TForm1.TrackBar1Change(Sender: TObject);
begin
BASS_RecordSetInput(ComboBox1.ItemIndex, 0, TrackBar1.Position);
end;
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
function RecordingCallBack(Handle: HRECORD; buffer: Pointer; length, user: DWord): boolean; stdcall;
var
form: TForm1;
i: integer;
peak: float;
db: float;
max: float;
begin
form := TForm1(user);
peak:=0;
BASS_ChannelGetData(RChannel,@fft,BASS_DATA_FFT16384);
max:=0;
for i:=1 to 8191 do
begin
dB:= 20 * log10(fft[i]);
if db<max then
begin
max:=db;
peak:=round(i*44100)/8191;
end;
end;
form.ListBox2.Items.Add(floattostr(peak));
Result:= true
end;
procedure TForm1.Button1Click(Sender: TObject); // START
begin
RChannel:= BASS_RecordStart(44100, 1, 0, @RecordingCallBack, self);
end;
procedure TForm1.Button2Click(Sender: TObject); // STOP
begin
BASS_ChannelStop(RChannel);
end;
end.