'===========================================================================
' Subject: SOUNDBLASTER VOC DIRECT            Date: 09-28-93 (00:00)       
'  Author: Edward Schlunder                   Code: PDS                    
'  Origin: FidoNet QUIK_BAS Echo            Packet: SOUND.ABC
'===========================================================================
'======================================================================
'                          SoundBlaster VOC Direct
'                  Release 1.11 (9-28-93) By Edward Schlunder
'              Filename: SBVOCDIR.BAS    Archive: !SBDIR11.ARJ
'
'        Released into the public domain. Do what you wish with it, but I'm
'   not liable for any undesirable outcomes. Also, common certesy suggests
'   that you give me credit in your program and/or your documents.
'
'               GTPN:       009/009
'               FidoNet:    1:114/151.0
'               Internet:   zilym@hndymn.fidonet.org
'               Snail Mail: Edward Schlunder
'                           554 N. Acacia Rd
'                           Apache Junction, AZ 85219-4313
'                           USA
'
'======================================================================

DEFINT A-Z
DECLARE SUB WriteDAC (DVal%)
DECLARE SUB SetVoice (ONOFF%)
DECLARE SUB PlayByte (BYVAL DVal%)

TYPE SoundSrcType
 Name     AS STRING * 13
 Han      AS INTEGER
 Addr     AS INTEGER
END TYPE

COMMON SHARED SdDevs()  AS SoundSrcType, SoundDev
DIM SdDevs(5)  AS SoundSrcType', SoundDev
SdDevs(0).Name = "PC-Speaker   ": SdDevs(0).Han = 0: SdDevs(0).Addr = &H42
SdDevs(1).Name = "LPT1-DAC     ": SdDevs(1).Han = 1: SdDevs(1).Addr = &H378
SdDevs(2).Name = "LPT2-DAC     ": SdDevs(2).Han = 1: SdDevs(2).Addr = &H278
SdDevs(3).Name = "LPT3-DAC     ": SdDevs(3).Han = 1: SdDevs(3).Addr = &H3BC
SdDevs(4).Name = "LPT4-DAC     ": SdDevs(4).Han = 1: SdDevs(4).Addr = &H37B
SdDevs(5).Name = "Sound Blaster": SdDevs(5).Han = 2: SdDevs(5).Addr = &H220

LastBeg = 1
Parm = INSTR(LastBeg, COMMAND$, "-")
IF Parm THEN
FileName$ = RTRIM$(LEFT$(COMMAND$, Parm))
ELSE
FileName$ = COMMAND$
END IF
DO
Parm = INSTR(LastBeg, COMMAND$, "-")
IF Parm THEN
P$ = MID$(COMMAND$, Parm, 2)
SELECT CASE P$
CASE "-C"                               'Playback device
SoundDev = VAL(MID$(COMMAND$, Parm + 2, 1))
CASE "-P"                               'Playback address
SdDevs(SoundDev).Addr = VAL("&H" + MID$(COMMAND$, Parm + 2, 3))
CASE "-S"                               'Playback slowdown
SlowDown = VAL(MID$(COMMAND$, Parm + 2, 2))
END SELECT
END IF
LastBeg = Parm + 2
LOOP UNTIL Parm = 0

IF SoundDev = 0 THEN
COLOR 14, 1
CLS
PRINT "Sound Device: "
FOR J = 0 TO 5
PRINT J; ":  "; SdDevs(J).Name
NEXT
LOCATE , , 1, 6, 8
DO
G$ = INKEY$
LOOP UNTIL LEN(G$)
PRINT G$
SoundDev = VAL(G$)

SELECT CASE SoundDev
CASE 5
PRINT "I/O Address of Sound Blaster:"
PRINT "1 :  210h"
PRINT "2 :  220h"
PRINT "3 :  230h"
PRINT "4 :  240h"
DO
G$ = INKEY$
LOOP UNTIL LEN(G$)
PRINT G$
Addr = VAL(G$)

SdDevs(SoundDev).Addr = &H200 + Addr * &H10
END SELECT

IF LEN(FileName$) = 0 THEN INPUT "Path and filename of file to play: ", FileName$
END IF

OPEN FileName$ FOR BINARY AS 1
SCREEN 12

VOCBytes& = LOF(1)
VOCSByte& = 1
VOCLeng = 32767
DO
LOCATE 30, 35                          'Print the output device name.
PRINT SdDevs(SoundDev).Name

IF VOCBytes& > 32767 THEN              '>32767 byte file handling
VOCLeng = 32767
VOCBytes& = VOCBytes& - 32767
ELSE
VOCLeng = VOCBytes&
VOCBytes& = 0
END IF
VOC$ = SPACE$(VOCLeng)
GET #1, VOCSByte&, VOC$
VOCSByte& = VOCSByte& + 32767

VSeg = SSEG(VOC$)                 'This needs to be changed for QB. I use
                                  'PDS. It should be VARSEG instead of SSEG
                                  'if you are using QB.
VOff& = SADD(VOC$)
VOff2& = VOff& - 640
SetVoice 1
DEF SEG = VSeg
FOR J& = 1 TO VOCLeng
              'You may need to add a delay loop in here if the VOC sounds
              'like it being played too fast.
'FOR K = 1 TO SlowDown: NEXT
VOff2& = VOff2& + 1
PRESET (ByteLoc + 1, PEEK(VOff2&))
VOff& = VOff& + 1
PlayByte PEEK(VOff&)
ByteLoc = ByteLoc + 1
PSET (ByteLoc, PEEK(VOff&)), 13
IF ByteLoc = 640 THEN ByteLoc = 0
NEXT
LOOP UNTIL VOCLeng = 0 OR LEN(INKEY$)
SetVoice 0
CLOSE 1
SCREEN 0: WIDTH 80
END

SUB PlayByte (BYVAL DVal)
SELECT CASE SdDevs(SoundDev).Han
 CASE 0
  OUT SdDevs(SoundDev).Addr, DVal \ 3
 CASE 1
  OUT SdDevs(SoundDev).Addr, DVal
 CASE 2
  DO                                    'This loops until the SoundBlaster is
  LOOP WHILE INP(SdDevs(SoundDev).Addr) AND &H80  'ready for data.
  OUT SdDevs(SoundDev).Addr, &H10
  DO                                    'This loops until the SoundBlaster is
  LOOP WHILE INP(SdDevs(SoundDev).Addr) AND &H80  'ready for data.
  OUT SdDevs(SoundDev).Addr, DVal
END SELECT
END SUB

SUB SetVoice (ONOFF)
IF ONOFF THEN
 SELECT CASE SdDevs(SoundDev).Han
  CASE 0
   OUT &H43, &HB6
   OUT &H42, &HFF
   OUT &H42, 0
   OUT &H43, &H90
   OUT &H61, INP(&H61) OR 3
  CASE 1
  CASE 2
   DO                                    'This loops until the SoundBlaster is
   LOOP WHILE INP(SdDevs(SoundDev).Addr) AND &H80        'ready for data.
   OUT SdDevs(SoundDev).Addr, &HD1
 END SELECT
ELSE
 SELECT CASE SdDevs(SoundDev).Han
  CASE 0
   OUT &H43, &HB6
   OUT &H61, INP(&H61) AND &HFC
  CASE 1
  CASE 2
   DO                                    'This loops until the SoundBlaster is
   LOOP WHILE INP(SdDevs(SoundDev).Addr) AND &H80        'ready for data.
   OUT SdDevs(SoundDev).Addr, &HD3
 END SELECT
END IF
END SUB
