Dark Bit Factory & Gravity
PROGRAMMING => General coding questions => Topic started by: Pot Noodle on July 03, 2011
-
Hi, I was wondering if there is anyone here that can convert C code to BlitzMax or even just some basic as I have been trying but with no luck. ???
Thanks.
void CALLBACK UpdateSpectrum(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
HDC dc;
int x,y,y1;
float fft[1024]; // get the FFT data
BASS_ChannelGetData(chan,fft,BASS_DATA_FFT2048);
if (!specmode) {
memset(specbuf,0,SPECWIDTH*SPECHEIGHT);
for (x=0;x<SPECWIDTH/2;x++) {
#if 1
y=sqrt(fft[x+1])*3*SPECHEIGHT-4; // scale it (sqrt to make low values more visible)
#else
y=fft[x+1]*10*SPECHEIGHT; // scale it (linearly)
#endif
// y=fft[x+1]*SPECHEIGHT; // scale it (linearly)
// y=fft[x+1]?SPECHEIGHT+((SPECHEIGHT/100.0)*(50+(20*log(fft[x+1])))):0;
if (y>SPECHEIGHT) y=SPECHEIGHT; // cap it
if (x && (y1=(y+y1)/2)) // interpolate from previous to make the display smoother
while (--y1>=0) specbuf[y1*SPECWIDTH+x*2-1]=y1+1;
y1=y;
while (--y>=0) specbuf[y*SPECWIDTH+x*2]=y+1; // draw level
}
} else {
for (x=0;x<SPECHEIGHT;x++) {
y=sqrt(fft[x+1])*3*127; // scale it (sqrt to make low values more visible)
if (y>127) y=127; // cap it
specbuf[x*SPECWIDTH+specpos]=128+y; // plot it
}
// move marker onto next position
specpos=(specpos+1)%SPECWIDTH;
for (x=0;x<SPECHEIGHT;x++) specbuf[x*SPECWIDTH+specpos]=255;
}
-
something like (completely untested, and possibly wrong!)
const SPECWIDTH=640
const SPECHEIGHT=480
dim fft#(1024)
dim specbuf(SPECWIDTH*SPECHEIGHT)
specpos%=0
'this function should be called regularly from a timer, don't know what rate though
Function UpdateSpectrum()
'don't know how to convert this line
'read the data from the mixer from channel 'chan' to array fft
BASS_ChannelGetData(chan,fft,BASS_DATA_FFT2048);
if specmode% = 0 then
'this code is for one type of equalizer
for x% = 0 To SPECWIDTH*SPECHEIGHT-1
specbuf(x) = 0
next
'for half the screen width
for x=0 to SPECWIDTH/2-1
y% = sqrt (fft(x+1))*3*SPECHEIGHT-4
if y > SPECHEIGHT y = SPECHEIGHT
if x > 0 then
y1% = (y + y1) / 2
for i% = y1-1 to 0 step -1
specbuf(i*SPECWIDTH+x*2-1)=i+1
next
end if
y1 = y
for i = y-1 to 0 step -1
specbuf(i*SPECWIDTH+x*2-1)=i+1
next
next
else
'this code is for a different type of equalizer
for x=0 to SPECHEIGHT-1
y = sqrt(fft(x+1))*3*127
if y>127 y=127
specbuf[x*SPECWIDTH+specpos]=128+y
next
end if
'wrap round
specpos = (specpos+1) Mod SPECWIDTH
'draw a vertical line at x=specpos
for x=0 to SPECHEIGHT-1
specbuf(x*SPECWIDTH+specpos) = 255
next
End Function
-
This is how the complete part from the example looks like in Purebasic.
So, maybe you can use Jim's code and this one to get a working Bmax code. ;)
Procedure UpdateSpectrum()
Define x.l, y.l, y1.l
Dim FFT.f(1024)
BASS_ChannelGetData(Handle,@FFT(),#BASS_DATA_FFT2048)
Select specmode
Case 0
Dim specbuf(#SPECWIDTH * (#SPECHEIGHT + 1)) ;' clear display
For x = 0 To (#SPECWIDTH/2)-1
Y = Sqr(fft(X + 1)) * 3 * #SPECHEIGHT - 4 ; scale it (sqrt to make low values more visible)
; Y = fft(X + 1) * 10 * #SPECHEIGHT ; scale it (linearly)
If Y>#SPECHEIGHT : Y=#SPECHEIGHT : EndIf
If X
y1 = (Y + y1) / 2
y1 = y1 - 1
While (y1 >= 0)
ind=y1 * #SPECWIDTH + X * 2 - 1
specbuf(ind) = y1 + 1
y1 = y1 - 1
Wend
EndIf
y1 = Y
Y = Y - 1
While (Y >= 0)
ind=Y * #SPECWIDTH + X * 2
specbuf(ind) = Y + 1
Y = Y - 1
Wend
Next X
Case 1
Dim specbuf(#SPECWIDTH * (#SPECHEIGHT + 1)) ; clear display
Define b0.l, BANDS.i
b0 = 0
BANDS = 21
Define sc.l, b1.l, sum.f
For X = 0 To BANDS
sum = 0
b1 = Pow(2, X * 10.0 / BANDS )
If (b1 > 1023) : b1 = 1023 : EndIf
If (b1 <= b0) : b1 = b0 + 1 : EndIf; make sure it uses at least 1 FFT bin
sc = 10 + b1 - b0
Repeat
sum = sum + fft(1 + b0)
b0 = b0 + 1
Until b0 >= b1
Y = (Sqr(sum / Log10(sc)) * 1.7 * #SPECHEIGHT) - 4 ;' scale it
If Y > #SPECHEIGHT : Y = #SPECHEIGHT : EndIf;' cap it
Y = Y - 1
While Y >= 0
FillMemory(@specbuf(Y * #SPECWIDTH + X * Int(#SPECWIDTH / BANDS)), #SPECWIDTH / BANDS - 2, Y + 1)
Y = Y - 1
Wend
Next X
Case 2
For X = 0 To #SPECHEIGHT - 1
Y = Sqr(fft(X + 1)) * 3 * 127 ;' scale it (sqrt to make low values more visible)
If (Y > 127) : Y = 127 : EndIf;' cap it
specbuf(X * #SPECWIDTH + specpos) = 128 + Y ;' plot it
Next X
;' move marker onto next position
specpos = (specpos + 1) % #SPECWIDTH
For X = 0 To #SPECHEIGHT - 1
specbuf(X * #SPECWIDTH + specpos) = 255
Next X
Case 3
Dim buf.f(0)
Define c.l, ci.BASS_CHANNELINFO
Dim specbuf(#SPECWIDTH * (#SPECHEIGHT + 1))
BASS_ChannelGetInfo(Handle, @ci)
Dim buf(ci\chans * #SPECWIDTH * 4)
BASS_ChannelGetData(Handle, @buf(0), (ci\chans * #SPECWIDTH * 4) | #BASS_DATA_FLOAT)
For c = 0 To ci\chans - 1
For X = 0 To #SPECWIDTH - 1
v.l = (1 - buf(X * ci\chans + c)) * #SPECHEIGHT / 2
If (v < 0)
v = 0
ElseIf (v >= #SPECHEIGHT)
v = #SPECHEIGHT - 1
EndIf
If (X = 0) : Y = v : EndIf
Repeat
If (Y < v)
Y = Y + 1
ElseIf (Y > v)
Y = Y - 1
EndIf
specbuf(Y * #SPECWIDTH + X) = IIf(c And 1, 127, 1)
Until (Y = v)
Next X
Next c
EndSelect
SetDIBitsToDevice_(GetDC_(WindowID(0)), 0, 0, #SPECWIDTH, #SPECHEIGHT, 0, 0, 0, #SPECHEIGHT, @specbuf(0), @bh, 0)
EndProcedure
-
Thanks guys, I'm getting there the only problem I have at the moment is an Error Msg saying FFT can't be indexed.
Well I know what it means but how to work around it (NO IDEA) = DUMB + "T..T" :whack:
-
Post your code.
Jim
-
Cheers Jim, Got it sorted Thanks.
-
waow impessive fft !
congrats !
-
Cheers Maracuja, You should see it now it's sorted ;D