' this software used part's of the open source project DUMB
' Dynamic Universal Music Bibliotheque, Version 0.9.3
' Copyright (C) 2001-2005 Ben Davis, Robert J Ohannessian and Julien Cugniere
' see http://dumb.sourceforge.net
#include once "windows.bi"
#include once "win/mmsystem.bi"

declare function OpenMod     lib "modlib" alias "_OpenMod"    (byval File as string) as any ptr
declare function GetLength   lib "modlib" alias "_GetLength"  (lpFile as any ptr) as integer
declare sub      CloseMod    lib "modlib" alias "_CloseMod"   (lpFile as any ptr)

declare function StartMod    lib "modlib" alias "_StartMod"    (lpFile as any ptr,byval n_channels as integer) as any ptr
declare function GetChannels lib "modlib" alias "_GetChannels" (lpMod as any ptr)as integer
declare function GetSamples  lib "modlib" alias "_GetSamples"  (lpMod as any ptr,n_Bits as integer,unsigned as integer,volume as single,delta as single,n_samples as integer, lpSamples as any ptr) as integer
declare function GetPosition lib "modlib" alias "_GetPosition" (lpMod as any ptr) as integer
declare sub      StopMod     lib "modlib" alias "_StopMod"     (lpMod as any ptr)

#inclib "modlib"

sub waveOutProc (byval hDevice as HWAVEOUT, _
                 byval msg     as uinteger, _
                 byval lpUser  as any ptr, _
                 byval unused1 as DWORD, _
                 byval unused2 as DWORD)
  dim as WAVEHDR ptr lpHdr
  select case as const msg
    case WOM_DONE
      lpHdr=cast(WAVEHDR ptr,unused1)
      lpHdr->dwLoops=-1
  end select
end sub


const nRate      as integer = 44100
const nBits      as integer = 16
const nChannels  as integer = 2
const FrameSize  as integer = (nBits\8)*nChannels
const nSamples   as integer = 2048*16
const BufferSize as integer = nSamples*FrameSize
const nBuffers   as integer = 3
dim   Delta      as single  = 65536.0f / nRate

dim as WAVEFORMATEX wfex
wfex.nSamplesPerSec  = nRate
wfex.nChannels       = nChannels
wfex.wBitsPerSample  = nBits
wfex.nBlockAlign     = FrameSize
wfex.nAvgBytesPerSec = FrameSize*nRate
wfex.wFormatTag      = WAVE_FORMAT_PCM
wfex.cbSize          = 0

dim as HWAVEOUT hDev
dim as WAVEHDR  whdr(nBuffers-1)

dim as string FileName = command(1)

dim as any ptr lpFile = OpenMod(filename)
if lpFile=0 then
  print "error: OpenMod() !"
  beep:sleep:end 1
end if
dim as integer Length=GetLength(lpFile)

dim as any ptr lpMod = StartMod(lpFile,nChannels)
if lpMod=0 then
  CloseMod(lpFile)
  print "error: StartMod() !"
  beep:sleep:end 1
end if


dim as any ptr lpCond=CondCreate()
dim as integer ret
ret=waveOutOpen(@hDev,-1,cptr(LPCWAVEFORMATEX,@wfex), _
                         cast(DWORD,@waveOutProc), _
                         cast(DWORD,lpCond), _
                         CALLBACK_FUNCTION)
if ret then
  StopMod(lpMod)
  CloseMod(lpFile)
  print "error: can't open playback device !"
  beep:sleep:end 1
end if

for i as integer=0 to nBuffers-1
   with whdr(i)
    .lpData        = callocate(BufferSize)
    .dwBufferLength= BufferSize
    .dwUser        = i
    .dwFlags       = 0
    .dwLoops       = 0
   end with
next

dim as integer nBytes,n,bc,posi

screenres 282,90
bload exepath & "/baby8.bmp"
windowtitle filename
'? Length\65536

' prepare N buffers
for i as integer=0 to nBuffers-1
  n=GetSamples(lpMod,nBits,0,1.0,delta,nSamples,whdr(i).lpData)
  nBytes+=n
  if waveOutPrepareHeader(hDev,@WHDR(i),sizeof(WAVEHDR)) then
    beep:goto exit_out
  end if
next

' write N buffers
for i as integer=0 to nBuffers-1
  ret=33
  while ret=33
    ret=waveOutWrite(hDev,@WHDR(i),sizeof(WAVEHDR)) 
    sleep 10
  wend
next
bc=-1

while 1
  while bc=-1
    for i as integer=0 to nBuffers-1
       if whdr(i).dwLoops<>0 then bc=i:exit for
    next
    ' any free buffer ?
    if (bc>-1) then
       WHDR(bc).dwLoops=0
       waveOutUnPrepareHeader(hDev,@WHDR(bc),sizeof(WAVEHDR))
       ' fill buffer with new samples
       n=GetSamples(lpMod,nBits,0,1.0,delta,nSamples,whdr(bc).lpData)
       nBytes+=n
       ' prepare buffer with new samples
       waveOutPrepareHeader(hDev,@WHDR(bc),sizeof(WAVEHDR))
       ret=33
       while ret=33
         ' send buffer to playback device
         ret=waveOutWrite(hDev,@WHDR(bc),sizeof(WAVEHDR))
         sleep 1
       wend
    else
      sleep 1
    end if
  wend
  bc=-1
  ' no more samples or a key ?
  if (n<nSamples) or inkey<>"" then exit while
wend

exit_out:
waveOutBreakLoop(hDev)
waveOutReset(hDev)

StopMod(lpMod)
CloseMod(lpFile)
for i as integer=0 to nBuffers-1
  waveOutUnprepareHeader(hDev,@WHDR(i),sizeof(WAVEHDR))
  if WHDR(i).lpData then deallocate(WHDR(i).lpData )
next
waveOutClose(hDev)



