home *** CD-ROM | disk | FTP | other *** search
- 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
-
-