Mod Player/3

 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)
Outer Court
Echo Basic Postings

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