![]() |
FFT Problem in verbindung mit WMP
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo
Hier mal meine FFT Routine..
Delphi-Quellcode:
Mein Problem ist nun das in dieser schleife bedingt durch TimedLevel function BASS_WMPVIS_Render(channel: DWORD): boolean; stdcall; BASS_ChannelGetData(channel, Data32, FFTSize or DWORD(IfThen(ChanInfo.chans = 2, BASS_DATA_FFT_INDIVIDUAL))); if (ChanInfo.chans = 2) then begin for i := 0 to 1023 do try begin VisData^.frequency[0, i] := Max(0, Min(1023, (Trunc(Power(Data32Pos^, FFTSAmplification) * 1023)))); Inc(Data32Pos, FFT_SkipCount); VisData^.frequency[1, i] := Max(0, Min(1023, (Trunc(Power(Data32Pos^, FFTSAmplification) * 1023)))); Inc(Data32Pos, FFT_SkipCount); end; except Result := false; exit; end; end else begin for i := 0 to 1023 do begin VisData^.frequency[0, i] := Max(0, Min(1023, (Trunc(Power(Data32Pos^, FFTSAmplification) * 1023)))); VisData^.frequency[1, i] := VisData^.frequency[0, i]; Inc(Data32Pos, FFT_SkipCount); end; end; FreeMem(Data32); try _IWMPEffects.Render(VisData^, BassWMPVis1.ContainerHdc, pRect); except Result := false; exit; end; Result := true; BassFuncs^.SetError(BASS_OK); exit; end; Result := False; BassFuncs^.SetError(BASS_ERROR_MEM); end; nur 1024 samples übergeben werden können.
Delphi-Quellcode:
Im Original Quelltext wird aber ein VariablesArray erstellt
if (ChanInfo.chans = 2) then
begin for i := 0 to 1023 do try begin VisData^.frequency[0, i] := Max(0, Min(1023, (Trunc(Power(Data32Pos^, FFTSAmplification) * 1023)))); Inc(Data32Pos, FFT_SkipCount); VisData^.frequency[1, i] := Max(0, Min(1023, (Trunc(Power(Data32Pos^, FFTSAmplification) * 1023)))); Inc(Data32Pos, FFT_SkipCount); end; TimedLvl.frequency = new byte[2048]; in dem nun unabhängig von TimedLevel die Daten ausgelesen werden können. Wie kann ich in meiner schleife den rechten Kanal trotzdem auslesen und die samples von 1024 to 2048 übergeben damit kein rangecheck error auftritt ?
Code:
Zur zeit sieht es so aus das rechts und links die gleichen Daten übergeben werden.
// The first value is the DC component so we'll skip it and start at index 1
for (int i = 1; i < 1024; i++) { try { float val = (fft[i] * 255); if (val < 0) val = 0; if (val > 255) val = 255; audioData[i] = (byte)val; audioData[i + 1024] = (byte)val; } catch (Exception ex) { Console.WriteLine("Exception occurred at index {0}", i); return false; } } return true; Und seltsamer weise (wohl bedingt durch den rechten Kanal) einige Samples bei einigen Plugins fehlen. Das sieht dann so aus siehe PIC die hellgrüne grundläsche die frei ist. Müßte eigentlich mit Samples belegt sein. Gruss Emil |
Re: FFT Problem in verbindung mit WMP
Dein
Delphi-Quellcode:
erfasst doch 2048 Byte wenn SA_BUFFER_SIZE = 1024 ist.
TimedLevel = record
frequency : array [0..1, 0..SA_BUFFER_SIZE-1] of byte; Sie sind nur nicht hintereinander angeordnet sondern untereinander. Kannst Du nicht erst die VisData.frequency[0,i] benutzen und wenn i > 1024 ist dann VisData.frequency[1,i mod 1024].
Delphi-Quellcode:
Vielleicht habe ich Dein Problem auch nicht klar verstanden.
for i:=0 to 2047 do
VisData.frequency[i div 1024, i mod 1024]:=... Grüße Klaus |
Re: FFT Problem in verbindung mit WMP
Zitat:
Mein problem ist nur die übergabe bzw.. die position wo ich den rechten kanal abfragen(übergeben kann) Du meinst ne if abfrage if i = 1024 then .. hmmm kann es mal testen ob sich das so einfach umsetzen läßt (meine nicht die IF Abfrage) aondern generell.
Delphi-Quellcode:
gruss Emil
VisData.frequency[i div 1024, i mod 1024]:=..
|
Re: FFT Problem in verbindung mit WMP
Liste der Anhänge anzeigen (Anzahl: 1)
Hi Klaus
Supi klappt bestens! Allerdings nicht mit 'DIV'
Delphi-Quellcode:
Geht zwar auch, aber dann schaltest du die Samples vom rechten Kanal quasi aus[0,i]
VisData.frequency[i + 1024, i mod 1024]:=
Max(0, Min(1023, (Trunc(Power(Data32Pos^, FFTSAmplification * 0.5) * 1023)))); Danke Gruss Emil |
Re: FFT Problem in verbindung mit WMP
Hmmm klappt doch nicht!
Habe zum testen den channel auf 1 gestellt(MONO) und nicht wieder entfernt. Nach einigen änderungen ist mir das aufgefallen und habe es geändert. Jetzt läuft er auf 2 Kanälen stürzt aber mit einen Stack overflow ab. Kommt keine Meldung wo der Fehler auftritt. Irgendwie stimmt das mit VisData.frequency[i + 1024, i mod 1024]:= .. i + 1024 nicht auch mit div geht es nicht! Eigentlich darf hier das Array auch nicht größer als 1 sein [0..1] Bei i + 1024 ist es sehr viel größer oder ? ;)
Delphi-Quellcode:
Gibt mir auch die Samples des Rechten Kanal nicht richtig zur auswertung.
VisData.frequency[1, i mod 1024]:= ..
Delphi-Quellcode:
i div 1024 ist eins! nur dann kann ich direkt die 1 eingeben und muss die nicht extra berechnen.
VisData.frequency[i div 1024, i mod 1024]:=
EDIT: Das hier funktioniert 100% ist aber nur MONO bzw. 1 Kanal(links)
Delphi-Quellcode:
gruss Emil
for i := 0 to 1023 do
begin VisData^.frequency[0, i] := Max(0, Min(1023, (Trunc(Power(Data32Pos^, FFTSAmplification * 1.0) * 1023)))); VisData^.frequency[1, i] := VisData^.frequency[0, i]; Inc(Data32Pos, FFT_SkipCount); end; |
Re: FFT Problem in verbindung mit WMP
Guten Morgen Emil,
Delphi-Quellcode:
war auch die Antwort auf diese Frage:
for i:=0 to 2047 do
VisData^.frequency[i div 1024, i mod 1024]:=.. Zitat:
Ein Stacküberlauf, deutet meines Erachtens eher auf eine sehr lange/endlos Schleife hin. Grüße Klaus |
Re: FFT Problem in verbindung mit WMP
Auch guten Morgen.
Zitat:
Zitat:
Hier nochmal die ganze schleife. Welche eigentlich keinen überlauf verursacht.
Delphi-Quellcode:
Der fehler tritt bei mehr als 1023 auf .
BASS_ChannelGetData(channel, Data32, FFTSize or
DWORD(IfThen(ChanInfo.chans = 2, BASS_DATA_FFT_INDIVIDUAL))); if (ChanInfo.chans = 2) then begin for i := 0 to 2047 do try begin if i < 1024 then begin VisData^.frequency[0, i] := Max(0, Min(1023, (Trunc(Power(Data32Pos^, FFTSAmplification * 0.8) * 1023)))); Inc(Data32Pos, FFT_SkipCount); end else begin VisData.frequency[1, i mod 1024]:= Max(0, Min(1023, (Trunc(Power(Data32Pos^, FFTSAmplification * 0.8) * 1023)))); Inc(Data32Pos, FFT_SkipCount); end; end; except Result := false; exit; end; end else begin for i := 0 to 1023 do begin VisData^.frequency[0, i] := Max(0, Min(1023, (Trunc(Power(Data32Pos^, FFTSAmplification * 1.0) * 1023)))); VisData^.frequency[1, i] := VisData^.frequency[0, i]; Inc(Data32Pos, FFT_SkipCount); end; end; Hier mal die Definition von BASS_DATA_FFT_INDIVIDUAL Zitat:
|
Re: FFT Problem in verbindung mit WMP
Hallo Emil,
Deine Schleifen gehen bei Stereo immer fix von 0 bis 2047. Ist das kein Problem, wenn die SampleRate <> 1024/2048 ist? Sollte i dann nicht eher anhänging von der SampleRate laufen? ![]() Zitat:
Wie Du merkst, verstehe ich noch nicht wie Du die Daten bekommst und wie sie angeordnet sind. Und noch vielleicht ein Copy und Paste Fehler:
Delphi-Quellcode:
sollte doch
begin
VisData.frequency[1, i mod 1024]:= Max(0, Min(1023, (Trunc(Power(Data32Pos^, FFTSAmplification * 0.8) * 1023)))); Inc(Data32Pos, FFT_SkipCount); end;
Delphi-Quellcode:
heißen, oder?
begin
VisData^.frequency[1, i mod 1024]:= Max(0, Min(1023, (Trunc(Power(Data32Pos^, FFTSAmplification * 0.8) * 1023)))); Inc(Data32Pos, FFT_SkipCount); end; Grüße Klaus |
Re: FFT Problem in verbindung mit WMP
Hi Klaus
Zitat:
Habe es von meiner Winamp Render function eingefügt da hieß die abfrage anders. Aber gut das du mich drauf aufmerksam gemacht hast. Zitat:
Das handhabe ich auch so.
Delphi-Quellcode:
Durch das Flag BASS_DATA_FFT_INDIVIDUAL werden die daten unter verwendung von BASS_DATA_FFT2048
case (FFT_WMP_SkipCount) of
1: FFTSize := BASS_DATA_FFT1024; 2: FFTSize := BASS_DATA_FFT2048; 3: FFTSize := BASS_DATA_FFT4096; else FFT_WMP_SkipCount := 1; FFTSize := BASS_DATA_FFT1024; end; BASS_ChannelGetData(channel, Data32, FFTSize or DWORD(IfThen(ChanInfo.chans = 2, BASS_DATA_FFT_INDIVIDUAL))); mit 2 mal 1024 samples zurückgegeben! Was ich nicht verstehe das die gleiche Renderfunktion in winamp funktioniert Der unterschied liegt doch nur in der übergabe der Samples welche hier 575 entsprechen. EDIT: Das ist die letzte Fehlermeldung! Zitat:
|
Re: FFT Problem in verbindung mit WMP
Zitat:
Erlaubt sind aber nur 2147348479 (LongInt) Bytes. Und die einzige Stelle wo Speicher reserviert wird ist diese:
Delphi-Quellcode:
Was Du damit meinst,
BASS_ChannelGetData(channel, Data32, FFTSize or DWORD(IfThen(ChanInfo.chans = 2,BASS_DATA_FFT_INDIVIDUAL)));
Zitat:
Grüße Klaus, der mit seinem Latein am Ende ist. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:23 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz