home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
QBAS
/
RUKQ10.ZIP
/
X02.BAS
< prev
next >
Wrap
BASIC Source File
|
1993-02-15
|
9KB
|
278 lines
DECLARE FUNCTION InitDevice% (device%, SIP AS ANY, IP AS ANY)
DECLARE FUNCTION PickDevice% (SIP AS ANY, HighRate%)
REM $INCLUDE: 'RUCKDAC.BI'
'---------------------------------------
'SEE X02_71.BAS FOR BASIC7/VBDOS EXAMPLE
'---------------------------------------
'X02.BAS - load and play mod data file from DOS memory
'
'31-Jan-93 -chh
'C>bc X02 /o;
'C>link X02,X02.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 SMP AS SetModPackTYPE
DIM PBP AS PlaybackPackTYPE
DIM XP AS XitPackTYPE
CLS
PRINT "X02.BAS - RUCKUS-DAC play of MOD 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 = ExitMod '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, HighRate)'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 " MOD filename: ", filename$
PRINT "Playback rate: ( 5000 to "; HighRate; ")";
LOCATE , 16
INPUT "", SampleRate
IF SampleRate < 5000 THEN SampleRate = 5000
IF SampleRate > HighRate THEN SampleRate = HighRate
filename$ = filename$ + CHR$(0) 'DOS requires ASCIIZ name
LP.Func = LoadMod
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 = 0 'load into DOS
stat = RUCKDAC(LP)
IF stat = 0 THEN
'data is loaded, set up play parameters
IF devID = 5 THEN 'just a quick bump of the Pro's out volumes
SPP.Func = SetVolMainSBP
SPP.Volume = &HF0F
stat = RUCKDAC(SPP)
SPP.Func = SetVolVocSBP
V = &HF0F
stat = RUCKDAC(SPP) 'see RUCKUS-MIDI for AdLib/FM volume adjust
END IF
SMP.VolCh1 = 255
SMP.VolCh2 = 255
SMP.VolCh3 = 255
SMP.VolCh4 = 255
SMP.Func = SetVolumeMod
stat = RUCKDAC(SMP)
IF devID < 5 THEN SMP.Stereo = 0 ELSE SMP.Stereo = 1
SMP.Func = SetStereoMod
stat = RUCKDAC(SMP)
SMP.IntRate = SampleRate 'IntRate and SliceAdj set with SetIntRateMod
'The SBPro doubles the sample rate when doing stereo output so
'here we double the requested rate to rate needed by SBPRO. This
'should be done _AFTER_ the SetStereoMod call above.
IF SMP.Stereo THEN 'this routine converts sample rates >32K
t& = 2& * SampleRate 'to a signed integer value
IF t& > 32767 THEN t& = t& - 65536
SMP.IntRate = t&
END IF
SMP.SliceAdj = 1 'fill DMA buffer 1 byte at a time (to 4K)
SMP.Func = SetIntRateMod 'error checking typically should always
stat = RUCKDAC(SMP) 'be performed but not here for clarity
''SMP.FastMode = 0 'on slow CPUs (XTs) set this to 1
''SMP.Func = SetFastMod 'and call SetFastMod function
''stat = RUCKDAC(SMP)
'if device is a Sound Blaster, use DMA+FG, else timer-0 FG
PBP.Func = PlayMod
IF devID < 4 THEN PBP.Mode = 0 ELSE PBP.Mode = 2
'for timer-0 background play set PBP.Mode = 1 and for DMA background
'play set PBP.Mode = 3 -- you must also poll dac@endmod in the
'RUCKUS-DAC data area (offset +14) and wait until it is non-zero
'to determine if mod playback has completed
'for complete compatibilty mod play is done as a foreground task
'in this example
PRINT "Playing as a foreground ";
IF devID >= 4 THEN PRINT "DMA"; ELSE PRINT "TIMER-0";
PRINT " task ";
IF devID = 5 THEN PRINT "in ((STEREO)) ";
PRINT "at"; SampleRate; "Hz mix rate"
PRINT
PRINT "Press CTRL-ALT to end or wait until tune is over."
'note that the PC speaker playback may sound better if the
'keyboard pause button is activated, try it
PBP.XMMhandle = 0
'Note that PBP.LoadPtrOff/Seg is not used with mod playback since
'only one mod can be in memory at a time
PBP.BufferSize = 4096 'each DMA buffer (2) is this size
stat = RUCKDAC(PBP) 'and allocated for SBs only (2048-64K)
IF stat = 0 THEN
'Playing in the foreground, wait until done or Ctrl-Alt pressed.
'Won't get here until CTRL-ALT is pressed or end of tune
'end play
XP.Func = EndMod
stat = RUCKDAC(XP)
'to release memory used by LoadMod use ExitMod
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 = ExitMod
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 ExitMod with _atexit
DIM XP AS XitPackTYPE 'local use for AtExitMod
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 ExitMod and notify if failure occured, non-fatal and unlikely
XP.Func = AtExitMod
stat2 = RUCKDAC(XP)
IF stat2 THEN INPUT "AtExitMod failed, press ENTER to continue", a$
END IF
InitDevice = stat
END FUNCTION
FUNCTION PickDevice (SIP AS SysInfoPackTYPE, HighRate)
'RUCKDAC SysInfoDac lib routine called to find available devices
'user prompted which device to use (0-5), -1 means no valid selection
'HighRate returned which is effective top-end of device
DIM device AS INTEGER
device = -1
HighRate = 5000
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 ((STEREO)), port "; HEX$(SIP.D5port); "h, IRQ"; SIP.D5IRQ; "and DMA"; SIP.D5DMA
PRINT
INPUT "Selection: ", device
device = device - 1
'ensure device selected is available
SELECT CASE device
CASE 0: HighRate = 18000
CASE 1: IF SIP.Device1 = 0 THEN device = -1 ELSE HighRate = 23000
CASE 2: IF SIP.Device2 = 0 THEN device = -1 ELSE HighRate = 7000
CASE 3: IF SIP.Device3 = 0 THEN device = -1 ELSE HighRate = 12000
CASE 4: IF SIP.Device4 = 0 THEN device = -1 ELSE HighRate = 23000
CASE 5: IF SIP.Device5 = 0 THEN device = -1 ELSE HighRate = 22750 'stereo
CASE ELSE
device = -1
END SELECT
END IF
PickDevice = device
END FUNCTION