home *** CD-ROM | disk | FTP | other *** search
- ' **********************************************************************
- ' ** Program: ADLPLAY.BAS **
- ' ** Type : Main Program **
- ' ** Author : Joseph Scally **
- ' ** Date : June 89 **
- ' ** Purpose: Play ADLIB MUSIC CARD .ROL FILES AND DISPLAY **
- ' ** STATISTICS. **
- ' **********************************************************************
-
- REM $INCLUDE: 'Mstruct.h'
- REM $INCLUDE: 'Sound.h'
- DEFINT A-Z
- DIM SHARED INSTRUM(MAXPARAMETERS) 'Holds Instrument Parameters
- DIM SHARED DirEntry$(255, 4) 'Directory Info For Display
- DIM Items$(55) 'Retains Instruments used for
- 'Display Purposes
-
- OpenScreen
-
- top:
- Iptr% = 0
- IECount = 0
- Path$ = "c:\music\*.rol"
- GetDirData Path$, DirEntry$(), 64, EntryCount%
- ShowDir 5, 4, 0, 0, 6, 1, 0, 17, DirEntry$(), Reply%, "N"
- Path$ = "c:\music\"
- Initialize
- SetMode PERCUSSIVE
- ROLFile = FREEFILE
- OPEN Path$ + DirEntry$(Reply%, 0) FOR BINARY AS ROLFile
- GET ROLFile, 1, Mh
- Tempo Mh.Tempo
- '=================== Set Tempo Events ==================
- FOR TE = 1 TO Mh.TEvents
- GET ROLFile, , TempoEvent
- Soundcard fSDSetTempo, (Mh.Tempo * TempoEvent.Tmultiplier), TempoEvent.TimeEvent, Mh.TicksPerBeat, NULL, NULL
- NEXT TE
- '========================================================
-
- FOR voice% = 0 TO MAXVOICES
- GET ROLFile, , VoiceHeader
- SetVoice voice%
- VHD = VoiceHeader.Vduration
- DO WHILE VHD > 0
- GET ROLFile, , Pnote
- LDuration = Pnote.Duration
- Dduration = Pnote.Duration
- IF Pnote.Note = NULL THEN
- Dduration = NULL
- END IF
- Pnote.Note = Pnote.Note - NOTEOFFSET
- PlayNote Pnote.Note, Dduration, Mh.TicksPerBeat, LDuration, Mh.TicksPerBeat
- VHD = VHD - Pnote.Duration
- LOOP
- '=========== Set Instrument Events =====================================
- GET ROLFile, , Af 'This Af stuff is necessary because
- 'I have to dump 15 unused bytes every
- 'So often.
-
- GET ROLFile, , NuminstruEvents
- FOR II = 1 TO NuminstruEvents.NumEvents
- GET ROLFile, , InstrumentEvent
- Setinstrument INSTRUM%(), InstrumentEvent.InstrumentName, InstrumentEvent.TimeInTicks, Mh.TicksPerBeat, Iptr%
- Iptr% = Iptr% + PARAMETERS
- ' **** Save instrument names for later display *****
- Newins$ = UCASE$(StripCString$(InstrumentEvent.InstrumentName))
- Items$(IECount) = STR$(voice%) + SPACE$(8 - (LEN(STR$(voice%)))) + Newins$ + SPACE$(10 - LEN(Newins$)) + STR$(InstrumentEvent.TimeInTicks)
- IECount = IECount + 1
- NEXT
- '========================================================================
-
- '========== Set Volume Events ===========================================
- GET ROLFile, , Af
- GET ROLFile, , NumVolEvents
- FOR VI = 1 TO NumVolEvents.NumEvents
- GET ROLFile, , VolumeEvent
- Soundcard 8, (255 * VolumeEvent.VolMultiplier), 255, VolumeEvent.TimeEvent, Mh.TicksPerBeat, 0
- NEXT
- '==========================================================================
-
- '========== Set Pitch Events ===============================================
- GET ROLFile, , Af
- GET ROLFile, , NumPitchEvents
- FOR Pitch = 1 TO NumPitchEvents.NumEvents
- GET ROLFile, , PitchEvent
- Soundcard FSDSETPITCH, 0, (PitchEvent.VolMultiplier * 100), 98, PitchEvent.TimeEvent, Mh.TicksPerBeat
- NEXT
- '============================================================================
- NEXT voice%
- CLOSE ROLFile
- COLOR 0, 6
- '============================================================================
- 'Put Some Stats on the Screen...More to come later
- LOCATE 6, 28
- PRINT "Basic Tempo "; Mh.Tempo
- LOCATE , 28
- PRINT "Time Events "; Mh.TEvents
- LOCATE , 28
- PRINT "Pitch Events "; NumPitchEvents.NumEvents
- LOCATE , 28
- PRINT "Volume Events "; NumVolEvents.NumEvents
- LOCATE , 28
- PRINT "Instrum Events "; IECount%
- LOCATE , 28
- PRINT "Ticks per Beat "; Mh.TicksPerBeat
- LOCATE 6, 55
- FOR Sins = 0 TO 16
- LOCATE , 55
- PRINT Items$(Sins)
- NEXT
- StartSong
-
- 'Low Level Call to Sound Driver. When AX = 0
- 'The song is over.
-
- OutRegs.ax = 1 'Force it to make one loop
- DO WHILE OutRegs.ax 'While AX <> 0
- InRegs.si = fSDGetState 'Call Function fSDGetState = 4
- 'Function in SI
- INTERRUPT &H65, InRegs, OutRegs 'Int 65H = Sound Driver.
- LOOP
- GOTO top
-
- DEFSNG A-Z
- SUB Initialize
- ' ******************************************************************
- ' ** This Routine Performs 3 functions. It Call function 0 to **
- ' ** Initialize The Driver, Starts The Relative Time Clock and **
- ' ** Sets the mode to Percussive which is used most of the time **
- ' ** Throughout these routines you will see "NULL" I defined this **
- ' ** to show where the value sent to the interface is meaningless **
- ' ******************************************************************
-
- Soundcard FSDINIT, NULL, NULL, NULL, NULL, NULL
- StartTime
- SetMode PERCUSSIVE
- END SUB
-
- DEFINT A-Z
- 'Set up the opening screen
- SUB OpenScreen STATIC
- CLS
- SetBack 176, 6 ' ***** Library Routine
- COLOR 14, 6
- LOCATE 1, 1
- PRINT SPACE$(80);
- LOCATE 2, 1
- PRINT " AdLib Player / Analyzer Ver 1.0 J. Scally June 89 "
- Makbox 5, 52, 0, 6, 25, 17, 0 ' ***** Library Routine
- Makbox 5, 24, 0, 6, 26, 17, 0
- LOCATE 5, 53
- PRINT "[Voice#]-[Instrum]-[Tick]"
- LOCATE 5, 32
- PRINT "[Statistics]"
-
- END SUB
-
- DEFSNG A-Z
- SUB PlayNote (Note%, Duration%, Dlay%, AfterH%, AfterL%)
- s0% = FSDPLAYNOTEDEL
- Soundcard s0%, Note%, Duration%, Dlay%, AfterH%, AfterL%
- END SUB
-
- DEFINT A-Z
- ' *****************************************************************
- ' ** This Routine Fills The screen Instantly With Char% in Color **
- ' ** Attr%. **
- ' *****************************************************************
- SUB SetBack (Char%, Attr%)
- Routine$ = "Setback"
- CLS
- InRegs.ax = &H900 + Char%
- InRegs.bx = Attr%
- InRegs.cx = &H7D0
- INTERRUPT &H10, InRegs, OutRegs
- END SUB
-
- '*******************************************************************
- '** This Routine Passes a Far Pointer to instrument parameters. **
- '** Since This can also represent a change of instruments at **
- '** a future time as specified in num/den, the array must remain **
- '** valid. Since you can't dim on the fly, or if someone knows of **
- '** a technique to do it I would love to here it, I used a single **
- '** table to hold all of the parameters. Believe me it's not as **
- '** bad as it sounds. **
- '*******************************************************************
- '
- SUB Setinstrument (ARRAY(), InsName$, num, den, ptr)
-
- InsFile = FREEFILE
- FileName$ = "c:\music\ins\" + StripCString$(InsName$) + ".ins"
- OPEN FileName$ FOR BINARY AS InsFile
- FOR i = 1 TO PARAMETERS
- GET InsFile, , ARRAY(i + ptr)
- NEXT i
- CLOSE InsFile
- Soundcard FSDSETTIMBRE, VARPTR(ARRAY(2 + ptr)), VARSEG(ARRAY(2 + ptr)), num, den, NULL
- 'Note in .Ins Files the first 2 bytes are not paramaters hence 2+ Ptr
- END SUB
-
- SUB SetMode (Mode%)
- 'Set Mode to PERCUSSIVE or MELODIC
- Soundcard FSDSETMODE, Mode, NULL, NULL, NULL, NULL
- END SUB
-
- DEFSNG A-Z
- SUB SetVoice (voice%)
- 'SET active Voice ( 0 - 11 )
- Soundcard FSDSETACTVOICE, voice%, NULL, NULL, NULL, NULL
- END SUB
-
- SUB StartSong
- 'Start Playing
- Soundcard FSDSETSTATE, CARDON, NULL, NULL, NULL, NULL
- END SUB
-
- SUB StartTime
- 'Called By Initialize and explained there
- Soundcard FSDRELTIMESTART, 0, 1, NULL, NULL, NULL
- END SUB
-
- DEFINT A-Z
- 'This function is necessary because the File Names in the .Ins files
- 'are C or Zero Terminated strings making it impossible to do an
- 'RTRIM$ to tidy up
- '
- FUNCTION StripCString$ (CString$)
- FOR l = 1 TO LEN(CString$)
- ch$ = MID$(CString$, l, 1)
- IF ch$ = CHR$(0) THEN EXIT FOR
- n$ = n$ + ch$ 'Build New String until NULL encountered
- NEXT
- StripCString$ = n$
- END FUNCTION
-
- DEFSNG A-Z
- SUB Tempo (beats)
- 'Set Tempo to Beats per
- Soundcard fSDSetTempo, beats, 0, 1, 0, 0
- END SUB
-
-