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