BBS: Inland Empire Archive Date: 11-30-92 (21:15) Number: 375 From: RICH GELDREICH Refer#: NONE To: ALL Recvd: NO Subj: Mod Player/3 Conf: (2) Quik_Bas
'<<Part 3 Starts Here>>
'Store the channel in an expanded format for ease of processing.
POKE C, sample
POKE C + 1, period \ 256
POKE C + 2, period AND 255
POKE C + 3, effect
POKE C + 4, operand
C = C + 5
NEXT
'Fill in the pattern's segment in the position table.
FOR d = 0 TO 127:IF PatternSegment(d)=A THEN PatternSegment(d)=B
NEXT
NEXT
'=====================================================================
'Load the samples.
FOR A = 0 TO S.Max - 1
LOCATE , 1: PRINT USING "Loading Sample ## "; A + 1;
d& = S.Length(A): IF d& < 0 THEN d& = d& + 65536
'Allocate 1024 bytes more than needed for mixer runoff.
d& = d& + 1024
IF d& > 65530 THEN ExitWithError "Sample Too Large"
B = Alloc(d& \ 16 + 1) 'Allocate memory for the sample.
S.Segment(A) = B
'Load the sample
CPU.ax = &H3F00
CPU.bx = FILEATTR(1, 2)
CPU.ds = B: CPU.dx = 0
CPU.cx = S.Length(A)
CALL interruptx(&H21, CPU, CPU)
IF (CPU.Flags AND 1) THEN ExitWithError "Error Loading Sample"
DEF SEG = B
A& = S.Length(A): IF A& < 0 THEN A& = A& + 65536
'Divide each byte of the sample by 4 for mixing. A lookup table is
'used because QB doesn't support signed bytes.
FOR B& = 0 TO A& - 1
POKE B&, Scale8to6(PEEK(B&))
NEXT
'Clear the end of the sample for mixer runoff.
FOR A& = A& TO A& + 1023
POKE A&, 0
NEXT
NEXT
'=====================================================================
LOCATE ,1:PRINT SPACE$(40);
IntRate = 11000 'Interrupt speed, in samples per second.
'Figure out how many samples per 1/50th of a second.
IntsPerClick = IntRate \ 50
'Precalculate a step for each period. The constant &H369040 is from the
'Amiga, it is scaled up by 256 (&h100) so floating point math can be
'eliminated.
K& = &H36904000 \ IntRate
FOR A = 20 TO 1023
A& = K& \ A
PeriodHigh(A) = A& \ 256
PeriodLow(A) = CINT(A&) AND 255
NEXT
'Precalculate the volume lookup tables. Enables the mixer to adjust the
'volume of a sample with slow multiples and divides.
FOR A = 0 TO 63
FOR B = -128 TO -1
C = (B * A) \ 64: IF C < 0 THEN C = C + 256
VolumeTable(A, B + 256) = C
NEXT
FOR B = 0 TO 127
VolumeTable(A, B) = (B * A) \ 64
NEXT
NEXT
'Make all channels inactive, and enable them.
FOR A = 0 TO 3: C.InactiveFlag(A) = True: ChannelOn(A)=True:NEXT
BufferOffset = 512 'Current mixing offset.
T.Tempo = 6 'Default tempo is 6/50th of a second.
T.ClicksLeft = 6 'Clicks left before a line.
T.Pos = 0 'Lines left before a new pattern.
GOSUB StartNewPattern
GOSUB DoLine
DEF SEG=&H0
'Save old interrupt 8 handler.
CPU.ax = &H3508:CALL interruptx(&H21, CPU, CPU)
Old8.Offset = CPU.bx:Old8.Segment = CPU.es
'<<-Continued On Next Message->>
--- MsgToss 2.0b
* Origin: Computer Co-Op - Voorhees, NJ | Ted Hare (1:266/29)

Books at Amazon:
Back to BASIC: The History, Corruption, and Future of the Language
Hackers: Heroes of the Computer Revolution (including Tiny BASIC)
Go to: The Story of the Math Majors, Bridge Players, Engineers, Chess Wizards, Scientists and Iconoclasts who were the Hero Programmers of the Software Revolution
The Advent of the Algorithm: The Idea that Rules the World
Moths in the Machine: The Power and Perils of Programming
Mastering Visual Basic .NET