fft, czestotliwosc dzwieku, biblioteka bass

1

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.
 
0

Jestem skłonny zapłacić jeżeli ktoś pomoże mi dokończyć ten program. [email protected]

1

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.
Szumy zawsze jakieś są, przy braku sensownego dźwięku algorytm

  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;

staje się czuły na każdy szmer i dostajesz bzdury. Powinieneś dodać ograniczenie, jeśli wynikowe max wychodzi poniżej jakiegoś „progu ciszy”, to nie uznawaj takiego wyniku.
Poza tym, jeśli szukasz największej wartości w tablicy, nie musisz dla każdej wartości liczyć 20log10. Szukaj po prostu maksymalnej wartości w fft[].

0

Gdy nic nie gra db waha się między -180 i -80, czyli mam uznać to za szum? Ustawiłem max na -80 i szukam większych wartości. Teraz wydaje się, że mikrofon nic nie odbiera.

1 użytkowników online, w tym zalogowanych: 0, gości: 1