Posted: 12th Mar 2003 1:33
Not sure if this is usefull to anyone, but here is a function that will draw a wav sound from an existing memblock.

It's only the mono version for now, I'm having a little problem with reading stereo sample data.
Posted: 12th Mar 2003 1:33
+ Code Snippet
sync on : sync rate 40

load sound "your_sound.wav",1

make memblock from sound 1,1

DrawMonoSnd(0,0,639,255,1,0,100,rgb(0,0,128),rgb(255,255,255),0)
DrawMonoSnd(0,300,320,364,1,0,100,rgb(128,0,0),rgb(255,255,0),1)

sync

wait key
delete memblock 1
end


Function DrawMonoSnd(left,top,right,bottom,block,startpercent#,endpercent#,bckcol,wavcol,drawmode)
  ` left, top, right, bottom = boxed area to draw sound
  ` block = number of memblock containing sound
  ` startpercent# = where to draw from in sound data
  ` endpercent# = where to draw to in sound data
  ` bckcol = background color
  ` wavcol = wav color
  ` drawmode = 0 for dot, 1 for line

  width = (right - left) + 1
  height = (bottom - top) + 1
  centerline = top + height/2
  vscale# = (height/2.0)/127.0

  blocksize = get memblock size(block)
  startpos = int((blocksize-12) * (startpercent#/100.0))
  endpos = int((blocksize-12) * (endpercent#/100.0))
  startpos = startpos + 12
  endpos = endpos + 12

  if startpos < 12 then startpos = 12
  if endpos > blocksize then endpos = blocksize

  skip = (endpos - startpos) / ((right - left) + 1)
  if skip < 1 then skip = 1

  ` draw background and set wav color
  ink bckcol,0 : box left,top,right+1,bottom+1
  ink wavcol,0

  x = left-1
  while (startpos < endpos) and (x <= right)

      ` read value from sound byte
      v = memblock byte(block,startpos) - 127

      x = x + 1
      y = centerline + (v * vscale#)
      startpos = startpos + skip

      if drawmode = 1
        ` draw as lines
        if x > left then line lastx,lasty,x,y
        lastx = x : lasty = y
      else
        ` draw as dots
        box x,y,x+1,y+1
      endif

  endwhile

endfunction
Posted: 12th Mar 2003 3:08
Thanks for making this.

One thing, though -- it seems like the waveforms display closer to the middle when they should be more distant from the middle and vise versa. See pic:



If you can fix that, this will be truly excellent.
Posted: 12th Mar 2003 3:48
@Steverino: The code works correcly, at least for me. If you look at the code, you see that it can only display wave files that are mono, and have =>8 bits<= per sample.

Actually the code flips the sound around the x axis, but it'a no problem to rectify that problem
Posted: 12th Mar 2003 3:56
Don't worry I'm getting there. I'm working on a function that will show both mono or stereo
Posted: 12th Mar 2003 4:09
You're right -- with an 8-bit sample, it looks more the way it ought to:



Brilliant job, Easily Confused!
Posted: 12th Mar 2003 4:25
Erm, how will you determine if the soundfile in the memblock is mono or stereo? As far as I can see, then there is no info in the memblock that you can use to determine that.

Detecting the bits per sample of the sound is however easy. Just paste this in a good place in your code:

+ Code Snippet
bits_per_sec = memblock dword(block,0)
  frequency = memblock dword(block,4)
  bits_per_sample = bits_per_sec / frequency
Posted: 12th Mar 2003 4:38
I thought something on the lines of:

bitspersec = memblock dword(block,0)
frequency = memblock dword(block,4)
if bitspersec/8 = frequency then mono = 1 else mono = 0

I'm not totaly sure if this is the correct method.
Posted: 12th Mar 2003 4:44
Hmmm, won't work. It will tell you if the sample is 8 bit or 16 bit (or 24,32 bit etc), but has nothing to do with the sample being mono/stereo.
Posted: 12th Mar 2003 5:20
Dang! Also when sending a stereo sound into a memblock you can't Make Sound From Memblock to another sound because when you play it, it sounds lousy. All that stereo data is turned into mono data. Double Dang!

So your right, there's no way for DBPro to tell if a loaded sound is mono or stereo.

erm.... when is patch 7 comming out hehe
Posted: 12th Mar 2003 14:31
Yeah, what a drag..
Posted: 13th Mar 2003 0:05
I can't get the waveform to draw correctly when it's a 16-bit sample. Has anyone got that figured out?
Posted: 13th Mar 2003 3:28
I think this will do it:

+ Code Snippet
function DrawMonoSnd(left,top,right,bottom,block,startpercent#,endpercent#,bckcol,wavcol,drawmode)
  ` function for drawing standard PCM WAV 8 and 16 bit mono sounds

  ` left, top, right, bottom = boxed area to draw sound
  ` block = number of memblock containing sound
  ` startpercent# = where to draw from in sound data
  ` endpercent# = where to draw to in sound data
  ` bckcol = background color
  ` wavcol = wav color
  ` drawmode = 0 for dot, 1 for line

  width = (right - left) + 1
  height = (bottom - top) + 1
  centerline = top + (height/2)

  ` draw background and set wav color
  ink bckcol,0 : box left,top,right+1,bottom+1
  ink wavcol,0

  ` exit now if there is no memblock
  if memblock exist(block) = 0 then exitfunction

  ` check for 8 or 16 bit sounds
  bitspersec = memblock dword(block,0)
  frequency = memblock dword(block,4)
  vscale# = (height/2.0)/128.0
  if bitspersec/8 = frequency
`    vscale# = (height/2.0)/128.0
    bits = 8
  endif
  if bitspersec/16 = frequency
`    vscale# = (height/2.0)/32768.0
    bits = 16
  endif

  blocksize = get memblock size(block)
  startpos = int((blocksize-12) * (startpercent#/100.0))
  endpos = int((blocksize-12) * (endpercent#/100.0))
  startpos = startpos + 12
  endpos = endpos + 12

  if startpos &lt; 12 then startpos = 12
  if endpos &gt; blocksize then endpos = blocksize

  skip = ((endpos - startpos) / ((right - left) + 1))
  if skip &lt; 1 then skip = 1

  if bits = 16
    ` make sure all are even
    if (startpos mod 2) then inc startpos,1
    if (endpos mod 2) then dec endpos,1
    if (skip mod 2) then inc skip,1
  endif

  vw as word

  for x = left to right
    if startpos &gt; endpos then exitfunction

    if bits = 8 then v = 0x80 - memblock byte(block, startpos)
    if bits = 16
      v = 0x8000 - memblock word(block, startpos)
      if v &gt; 0 then v = 32678 - v else v = -32678 - v
      v = v / 128
   endif

    y = centerline + (v * vscale#)

    if drawmode = 1
      ` draw as lines
      if x &gt; left then line lastx,lasty,x,y
      lastx = x : lasty = y
    else
      ` draw as dots
      box x,y,x+1,y+1
    endif

    startpos = startpos + skip
  next x

endfunction


I hope
Posted: 13th Mar 2003 3:30
Oh! Remove those commented yscale# lines in the middle, I forgot to take those out.
Posted: 13th Mar 2003 3:32
Scratch that! Use this one.

+ Code Snippet
function DrawMonoSnd(left,top,right,bottom,block,startpercent#,endpercent#,bckcol,wavcol,drawmode)
  ` function for drawing standard PCM WAV 8 and 16 bit mono sounds

  ` left, top, right, bottom = boxed area to draw sound
  ` block = number of memblock containing sound
  ` startpercent# = where to draw from in sound data
  ` endpercent# = where to draw to in sound data
  ` bckcol = background color
  ` wavcol = wav color
  ` drawmode = 0 for dot, 1 for line

  width = (right - left) + 1
  height = (bottom - top) + 1
  centerline = top + (height/2)

  ` draw background and set wav color
  ink bckcol,0 : box left,top,right+1,bottom+1
  ink wavcol,0

  ` exit now if there is no memblock
  if memblock exist(block) = 0 then exitfunction

  ` check for 8 or 16 bit sounds
  bitspersec = memblock dword(block,0)
  frequency = memblock dword(block,4)
  if bitspersec/8 = frequency then bits = 8
  if bitspersec/16 = frequency then bits = 16

  blocksize = get memblock size(block)
  startpos = int((blocksize-12) * (startpercent#/100.0))
  endpos = int((blocksize-12) * (endpercent#/100.0))
  startpos = startpos + 12
  endpos = endpos + 12

  if startpos &lt; 12 then startpos = 12
  if endpos &gt; blocksize then endpos = blocksize

  skip = ((endpos - startpos) / ((right - left) + 1))
  if skip &lt; 1 then skip = 1

  if bits = 16
    ` make sure all are even
    if (startpos mod 2) then inc startpos,1
    if (endpos mod 2) then dec endpos,1
    if (skip mod 2) then inc skip,1
  endif

  vscale# = (height/2.0)/128.0

  for x = left to right
    if startpos &gt; endpos then exitfunction

    if bits = 8 then v = 0x80 - memblock byte(block, startpos)
    if bits = 16
      v = 0x8000 - memblock word(block, startpos)
      if v &gt; 0 then v = 32678 - v else v = -32678 - v
      v = v / 128
   endif

    y = centerline + (v * vscale#)

    if drawmode = 1
      ` draw as lines
      if x &gt; left then line lastx,lasty,x,y
      lastx = x : lasty = y
    else
      ` draw as dots
      box x,y,x+1,y+1
    endif

    startpos = startpos + skip
  next x

endfunction
Posted: 13th Mar 2003 4:06
Hmmm, a minor scaling problem when viewing 16 bit samples.

Change:

v = v / 128

to:

v = v / 256
Posted: 13th Mar 2003 4:08
Man, I would never have figured that out. I do get part of the waveform falling outside the box, though:



I tried adding
if y < top then y = top
if y > bottom then y = bottom
after the line where y is defined, but it just looked clipped.

I think the numbers 32678 should really be 32768, but that doesn't change the look at all. The 8-bit samples display entirely within the box.
Posted: 13th Mar 2003 4:16
Whoops! Your right, got my 6's and 7's the wrong way around

+ Code Snippet
function DrawMonoSnd(left,top,right,bottom,block,startpercent#,endpercent#,bckcol,wavcol,drawmode)
  ` function for drawing standard PCM WAV 8 and 16 bit mono sounds

  ` left, top, right, bottom = boxed area to draw sound
  ` block = number of memblock containing sound
  ` startpercent# = where to draw from in sound data
  ` endpercent# = where to draw to in sound data
  ` bckcol = background color
  ` wavcol = wav color
  ` drawmode = 0 for dot, 1 for line

  width = (right - left) + 1
  height = (bottom - top) + 1
  centerline = top + (height/2)

  ` draw background and set wav color
  ink bckcol,0 : box left,top,right+1,bottom+1
  ink wavcol,0

  ` exit now if there is no memblock
  if memblock exist(block) = 0 then exitfunction

  ` check for 8 or 16 bit sounds
  bitspersec = memblock dword(block,0)
  frequency = memblock dword(block,4)
  if bitspersec/8 = frequency then bits = 8
  if bitspersec/16 = frequency then bits = 16

  blocksize = get memblock size(block)
  startpos = int((blocksize-12) * (startpercent#/100.0))
  endpos = int((blocksize-12) * (endpercent#/100.0))
  startpos = startpos + 12
  endpos = endpos + 12

  if startpos &lt; 12 then startpos = 12
  if endpos &gt; blocksize then endpos = blocksize

  skip = ((endpos - startpos) / ((right - left) + 1))
  if skip &lt; 1 then skip = 1

  if bits = 16
    ` make sure all are even
    if (startpos mod 2) then inc startpos,1
    if (endpos mod 2) then dec endpos,1
    if (skip mod 2) then inc skip,1
  endif

  vscale# = (height/2.0)/128.0

  for x = left to right
    if startpos &gt; endpos then exitfunction

    if bits = 8 then v = 0x80 - memblock byte(block, startpos)
    if bits = 16
      v = 0x8000 - memblock word(block, startpos)
      if v &gt; 0 then v = 32768 - v else v = -32768 - v
      v = v / 256
    endif

    y = centerline + (v * vscale#)

    if drawmode = 1
      ` draw as lines
      if x &gt; left then line lastx,lasty,x,y
      lastx = x : lasty = y
    else
      ` draw as dots
      box x,y,x+1,y+1
    endif

    startpos = startpos + skip
  next x

endfunction
Posted: 13th Mar 2003 4:17
...which you solved while I was describing the problem.

My apologies for being all needy, but I have a hard time getting my brain around memblocks.

Thanks again.
Posted: 13th Mar 2003 4:19
hehe Your welcome