home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 18
/
CD_ASCQ_18_111294_W.iso
/
dos
/
prg
/
bas
/
ruckus
/
xmplesrc
/
x01.bas
< prev
next >
Wrap
BASIC Source File
|
1994-10-20
|
11KB
|
326 lines
DECLARE FUNCTION InitDevice% (device%, SIP AS ANY, IP AS ANY)
DECLARE FUNCTION PickDevice% (SIP AS ANY, XMSflag%)
REM $INCLUDE: 'RUCKDAC.BI'
'--------------------------------------
'SEE X01_71.BAS FOR BASIC7/VBDOS EXAMPLE
'--------------------------------------
'X01.BAS - load and play digital data file into DOS memory
'
' - The SB is always played in DMA mode in this example, this means
' - that stereo or high-sample rate files will not play correctly;
' - they will play correctly on an SB PRO or on the other devices.
' - To play stereo or high-sample rate files on the SB, PBP.Mode
' - must be set to either 0 or 1 (i.e., non-SB/DMA mode).
'
'31-Jan-93 -chh
'C>bc X01 /o;
'C>link X01,X01.EXE,nul,RUCKDAC.LIB;
ver$ = "[930131]"
DEFINT A-Z
'The packs could be made global but passing them as paramters works
DIM SIP AS SysInfoPackTYPE
DIM IP AS InitPackTYPE
DIM LP AS LoadPackTYPE
DIM SP AS SetPackTYPE
DIM PBP AS PlaybackPackTYPE
DIM GDP AS GetDataPackTYPE
DIM DP AS DeallocPackTYPE
DIM XP AS XitPackTYPE
CLS
PRINT "X01.BAS - RUCKUS-DAC play of VOC or WAVE file example."; ver$
InIDE = -1 'since the IDE needs more than 2K available, use this to
'flag if operating in QB's ennvironment
'RUCKDAC uses memory from the operating system pool
'since BASIC starts up claiming all memory, instruct it to return excess
'memory back to OS pool
nix& = SETMEM(700000) 'return to QB environment any previous release
nix& = SETMEM(0) 'see how much is available
nix& = nix& - 2100 'release all but 2K to operating system
IF InIDE THEN
nix& = nix& - 66000 'leave 64K more for IDE
XP.Func = ExitDac 'and shut down any loose ends
nix = RUCKDAC(XP)
END IF
nix& = SETMEM(-nix&) 'this call does the actual release
'pick device to use
devID = PickDevice(SIP, XMSflag)'id system and get device to use
IF devID < 0 THEN PRINT "Ended.": END
CLS
LOCATE 5
'initialize the selected device and register ExitDac via AtExitDac
stat = InitDevice(devID, SIP, IP)
IF stat = 0 THEN
'The following load and play example source is coded inline here
'to simplify readability -- but it's so easy to add things I just
'kept adding stuff, so take it slow if you don't follow at first
'load file and setup playback parameters
INPUT "VOC/WAVE filename: ", filename$
filename$ = filename$ + CHR$(0) 'DOS requires ASCIIZ name
LP.Func = LoadDac
LP.FilenamePtrOff = SADD(filename$) 'QB format
LP.FilenamePtrSeg = VARSEG(filename$)
'LP.FilenamePtrOff = SADD(filename$) 'BASIC7 format
'LP.FilenamePtrSeg = SSEG(filename$)
LP.StartPos = 0& 'start load at byte 0 of filename$
LP.LoadSize = 0& 'load entire file
LP.XMMflag = XMSflag 'load into DOS or XMS memory (selected in PickDevice)
stat = RUCKDAC(LP)
IF stat = 0 THEN
'immediately after load, but before play if non-DMA, we can peek
'into the DAC data to get the file's recorded sample rate, in case
'of SR > 32767, we just add 65536 to get unsigned value
DEF SEG = IP.InfoPtrSeg
bp = IP.InfoPtrOff
fileSR& = 256 * PEEK(bp + 25) + PEEK(bp + 24)
IF fileSR& < 0 THEN fileSR& = fileSR& + 65536
PRINT " Sample rate:"; fileSR&; "Hz (at load time)"
PRINT " File format: ";
IsStereo = PEEK(bp + 26)
FormatIs = PEEK(bp + 20)
IF IsStereo THEN PRINT "Stereo"; ELSE PRINT "Mono";
IF FormatIs = 1 THEN PRINT " voc" ELSE PRINT " wave"
DEF SEG
'data is loaded, if device is a Sound Blaster, use DMA at
'file sample rate else set rate to either file sample rate, or
'if > 11025 (most ATs can handle 11kHz in non-DMA mode), set to 8000
PBP.Func = PlayDac
IF devID >= 4 THEN
PBP.Mode = 2
ELSE
SP.Func = SetIntRateDac
'to play hal.voc using PCSPKR1 (the hi-rez mode) set
'SP.IntRate=8463. This results in an upsample rate of 17045Hz
IF fileSR& < 11025 THEN 'if the recorded sample rate is <11025
SP.IntRate = fileSR& 'according to the VOC or WAVE file hdr
ELSE 'then just go ahead and use that, else
SP.IntRate = 8000 'down sample to 8000 (or closest fit)
END IF
stat = RUCKDAC(SP)
IF stat THEN
PRINT "Unexpected error at SetIntRateDac, stat:"; stat
END
END IF
PBP.Mode = 1
END IF
IF LP.XMMflag = 0 THEN
PBP.XMMhandle = 0
PBP.LoadPtrOff = LP.LoadPtrOff
PBP.LoadPtrSeg = LP.LoadPtrSeg
ELSE
PBP.XMMhandle = LP.XMMhandle
PBP.LoadPtrOff = 0
PBP.LoadPtrSeg = 0
IF PBP.Mode < 2 THEN PRINT "Loading into XMS requires DMA mode.": END
END IF
stat = RUCKDAC(PBP)
IF stat = 0 THEN
'Playing in the background, wait until done or key pressed.
'To check if data done playing, read directly into DAC data segment
'and check to word at offset +10. Checking just the byte will do.
DEF SEG = IP.InfoPtrSeg
bp = IP.InfoPtrOff
actualSR& = 256& * PEEK(bp + 25) + PEEK(bp + 24)
IF actualSR& < 0 THEN actualSR& = actualSR& + 65536
usedK = 256 * PEEK(bp + 23) + PEEK(bp + 22)
DOSleftK = 256 * PEEK(bp + 17) + PEEK(bp + 16)
XMSleftK = 256 * PEEK(bp + 19) + PEEK(bp + 18)
PRINT " Device ID:"; devID
PRINT " Play rate:"; actualSR&; "Hz"
IF LP.XMMflag = 0 THEN
PRINT " Memory type: DOS"
PRINT "K bytes left:"; DOSleftK
PRINT "K bytes used:"; usedK
PRINT "Load address: "; RIGHT$("000" + HEX$(LP.LoadPtrSeg), 4) + ":" + RIGHT$("000" + HEX$(LP.LoadPtrOff), 4)
ELSE
PRINT " Memory type: XMS"
PRINT "K bytes left:"; XMSleftK
PRINT "K bytes used:"; usedK
PRINT " XMS handle:"; LP.XMMhandle
END IF
PRINT "Current byte: ";
CurrRow = CSRLIN
CurrCol = POS(0)
byte& = 0&
DO
DacIsDone = PEEK(bp + 10)
'do something to demonstate playback is a background operation
'here we just get the current byte position and print if not 0
LOCATE CurrRow, CurrCol
GDP.Func = GetBytePosDac
nix = RUCKDAC(GDP)
IF GDP.BytePos <> 0 THEN byte& = GDP.BytePos
PRINT RIGHT$("000000" + HEX$(byte&), 7)
LOOP UNTIL (DacIsDone <> 0) OR LEN(INKEY$)
DEF SEG
'end play
XP.Func = EndDac
stat = RUCKDAC(XP)
'release memory used by LoadDac (ExitDac would do that, too)
DP.Func = DeallocDac
IF LP.XMMflag = 0 THEN
DP.HandSeg = LP.LoadPtrSeg
DP.TypeFlag = 0
ELSE
DP.HandSeg = LP.XMMhandle
DP.TypeFlag = 1
END IF
stat = RUCKDAC(DP)
ELSE
PRINT "Play of "; filename$; "failed, stat:"; stat
END IF
ELSE
PRINT "Load of "; filename$; "failed, stat:"; stat
END IF
ELSE
PRINT "InitDevice failed, stat:"; stat
END IF
'shut down RUCKDAC and end program
XP.Func = ExitDac
nix = RUCKDAC(XP)
PRINT " Done, stat:"; stat
nix& = SETMEM(700000) 'return to QB environment any previous release
END
FUNCTION InitDevice (device, SIP AS SysInfoPackTYPE, IP AS InitPackTYPE)
'Initialize RUCKDAC and device and register ExitDac with _atexit
'The IP.port for devices 0 and 3 are set to 0 for low-rez mode, or their
'repective actual ports for hi-rez mode (&H42 and &H388)
DIM XP AS XitPackTYPE 'local use for AtExitDac
IP.Func = InitDac
IP.DeviceID = device
SELECT CASE device
CASE 0: IP.IOport = 0: IP.IRQline = SIP.D0IRQ: IP.DMAch = SIP.D0DMA
CASE 1: IP.IOport = SIP.D1port: IP.IRQline = SIP.D1IRQ: IP.DMAch = SIP.D1DMA
CASE 2: IP.IOport = SIP.D2port: IP.IRQline = SIP.D2IRQ: IP.DMAch = SIP.D2DMA
CASE 3: IP.IOport = 0: IP.IRQline = SIP.D3IRQ: IP.DMAch = SIP.D3DMA
CASE 4: IP.IOport = SIP.D4port: IP.IRQline = SIP.D4IRQ: IP.DMAch = SIP.D4DMA
CASE 5: IP.IOport = SIP.D5port: IP.IRQline = SIP.D5IRQ: IP.DMAch = SIP.D5DMA
END SELECT
stat = RUCKDAC(IP)
IF stat = 0 THEN
'register ExitDac and notify if failure occured, non-fatal and unlikely
XP.Func = AtExitDac
stat2 = RUCKDAC(XP)
IF stat2 THEN INPUT "AtExitDac failed, press ENTER to continue", a$
END IF
InitDevice = stat
END FUNCTION
FUNCTION PickDevice (SIP AS SysInfoPackTYPE, XMSflag)
'RUCKDAC SysInfoDac lib routine called to find available devices
'user prompted which device to use (0-5), -1 means no valid selection
'if XMSflag = 1 on return, user selected XMS load of data
DIM device AS INTEGER
device = -1
XMSflag = 0
SIP.Func = SysInfoDac
stat = RUCKDAC(SIP)
IF stat = 0 THEN
'list devices that are available
PRINT
PRINT "0. End program"
PRINT "1. PC speaker at port 42h"
IF SIP.Device1 THEN PRINT "2. LPT-DAC on LPT1, port "; HEX$(SIP.D1port); "h"
IF SIP.Device2 THEN PRINT "3. Disney Sound System port "; HEX$(SIP.D2port); "h"
PRINT
IF SIP.Device3 THEN PRINT "4. AdLib Music Synthesizer Card, port 388h"
IF SIP.Device4 THEN PRINT "5. Sound Blaster, port "; HEX$(SIP.D4port); "h, IRQ"; SIP.D4IRQ; "and DMA 1"
IF SIP.Device5 THEN PRINT "6. Sound Blaster Pro, port "; HEX$(SIP.D5port); "h, IRQ"; SIP.D5IRQ; "and DMA"; SIP.D5DMA
PRINT
IF SIP.Device4 THEN PRINT "7. Sound Blaster as 5 but use XMS (if applicable)"
IF SIP.Device5 THEN PRINT "8. Sound Blaster Pro as 6 but use XMS (if applicable)"
PRINT
INPUT "Selection: ", device
device = device - 1
'ensure device selected is available
SELECT CASE device
CASE 0
CASE 1: IF SIP.Device1 = 0 THEN device = -1
CASE 2: IF SIP.Device2 = 0 THEN device = -1
CASE 3: IF SIP.Device3 = 0 THEN device = -1
CASE 4: IF SIP.Device4 = 0 THEN device = -1
CASE 5: IF SIP.Device5 = 0 THEN device = -1
CASE 6: IF SIP.Device4 = 0 THEN device = -1 ELSE device = 4: XMSflag = 1
CASE 7: IF SIP.Device5 = 0 THEN device = -1 ELSE device = 5: XMSflag = 1
CASE ELSE
device = -1
END SELECT
END IF
PickDevice = device
END FUNCTION