'===========================================================================
' Subject: PB .WAV PLAYER                     Date: 03-27-96 (00:00)       
'  Author: Dave Navarro, Jr.                  Code: PB                     
'  Origin: www.powerbasic.com/source        Packet: SOUND.ABC
'===========================================================================
'=============================================================================
'                   Source code snippet: PowerBASIC for DOS
'
' Original found at http://www.fys.ruu.nl/~bergmann/basic.html
' converted to PowerBASIC by Dave Navarro, Jr.
' additional work by unknown author on CompuServe
'
' Play wave files through the SoundBlaster.
'
'=============================================================================

DEFINT A-Z

MaxTicks& = 1193180
SHARED WritePort%, MaxTicks&

'-Div.Init (maybe you get the filename from command line?
CLS
FILES ("*.WAV")
INPUT "Select Wave File"; VocFile$
VocFile% = FREEFILE

'-open the voc-file
OPEN VocFile$ FOR BINARY AS #VocFile%

TestPort$ = ENVIRON$("BLASTER")
IF TestPort$ > "" THEN
  PortAddress$ = "&H" + MID$(TestPort$, 2, 3)
  PortAddress = VAL(PortAddress$)
  WritePort = PortAddress + 12
ELSE
  WritePort = &H22C
END IF

'-parameters for copy-to-soundblaster
Bytes& = LOF(VocFile%)                 'number of bytes
X$ = SPACE$(40) 'riff file header stuff
GET #VocFile, , X$
Speed = ASC(MID$(X$, 26, 1)) * 256 OR ASC(MID$(X$, 25, 1))

'Playrate in Bytes per second.
'We are assuming an 8 bit *.Wav File Here
' And my 386-16 will hang in there at 11025 BPS under DOS
Clocks = MaxTicks& \ Speed 'using an integer divide. Close enough
                           'and doesn't pull in floating point math pack
                           'Maxticks are for the "normal" PC Clock at
                           '18.206 + ticks per second.
                           'We'll use this to time the play rate.
Bytes& = Bytes& - 40
BytesRemaining& = Bytes&               'number of remaining bytes
BufferMax% = &H3F00                    'largest buffer
Buffer$ = SPACE$(BufferMax%)           'create buffer
SetVoice 1                             'Soundblaster on

'-read {BufferMax%} bytes from disc, output on SB
DO
  BytesRemaining& = BytesRemaining& - BufferLen%
  IF BytesRemaining& = 0 THEN EXIT DO  'nothing left over?
  IF BytesRemaining& > BufferMax% THEN 'how many bytes?
    BufferLen% = BufferMax%
  ELSE
    BufferLen% = BytesRemaining&       'remaining (<BufferMax%)..
    Buffer$ = SPACE$(BufferLen%)       '..throw it into SB :-)
  END IF

  GET #VocFile%, , Buffer$             'read buffeer
  T = 0
  DEF SEG = STRSEG(Buffer$)
  K = STRPTR(Buffer$)
  OUT &H43, &H34 'PIT Timer select one shot then we can let the
  OUT &H40, 0  'clock keep up.
  OUT &H40, 0  ' set the clock to 0 and start the count down
  Rate& = 65536 - Clocks 'First count down stopping value
                         ' "zero" - Rate
  DO             'output od {bufferlen%}
     Char = PEEK(K + T)
     WAIT WritePort, &H80, &HFF             'wait for data-ready
     OUT WritePort, &H10
     WAIT WritePort, &H80, &HFF
     OUT WritePort, Char 'Direct DAC method
     T = T + 1
     DO
      C& = (INP(&H40) + INP(&H40) * 256&) 'check the ticker
    LOOP UNTIL C& <= Rate& 'end if it's at or below the ticks we alloted
    Rate& = Rate& - Clocks
    IF Rate& < 0 THEN
        OUT &H40, 0  'reset the ticker to 0
        OUT &H40, 0  'both bytes
        Rate& = 65536 - Clocks  'Reset the Rate& value
    END IF
  LOOP UNTIL T = BufferLen 'This is faster than a for next loop
  OUT &H43, 4
LOOP UNTIL Forever
SetVoice 0                             'SB off
CLOSE #VocFile%                        'close file
END                                    '.. good bye :-)

' Turns Speaker on and off
SUB SetVoice (OnOff%)
  IF OnOff% THEN
    WAIT WritePort%, &H80, &HFF             'wait for data-ready on SB
    OUT WritePort%, &HD1 'ON
  ELSE
    WAIT WritePort%, &H80, &HFF
    OUT WritePort%, &HD3 'OFF
  END IF
END SUB
