Author Topic: Convert  (Read 5096 times)

0 Members and 1 Guest are viewing this topic.

Offline Pot Noodle

  • Sponsor
  • Amiga 1200
  • *******
  • Posts: 271
  • Karma: 15
  • Computers have lots of memory but no imagination
    • View Profile
Convert
« 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.

Code: [Select]
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;
}
« Last Edit: July 04, 2011 by Jim »

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Convert
« Reply #1 on: July 04, 2011 »
something like (completely untested, and possibly wrong!)
Code: [Select]
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
« Last Edit: July 04, 2011 by Jim »
Challenge Trophies Won:

Offline padman

  • Senior Member
  • Pentium
  • ********
  • Posts: 990
  • Karma: 260
    • View Profile
Re: Convert
« Reply #2 on: July 04, 2011 »
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. ;)

Code: [Select]
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

Challenge Trophies Won:

Offline Pot Noodle

  • Sponsor
  • Amiga 1200
  • *******
  • Posts: 271
  • Karma: 15
  • Computers have lots of memory but no imagination
    • View Profile
Re: Convert
« Reply #3 on: July 04, 2011 »
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:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Convert
« Reply #4 on: July 04, 2011 »
Post your code.

Jim
Challenge Trophies Won:

Offline Pot Noodle

  • Sponsor
  • Amiga 1200
  • *******
  • Posts: 271
  • Karma: 15
  • Computers have lots of memory but no imagination
    • View Profile
Re: Convert
« Reply #5 on: July 06, 2011 »
Cheers Jim, Got it sorted Thanks.

Offline maracuja

  • C= 64
  • **
  • Posts: 31
  • Karma: 4
    • View Profile
Re: Convert
« Reply #6 on: August 02, 2011 »
waow impessive fft !

congrats !

Offline Pot Noodle

  • Sponsor
  • Amiga 1200
  • *******
  • Posts: 271
  • Karma: 15
  • Computers have lots of memory but no imagination
    • View Profile
Re: Convert
« Reply #7 on: August 04, 2011 »
Cheers Maracuja, You should see it now it's sorted  ;D