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ć ???
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
"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).
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 ???
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.
setlength(FftBuf,1024);
nie wiem czemu wywala mi błąd "incompatible types"