Metropoli BBS
VIEWER: x03_71.bas MODE: TEXT (ASCII)
DECLARE FUNCTION InitDevice% (device%, SIP AS ANY, IP AS ANY)
DECLARE FUNCTION PickDevice% (SIP AS ANY, XMSflag%)

REM $INCLUDE: 'RUCKDAC.BI7'

'--------------------------------------
'SEE X03.BAS FOR QUICKBASIC 4.5 EXAMPLE
'--------------------------------------

'X03_71.BAS - record digital data and playback
'
'31-Jan-93 -chh
'C>bc X03_71 /o;
'C>link X03_71,X03_71.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 SPP AS SetProPackTYPE
DIM PBP AS PlaybackPackTYPE
DIM RP AS RecordPackTYPE
DIM GDP AS GetDataPackTYPE
DIM DP AS DeallocPackTYPE
DIM XP AS XitPackTYPE

CLS
PRINT "X03_71.BAS - RUCKUS-DAC record and save of a digital 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
   
   'see how much memory is available to record in

   DEF SEG = IP.InfoPtrSeg
   bp = IP.InfoPtrOff

   DOSleftK = 256 * PEEK(bp + 17) + PEEK(bp + 16)
   XMSleftK = 256 * PEEK(bp + 19) + PEEK(bp + 18)

   RecSeconds = 5
   RecRate = 12000

   'select source input

   SPP.Func = SetSourceSBP
   SPP.SourceIn = 0     'mic
   stat = RUCKDAC(SPP)

   PRINT "   Device ID:"; devID
   PRINT " Record from: Mic"
   PRINT " Record time:"; RecSeconds; "secs"
   PRINT " Record rate:"; RecRate; "Hz"

   IF XMSflag = 0 THEN
      PRINT " Memory type: DOS"
      PRINT "K bytes left:"; DOSleftK
   ELSE
      PRINT " Memory type: XMS"
      PRINT "K bytes left:"; XMSleftK
   END IF
   PRINT

   'prepare for record (5 seconds at 12000 Hz sample rate)

   RP.Func = RecordDac
   RP.SampleRate = RecRate
   RP.XMMhandle = XMSflag   'if -1 auto-alloc an XMS handle else use DOS
   RP.RecordPtrOff = 0
   RP.RecordPtrSeg = 0
   RP.RecordBytes = 1& * RecSeconds * RecRate
   RP.StereoFlag = 0        'recording from mic is mono

   INPUT "Press Enter to begin 5-second record...", a$

   stat = RUCKDAC(RP)

   'wait until the 5-second recording is done

   DO
      DacIsDone = PEEK(bp + 10)
   LOOP UNTIL DacIsDone

   INPUT "Press Enter to playback recording", a$

   PBP.Func = PlayDac
   PBP.Mode = 2
   IF XMSflag = 0 THEN
      PBP.XMMhandle = 0
      PBP.LoadPtrOff = RP.RecordPtrOff
      PBP.LoadPtrSeg = RP.RecordPtrSeg
   ELSE
      PBP.XMMhandle = RP.XMMhandle
      PBP.LoadPtrOff = 0
      PBP.LoadPtrSeg = 0
   END IF
   stat = RUCKDAC(PBP)

   DO
      DacIsDone = PEEK(bp + 10)
   LOOP UNTIL DacIsDone
   DEF SEG

   'end play

   XP.Func = EndDac
   stat = RUCKDAC(XP)

   'release memory used by RecordDac (ExitDac would do that, too)

   DP.Func = DeallocDac
   IF XMSflag = 0 THEN
      DP.HandSeg = RP.RecordPtrSeg
      DP.TypeFlag = 0
   ELSE
      DP.HandSeg = RP.XMMhandle
      DP.TypeFlag = 1
   END IF
   stat = RUCKDAC(DP)

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 for save of record

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"
   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 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

[ RETURN TO DIRECTORY ]