Rysowanie spektrum

0

Witam.
Mam problem z rysowaniem spektrum, tzn wykres ma się rysować w zależności wielkości bajtu w czasie.
No i czas mam ustawiony ale nie mogę zrobić tak by odczytać bajtu w danym czasie może ktoś wie jak to zrobić ???

0

A może jakiś przykład jak to robisz ?

To co napisałeś nie niesie żadnych informacji które mogły by pomóc Ci

0

"wielkość" bajtu w czasie to nie spektrum. spektrum to inaczej widmo, przeważnie w dziedzinie częstotliwości. jeśli o to Ci chodzi, to poszukaj u nas lub na google pod hasłem fft (szybka transformata fouriera).

0

kontynuując

 
procedure TGame.LoadSound(Dir:String);
var
  Int: HSTREAM;
  f: PChar;
  ScanTime:Integer;
  Info: BASS_CHANNELINFO;
  Czas: Cardinal;
  I:Integer;
  Y:Integer;
  L:LOWORD;
  FftBuf: array of Pointer;
 
begin
 
 if not FileExists(Dir) then begin Error('Error creating stream!'); Exit; end else begin
        f := PChar(Dir);
        Int := BASS_StreamCreateFile(False, f, 0, 0, 0);
 end;
 
 
 Czas := BASS_ChannelGetLength(int,BASS_POS_BYTE);
 Czas := Trunc(BASS_ChannelBytes2Seconds(int, Czas)*1000/60);
 Spectrum.Width:=Trunc(Czas/10);
 Spectrum.Canvas.Brush.Color := clBlack;
 Spectrum.Canvas.FillRect(Rect(0,0,Spectrum.Width,Spectrum.Height));
 
 BASS_ChannelGetData(Int, @FftBuf, BASS_DATA_FFT1024);
 for I:=0 to Trunc(Czas) do
 begin
 Application.ProcessMessages;
  Y:=FftBuf[I];
  Spectrum.Canvas.MoveTo(I,Spectrum.Height);
  Spectrum.Canvas.Pen.Color:=clLime;
  Spectrum.Canvas.LineTo(i,Trunc(Spectrum.Height-y/32768));
  WPT.Items.Add('T:'+IntToStr(i)+' H:'+IntToStr(Y));
 end;
 
 
end;

No i nie wiem czemu po wczytaniu pliku audio wyłącza się program a Delphi wyświetla debugera CPU w którym odwołuje się do nie istniejących adresów ???

0
FftBuf: array of Pointer;
BASS_ChannelGetData(Int, @FftBuf, BASS_DATA_FFT1024);

Tablicę dynamiczną należy wpierw zainicjować za pomocą setlength().
Poza tym pobieranie wskaźnika do tablicy dynamicznej nie robi tego co ci się wydaje: należy brać adres pierwszego elementu tablicy (@FftBuf[0]), a nie tablicy.
Poza poza tym, nawet prawidłowe branie wskaźnika to nienajlepszy pomysł, gdyż podczas zmiany rozmiaru (setlength) tablica może ulec relokacji i wskaźnik traci aktualność (w tym przykładzie to akurat nie zaszkodzi, ale kiedyś się zapomnisz…)

Krótko: zrób normalną tablicę

FftBuf: array[0..1023] of Pointer; // czy ile tam rozmiaru trzeba

a jeśli chcesz dynamiczną, to i tak trzeba ustawić jej rozmiar

FftBuf: array of Pointer;
setlength(FftBuf,1024);
BASS_ChannelGetData(Int, @FftBuf[0], BASS_DATA_FFT1024); // ta linia zadziała dla obu rodzajów tablic

dalej:

 for I:=0 to Trunc(Czas) do
 begin
 Application.ProcessMessages;

raczej wywal to processmessages, bo w pętli nie robisz nic długotrwałego - tylko rysowanie, które przecież chcesz by trwało jak najszybciej.

  Spectrum.Canvas.Pen.Color:=clLime;

raz ustawiony kolor (przed pętlą) zostaje, nie trzeba go ustawiać w każdej iteracji.

0
setlength(FftBuf,1024);

nie wiem czemu wywala mi błąd "incompatible types"

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