QB64 Phoenix Edition
QB64-PE v4's new 4-voice sound generator - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: Official Links (https://qb64phoenix.com/forum/forumdisplay.php?fid=16)
+--- Forum: Learning Resources and Archives (https://qb64phoenix.com/forum/forumdisplay.php?fid=13)
+--- Thread: QB64-PE v4's new 4-voice sound generator (/showthread.php?tid=3291)



QB64-PE v4's new 4-voice sound generator - a740g - 12-17-2024

As many of you have noticed, QB64-PE v4.0.0 brings exciting new retro audio capabilities! Here's a quick look at the updated commands:

Code: (Select All)
SOUND frequency!, duration![, volume!][, panPosition!][, waveform&][, waveformParameters!][, voice&]
SOUND WAIT
SOUND RESUME
PLAY mmlString1$[, mmlString2$][, mmlString3$][, mmlString4$]
remaining# = PLAY(voice&)
_WAVE voice&, waveDefinition%%([index&])[, frameCount&]

With these features, we can now play retro music using 4 simultaneous channels (a.k.a. voices). Each voice can have its own waveform, volume, and pan position, allowing for rich, layered audio playback.

The notes can be programmed in two main ways: 
  1. Using the SOUND command, combined with SOUND WAIT and SOUND RESUME for synchronization between voices.
  2. Using the PLAY command, where each voice can be controlled with its own MML string.

In v4, the QB64-PE MML syntax has been extended to support all the new features. Much of the design draws inspiration from the SOUND and PLAY capabilities of Amiga Basic and Advanced BASIC (for the Tandy 1000 and IBM PCjr systems). This means many classic BASIC programs using SOUND and PLAY can run in QB64-PE with minimal or no modifications.

The purpose of this post is to showcase what’s possible with these new features. 

I’m no musician by any stretch of the imagination. But I do understand the math (well, mostly!), and I’ve been able to port a few forgotten and abandoned gems from Amiga Basic and BASICA into QB64-PE. Below are a few examples of these ports. I’ll continue to share more as I complete them.

If you’ve created something cool using these new audio features, feel free to post and share it here!

[Image: Screenshot-2024-12-18-044813.png]

Code: (Select All)
' Music - AmigaBasic Music/Graphic-Demo --- 20. July 1985
DEFLNG A-Z

CONST VOLUME! = 0.25!

DIM F#(88), CF(19), CT#(19)

GOSUB InitSound
GOSUB InitGraphics

DO
    SOUND RESUME
    RESTORE Song
    GOSUB PlaySong

    ' This ensures all voices have played completely before playing the song again
    WHILE PLAY(0) > 0 _ORELSE PLAY(1) > 0 _ORELSE PLAY(2) > 0 _ORELSE PLAY(3) > 0
        IF _KEYHIT = 27 THEN END
        _LIMIT 60
    WEND
LOOP

InitGraphics:
SCREEN 12
_TITLE "AmigaBasic Music/Graphic Demo (QB64-PE port by a740g)"
iDraw = 30
iErase = 0
ON TIMER(1) GOSUB TimeSlice
TIMER ON
RETURN

TimeSlice:
FOR linestep = 1 TO 15
    DrawLine iDraw, 1
    DrawLine iErase, 0
    _LIMIT 60
NEXT linestep
RETURN

PlaySong:
' Array VO contains the base octave for a voice.
FOR v = 0 TO 3
    READ VO(v)
    VO(v) = 12 * VO(v) + 3
NEXT v

DO
    SOUND WAIT
    FOR v = 0 TO 3
        t# = VT#(v)
        Fi = -1
        READ p$
        IF p$ = "x" THEN RETURN
        FOR I = 1 TO LEN(p$)
            Ci = INSTR(C$, MID$(p$, I, 1))
            IF Ci <= 8 THEN
                IF Fi >= 0 THEN SOUND F#(Fi), t#, VOLUME, , , , v: t# = VT#(v)
                IF Ci = 8 THEN Fi = 0 ELSE Fi = CF(Ci) + VO(v)
            ELSEIF Ci < 11 THEN '# or -
                Fi = Fi + CF(Ci)
            ELSEIF Ci < 17 THEN '1 through 8
                t# = CT#(Ci)
            ELSEIF Ci < 19 THEN '< or >
                VO(v) = VO(v) + CF(Ci)
            ELSE 'ln
                I = I + 1
                Ci = INSTR(C$, MID$(p$, I, 1))
                VT#(v) = CT#(Ci)
                IF Fi < 0 THEN t# = VT#(v)
            END IF
        NEXT I
        IF Fi >= 0 THEN SOUND F#(Fi), t#, VOLUME, , , , v
    NEXT v
    SOUND RESUME
    IF _KEYHIT = 27 THEN END
    _LIMIT 60
LOOP

InitSound:
' F#() contains frequencies of the chromatic scale.
' Note A in octave 0 = F#(12) = 55 Hz.
Log2of27.5# = LOG(27.5#) / LOG(2#)
FOR x = 1 TO 88
    F#(x) = 2 ^ (Log2of27.5# + x / 12#)
NEXT x

' Create the waveform of tones,
' determines timbre.
DIM Timbre(255) AS _BYTE
FOR I = 0 TO 255
    READ Timbre(I)
NEXT I

' The following DATA rows were created using the following formula.
' Reading from these DATAs is faster than calculating the sine 1024 times.
'  K# = 2 * 3.14159265/256
'  FOR I = 0 TO 255
'    Timbre(I) = 31 * (SIN(I * K#) + SIN(2 * I * K#) + SIN(3 * I * K#) + SIN( 4 * I * K#))
'  NEXT I
DATA 0,8,15,23,30,37,44,51,57,63,69,74,79,83,87,91
DATA 93,96,98,99,100,100,100,99,98,97,95,92,89,86,83,79
DATA 75,71,66,62,57,52,48,43,39,34,30,25,21,18,14,11
DATA 8,5,3,0,-1,-3,-4,-5,-5,-6,-6,-5,-5,-4,-3,-1
DATA 0,2,3,5,7,9,11,13,15,17,18,20,21,23,24,25
DATA 26,26,27,27,27,27,27,26,25,24,23,22,20,18,17,15
DATA 13,11,9,7,5,3,1,-1,-3,-5,-6,-8,-9,-10,-11,-12
DATA -12,-13,-13,-13,-13,-13,-12,-11,-11,-10,-8,-7,-6,-4,-3,-2
DATA 0,2,3,4,6,7,8,10,11,11,12,13,13,13,13,13
DATA 12,12,11,10,9,8,6,5,3,1,-1,-3,-5,-7,-9,-11
DATA -13,-15,-17,-18,-20,-22,-23,-24,-25,-26,-27,-27,-27,-27,-27,-26
DATA -26,-25,-24,-23,-21,-20,-18,-17,-15,-13,-11,-9,-7,-5,-3,-2
DATA 0,1,3,4,5,5,6,6,5,5,4,3,1,0,-3,-5
DATA -8,-11,-14,-18,-21,-25,-30,-34,-39,-43,-48,-52,-57,-62,-66,-71
DATA -75,-79,-83,-86,-89,-92,-95,-97,-98,-99,-100,-100,-100,-99,-98,-96
DATA -93,-91,-87,-83,-79,-74,-69,-63,-57,-51,-44,-37,-30,-23,-15,-8

' Set AMIGA PAULA like panning (well mostly)
SOUND 0, 0, , -0.75!, 10, , 0 ' pan left
SOUND 0, 0, , 0.75!, 10, , 1 ' pan right
SOUND 0, 0, , 0.75!, 10, , 2 ' pan right
SOUND 0, 0, , -0.75!, 10, , 3 ' pan left

_WAVE 0, Timbre()
_WAVE 1, Timbre()
_WAVE 2, Timbre()
_WAVE 3, Timbre()

' Array CF maps MML commands to frequency indices.
C$ = "cdefgabp#-123468<>l"
FOR I = 1 TO 19
    READ CF(I)
NEXT I
DATA 0,2,4,5,7,9,11,0,1,-1,0,0,0,0,0,0,-12,12,0

' Array CT# assigns note lengths to MML commands.
FOR I = 1 TO 18
    READ CT#(I)
NEXT I
' MML commands p1,p2,p3,p4,p6,p8 correspond to pause times 36.4 ... 4.55 units
DATA 0,0,0,0,0,0,0,0,0,0,36.4,18.2,12.133333,9.1,6.0666667,4.55,0,0,0
RETURN


' The music is written in special commands (MML), but as per the Wiki page
' below MML not fully implemented here, missing o, v and t commands:
' https://en.wikipedia.org/wiki/Music_Macro_Language#Modern_MML

' The first 4 numbers are the base octaves (0-7) for each voice.
' ln    - sets note length for the following notes of this voice:
'          l1 = whole note, l2 = half note, l4 = quarter note, etc.
' >      - selects the next higher octave for this voice.
' <      - selects the next lower octave for this voice.
' a to g - play the respective note,
'          # (sharp) or - (flat) may follow directly.
'          It may also follow a number to determine the duration of this note.
' pn    - make a rest/pause length as for note length (ln) above.

Song:
DATA 1,3,3,3
DATA l2g>ge,l2p2de,l2p2l6g3f#g3a,l6p6gab>dcced
DATA <b>e<e,ge<b,b3ab3ge3d,dgf#gd<bgab
DATA ab>c,a>dc,e3f#g3de3<b,>cdedc<babg
DATA df#d,c<a>f#,a3>da3ga3f#,f#gadf#a>c<ba
DATA gec,g<g>e,d3f#g3f#g3a,bgab>dcced
DATA <b>ed,ge<b,b3ab3ge3g,dgf#gd<bgab
DATA cc#d,>ced,a3f#g3e<a3>c,e>dc<bagdgf#
DATA <gp3>g6d3<b6,dp2b3g6,<b3>gb3>dg3d,gb>dgd<bgb>d
DATA g>f#e,d<gg,l2<g1g,l2<b1>c
DATA f#ed,agf#,a1b,d1d
DATA ef#g,gag,bag,c1<b
DATA dp3d6d3d6,f#a3a6>d3d6,al6d3ef#3g,l6adef#aga>c<b
DATA <d>p3d6d3d6,f#3a6f#3d6<a3>d6,a3>c<a3f#d3f#,>c<af#df#a>c<ba
DATA gf#e,dde,g3dg3f#g3a,bgab>dcced
DATA b<b>e,gd<b,b3ag3f#e3g,dgf#gd<bgab
DATA cd<d,l4>c<a>d<b>c<al2,a3gf#3ga3c,e>dc<bagdgf#
DATA g>ge,b>de,<b3>dg3f#g3a,gbab>dcced
DATA <b>e<e,ge<b,b3ab3ge3d,dgf#gd<bgab
DATA ab>c,a>dc,e3f#g3de3<b,>cdedc<babg
DATA df#d,c<a>f#,a3>f#a3ga3f#,f#gadf#a>c<ba
DATA gec,g<g>e,d3f#g3f#g3a,bgab>dcced
DATA <b>ed,ge<b,b3ab3ge3g,dgf#gd<bgab
DATA cc#d,>ced,a3f#g3e<a3>c,e>dc<bagdgf#
DATA <g>f#e,d<gg,l2b1>c,l2g1g
DATA f#ed,agf#,d1d,a1b
DATA ef#g,gag,c1<b,bag
DATA dp3d6d3d6,f#l6a3a>d3d,al6d3ef#3g,l6ddef#aga>c<b
DATA <dp3>d6d3d6,f#3af#3d<a3>d,a3>c<a3f#d3f#,>c<af#df#a>c<ba
DATA gf#e,l2dde,l2b1>c,bgab>dcced
DATA b<b>e,gd<b,d1<b,dgf#gd<bgab
DATA cd<d,l4>c<a>d<b>c<a,a4b8>c8<ba,e>dc<bagdgf#
DATA g>ge,l2b>de,l6g3dg3f#g3a,gbab>dcced
DATA <b>e<e,ge<b,b3ab3ge3d,dgf#gd<bgab
DATA ab>c,a>dc,e3f#g3de3<b,>cdedc<babg
DATA df#d,c<a>f#,a3>da3ga3f#,f#gadf#a>c<ba
DATA gec,g<g>e,d3f#g3f#g3a,bgab>dcced
DATA <b>ed,ge<b,b3ab3ge3g,dgf#gd<bgab
DATA cc#d,>ced,a3f#g3e<a3>c,e>dc<bagdgf#
DATA <gp3>g6f#3e6,dp3g6d3e6,<b3>gb3>dg3<g,gb>dgd<bdb>c#
DATA dc<b,f#dd,l2a1b,d<def#ag#g#ba
DATA a>a4g4f4e4,e<a>a,>c1c,a>c<b>c<aecde
DATA d<b>e,aag#,<bb4>c8d8<b,f>dcd<bg#ef#g#
DATA a>fd,e<a>f#,al6a3g#a3b,a>c<b>ceddfe
DATA cfe,afc,>c3<b>c3<af3a,eag#aec<ab>c
DATA dd#e,df#e,a3g#a3f#<b3>d,fedc<baeag#
DATA <a>ab,c<ag,>l2c1d,a>ceap3l2d
DATA >c<ae,>cag,e1e,l6ecdegfgb-a
DATA fdg,df#g,dd4e8f8d,a>c<b>c<afdef
DATA cec,geg,l6c3<g>c3<ge3d,egfgec<gab-
DATA fdg,fag,c3ef3ab3>d,a>c<b>c<afdef
DATA cp3c6<b3>d6,gp3d6d3d6,c3<g>c3<a>d3<f#,ecdegf#gba
DATA <g>ge,dde,l2b1>c,bgab>dcced
DATA <b>e<e,ge<b,d1d,dgf#gd<bgab
DATA ab>c,a>dc,c<b1,>cdedc<babg
DATA dp3d6d3d6,cl6<a3a>d3d,l6a3c#d3ef#3g,f#def#aga>c<b
DATA <dp3>d6d3d6,f#3af#3d<a3>d,a3>c<a3f#d3f#,>c<af#df#a>c<ba
DATA gf#e,l2dde,l2b1>c,bgab>dcced
DATA b<b>e,gd<b,d1<b,dgf#gd<bgab
DATA cd<d,l4>c<a>d<b>c<a,a4b8>c8<ba,e>dc<bagdgf#
DATA g1g2,l2gp3>g6d3g6,gl6<b3>dg3d,gb>dgd<bgb>a
DATA g1g2,dp3g6e3c6,<b3g>d3b>c2,fd<bgb>ded<a
DATA g1g2,<ap3>d6<b3>e6,c3<ab2b3g,f#a>cd<bgegb
DATA g1g2,<e3a6f#3>a6f#3d6,a2a3f#d3f#,>c<af#df#a>c<ba
DATA g>ge,dde,g3dg3f#g3a,bgab>dcced
DATA <b>e<e,ge<b,b3ab3ge3d,dgf#gd<bgab
DATA ab>c,a>d<c,e3f#g3de3<b,>cdedc<babg
DATA df#d,c<a>f#,a3>da3ga3f#,f#gadf#a>c<ba
DATA gec,g<g>e,d3f#g3f#g3a,bgab>dcced
DATA <b>ed,ge<d,b3ab3ge3g,dgf#gd<bgab
DATA cc#d,d1d2,a3f#g3e<a3>c,e>dc<bagdgf#
DATA <g1g2,p2,<b1b2,g1g2
DATA p1,p1,p1,p1
DATA x

SUB DrawLine (iStep, hue) STATIC
    winWidth = _WIDTH
    winHeight = _HEIGHT
    iStep = (iStep + 1) MOD 60
    side = iStep \ 15
    I! = (iStep MOD 15) / 15!
    i1! = 1! - I!

    ON side + 1 GOSUB dl_top, dl_left, dl_bottom, dl_right

    EXIT SUB

    dl_top:
    LINE (winWidth * I!, 0)-(winWidth, winHeight * I!), hue
    RETURN

    dl_left:
    LINE (winWidth, winHeight * I!)-(winWidth * i1!, winHeight), hue
    RETURN

    dl_bottom:
    LINE (winWidth * i1!, winHeight)-(0, winHeight * i1!), hue
    RETURN

    dl_right:
    LINE (0, winHeight * i1!)-(winWidth * I!, 0), hue
    RETURN
END SUB

[Image: Screenshot-2024-12-18-044902.png]

Code: (Select All)
'-----------------------------------------------------------------------------------------------------------------------
' QB64-PE v4.0.0 Multi-voice PLAY Demo by a740g
'-----------------------------------------------------------------------------------------------------------------------

$IF VERSION < 4.0.0 THEN
    $ERROR This requires the latest version of QB64-PE from https://github.com/QB64-Phoenix-Edition/QB64pe/releases/latest
$END IF

_DEFINE A-Z AS LONG
OPTION _EXPLICIT

CONST APP_NAME = "Multi-voice PLAY Demo"
CONST LOOPS = 3

_TITLE APP_NAME

DIM AS STRING CH0Verse_1, CH0Verse_2, CH1Verse_1, CH1Verse_2, CH2Verse_1, CH2Verse_2, CH2Verse_3, CH3Verse_1
DIM AS STRING Channel_0, Channel_1, Channel_2, Channel_3, Caption
DIM c AS LONG

DO
    DO
        CLS
        PRINT
        PRINT "Enter number for a tune to play."
        PRINT
        PRINT "1. Demo 1 by J. Baker"
        PRINT "2. Demo 2 by Wilbert Brants"
        PRINT "3. Demo 3 by Wilbert Brants"
        PRINT "4. Demo 4 by J. Baker"
        PRINT "5. Demo 5 by Wilbert Brants"
        PRINT
        INPUT "Your choice (0 exits)"; c
    LOOP WHILE c < 0 OR c > 7

    SELECT CASE c
        CASE 1
            Caption = "Demo 1 by J. Baker"

            144
            CH0Verse_1 = "t144 l4 q0 w1 o0 ^75_100 v32 w1 ^75_100 o0 dd2 w8 ^100_80 o4 c"
            CH0Verse_2 = "w4 ^75_100 o0 d2 w8 ^100_80 o4 cd"

            CH1Verse_1 = "t144 q0 w1 o2 /1^100_99 v31 l1 gba /1\20^25_79 l4 gab2"
            CH1Verse_2 = "v40 /9^100\1 l1 gba \2 l4 gab2"

            CH2Verse_1 = "t144 l4 w2 o3 q20 v33 r1r1"
            CH2Verse_2 = "cd>d<e"
            CH2Verse_3 = "cd>d2<"

            CH3Verse_1 = "t144 q0 w9 y15 o3 _100 v29 l8 d"

            Channel_0 = RepeatVerse(CH0Verse_1 + CH0Verse_1 + CH0Verse_1 + CH0Verse_1 + CH0Verse_1 + CH0Verse_1 + CH0Verse_1 + CH0Verse_1 + CH0Verse_2 + CH0Verse_2 + CH0Verse_2 + CH0Verse_2, LOOPS)
            Channel_1 = RepeatVerse(CH1Verse_1 + CH1Verse_1 + CH1Verse_2, LOOPS)
            Channel_2 = RepeatVerse(CH2Verse_1 + CH2Verse_1 + CH2Verse_1 + CH2Verse_1 + CH2Verse_2 + CH2Verse_2 + CH2Verse_2 + CH2Verse_3, LOOPS)
            Channel_3 = RepeatVerse(CH3Verse_1, 96 * LOOPS)

        CASE 2
            Caption = "Demo 2 by Wilbert Brants"

            CH0Verse_1 = "t103 w2 o0 q8 v38 L8 G4B-B-G4B-B-  G4>E-E-<G4>E-E-<  A>CF4<A>CF4<  F4AAGB->D4<"
            CH1Verse_1 = "t103 w1 o1 q2 v33 L8 GB->D4<GB->D4<  GB->E-<B-GB->E-<B-  A>CF4<A>CF4<  FA>C<AGB->D4<"
            CH2Verse_1 = "t103 w1 o3 q1 v35 L4 GG2G8F8 E-E-2E-8D8 CCCD E-2D2"
            CH2Verse_2 = "B-B-2B-8A8 GG2G8F8 CCCD E-2D2"
            CH2Verse_3 = "B-B-2B-8A8 GG2G8F8 ACFA G2D2"

            Channel_0 = CH0Verse_1 + CH0Verse_1 + CH0Verse_1 + CH0Verse_1
            Channel_1 = CH1Verse_1 + CH1Verse_1 + CH1Verse_1 + CH1Verse_1
            Channel_2 = CH2Verse_1 + CH2Verse_2 + CH2Verse_1 + CH2Verse_3
            Channel_3 = _STR_EMPTY

        CASE 3
            Caption = "Demo 3 by Wilbert Brants"

            CH0Verse_1 = "t144 w2 o0 q16 v22 l8 v+cv-ceeg4 v+ f v- faa>cc< v+ c v- ceeg4 v+ f v- faa>cc< ggbb>d4< q8 g4c2"
            CH1Verse_1 = "t144 w1 o1 q2 v20 l4 gec f2a8c8 gec f2a8c8 gbd ec2"
            CH2Verse_1 = "t144 w3 o3 q2 v22 l8 cegceg l4 caf l8 cegceg l4 caf l8 gbdgbd l4 cgg"

            Channel_0 = RepeatVerse(CH0Verse_1, LOOPS)
            Channel_1 = RepeatVerse(CH1Verse_1, LOOPS)
            Channel_2 = RepeatVerse(CH2Verse_1, LOOPS)
            Channel_3 = _STR_EMPTY

        CASE 4
            Caption = "Demo 4 by J. Baker"

            Channel_0 = "t120 w1 o0 q2 v20 l8 <dced> dcge4 l4 q1 <d1> r8 l8 q2 dg l4 q1 <d1> l8 q2 dge q1 <d1> q2 dcdrr v+ <<dd>> v- r"
            Channel_1 = "t120 w1 o1 q1 v21 l8 >dcde< dcde#4 l4 >d1< l8 de l4 >f1 l8 ddfe1< dedfe dd r4"
            Channel_2 = _STR_EMPTY
            Channel_3 = _STR_EMPTY

        CASE 5
            Caption = "Demo 5 by Wilbert Brants"

            CH0Verse_1 = "T103 q16 O0 V22 W2 L4 V+CV-E8E8 <FA> <V+GV-B8B8> CE"
            CH1Verse_1 = "T103 q8 O2 V22 W1 L8 CEG>C< <FA>CF <GB>DG CEG>C<"
            CH2Verse_1 = "T103 q1 O3 v60 W4 L4 CEC<G> CEC2 CEC<G> CE16R16E16R16C2 CEC<G> CEC2 CEC<G> C<G16>R16E16R16C2"

            Channel_0 = RepeatVerse(CH0Verse_1, 4 * LOOPS)
            Channel_1 = RepeatVerse(CH1Verse_1, 4 * LOOPS)
            Channel_2 = RepeatVerse(CH2Verse_1, LOOPS)
            Channel_3 = _STR_EMPTY

        CASE ELSE
            EXIT DO ' Exit program
    END SELECT

    PlayMML Channel_0, Channel_1, Channel_2, Channel_3, Caption
LOOP

SYSTEM

SUB PlayMML (chan0 AS STRING, chan1 AS STRING, chan2 AS STRING, chan3 AS STRING, caption AS STRING)
    PLAY chan0, chan1, chan2, chan3

    PRINT
    PRINT "Playing "; caption; "..."

    DIM curLine AS LONG: curLine = CSRLIN

    DO
        _LIMIT 15

        LOCATE curLine, 1
    LOOP WHILE DisplayVoiceStats

    SLEEP 1
    _KEYCLEAR
END SUB

FUNCTION RepeatVerse$ (verse AS STRING, count AS _UNSIGNED LONG)
    DIM buffer AS STRING

    DIM i AS _UNSIGNED LONG

    WHILE i < count
        buffer = buffer + verse
        i = i + 1
    WEND

    RepeatVerse = buffer
END FUNCTION

FUNCTION DisplayVoiceStats%%
    STATIC voiceTotalTime(0 TO 3) AS DOUBLE

    DIM voiceElapsedTime(0 TO 3) AS DOUBLE
    DIM i AS LONG

    FOR i = 0 TO 3
        voiceElapsedTime(i) = PLAY(i)

        IF voiceElapsedTime(i) > voiceTotalTime(i) THEN
            voiceTotalTime(i) = voiceElapsedTime(i)
        END IF

        PRINT USING "Voice #: ### of ### seconds left"; i; voiceElapsedTime(i); voiceTotalTime(i)
    NEXT i

    DIM playing AS _BYTE: playing = voiceElapsedTime(0) > 0 _ORELSE voiceElapsedTime(1) > 0 _ORELSE voiceElapsedTime(2) > 0 _ORELSE voiceElapsedTime(3) > 0

    IF NOT playing THEN
        FOR i = 0 TO 3
            voiceTotalTime(i) = 0
        NEXT i
    END IF

    DisplayVoiceStats = playing
END FUNCTION



RE: QB64-PE v4's new 4-voice sound generator - Bhsdfa - 12-17-2024

Amazing stuff!  Big Grin


RE: QB64-PE v4's new 4-voice sound generator - a740g - 12-17-2024

Port of BACH.BAS for Tandy 1000 Advanced BASIC. I got rid of all the line numbers and used a lot of modern QB64-PE features. However, the MML is almost untouched.

Warning: Has palette animation.

[Image: Screenshot-2024-12-18-045150.png]

Code: (Select All)
' BACH.BAS Copyright (c) 1987 by Unique Software
' Ported from TANDY 1000 Advanced BASIC to QB64-PE by a740g

_DEFINE A-Z AS LONG
OPTION _EXPLICIT

_TITLE "Trio Sonata No. 1 in E-Flat Allegro"

RESTORE data_bach_bmp
$RESIZE:SMOOTH
SCREEN _LOADIMAGE(Base64_LoadResourceData, 256, "memory, adaptive")

DIM m(0 TO 2) AS STRING

RESTORE data_bach_mml
DO
    READ m(0), m(1), m(2)
    PLAY m(0), m(1), m(2)
LOOP WHILE LEN(m(0)) _ANDALSO LEN(m(1)) _ANDALSO LEN(m(2))

DIM c AS _UNSIGNED LONG

WHILE PLAY(0) > 0 _ORELSE PLAY(1) > 0 _ORELSE PLAY(2) > 0
    c = _PALETTECOLOR(1)
    _PALETTECOLOR 1, _PALETTECOLOR(2)
    _PALETTECOLOR 2, _PALETTECOLOR(3)
    _PALETTECOLOR 3, c

    _LIMIT 10
WEND

SLEEP 1

SYSTEM

data_bach_mml:
DATA "mb","mb","mb"
DATA "v12 t120 o3 e-8 >e-8","v12 t120 o2 p4","v12 t120 o2 e-4"
DATA "o4 <f8 >e-8","o2 p4","o2 e-4"
DATA "o4 <g8 >e-8","o2 p4","o2 p4"
DATA "o4 <a-8 >e-8","o2 p4","o2 c4"
DATA "o4 <b-8 >e-8","o2 p4","o2 c4"
DATA "o4 c8 e-8","o2 p4","o2 p4"
DATA "o4 <b-16 >e-16 d16 c16","o2 p4","o1 g4"
DATA "o4 <b-16 >g16 f16 e-16","o2 p4","o1 a-4"
DATA "o4 d16 c16 <b-16 a-16","o2 p4","o1 b-4"
DATA "o3 g16 a-16 b-16 g16","o2 p4","o1 e-4"
DATA "o3 e-16 g16 b-16 >e-16","o2 p4","o1 g4"
DATA "o4 <f16 a16 >c16 e-16","o2 p4","o1 a4"
DATA "o4 d16 c16 d16 f16","o2 b-8 >b-8","o1 b-4"
DATA "o4 e-16 d16 e-16 g16","o3 c8 b-8","o1 b-4"
DATA "o4 f16 e-16 f16 a-16","o3 d8 b-8","o1 p4"
DATA "o4 g16 f16 g16 b-16","o3 e-8 b-8","o1 b-4"
DATA "o4 d16 c16 d16 b-16","o3 f8 b-8","o1 b-4"
DATA "o4 e-16 d16 e-16 b-16","o3 g8 b-8","o1 p4"
DATA "o4 d8 f8","o3 f16 b-16 a16 g16","o1 b-4"
DATA "o4 b-8 d8","o3 f16 >d16 c16 <b-16","o1 >d4"
DATA "o4 c8 a8","o3 a16 g16 f16 e-16","o2 f4"
DATA "o4 b-8 d8","o3 d16 e-16 f16 d16","o2 b-4"
DATA "o4 f8 d8","o3 <b-16 >d16 f16 b-16","o2 b-4"
DATA "o4 <b-8 >d8","o3 d16 f16 a-16 b-16","o2 p4"
DATA "o4 e-8 p8","o3 g16 f16 g16 b-16","o1 e-8 >e-8"
DATA "o4 e-8 p8","o3 a-16 g16 a-16 >c16","o2 <f8 >e-8"
DATA "o4 e-8 p8","o3 <b-16 a-16 b-16 >d-16","o2 <g8 >e-8"
DATA "o4 e-8 p8","o4 c16 <b-16 >c16 e-16","o2 <a-8 >e-8"
DATA "o4 e-8 p8","o4 <g16 f16 g16 >e-16","o2 <b-8 >e-8"
DATA "o4 e-8 p8","o4 <a-16 g16 a-16 >e-16","o2 c8 e-8"
DATA "o4 p16 e-16 f16 g16","o4 <g8 b-8","o2 <b-8 p8"
DATA "o4 a-16 b-16 >c16 <b-16","o3 >e-8 <g8","o1 >c8 p8"
DATA "o4 a-16 g16 f16 a-16","o3 f8 b-8","o2 d8 p8"
DATA "o4 g8 <b-8","o3 p16 e-16 f16 g16","o2 e-4"
DATA "o3 >c8 <a-8","o3 a-16 b-16 >c16 <b-16","o2 e-4"
DATA "o3 >f4","o3 a-16 g16 f16 a-16","o2 d4"
DATA "o4 p16 a-16 g16 f16","o3 g8 <b-8","o2 e-4"
DATA "o4 e-16 d16 c16 <b-16","o2 >c8 <a-8","o2 a-4"
DATA "o3 a-16 g16 a-16 >f16","o2 >f4","o2 p4"
DATA "o4 <g16 >f16 e-16 d16","o3 p16 a-16 g16 f16","o2 <b4"
DATA "o4 c16 <b-16 a-16 g16","o3 e-16 d16 c16 <b-16","o1 >c4"
DATA "o3 f4","o2 a-16 g16 a-16 >f16","o2 d4"
DATA "o3 p16 a-16 g16 f16","o3 <g16 >f16 e-16 d16","o2 <e-4"
DATA "o3 e-4","o3 c16 <b-16 a-16 g16","o1 a-4"
DATA "o3 p16 d16 e-16 f16","o2 f4","o1 a-4"
DATA "o3 <b8 >d8","o2 p16 a-16 g16 f16","o1 g4"
DATA "o3 g8 b8","o2 e-8 g8","o1 p16 >g16 f16 g16"
DATA "o3 >c8 d8","o2 a8 b8","o2 e-16 f16 d16 e-16"
DATA "o4 e-16 c16 <b16 >c16","o3 c8 p8","o2 c8 e-8"
DATA "o4 <g16 >c16 <b16 >c16","o3 p4","o2 c8 e-8"
DATA "o4 e-16 c16 <b-16 >c16","o3 p4","o2 c8 e-8"
DATA "o4 <a-8 p8","o3 p16 f16 e-16 f16","o2 <f8 >a-8"
DATA "o3 >e-8 p8","o3 c16 f16 e-16 f16","o2 <f8 >a-8"
DATA "o4 e-8 p8","o3 a-16 f16 e-16 f16","o2 <f8 >a-8"
DATA "o4 p16 <b-16 a-16 b-16","o3 d8 p8","o2 <b-8 >d8"
DATA "o3 f16 b-16 a-16 b-16","o3 a-8 p8","o2 <b-8 >d8"
DATA "o3 >d16 <b-16 a-16 b-16","o3 a-8 p8","o2 <b-8 >d8"
DATA "o3 g8 p8","o3 p16 e-16 d-16 e-16","o2 <e-8 >g8"
DATA "o3 >d-8 p8","o3 <b-16 >e-16 d-16 e-16","o2 <e-8 >g8"
DATA "o4 d-8 p8","o3 g16 e-16 d-16 e-16","o2 <e-8 g8"
DATA "o3 p16 a-16 g16 a-16","o3 c16 f16 e16 f16","o1 a-8 >c8"
DATA "o3 f16 a-16 g16 a-16","o3 c16 f16 e16 f16","o2 <a-8 >c8"
DATA "o3 >c16 <a-16 g16 a-16","o3 a-16 f16 e-16 f16","o2 <a-8 >c8"
DATA "o3 f16 b-16 a-16 b-16","o3 d8 f8","o2 <a-8 >d8"
DATA "o3 >d16 <b-16 a-16 b-16","o3 b-4","o2 <a-8 >d8"
DATA "o3 >f16 d16 c16 d16","o3 b-4","o2 <a-8 >d8"
DATA "o4 b-8 g8","o3 p16 <b-16 a-16 b-16","o2 <g8 >e-8"
DATA "o4 e-4","o2 >e-16 <b-16 a-16 b-16","o2 <g8 >e-8"
DATA "o4 e-4","o2 >g16 e-16 d16 e-16","o2 <g8 >e-8"
DATA "o4 p16 d16 c16 <b-16","o3 a16 b-16 a16 g16","o2 <f4"
DATA "o3 a16 b-16 a16 g16","o3 f16 >d16 c16 <b-16","o1 p4"
DATA "o3 f16 >e-16 d16 c16","o3 a16 g16 f16 e-16","o1 p4"
DATA "o3 b-4","o3 d16 c16 d16 f16","o1 b-8 >b-8"
DATA "o3 b-4","o3 e-16 d16 e-16 g16","o2 c8 b-8"
DATA "o3 b-4","o3 f16 e-16 f16 a-16","o2 d8 b-8"
DATA "o3 p16 a16 b-16 >e-16","o3 g16 f16 g16 b-16","o2 e-8 b-8"
DATA "o4 <b-16 a16 b-16 >d16","o3 d16 c16 d16 b-16","o2 f8 b-8"
DATA "o4 c4","o3 e-16 d16 e-16 b-16","o2 g8 b-8"
DATA "o4 p16 g16 f16 e-16","o3 d4","o2 f8 b-8"
DATA "o4 d16 b-16 a16 g16","o3 p16 >d16 c16 <b-16","o2 e-8 b-8"
DATA "o4 f16 e-16 d16 c16","o3 a16 g16 f16 e-16","o2 f8 a8"
DATA "o3 b-8 >f8","o3 d16 b-16 a16 b-16","o1 b-4"
DATA "o4 g8 f8","o3 e-16 b-16 d16 b-16","o1 p4"
DATA "o4 g8 f8","o3 e-16 b-16 c16 b-16","o1 p4"
DATA "o4 f16 b-16 a16 b-16","o3 d8 f8","o1 b-4"
DATA "o4 e-16 b-16 d16 b-16","o3 g8 f8","o1 p4"
DATA "o4 e-16 b-16 c16 b-16","o3 g8 e-8","o1 p4"
DATA "o4 d4","o3 f16 <b-16 >c16 d16","o1 p8 >f8"
DATA "o4 p16 <b-16 >c16 d16","o3 e-4","o2 g8 f8"
DATA "o4 e-16 f16 g16 a16","o3 p16 d16 e-16 c16","o2 g8 e-8"
DATA "o4 b-8 <b-8","o3 f8 d8","o2 d8 g8"
DATA "o3 >c8 p8","o3 e-8 p8","o2 e-8 p8"
DATA "o4 <a4","o3 c4","o2 f4"
DATA "o3 mlb-4","o3 mld4","o1 mlb-4"
DATA "o3 b-4","o3 d4","o1 b-4"
DATA "o3 b-4","o3 d4","o1 b-4"
DATA "","",""

data_bach_bmp:
DATA 65078,2296,-1
DATA "eNrslrV1BEEUwGR29OtwBZcacofX5FXiloy38N+8P2ZmaVnLiubkdHEDAIttOACONuAM2GCfmQuKDTpWrJdrVuP0UpbrNetxEREREfl1bCRsJWwm"
DATA "T3l9aXvYz372e5O3n/3kXdzr3I5bb/19X9p+9rOf/d7m7Wc/eR9bSds+M47U3z60n/3e5O1nP/vZ733Io+PFh7FT2yTf2i8i+GDsZ7+oNjHSrStc"
DATA "2+9VHrXro3wz/RNyqcfXXUldX0/+D/3sFwRAAAEEAUAAAQDU3w/t3QFq7DgQhOG+wX//2y7LUDyaAmOrJ5adVMHOSC0pD394skZKSKvYa1vXvD8k"
DATA "Nr+tqj76M34Hid/C+ZHDzv3+j/v1irm2uf07gFZ3P1v1mf8tv/4crW78nuTX3UoS/QpUNj/Vu093Kv8Kvd1XVfz+qJ8g9JShV9XK/JqiXv1pyJ9f"
DATA "RK5VbX6vx+9pft+MqVRrW81WnZvr9uXjO86PDja24nd2/3Tst3Z1+iR6vTz6PB5Yvdwvfsnj/eIXvz+RnB8B5PxjokcRv1EgfvH7bvjkHxBQ/VUN"
DATA "QG1Vyf0HAGp6Wr3Ki2z22x/0jl702kcOivPsPz+a+kHt99u3fzoIn7gfED+LRS7uJ6X4HYYjP9zPUOMH5X7Ax1YpvMkf95OG+YlWA3orenGr3/5I"
DATA "0P1eke37fwJb8cv+qd1+6DV+VwQr99/NiV/84pfk94+yf/+txC9+AKCOSr1gO38KLdWH+1j1qNzb0PdueMP9B+VPw/gVHBUAH/eqr2xtkKFqvMCv"
DATA "uh+oqhe/aNfvUordxz5ou6v9jRecH9FwwC5vk99bzo8EBlSxz6/M7x37p/8u/ft+ZueDfTm81u/T+ik/lAaE/2Pv9IPqftTcT1jm54Mv//wiP8Fx"
DATA "1Y/yVWAlH3S/eqOfWv0p+NgPAK3QqvH3PzWAV5wfUQVqWczvRIyIOh4EH+Yt50cUqHUYlvyOn1/mftv3T+GkXxG/Q76Fz6+v8dnA8SDv9QPo37yP"
DATA "c9LvxP5LT1lu9Uvil/OjnB9l/z6JX/ziFz9L/JJbzo+SH90/jV/84he/+KG0XllP3bLgO4d9LmhYrT6lz6zy0eeeHxmLOtbzq7HDE5vrLn7gq1Uq"
DATA "gY8++/wIsO1k72EVX47NtYaVsDF8dP/+6dTPkRTozUN0DMZFqeI3+3HBj0v3X5Xy2/xwE8Wumit+8as1vwJwPx/9O35c8VPX/Xz00edH5se1739+"
DATA "ref9/P7z0cefH5lfe3O/siA9nzv//vf0/VPzK8zPKFq63iGbIVvFRl/kpw4q2k0F+Horgj8ZI9mODGZmo+/xA0Ak6vVBjxf7XAB8eS+g+Ohz/Wh+"
DATA "jPmLGmTA9W6/epPfcfb6MfR72/mRPaosXRPs99uzfwq018Vroj35LOfkaoCn+PWs+pWWv9nvb0R88Rv4VfzWAzecH8VvcH4Uv/z8ffzi98wAL/OL"
DATA "Hwo+AMfrDidbyaIJ3rES4EpWAbj3/IgeH+LkSp9rNcv5L0CnBHyiWneeH9kPVG32w4dxyT4Vd75r/9TE1DXQBUCvWPDgg6hJX2HT1LnTzz29N/j8"
DATA "lcfmeHzopF/d7VfHfnXh+m2Busdxn+ZX5VzqWOV+P8AAl3N5MXiv+bmKJii9ssOPT+uyH8AQEDj2q3v9LsT8WPFj7McGv6+dHw39/PKBBT+BKXO/"
DATA "u/ZPAWrZr00HtP6Sn9TNrzT2PD8PwBU/8xfFoh/++ZXnr/XD8imO/AyDergfrPlhufQVBEd/c6rn+7Hih0fXenb9Gb+6028pKF/z48L65lcdgIHf"
DATA "fedHYz/jG/iZhYbND5xXxVv3nwd+/tTMyK9JgdIBfbJaKC/xsyYw9+sTHNCrWO70q1U/rfXUFUD5qbvmVxv8xs/PsOannPGrwkdctHze4/1GfOan"
DATA "Pn20t5Q20+bdd3408ePLfibQhErxUlu+6fePvudXF2J+xQIBwKafvx/4+V6JMvBT6XV+BRcddNVTwLEf2/w8AEtTpwcnxI8v+HEdg61+MHiCZnAR"
DATA "7clOq9nrt5D1DVDfKWb5H1Zv6Lfh94/oWfy/p7Ls1/o197tv/3QGOFhtCxf96iF+up9GBquL1ySUe/2S+MXviX7J3/j9IyB//8NQqoq+kYPaZ/+Y"
DATA "UvzQq/3XjeNnfsA5P3L/eboN4H4qx8/j9xa+J6uRp/rtDUXvesjfPzoI1mOvX/7+R/ziF78bEr/4JT9zfmT3Y+rX9k/jF7/4xe+oHr/4fTU5P9K7"
DATA "3Zeqp97KK36pxy9+8Ytf/IZJVp4rU1d5yS/1+MUvfvGL3yzJf4Ljix4="

' Converts a base64 string to a normal string or binary data
FUNCTION Base64_Decode$ (s AS STRING)
    DIM srcSize AS _UNSIGNED LONG: srcSize = LEN(s)
    DIM buffer AS STRING: buffer = SPACE$((srcSize \ 4) * 3) ' preallocate complete buffer
    DIM j AS _UNSIGNED LONG: j = 1
    DIM AS _UNSIGNED _BYTE index, char1, char2, char3, char4

    DIM i AS _UNSIGNED LONG: FOR i = 1 TO srcSize STEP 4
        index = ASC(s, i): GOSUB find_index: char1 = index
        index = ASC(s, i + 1): GOSUB find_index: char2 = index
        index = ASC(s, i + 2): GOSUB find_index: char3 = index
        index = ASC(s, i + 3): GOSUB find_index: char4 = index

        ASC(buffer, j) = _SHL(char1, 2) OR _SHR(char2, 4)
        j = j + 1
        ASC(buffer, j) = _SHL(char2 AND 15, 4) OR _SHR(char3, 2)
        j = j + 1
        ASC(buffer, j) = _SHL(char3 AND 3, 6) OR char4
        j = j + 1
    NEXT i

    ' Remove padding
    IF RIGHT$(s, 2) = "==" THEN
        buffer = LEFT$(buffer, LEN(buffer) - 2)
    ELSEIF RIGHT$(s, 1) = "=" THEN
        buffer = LEFT$(buffer, LEN(buffer) - 1)
    END IF

    Base64_Decode = buffer
    EXIT FUNCTION

    find_index:
    IF index >= 65 AND index <= 90 THEN
        index = index - 65
    ELSEIF index >= 97 AND index <= 122 THEN
        index = index - 97 + 26
    ELSEIF index >= 48 AND index <= 57 THEN
        index = index - 48 + 52
    ELSEIF index = 43 THEN
        index = 62
    ELSEIF index = 47 THEN
        index = 63
    END IF
    RETURN
END FUNCTION

' Loads a binary file encoded with Bin2Data
' Usage:
'  1. Encode the binary file with Bin2Data
'  2. Include the file or it's contents
'  3. Load the file like so:
'      Restore label_generated_by_bin2data
'      Dim buffer As String
'      buffer = LoadResource  ' buffer will now hold the contents of the file
FUNCTION Base64_LoadResourceData$
    DIM ogSize AS _UNSIGNED LONG, resize AS _UNSIGNED LONG, isComp AS _BYTE
    READ ogSize, resize, isComp ' read the header

    DIM buffer AS STRING: buffer = SPACE$(resize) ' preallocate complete buffer

    ' Read the whole resource data
    DIM i AS _UNSIGNED LONG: DO WHILE i < resize
        DIM chunk AS STRING: READ chunk
        MID$(buffer, i + 1) = chunk
        i = i + LEN(chunk)
    LOOP

    ' Decode the data
    buffer = Base64_Decode(buffer)

    ' Expand the data if needed
    IF isComp THEN buffer = _INFLATE$(buffer, ogSize)

    Base64_LoadResourceData = buffer
END FUNCTION



RE: QB64-PE v4's new 4-voice sound generator - NakedApe - 12-17-2024

Great sounds, a740g! These are like time machines to the 80s.


RE: QB64-PE v4's new 4-voice sound generator - a740g - 12-17-2024

Ok. Here is another one. This one had a bit too much spaghetti. So, I left some of it in there for you guys to enjoy. Nonetheless, it works like a champ.

[Image: Screenshot-2024-12-18-045238.png]

Code: (Select All)
' TWELVE.BAS COPYRIGHT (c) 1987 by Unique Software
' Ported from TANDY 1000 Advanced BASIC to QB64-PE by a740g

_DEFINE A-Z AS LONG
OPTION _EXPLICIT

_TITLE "The Twelve Days of Christmas"

RESTORE data_twelve_bmp
$RESIZE:SMOOTH
SCREEN 7

DIM background AS LONG: background = _LOADIMAGE(Base64_LoadResourceData, 256, "memory")
_PUTIMAGE , background

DIM P(12, 3) AS LONG
DIM AS LONG P, Z, I
DIM M(1 TO 3) AS STRING

FOR Z = 1 TO 13
    PALETTE Z, 2
NEXT Z
PALETTE 5, 12
PALETTE 14, 12
PALETTE 15, 0

RESTORE 1310
FOR Z = 2 TO 12
    FOR I = 0 TO 3
        READ P(Z, I)
    NEXT I
NEXT Z

PLAY "MBV13T120", "MBV11T120", "MBV12T120"

FOR Z = 1 TO 12
    PLAY "O3C8C8", "O3P4", "O3P4": IF Z > 1 THEN GOSUB 7: PALETTE 1, 2
    IF Z = 2 OR Z = 7 THEN PLAY "O3C8C8F8F8F4E8F8", "O2MLF3A3O3MNC3", "O1F1"
    IF Z = 11 THEN PLAY "O3C12C12C12F8F8F4E8F8", "O2MLF3A3O3MNC3", "O1F1"
    IF Z <> 2 AND Z <> 7 AND Z <> 11 THEN PLAY "O3C4F8F8F4E8F8", "O2MLF3A3O3MNC3", "O1F1"
    PLAY "O3G8A8B-8G8A4.", "O2E6B-6O3C6O2F12.A12.O3MNC12.", "O1C2F4."
    ON Z GOTO 1170, 1160, 1150, 1140, 1180, 1190, 1200, 1210, 1220, 1230, 1240, 1250
    1140 GOSUB 7: PALETTE 5, 12: PALETTE 4, 15: PLAY "O4C4O3G8A8B-4", "O2MLG4MNB-4MLE8O3MNC8", "O1MLC2."
    1150 GOSUB 7: PALETTE 4, 2: PALETTE 3, 14: PLAY "O4C4O3MLG8MNA8B-4", "O2MLG4MNB-4MLE8O3MNC8", "O1MLC2."
    1160 GOSUB 7: PALETTE 3, 2: PALETTE 2, 15: PLAY "O4C4O3G8A8B-4A8B-8", "O2MLG4MNB-4MLE4O3MNC4", "O1C1": GOTO 1270
    1170 PLAY "O3B-8", "O3P8", "O3P8": GOTO 1270
    1180 RESTORE 1500: GOTO 1260
    1190 RESTORE 1490: GOTO 1260
    1200 RESTORE 1480: GOTO 1260
    1210 RESTORE 1470: GOTO 1260
    1220 RESTORE 1460: GOTO 1260
    1230 RESTORE 1450: GOTO 1260
    1240 RESTORE 1440: GOTO 1260
    1250 RESTORE 1430
    1260 GOSUB 2

    1270:
    GOSUB 7
    PALETTE 2, 2
    PALETTE 1, 14
    PLAY "O4C4MLD8O3MNB-8A8F8G4", "O2A4B-4O3MLC4O2E12B-12O3MNC12", "O1F2.C4"
    PLAY "O3F2.", "O2MLF6.A6.O3MNC6.", "O1F4C4F4"
NEXT Z

GOSUB 7

SYSTEM

1310 DATA 03,02,02,15,04,02,03,14,05,12,04,15,06,02,05,14,07,02,06,08,08,02,07,15,09,02,08,15,10,02,09,10,11,02,10,10,12,02,11,07,15,15,12,00
1430 DATA "O4C4O3G8A8B-8G8","O2MLG4MNB-4MLE8O3C8","O1C2.",12
1440 DATA "O4C12C12C12O3G8A8B-8G8","O2MLG4MNB-4MLE8O3C8","O1C2.",11
1450 DATA "O4C4O3G8A8B-8G8","O2MLG4MNB-4MLE8O3C8","O1C2.",10
1460 DATA "O4C4O3G8A8B-8G8","O2MLG4MNB-4MLE8O3C8","O1C2.",9
1470 DATA "O4C4O3G8A8B-8G8","O2MLG4MNB-4MLE8O3C8","O1C2.",8
1480 DATA "O4C8C8O3G8A8B-8G8","O2MLG4MNB-4MLE8O3C8","O1C2.",7
1490 DATA "O4C4O3G8A8B-8G8","O2MLG4MNB-4MLE8O3C8","O1C2.",6
1500 DATA "O4C4..D8O3B8O4C4..","O2MLE12..A12..O3MNC12..O2MLF8MNB8MLE12..G12..O3MNC12..","O1A4..G4E4..",5
DATA "O4MLC8O3MNB-8A8G8F4","O2MLF6.A6.O3C6.","O1F2.",4
DATA "O3B-4D4F4","O2F6.B-6.O3D6.","O1B-2.",3
DATA "O3MLG8MNF8E8D8C4A8B-8","O2F4MNB4MLE12G12P4","O1G2C4O2P4",2
DATA "","","",0

2:
READ M(1), M(2), M(3), P
IF LEN(M(1)) = 0 _ANDALSO LEN(M(2)) = 0 _ANDALSO LEN(M(3)) = 0 THEN
    RETURN
END IF

4:
IF PLAY(0) > 0 _ORELSE PLAY(1) > 0 _ORELSE PLAY(2) > 0 THEN
    _LIMIT 60
    GOTO 4
ELSE
    PALETTE P(P, 0), P(P, 1)
    PALETTE P(P, 2), P(P, 3)
    PLAY M(1), M(2), M(3)
    GOTO 2
END IF

7:
WHILE PLAY(0) > 0 _ORELSE PLAY(1) > 0 _ORELSE PLAY(2) > 0
    _LIMIT 60
WEND

RETURN

data_twelve_bmp:
DATA 32118,5640,-1
DATA "eNo0g7EBAUAAxAItjGEL6JW3yncWujWArQJIksNxnPgwgA2wm8ADmDDnz2X5fc13QOOHghQ1JlpqVKikmvgxsa3tk3gyVEIABkPw/c04mo87G4+t"
DATA "dfsIFJU2BsDtbh898DA5olZ693Gdym78WQnY3ozpi3sZLvp9fT4AGInZn5UTTAbTF/cyXiSl8j66/rNvtL69r3//oByJrs2YH/wPJaXyvlltfoHy"
DATA "/4/0DM+ndQ98SQoxfTFLKn/YInLU5RnsBdiCAGnxeDrFMOHYl2ZtUoPXXTbwHUwbnIFUWuZk502bGXA4kgVx3IID2D8Ssume+UzBABwNAXDA3TfY"
DATA "BRgcAhjcYYDAQXM0AA8CCzQWwDHMJ7h79X7+PB5rc91desflkk5++VdVvaqKWnHC6hvUSfLTmFo2//+7AVuBMD8yrR/vzw3wVL+6fT99en399HIf"
DATA "Hjf2c7FbzVAL2+gl7Qed/WIjpeq1zVsFXraXO/G4Gz75bVvPC5NpMp4M6Bd3k1+KqaYzX4V9B2CPfN+3STZp7z+VJX3fXtHvTjwALR9hZTuOYcLU"
DATA "fYcP+X6E7048vBMC3oKSsJIt8K4VwI/x7Z7UWLhXr/m6m84CSr0cVrWAav3X8nXwgXfSU0tHatztXQP2N+nWytLKZ77zeahemKa4sFPo10QtfPfj"
DATA "2cOz+laW8djK5zB1qEKROvNpF1elrAUkpf8vYH+7NXzHa81Xl8m99vmq+LrUTc6nk06S3t6+IXt13/1gthCw4Rtlvin46jI5DPmCx4ST8yn4Mh6A"
DATA "Sb4P7y4Q0GHV8nUprrpM7vfnvXkcn86n4Ht4CxNR2y+VDwFnh1XL103JQgj9yj94zEc+1XyO2oXyIWD+ig4r8zl/O6UpSXKZdCDwPAqniXwyHw5O"
DATA "VK5l8gGY34Owcokl3iVBKJfJIl0XfzPPp5dSOZLS5Hwi/iRNb+UuvhJ4C6yfHVYusXV8wUeZdMoED11JNylfo+A7naSHb45a9XHfIu8ioMOKEntS"
DATA "2FVjxUeZ9GN43DVVfILPUaublstHVxfe+tMlFr7jtdDwSZRJgRM86PcaAdjo56hVj3zLBRzwFhIQgfB1U3gKAS1fzccXGJ2/P1P8HLXIt9wk1XzU"
DATA "i8KXACICLV/hoSt5iQQmn4p+OX3rqF0snwVEjZZP5iMV4YPH3Umqz4+HkI+71klerOE7js6PlKg6USbdTcEDn+R8Iv7ETZw6y+X79ZcioL1lPhF+"
DATA "1F+qTuajm9LTKXj+khS3SM4nbhZRC1+z/70X78vnAih7S6cZG2UpJqpOP9NNZdbdKXgGCXM+WT9H7Xz72O637rPfvnxBQMGXP6KnKXK31yW56tBN"
DATA "7bJ+O+c3RrxaPxCZ5Bby/ZTv/UwE4q34CDdT8lCC1w/upk7Sifw5DzUf+ll1N/XsL5fyAUiJ7ZHPQ4n59PxM/u60g+fMS6IjLflk/Yha8Nbhw8Mm"
DATA "mWk9vspNa8sXPGe+Ax1puNt8RC3eXcZH/MFn/QLNQ5Nqvstz6AJf5HfRbnDHN8p8CCj4lsUf+YtJJhHNlPkcf5eLksynUUPNV82/DsuPy/lc/xAQ"
DATA "/TiXbg3f5XKhm4JPFR+nrvUjLJFvaf2rF34mCQH7etYN6kPwSS1f6Uj5g36EJe+ILZs/bBkV/RDQs66pc/QpAjDz7eAb9uezhtJR2Wpsf/UgXQXQ"
DATA "JO6mGErQD75DOVjR772E2Rk+zVjNpxZvMaD1I4U9lFg/ClvR7/FRimetnw+dlg+85YDMO+inqZ89lJiaxCR/4duHwA/khiyf+VbEA5AOGj51hY+h"
DATA "pEnMot+/79JwHkr6IjjyOSzXxAOw5uumudTndzn+qsQM/fJP9uWpfeb7VoLB8jks18MDkA6VEqGEj8KNg/Wz47J+8FWO7EvEjmFXh6XxVu2gIekm"
DATA "NkDBZ/0qPvTby/W7YxSn7Scs18ZzB/3HE/LRwWcMhTX6PeYAFI00I3tfSmbcQ1i6Lq8I6A4avtAiQ+Q0mNTqJyk/E420w+E2MzeJsFwXD0D4gifR"
DATA "ccLXWT8Sk/hTlrY00mQTJ87xGvLxNcBb1eigWZ6wkYJvgo/ErPU7BblnScbiqxyWBN/aAnrld7zCp0cl60dimk/+Dza5Rb7gwzaQD0CWJ2xUskY4"
DATA "j6pDYhrrueabGz7wtlFQ8HFIJFk/JyZpezgUvq7lA28TE2b94JP14x+ymY+RvZ/FVnCszo3NBJQ3UuQyViUm+l0KHyO74himZm4pHwImb6RELmNO"
DATA "zBnT5fIcfPwAQpPPTZvJh4AsT9CCXK5N7vQOmY9COAUfM4iOEYSbyOchhuWJ2EiRy5zF/l1Ihe85+Jy/NZ9G5GP0Ws0YAhHQfKFFJ2sJAAKGfNIB"
DATA "/eArppG1dTW6rsoXxvLEG175LGaKdKen4NPv2omRnRnp4Z8s82j5GP0XW7OE4BO9QfVZDJ87PfhCP0Z25ksdgw88Vieb8KniS4mz2A6k0xMW8cfI"
DATA "Dp8U92zN90Ed/tVILkfdxX/xJzo9pmIPwuaDkOhbm4/4w4Qp5PNZIplBt9l7QfK3SxPShlk+x98WfJ77gWr4+q/sBdGPch6p7ZmoWT2tY8azgPhQ"
DATA "qeGbvTeyfoXPwyfyrV7/TPXRAuLDksucxcFHhTGf4y9N6Alg/V6rWrXJqna7mY9jlR5As/nQr2kemq3V+oAKPjP4LEbAH+D7sG3/jJnPxrHF6cZe"
DATA "0HzuDs23ff/c8PksFr2z94I84Dftlm/D/rTh4ywGL+OwF7R+/Kbt4XNTvArQPsR8FouR13vBd/Qrl4dP420MiA8JroqPkdd7QW9ndPLwuTmeqwM+"
DATA "JLg4i6O44FLvBWs+D5+uUFsD4kOCK+z4dxRn+Byb9fbIw+f2eD7e8KF/uhxp4AsfGMN/7ZwJaivPEcZLzR42GRuDHxCauoHwCQy6wINcwJAL+Qhm"
DATA "x5cKAZJzxDU/+qMZPammo9ECf5eeoMfyQz9/vUzX0qPoEfp9f/p8BTwA1YcK6Hd8rS7tX330aPr4/Rp4VDl/fYeynsWnJBFLCnx99IjPn8+fG6Uu"
DATA "EvD9K+xdfC1HBB91aYoe/W58K8hXRsLR6Id/GdtnbVmCT9GjviwMvIvy0cNfXUEM+4PgC/1aXVqLHoV+Etguzwdgx0esV/qpLk18lF2duTAX92rm"
DATA "ZRqCpbib+fQq5pXrzv72+evr+x/isD+d+vA/Mf6oSyN6hH4r8Pm3mXupgeLVq4eVqe3T9eEiSMKBWC91BqEfdWkq/uz02/5BE5SYAMy5DoVsroiH"
DATA "cPEyN1TTpXP9p5TS57c4rZo3UkXM36hLIxKMfpSFHeAFRy3W+Cy+Mr4Tvmq9TT8u4jOrLr7K9Z/C+SEO/hHW5q8iwejHzdkO7YDvmH4FcPGF0uKr"
DATA "0/UhH4Or50O/kA9C9KMs7Bhf6fmCDLGsnOQrJr7C9cxAONQvJq8KoDX+GH3Hxl/xaEs/3kf1K9VDNfF5ma7tQEDEkX+JfrH4yWVCP/hOLGYlWdnE"
DATA "5+7x9jr1rzttn/evBNT9Q/rBFz8jdCD9tivwxdtq9KiF0DSsWI3rmd+vghOJhX5Rl8aSSCS48c2P5oFUcz4MvppuFRQ3gY8vx7+ETwcciB6JT3Gw"
DATA "2T2BRsoX/SqkAl9S8tT0k38pPi2Jyo7QveIbt8KQM2ArfEnJGOLIv5TLq5BRN/7yE74poVXr9bOMz/jy3n8L/T4aH5Fg9NuO8+WW8W16Pun38iL9"
DATA "gg+z6/Bp/MGHOMR6ZcEXyGwRxDc8/s4vuTP0I26LkXljSexsez2+Pu7ZJifyseWLzJuWxIgywCdAu7hJkj7aoVNZkdlqS6LirMkR30tFUqMlBnIJ"
DATA "H/CxJCrOunbU1NkhpoDgwcB6PGXe2pLYYh3bdfG0z08Aw8SAfGS2Plhyus9WxdM+cAGgGJAPvocjfJZZXYcPQHy2GR/Gkjjns6vxAUhYAAa5k136"
DATA "axZntevxAUjU6r8w4E6q1DTkU5z1BJ67szn3aFe9z+Yz8cGAO6kCBJbu7mDf9phiLj65i6l+/FWZgH+HDwadykI+Qr/EWZFvgM9rShiMGSBBn8YQ"
DATA "hCpAIPRLrFx4KV/3ys3zGx1RIRim+duVmhL6/SdxVnr3KJ+z53SHzX0RX6mZgPC9BwN8rQChuSbPTw9v0/izU3xZ5Oz4zMoAg09rXLiTKkCA7/3p"
DATA "aYK3hO9SsUCWwH8HA+5kCEhwja3hfv9G767OlxsCgkfncuqT6NDE97Tf7+nd9fs3NwSErz+1yFah8b0h3/UNATHwWP9oT/rtJz67oenZFbiTMXmR"
DATA "b3Ld92HId1MBuVkEH8cAqJr9x0PMjr1dyLwuFpCbRcxf8YV+0+S4lHzuJal5koDKE8biHGsL+sF3kWqXfMrLldVijClwH/q9IR9e8635OD+hwD3I"
DATA "a1f7OXmaWqwQFs+ecqc4IFEDBe5bXHegWs095yskajArXmrGZ+pf5IOw6TdU7VeW9arrZXWAj/MTGPpdgs+Drza+Umo2/hSn5PwEJv0WVvsppbCQ"
DATA "r8LHf0n4rMXJH+Bjp4V+yJfPX1Iyi8ZfcVcfl1qz9U9xStX/s9NCvz7qtRZfkJXGV9Kn8MH3G77WueJb+OS8wmupfu4ejVNBmP7pddJvPv62+q18"
DATA "2YAvByyhW/OiopEBbg39dH5CT22Ij7DRmZvwLTMBbvo6BAL37O+Ftx6fwTcEyGTtos7BF/oJbzU+7h+j21Mmg85PEImJ/PoXA2A9PvCWm/SDr080"
DATA "fIWBd0Pr9Iv5O+P7vDWe8tTcf4OPqatnstiNTfrBJ28EvtvK1+//Xjg/IW/ka6rh+bRbm/YvH5G5bN5ISBdmd2CMuOAL+aD9Bd/W7sHaIwaIOHOl"
DATA "5yLegW1Cv+/EFrku+O6ldzWH4wEc5LrgWyafex2NSRacDqfCLq6TbGvwvcBHrFJ86eNJCre24nwj33/y5lvNW4UOjeKeZKujg3lAyIwvf7xL5S0+"
DATA "O81X+SVHQ1U45dl++F4aH67vNuUrFgIs5vNardYBPvmNm4lv1r/544VK46m2iA/XEj6vjc9zPuvPNcj1HeIjLrCcrxbpV3O+TX+uQa5vzlfFV61w"
DATA "ffzrqvV87vB58Wz8wad8G/qZLR1/M76S8BWv7sUdSHOvyfydnWtAv63Z8vnb8dWET78S6rE6ZeufBCTXhX6GLVv/GH9WWN5ODdc6VIwv95YGuS70"
DATA "02fr3T/4A0YPC2DReOrWv+1m/eMyHjbIJ8Dge3+bRGT+ro6HenW0HKDje5I3l+DdJolENrCPlttdGCxkA8WHevcESDYQvjvCUw/v4cMboXfvCnAf"
DATA "Jv3uB48efiIbiH707n0Bot3rtVaWUgd7GL7Hx911Bl+xMYvuDds9TjIulK/KO8Jor8/HFEHAwNvZMoOmZ7oUnzW+1+9/u+0qfPlRs2EBX8N26ehr"
DATA "h0r0Nlxu2lX9nB01GzHUC0snbxCoXq2Wjs8qfMfwZkfNRgWUfHm/jvMpw1XKWXwPC/m617zG7jhff1TKh2cI8m2X8GnsqaauzGs8Mz6ro3zIt4zv"
DATA "wEr32XH9THxefLCDY36cUUk8wNcWgCELvh3ypXx+Bh/v8TX6cff4ujQu6Xn/5kfNBm3zSvde0pi3/yff4xX4iJrCN2qPzN6LGjE4+MY7eJfId3M/"
DATA "5IfvHGN1+eE7o4Pth+8MO697f/g29hfj+x+mDUsq"

' Converts a base64 string to a normal string or binary data
FUNCTION Base64_Decode$ (s AS STRING)
    DIM srcSize AS _UNSIGNED LONG: srcSize = LEN(s)
    DIM buffer AS STRING: buffer = SPACE$((srcSize \ 4) * 3) ' preallocate complete buffer
    DIM j AS _UNSIGNED LONG: j = 1
    DIM AS _UNSIGNED _BYTE index, char1, char2, char3, char4

    DIM i AS _UNSIGNED LONG: FOR i = 1 TO srcSize STEP 4
        index = ASC(s, i): GOSUB find_index: char1 = index
        index = ASC(s, i + 1): GOSUB find_index: char2 = index
        index = ASC(s, i + 2): GOSUB find_index: char3 = index
        index = ASC(s, i + 3): GOSUB find_index: char4 = index

        ASC(buffer, j) = _SHL(char1, 2) OR _SHR(char2, 4)
        j = j + 1
        ASC(buffer, j) = _SHL(char2 AND 15, 4) OR _SHR(char3, 2)
        j = j + 1
        ASC(buffer, j) = _SHL(char3 AND 3, 6) OR char4
        j = j + 1
    NEXT i

    ' Remove padding
    IF RIGHT$(s, 2) = "==" THEN
        buffer = LEFT$(buffer, LEN(buffer) - 2)
    ELSEIF RIGHT$(s, 1) = "=" THEN
        buffer = LEFT$(buffer, LEN(buffer) - 1)
    END IF

    Base64_Decode = buffer
    EXIT FUNCTION

    find_index:
    IF index >= 65 AND index <= 90 THEN
        index = index - 65
    ELSEIF index >= 97 AND index <= 122 THEN
        index = index - 97 + 26
    ELSEIF index >= 48 AND index <= 57 THEN
        index = index - 48 + 52
    ELSEIF index = 43 THEN
        index = 62
    ELSEIF index = 47 THEN
        index = 63
    END IF
    RETURN
END FUNCTION

' Loads a binary file encoded with Bin2Data
' Usage:
'  1. Encode the binary file with Bin2Data
'  2. Include the file or it's contents
'  3. Load the file like so:
'      Restore label_generated_by_bin2data
'      Dim buffer As String
'      buffer = LoadResource  ' buffer will now hold the contents of the file
FUNCTION Base64_LoadResourceData$
    DIM ogSize AS _UNSIGNED LONG, resize AS _UNSIGNED LONG, isComp AS _BYTE
    READ ogSize, resize, isComp ' read the header

    DIM buffer AS STRING: buffer = SPACE$(resize) ' preallocate complete buffer

    ' Read the whole resource data
    DIM i AS _UNSIGNED LONG: DO WHILE i < resize
        DIM chunk AS STRING: READ chunk
        MID$(buffer, i + 1) = chunk
        i = i + LEN(chunk)
    LOOP

    ' Decode the data
    buffer = Base64_Decode(buffer)

    ' Expand the data if needed
    IF isComp THEN buffer = _INFLATE$(buffer, ogSize)

    Base64_LoadResourceData = buffer
END FUNCTION



RE: QB64-PE v4's new 4-voice sound generator - a740g - 12-18-2024

Another one. This one is almost untouched with line numbers, GOTOs and other weird stuff.

[Image: Screenshot-2024-12-18-065945.png]

Code: (Select All)
' MEDLEY.BAS Copyright (c) 1987 by Unique Software
_TITLE "Christmas Medley"
1 GOTO 8
2 READ L$, L, M1$, M2$, M3$, P
3 IF P = 1 THEN C = C + 1: C = C - (C = 8) + 12 * (C > 13): COLOR C, 0
4 IF P = 2 THEN PALETTE 14, 14
5 IF PLAY(0) > 0 _ORELSE PLAY(1) > 0 _ORELSE PLAY(2) > 0 THEN _LIMIT 60: GOTO 5
6 IF MF = 0 THEN PRINT L$; MID$(CHR$(13), 1, L MOD 2);
7 PLAY M1$, M2$, M3$: GOTO 2
8 DEFINT A-Z: KEY OFF: ON ERROR GOTO 10: LOCATE 1, 1, 1, 0, 7: C = 1
9 WIDTH 80: COLOR 8, 0: CLS: PALETTE 14, 0: COLOR 15, 0: PRINT "            Christmas Medley Copyright (c) 1987 by Unique Software": LOCATE 25, 22: COLOR 14, 0: PRINT "Merry Christmas from Unique Software";: LOCATE 2, 1: VIEW PRINT 2 TO 24: COLOR 1, 0: GOSUB 2
10 IF PLAY(0) > 0 _ORELSE PLAY(1) > 0 _ORELSE PLAY(2) > 0 THEN _LIMIT 60: GOTO 10 ELSE SLEEP 1: SYSTEM
11 DATA "We ",0,"MBV12T120O3 C4","MBV9T120O3 P4","MBV10T120O3 P4",0
12 DATA "wish you a Mer-ry ",0,"O3F4F8G8F8E8","O2MLD6.F6.A6.","O1F2.",0
13 DATA "Christ-mas, We ",0,"O3D4D4D4","O2D6.F6.B-6.","O1B-2.",0
14 DATA "wish you a Mer-ry ",0,"O3G4G8A8G8F8","O2D6.B6.O3MND6.","O1G2.",0
15 DATA "Christ-mas, We ",0,"O3E4C4C4","O2MLC6G6MNB-6P4","O1C2.",0
16 DATA "wish you a Mer-ry ",0,"O3A4A8B-8A8G8","O2MLF6.A6.O3C6.","O1F2.",0
17 DATA "Christ-mas, and a ",0,"O3F4D4C8C8","O2F6A6O3MND6O2MLF12A12O3C12","O1D2F4",0
18 DATA "hap-py New ",0,"O3D4G4E4","O2F6B-6O3MND6O2MLG12B-12O3MNC12","O1B-2O2C4",0
19 DATA "Year!",1,"O3MLF2","O2MLF3A3O3MNC3","O1F2",0
20 DATA "It ",0,"T90O3MNF8","T90O3P8","T90O3P8",1
21 DATA "came up-on the ",0,"O4D4C8MLC8O3MNB-8G8","O2F4F#8MLE-8.MNG8.","O1MLB-2.",0
22 DATA "mid-night clear, That ",0,"O3F4G8F4F8","O2MLD4.MNB-4.","O1MNB-2.",0
23 DATA "glo-rious song of ",0,"O3MLG8MNA8B-8MLB-8O4MNC8D8","O2E-8F8G8MLE8.O3C8.","O1E-4.C4.",0
24 DATA "old, From ",0,"O4MLC4.MNC4O3F8","O2F12.A12.O3C12.O2F12A12O3MNC12O2P8","O1MLF4.MNF4P8",0
25 DATA "an-gels bend-ing ",0,"O4D4O3A8O4MLC8O3MNB-8G8","O2F4F#8MLE-8.MNG8.","O1MLB-2.",0
26 DATA "near the earth to ",0,"O3F4G8F4F8","O2MLD4.B-4.","O1MNB-2.",0
27 DATA "touch their harps of ",0,"O3G4G8MLA8MNG8F8","O2G8.MNB-8.MLF8.O3MNC8.","O1E-4.F4.",0
28 DATA "gold, `Peace ",0,"O3MLB-4.MNB-4O4D8","O2MLD12.E12.B-12.D12E12MNB-12P8","O1MLB-4.MNB-4P8",0
29 DATA "on the earth, good ",0,"O4D4O3D8MLD8MNE8F#8","O2MLD12.F#12.MNA12.F8G8A8","O1D2.",0
30 DATA "will to men, From ",0,"O3G4A8B-4O4D8","O2MLD6.G6.MNB-6.","O1G2.",0
31 DATA "heav'n's all gra-cious ",0,"O4MLC8O3MNB-8A8MLG8MNA8G8","O2A8O3D8MLC8C12.O2B-12.MNE12.","O1C2.",0
32 DATA "King.' The ",0,"O3MLF4.MNF4F8","O2MLF12.A12.O3C12.O2F12A12O3MNC12O2P8","O1MLF4.MNF4P8",0
33 DATA "world in sol-emn ",0,"O4D4O3A8O4MLC8O3MNB-8G8","O2F4F#8MLE-8.MNG8.","O1MLB-2.",0
34 DATA "still-ness lay, To ",0,"O3F4G8F4F8","O2MLD4.MNB-4.","O1MNB-2.",0
35 DATA "hear the an-gels ",0,"O3G4G8MLA8MNG8F8","O2MLG8.MNB-8.MLF8.O3MNC8.","O1E-4.F4.",0
36 DATA "sing.",1,"O3MLB-4.B-4","O2MLD12.F12.B-12.D12F12MNB-12","O1MLB-4.MNB-4",0
37 DATA "O ",0,"T120O3MNB4","T120O3P4","T120O3P4",1
38 DATA "lit-tle town of ",0,"O3B4B4A#4B4","O2MLB4O3MND4MLC#8MNE8O2MLB8O3MND8","O1G1",0
39 DATA "Beth-le-hem, How ",0,"O4D4C4O3E4A4","O2MLG#12B12O3MNF12O2MLA6.O3C6.MNE6.","O1C1",0
40 DATA "still we see thee ",0,"O3G4MLF#8MNG8A4D4","O2B4A8B8MLF#4O3MNC4","O1D1",0
41 DATA "lie! A-",0,"O3B2.B4","O2MLG6.B6.O3MND6.P4","O1G2.P4",0
42 DATA "bove thy deep and",0,"O3B4B4O4E4D4","O2MLG8MNB8MLF8MNA8MLE6G#6B6","O1G4F4E2",0
43 DATA "dream-less sleep, The ",0,"O4D4C4O3E4A4","O2E3A3O3MNC3","O1A2.C4",0
44 DATA "si-lent stars go ",0,"O3G4MLF#8MNG8B4A4","O2B4A#8B8MLF#4O3MNC4","O1D1",0
45 DATA "by, Yet ",0,"O3G2.B4","O2MLG6.B6.O3MND6.O2MLG8O3D8","O1G2.P4",0
46 DATA "in thy dark streets ",0,"O3B4B4A4G4","O3MND2C4C#4","O2G2A4A#4",0
47 DATA "shin-eth The ",0,"O3F#2F#4F#4","O3D#2.D4","O2B2.B4",0
48 DATA "ev-er-last-ing ",0,"O3E4F#4G4A4","O2E4F#4G4MLA12O3C12MNE12","O2P2P4C4",0
49 DATA "Light, The ",0,"O3B2.B4","O2MLF#6.B6.O3MND#6.P4","O1B2.P4",0
50 DATA "hopes and fears of ",0,"O3B4B4A#4B4","O2MLG6B6O3MND6MLC#8MNE8O2MLB8O3MND8","O1G1",0
51 DATA "all the years, Are ",0,"O4D4C4O3E4O4E4","O2MLG#12B12O3MNF12O2MLA6O3C6MNE6O2E8F#8","O1C1",0
52 DATA "met in thee to-",0,"O4D4O3G4B4.A8","O2MLG8MNB8MLA8O3MNC#8O2MLB8O3MND8O2MLF#8O3MNC8","O1D4E4D2",0
53 DATA "night. ",1,"O3MLG2.","O2MLG6.B6.O3MND6.","O1G2.",0
54 DATA "Good King Wen-ces-",0,"t170O3MNG4G4G4A4","t170O2MLD6G6MNB6MLE2","t170O1G2E2",1
55 DATA "las looked out, ",1,"O3G4G4D2","O2E6G6O3MNC6O2MLF#4MNA4","O1C2D2",0
56 DATA "On the Feast of ",0,"O3E4D4E4F#4","O2MLG4O3MNC4O2F#2","O1C2D2",0
57 DATA "Ste-phen, ",1,"O3G2G2","O2MLD3G3MNB3","O1G1",0
58 DATA "When the snow lay ",0,"O3G4G4G4A4","O2MLD6G6MNB6MLE2","O1G2E2",0
59 DATA "rounda-bout, ",1,"O3G4G4D2","O2E6G6O3MNC6O2MLF#4MNA4","O1C2D2",0
60 DATA "Deep, and crisp, and ",0,"O3E4D4E4F#4","O2MLG4O3MNC4O2F#2","O1C2D2",0
61 DATA "e-ven, ",1,"O3G2G2","O2MLD3G3MNB3","O1G1",0
62 DATA "Bright-ly shone the ",0,"O4D4C4O3B4A4","O2B4A4G4F#4","O1G1",0
63 DATA "moon that night, ",1,"O3B4A4G2","O2G4F#4E2","O1D2E2",0
64 DATA "Though the frost was ",0,"O3E4D4E4F#4","O2MLE4O3MNC4O2F#2","O1C2D2",0
65 DATA "cru-el, ",1,"O3G2G2","O2MLD3G3MNB3","O1G1",0
66 DATA "When a poor man ",0,"O3D4D4E4F#4","O2G2O3C2","O1B2O2C2",0
67 DATA "came in sight, ",1,"O3G4G4A2","O2MLG6B6O3MNE6O2MLF#6A6O3MND6","O1E2D2",0
68 DATA "Gath-'ring win-ter ",0,"O4D4C4O3B4A4","O3D4E4D4O2F#4","O1B4O2C4O1D2",0
69 DATA "fu-",0,"O3MLG2O4MNC2","O2MLB4O3MNE4MLC4MNE4","O1E2C2",0
70 DATA "el. ",1,"O3G1","O2MLG3B3O3MND3","O1G1",0
71 DATA "",0,"O3A1","O3F#1","O3C1",1
72 DATA "God ",0,"O3E4","O3P4","O3P4",0
73 DATA "rest you mer-ry ",0,"O3E4B4B4A4","O2MLE6G6B6D#4F#4","O1E2D#2",0
74 DATA "gen-tle-men, Let ",0,"O3G4F#4E4D4","O2E6G6B6A4O3C4","O1E2A2",0
75 DATA "noth-ing you dis-",0,"O3E4F#4G4A4","O2E6G6MNB6MLA4O3MNC4","O1B2A2",0
76 DATA "may, Re-",0,"O3B2.E4","O2MLD#6.F#6.MNB6.P4","O1B2.P4",0
77 DATA "mem-ber Christ our ",0,"O3E4B4B4A4","O2MLE6G6B6D#4F#4","O1E2D#2",0
78 DATA "Sav-iour was ",0,"O3G4F#4E4D4","O2E6G6B6A4O3C4","O1E2A2",0
79 DATA "born on Christ-mas ",0,"O3E4F#4G4A4","O2E6G6MNB6MLA4O3MNC4","O1B2A2",0
80 DATA "Day. To ",0,"O3B2.B4","O2MLD#6.F#6.MNB6.P4","O1B2.P4",0
81 DATA "save us all from ",0,"O4C4O3A4B4O4C4","O2MLA4O3MNC4O2MLB4O3MND4","O1A2E2",0
82 DATA "Sa-tan's pow'r when ",0,"O4D4E4O3B4A4","O2MLD4MNG4MLD#4MNF#4","O1D2B2",0
83 DATA "we were gone a-",0,"O3G4E4F#4G4","O2MLG4MNB4MLA4O3C4","O1E2A2",0
84 DATA "stray. ",1,"O3A2","O2F#6O3C6MND6","O1D2",0
85 DATA "O ",0,"O3MLG4MNA4","O2MLE4MNF#4","O2P2",0
86 DATA "ti-dings of ",0,"O3B2O4C4O3B4","O2G2MLE4O3MNC4","O1G2C2",0
87 DATA "com-fort and ",0,"O3MLB4MNA4G4F#4","O2MLG8O3MND8O2MLA8O3MNC8O2MLB4B8O3MND#8","O1G4A4B2",0
88 DATA "joy, com-fort and ",0,"O3E2G8F#8E4","O2MLG3B3O3MNE3","O1E1",0
89 DATA "joy, O ",0,"O3A2MLG4MNA4","O2MLF#6A6O3MND6O2B4O3C4","O1D2P2",0
90 DATA "ti-dings of ",0,"O3MLB4O4MNC4D4E4","O2MLG4O3MNE4O2MLG4O3MND4","O1E2B2",0
91 DATA "com-fort and ",0,"O3MLB4MNA4G4F#4","O3D4C4O2MLB4B8O3MND#8","O1G4A4B2",0
92 DATA "joy. ",1,"O3E2.","O2MLG6.B6.O3MNE6.","O1E2.",0
93 DATA "O ",0,"t140O3MNE4","t140O3P4","t140O3P4",1
94 DATA "come, O come, Em-",0,"O3G4B4B4B4","O2MLE3G3B3","O1E1",0
95 DATA "man-u-",0,"O3MLA4O4C4O3MNB4A4","O2E3F#3O3C3","O1A1",0
96 DATA "el. And ",0,"O3G2.A4","O2E6.G6.MNB6.P4","O1E2.P4",0
97 DATA "ran-som cap-tive ",0,"O3B4G4E4G4","O2MLD6G6MNB6O3MLC4O2B4","O1G2.E4",0
98 DATA "Is-ra-",0,"O3MLA4F#4MNE4D4","O2E3A3O3C3","O1C1",0
99 DATA "el, That ",0,"O3E2.A4","O2E6.G6.MNB6.P4","O1E2.P4",0
100 DATA "mourns in lone-ly ",0,"O3A4E4E4F#4","O2MLE6A6O3MNC6O2MLG4F#8A8","O1A2G4F#4",0
101 DATA "ex-ile ",0,"O3MLG2MNF#4E4","O2G4MNB4A4MLG8O3MNC#8","O1E2D4A4",0
102 DATA "here. Un-",0,"O3D2.G4","O2MLF#4.O3MND4.P4","O1D2.P4",0
103 DATA "til the Son of ",0,"O3A4B4B4B4","O2MLF#4O3MND4O2MLG4B4","O1D2G2",0
104 DATA "God ap-",0,"O3MLA4O4C4O3MNB4A4","O2G6O3C6MNE6O2MLB8O3D8O2F#12O3C12D12","O1C2D2",0
105 DATA "pear. ",1,"O3G2.","O2G6.B6.O3MND6.","O1G2.",0
106 DATA "Re-",0,"O4D4","O2MLG12B12O3D12","O1G4",0
107 DATA "joice! Re-",0,"O4D2.O3B4","O2F#6.A6.O3D6.","O1D2.E4",0
108 DATA "joice! Em-",0,"O3B2.B4","O2F#6.B6.O3MND6.P4","O1B2.P4",0
109 DATA "man-u-",0,"O3MLA4O4C4O3MNB4A4","O3MLC4MNE4O2MLB8O3D8O2F#8O3C8MND8","O1C2D2",0
110 DATA "el, Shall ",0,"O3G2.A4","O2MLG6.B6.O3MNE6.P4","O1E2.P4",0
111 DATA "come to thee, O ",0,"O3B4G4E4G4","O2MLD6G6MNB6O3C4O2B4","O1G2C4E4",0
112 DATA "Is-ra-",0,"O3MLA4F#4MNE4D4","O2MLA4O3MNC4O2MLG8B8F#8B8","O1A2B2",0
113 DATA "el. ",1,"O3E2.","O2E6.G6.MNB6.","O1E2.",0
114 DATA "",0,"O3F#8G8G#8A8A#8B8O4C8C#8","O3P1","O3P1",1
115 DATA "A-",0,"t120O4D4","t120O2B4","t120O2P4",0
116 DATA "way in a ",0,"O4D4.C8O3B4","O2B4.A8G4","O1MLG2.",0
117 DATA "man-ger, no ",0,"O3B4.A8G4","O3D4.C8O2B4","O1MNG2.",0
118 DATA "crib for His ",0,"O3G4F#4E4","O2MLE4.O3MNC4.","O1C2.",0
119 DATA "bed, the ",0,"O3D2D4","O2MLG4MNB4P4","O1G2P4",0
120 DATA "lit-tle Lord ",0,"O3D4.E8D4","O2MLF#4.O3C4.","O1MLD2.",0
121 DATA "Je-sus laid ",0,"O3D4A4F#4","O2F#4.O3MNC4.","O1MND2.",0
122 DATA "down His sweet ",0,"O3E4D4G4","O2MLG4.B4.","O1MLG2.",0
123 DATA "head. ",1,"O3B2","O2G6B6O3MND6","O1G2",0
124 DATA "The ",0,"O4D4","O2B4","O2P4",0
125 DATA "stars in the ",0,"O4D4.C8O3B4","O2B4.A8G4","O1MLG2.",0
126 DATA "sky look'd ",0,"O3MLB4.MNA8G4","O3D4.C8O2B4","O1MNG2.",0
127 DATA "down where He ",0,"O3G4F#4E4","O2MLE4.O3MNC4.","O1C2.",0
128 DATA "lay, the ",0,"O3D2D4","O2MLG4MNB4P4","O1G2P4",0
129 DATA "lit-tle Lord ",0,"O4C4.O3B8A4","O2MLF#6.A6.O3D6.","O1D2.",0
130 DATA "Je-sus a-",0,"O3B4A4G4","O2G6.B6.O3MND6.","O1G2.",0
131 DATA "sleep on the ",0,"O3A4E4F#4","O3C2MLD4","O1C2D4",0
132 DATA "hay. ",1,"O3G2","O2G6B6O3MND6","O1G2",0
133 DATA "",0,"O3MLG#4A4MNA#4","O2MLG#4A4MNA#4","O1MLG#4A4MNA#4",0
134 DATA "We three ",0,"MBV12T85O3B4A8","MBV12T85O2MLE12.G12.B12.","MBV12T85O1MLE4.",1
135 DATA "kings of ",0,"O3G4F#8","O2MLE12.G12.B12.","O1MNE4.",0
136 DATA "O-ri-ent ",0,"O3F#8G8F#8","O2D#12.A12.B12","O1B4.",0
137 DATA "are, ",1,"O3E4.","O2E12.G12.MNB12.","O1E4.",0
138 DATA "Bear-ing ",0,"O3B4A8","O2MLE12.G12.B12.","O1MLE4.",0
139 DATA "gifts we ",0,"O3G4F#8","O2MLE12.G12.B12.","O1MNE4.",0
140 DATA "tra-verse a-",0,"O3F#8G8F#8","O2D#12.A12.B12","O1B4.",0
141 DATA "far, ",1,"O3E4.","O2E12.G12.MNB12.","O1E4.",0
142 DATA "Field and ",0,"O3G4G8","O2MLE8.MNB8.","O1E4.",0
143 DATA "foun-tain, ",0,"O3A4A8","O2MLF#8.MNA8.","O1D4.",0
144 DATA "moor and ",0,"O3B4B8","O2MLD12.G12.MNB12.","O1G4.",0
145 DATA "moun-tain, ",0,"O4MLD8MNC8O3B8","O2B8A8G8","O1G4.",0
146 DATA "Fol-low-ing ",0,"O3A8B8A8","O2MLE12.A12.O3MNC12.","O1A4.",0
147 DATA "yon-der ",0,"O3G4F#8","O2MLD12.A12.B12.","O1B4.",0
148 DATA "star. ",1,"O3E4.","O2E12.G12.MNB12.","O1E4.",0
149 DATA "",0,"O3MLF#2MNA4","O2MLD6.A6.O3C6.","O1D2.",0
150 DATA "An-gels we have ",0,"T140V12O3B4B4B4>D4","T140V9O2G3B3D3","T140V10O1G1",1
151 DATA "heard on high, ",1,"O4D4.C8<B2","O2F6A6>D6<G6B6>D6<","O1D2G2",0
152 DATA "Sweet-ly sing-ing ",0,"O3B4A4B4>D4","O2G4F+4G4B4","O1MLD1",0
153 DATA "o'er the plains. ",1,"O3B4.A8G2","O2MLF4MN>C4<MLG4MNB4","O1MND2G2",0
154 DATA "And the moun-tains ",0,"O3B4B4B4>D4","O3D4D+4E4<B4","O1G1",0
155 DATA "in re-ply, ",1,"O4D4.C8<B2","O2MLA8>MNC8<MLF+8>MND8<MLG6B6MN>D6<","O1D2G2",0
156 DATA "Ech-o-ing their ",0,"O3B4A4B4>D4","O2G4F+4G4B4","O1MLD1",0
157 DATA "joy-ous strains. ",1,"O3B4.A8G2","O2MLF4MN>C4<MLG4MNB4","O1MND2G2",0
158 DATA "",0,"V14","V13","V13",0
159 DATA "Glo-",0,"O4MLD2E8D8C8<B8","O2B2G#2","O2P4G8>D8P4D8E8",0
160 DATA "o-",0,"O4C2D8C8<B8A8","O2A2F#2","O3P4C8E8P4C8D8",0
161 DATA "o-",0,"O3B2>C8<B8A8G8","O2G2E2","O3P4B8>D8<P4G8>C8",0
162 DATA "ri-a ",0,"O3MNA4.D8D2","O2F+1","O3P4C8D8P4C8D8",0
163 DATA "in ex-cel-sis ",0,"O3G4A4B4>C4","O2B4>C4D4E4","O2G1",0
164 DATA "De-o, ",1,"O3B2A2","O3MLD2<F+6>C6MND6","O2D1",0
165 DATA "Glo-",0,"V14O4MLD2E8D8C8<B8","V12O2B2G#2","V13O2P4G8>D8P4D8E8",0
166 DATA "o-",0,"O4C2D8C8<B8A8","O2A2F#2","O3P4C8E8P4C8D8",0
167 DATA "o-",0,"O3B2>C8<B8A8G8","O2G2E2","O3P4B8>D8<P4G8>C8",0
168 DATA "ri-a ",0,"V12O3MNA4.D8D2","V9O2F+1","V10O3P4C8D8P4C8D8",0
169 DATA "in ex-cel-sis ",0,"O3G4A4B4>C4","O2B4>C4D4E4","O1G1",0
170 DATA "De-",0,"O3B2A2","O3MLD2<F+6>C6MND6","O1D1",0
171 DATA "-o! ",1,"O3MLG2.G8.G16V12","O2G3B3MN>D3V9","O1MNG1V10",0
172 DATA "Si-lent night, ",0,"V11T100O3MLG4.MNA8G4E2.","V9T100O2E4.F8E4G2.","V10T100O1MLC2.MNC2.",1
173 DATA "ho-ly night. ",1,"O3MLG4.MNA8G4E2.","O2E4.F8E4G2.","O1MLC2.MNC2.",0
174 DATA "All is calm, ",0,"O4D2D4O3B2.","O2MLF6.G6.B6.F6.G6.MNB6.","O1MLG2.MNG2.",0
175 DATA "all is bright. ",1,"O4C2C4O3G2.","O2MLE6.G6.O3C6.O2E6.G6.O3MNC6.","O1MLC2.MNC2.",0
176 DATA "Round yon Vir-gin ",0,"O3A2A4O4MLC4.O3MNB8A4","O2MLD6.F6.MNA6.A4.G8F4","O1MLF2.MNF2.",0
177 DATA "Moth-er and Child. ",1,"O3G4.A8G4E2.","O2MLE6.G6.O3C6.O2E6.G6.O3MNC6.","O1MLC2.MNC2.",0
178 DATA "Ho-ly In-fant so ",0,"O3A2A4O4C4.O3B8A4","O2MLD6.F6.MNA6.A4.G8F4","O1MLF2.MNF2.",0
179 DATA "ten-der and mild, ",1,"O3G4.A8G4E2.","O2MLE6.G6.O3C6.O2E6.G6.O3MNC6.","O1MLC2.MNC2.",0
180 DATA "Sleep in ",0,"O4D2D4","O2MLG4.B4.","O1MLG2.",0
181 DATA "heav-en-ly ",0,"O4F4.D8O3B4","O2G4.MNB4.","O1MNG2.",0
182 DATA "peace, ",1,"O4MLC2.MNE2.","O2MLG6.O3C6.E6.O2G6.O3C6.MNE6.","O1MLC2.MNC2.",0
183 DATA "Sleep in ",0,"O4MLC4O3MNG4E4","O2MLE4.O3MNC4.","O1MLG2.",0
184 DATA "heav-en-ly ",0,"O3G4.F8D4","O2MLF4.MNB4.","O1MNG2.",0
185 DATA "peace. ",1,"O3MLC2.MNC2.","O2MLE4.G4.E4.MNG4.","O1MLC2.MNC2.",0
186 DATA "",0,"O3MLF#4A4O4MNC#4","O2MLF#4A4O3MNC#4","O1MLF#4A4O2MNC#4",1
187 DATA "Joy to the world! The ",0,"v12t110O4D4C#8.O3B16A4.G8","v9t110O2F#4A8.G16F#4.MLG16B16","v10t110O1MLD2D4.G8",0
188 DATA "Lord is come. ",1,"O3F#4E4D4.","O2D8F#8C#8G8D12.F#12.MNA12.","O1A2D4.",0
189 DATA "Let earth re-",0,"O3A8B4.B8","O2P8MLD6G6MNB6","O1P8G2",0
190 DATA "ceive her King. ",1,"O4C#4.C#8MND2.","O2MLE6G6A6D6.F#6.MNA6.","O1A2D2.",0
191 DATA "Let ev-'ry ",0,"O4MLD8MNC#8O3MLB8MNA8","O2F#8A8G8F#8","O1D2",0
192 DATA "heart pre-",0,"O3MLA8.G16MNF#8O4D8","O2MLF#8.E16MND8F#8","O1D2",0
193 DATA "pare Him ",0,"O4MLD8MNC#8O3MLB8MNA8","O2F#8A8G8F#8","O1D2",0
194 DATA "room. ",1,"O3MLA8.G16MNF#8","O2MLF#8.E16MND8","O1MND4.",0
195 DATA "And heav'n and na-ture sing, ",1,"O3F#8F#8F#8F#8MLF#16MNG16A4.","O2P8MLD6F#6A6D24F#24MNA24MLD24F#24MNA24MLD24F#24MNA24","O1P8MLD2D4.",0
196 DATA "And heav'n and na-ture sing, ",1,"O3MLG16MNF#16E8E8E8MLE16MNF#16G4.","O2MLD24F#24MNA24MLC#6G6A6C#24G24A24C#24G24A24C#24G24A24","O1MND8MLA2A4.",0
197 DATA "And heav-en, and ",0,"O3MLF#16MNE16D8O4D4O3B8","O2MLC#24G24MNA24MLF#8.MNA8MLG16MNB16","O1MNA8D2",0
198 DATA "heav-en and ",0,"O3MLA8.MNG16F#8G8","O2MLF#8.MNA8.MLG16MNB16","O1D4.G8",0
199 DATA "na-ture sing. ",1,"O3F#4E4D2","O2MLD12F#12A12MNA8G8MLD4MNF#4","O1A2D2",0
200 DATA "",0,"v11O3MLE2MNF#2","v8O2MLE2MNF#2","v9O1MLE2MNF#2",1
201 DATA "O come,all ye ",0,"v11t120O3G4G2D4G4","v8t120O2P4MLG3B3O3D3","v9t120O1P4G1",1
202 DATA "faith-ful, ",0,"O3A2D2","O2F#3A3O3MND3","O1D1",0
203 DATA "joy-ful and tri-",0,"O3B4A4B4O4C4","O2MLG8MNB8MLF#8MNA8MLG8B8G12O3E12","O1G4F#4G4C4",0
204 DATA "um-phant. ",1,"O3B2A4","O2MNG2MLF#8MNA8","O1D2.",0
205 DATA "O come ye, O ",0,"O3G4G2F#4E4","O2MLG8MNB8B4O3C#4O2MLA8O3MND8O2MLG8O3MNC8","O1E4E2D4A4",0
206 DATA "come ye to ",0,"O3MLF#4MNG4A4B4","O2MLF#8MNA8MLG8MNB8MLF#8MNA8MLG8MNB8","O1D2.G4",0
207 DATA "Beth-le-",0,"O3MLF#2MNE4D4","O2MLF#4A4G6A6O3MNC#6","O1A1",0
208 DATA "hem! ",1,"O3MLD2MND2","O2MLF#3A3O3MND3","O1D1",0
209 DATA "Come and be-",0,"O4D2C4O3B4","O2MLG4MNB4E8F#8MLG8MNB8","O1G2A4G4",0
210 DATA "hold Him, ",0,"O4C2O3B2","O2E4F#4MLG4MNB4","O1D2G2",0
211 DATA "born the King of ",0,"O3A4B4G4A4","O2A4G4B4O3C4","O1F#4G4E4C4",0
212 DATA "an-gels! ",1,"O3MLF#4.MNE8D4","O2MLA4.MNG8F#4","O1D2.",0
213 DATA "O come,let us a-",0,"V12O3G4G4F#4G4A4","V9O3D4MLD1","V10O2B4B4A4B4O3C4",2
214 DATA "dore Him, ",1,"O3G2D4","O3MND2.","O2B2.",0
215 DATA "O come,let us a-",0,"V13O3B4B4A4B4O4C4","V10O3D4MLD1","V11O2G4G4F#4G4A4",0
216 DATA "dore Him, ",1,"O3B2A4","O3MND2.","O2MLG4MNB4MLF#8MNA8",0
217 DATA "O come,let us a-",0,"V15O3B4O4C4O3B4A4G4","V12O2MLG12B12O3MND12O2E8F#8MLG8MNB8MLF#8A8E12A12O3C#12","V13O1G4A4G4F#4E4",0
218 DATA "dore Him, ",1,"O3F#2MLG4O4MNC4","O3MND4C4O2MLG8B8G12O3C12MNE12","O1D2E4C4",0
219 DATA "Christ, the Lord! ",1,"O3MLB2MNA4.G8G2.","O2MLG6B6O3D6O2F#4O3C4O2G6.B6.O3MND6.","O1D1G2.",0



RE: QB64-PE v4's new 4-voice sound generator - a740g - 12-18-2024

The Rainbow Connection. I think I messed up the graphics. Oh well.

[Image: Screenshot-2024-12-18-081323.png]

Code: (Select All)
' RBOW.BAS COPYRIGHT (c) 1987 by Unique Software
' Ported from TANDY 1000 Advanced BASIC to QB64-PE by a740g

_DEFINE A-Z AS LONG
OPTION _EXPLICIT

_TITLE "The Rainbow Connection"

$RESIZE:SMOOTH

SCREEN 7
LOCATE 1, 1, 1, 0, 7
VIEW PRINT 1 TO 2

RESTORE data_rbow_bmp
DIM background AS LONG: background = _LOADIMAGE(Base64_LoadResourceData, 256, "memory")

DIM L$, L, M1$, M2$, M3$, M, P, P(29), T, V

GOTO 7

2:
READ L$, L, M1$, M2$, M3$, P
IF LEN(M1$) = 0 _ANDALSO LEN(M2$) = 0 _ANDALSO LEN(M3$) = 0 THEN GOTO 12
IF L = 0 THEN M = 14 - M: PALETTE 1, M
PALETTE P(P * 2), P(P * 2 + 1)
T = (T + 1) MOD 7
PALETTE 15, T + 9

4:
WHILE PLAY(0) > 0 _ORELSE PLAY(1) > 0 _ORELSE PLAY(2) > 0
    _LIMIT 60
WEND

PRINT L$; MID$(CHR$(13), 1, L MOD 2);
PLAY M1$, M2$, M3$: GOTO 2

7:
RESTORE data_rbow_pal: FOR P = 0 TO 29: READ P(P): NEXT P: FOR V = 1 TO 6: READ P, L: PALETTE P, L: NEXT V: _PUTIMAGE , background
RESTORE 15: PALETTE 8, 9
LINE (0, 0)-(319, 15), 0, BF
M = 2: V = 1: GOSUB 2

12:
WHILE PLAY(0) > 0 _ORELSE PLAY(1) > 0 _ORELSE PLAY(2) > 0
    _LIMIT 60
WEND

SLEEP 1

SYSTEM

data_rbow_pal:
DATA 00,00,13,11,13,14,03,11,03,14,08,02,08,15,14,14,12,12,05,05,09,09,14,11,12,11,05,11,09,11,6,15,4,12,1,12,13,11,3,11,8,2

15:
DATA "",2,"v10","v11","v12",00,"",2,"o3 p8. e16 >c#8.< e16 >c#8.< e16","o3 p8. p16 a8. p16 a8. p16","o2 a2.",00,"",2,"o3 p8. mlf#16 mna2","o4 p8. p16 d2.","o2 a2.",00,"",2,"o3 p8. e16 >c#8.< e16 >c#8.< e16"
DATA "o3 p8. p16 a8. p16 a8. p16","o2 a2.",00,"",2,"o3 p8. mlf#16 mna2","o4 p8. p16 d2.","o2 a2.",00,"Why are there ",0,"o3 c#4 e4 a4","o2 p4 mla8mn>c#8< mla8>mnc#8","o1 a4 >e4 e4",00,"so man-y ",0,"o3 b8.>c#16 c#2"
DATA "o3 p4 mlc#8mnf#8 mlc#8mne8","o2 f#4 a4 a4",00,"songs a-bout ",0,"o3 d4 e4 a4","o2 p4 mla8mn>d8< mla8mn>d8","o1 b4 >f#4 f#4",00,"rain-bows, and ",0,"o3 a4 b4. <b8","o3 f#4 e4 <b4","o2 e4 b4 g#4",00,"what's on the ",0,"o3 c#4 e4 g#4"
DATA "o2 p4 mla8>mnc#8< mlb8>mne8","o1 a4>e4 g#4",00,"oth-er ",0,"o3 a2 e4","o3 p4 mlc#8mne8 ml<a8>mnc#8","o2 f#2 e4",00,"side?",0,"o3 mlf#2.","o2 p4 mla8>mne8< mla8>mne8","o2 d2.",00,"",1,"o3 mnf#2 p4","o2 p4 mla8>mnd8< mla8mnb8"
DATA "o2 d2 p4",00,"Rain-bows are ",0,"o3 c#4 e4 a4","o2 p4 mla8>mnc#8< mla8>mnc#8","o1 a4 >e4 e4",00,"vis-ions, but ",0,"o3 b8 >mlc#8mnc#4 p8 <c#8","o3 g#8a8 mlc#8mne8 mlc#8mne8","o2 f#4 a4 a4",11,"on-ly il-",0,"o3 d4 e4 a4"
DATA "o2 p4 mlb8>mnd8< mlb8>mnd8","o1 b4 >f#4 f#4",14,"lu-sions. And ",0,"o3 a4 b4. <b8","o3 f#4 e4 <b4","o2 e4 b4 g#4",12,"rain-bows have ",0,"o3 c#4 e4 g#4","o2 p4 mla8>mnc#8< mlb8>mne8","o1 a4>e4 g#4",13,"noth-ing to ",0,"o3 a4 a4 e4"
DATA "o3 p4 mlc#8mne8 ml<a8>mnc#8","o2 f#2 e4",00,"hide.",0,"o3 mlf#2.","o2 p4 mla8>mne8< mla8>mne8","o2 d2.",00,"",1,"o3 mnf#2.","o2 p4 mla8>mne8< mla8>mne8","o1 a2.",00,"So we've been ",0,"o3 f#4 >c#4< f#4","o3 p8 c#8< a8 f#8 a8 f#8"
DATA "o2 d2.",00,"told, and some ",0,"o4 c#4 <f#4 >c#4","o3 p8 c#8< a8 f#8 a8 f#8","o2 d2.",00,"choose to be-",0,"o3 f#4 >c#4< f#4","o3 p8 c#8< a8 f#8 a8 f#8","o2 d2.",00,"lieve it,",1,"o4 c#4 <f#2","o3 p8 c#8< a8 f#8 a8 f#8","o2 d2.",00
DATA "I know they're ",0,"o3 g#4 g#4 g#4","o3 p8 d#8< b8 g#8 b8 g#8","o2 c#2.",00,"wrong, wait and ",0,"o3 b4 g#4 e4","o3 p8 d#8< b8 g#8 b8 g#8","o2 c#2.",00,"see.",0,"o3 mlg#2.","o3 p8 d#8< b8 g#8 b8 g#8","o2 c#2.",00
DATA "",1,"o3 mng#2 p4","o3 p8 d#8< b8 g#8 b8 g#8","o2 c#2.",00,"Some day we'll ",0,"o3 d4 f#4 a4","o2 p4 mla8mn>d8< mla8mn>d8","o1 b4 >f#4 f#4",00,"find it, the ",0,"o3 g#4 a4. e8","o2 p4 mla8mn>d8< mla8mn>d8","o1 e4 >f#4 f#4",00
DATA "Rain-bow Con-",0,"o3 e4 g#4 b4","o2 p4 mlb8>mne8< mlb8>mne8","o2 c#4 g#4 g#4",00,"nect-tion, the ",0,"o3 g#4 a#4. c#8","o3 e4 mlc#8mne8 mlc#8mne8","o2 f#2 p8 <a#8",00,"lov-ers, the ",0,"o3 d8 mlf#8 mnf#4 a4"
DATA "o2 p4 mla8>mnd8< mla8>mnd8","o2 b4 f#4 f#4",00,"dream-ers and ",0,"o4 c#8 mlc#8 mnc#4 <b4","o3 p4 mld8mne8 mld8mne8","o2 e2.",00,"me.",0,"o3 a8. e16 >c#8. <e16 >c#8. <e16","o3 p4 a8. p16 a8. p16","o2 a2.",00,"",2
DATA "o3 p8. mlf#16 mnf#2","o3 p8. p16 mla4>mnd4","o2 a2.",00,"",2,"o3 p8. e16 >c#8. <e16 >c#8. <e16","o3 p4 a8. p16 a8. p16","o2 a2.",00,"",1,"o3 p8. mlf#16 mnf#2","o3 p8. p16 mla4>mnd4","o2 a2.",00,"Who said that ",0,"o3 c#4 e4 a4"
DATA "o2 p4 mla8mn>c#8< mla8>mnc#8","o1 a4 >e4 e4",00,"ev-'ry wish would ",0,"o3 b8.>c#16 c#4. <c#8","o3 p4 mlc#8mnf#8 mlc#8mne8","o2 f#4 a4 a4",04,"be heard and ",0,"o3 d4 e4 a4","o2 p4 mla8mn>d8< mla8mn>d8","o1 b4 >f#4 f#4",00
DATA "an-swered when ",0,"o3 a4 b4. <b8","o3 f#4 e4 <b4","o2 e4 b4 g#4",00,"wished on the ",0,"o3 c#4 e4 g#4","o2 p4 mla8>mnc#8< mlb8>mne8","o1 a4>e4 g#4",00,"morn-ing ",0,"o3 a2 e4","o3 p4 mlc#8mne8 ml<a8>mnc#8","o2 f#2 e4",02,"star?"
DATA 0,"o3 mlf#2.","o2 p4 mla8>mne8< mla8>mne8","o2 d2.",00,"",1,"o3 mnf#2 p4","o2 p4 mla8>mnd8< mla8mnb8","o2 d2 p4",00,"Some-bod-y ",0,"o3 c#4 e4 a4","o2 p4 mla8>mnc#8< mla8>mnc#8","o1 a4 >e4 e4",00,"thought of that, and ",0
DATA "o3 b8 >mlc#8mnc#4 p8 <c#8","o3 g#8a8 mlc#8mne8 mlc#8mne8","o2 f#4 a4 a4",00,"some-one be-",0,"o3 d4 e4 a4","o2 p4 mlb8>mnd8< mlb8>mnd8","o1 b4 >f#4 f#4",00,"lieved it,",1,"o3 a4 b4. <b8","o3 f#4 e4 <b4","o2 e4 b4 g#4",00
DATA "Look what it's ",0,"o3 c#4 e4 g#4","o2 p4 mla8>mnc#8< mlb8>mne8","o1 a4>e4 g#4",00,"done so ",0,"o3 a4 a4 e4","o3 p4 mlc#8mne8 ml<a8>mnc#8","o2 f#2 e4",00,"far.",0,"o3 mlf#2.","o2 p4 mla8>mne8< mla8>mne8","o2 d2.",01
DATA "",1,"o3 mnf#2.","o2 p4 mla8>mne8< mla8>mne8","o1 a2.",00,"What's so a-",0,"o3 f#4 >c#4< f#4","o3 p8 c#8< a8 f#8 a8 f#8","o2 d2.",00,"maz-ing that ",0,"o4 c#4 <f#4 >c#4","o3 p8 c#8< a8 f#8 a8 f#8","o2 d2.",00
DATA "keeps us star-",0,"o3 f#4 >c#4< f#4","o3 p8 c#8< a8 f#8 a8 f#8","o2 d2.",02,"gaz-ing And ",1,"o4 c#4 <f#2","o3 p8 c#8< a8 f#8 a8 f#8","o2 d2.",00,"what do we ",0,"o3 g#4 g#4 g#4","o3 p8 d#8< b8 g#8 b8 g#8","o2 c#2.",00
DATA "think we might ",0,"o3 b4 g#4 e4","o3 p8 d#8< b8 g#8 b8 g#8","o2 c#2.",00,"see?",0,"o3 mlg#2.","o3 p8 d#8< b8 g#8 b8 g#8","o2 c#2.",00,"",1,"o3 mng#2 p4","o3 p8 d#8< b8 g#8 b8 g#8","o2 c#2.",00
DATA "Some day we'll ",0,"o3 d4 f#4 a4","o2 p4 mla8mn>d8< mla8mn>d8","o1 b4 >f#4 f#4",00,"find it, the ",0,"o3 g#4 a4. e8","o2 p4 mla8mn>d8< mla8mn>d8","o1 e4 >f#4 f#4",00,"Rain-bow Con-",0,"o3 e4 g#4 b4"
DATA "o2 p4 mlb8>mne8< mlb8>mne8","o2 c#4 g#4 g#4",00,"nect-tion, the ",0,"o3 g#4 a#4. c#8","o3 e4 mlc#8mne8 mlc#8mne8","o2 f#2 p8 <a#8",00,"lov-ers, the ",0,"o3 d8 mlf#8 mnf#4 a4","o2 p4 mla8>mnd8< mla8>mnd8","o2 b4 f#4 f#4",00
DATA "dream-ers and ",0,"o4 c#8 mlc#8 mnc#4 <b4","o3 p4 mld8mne8 mld8mne8","o2 e2.",00,"me.",1,"o3 a2.","o3 p4 mlc#8mne8 mlc#8mne8","o2 b2.",00,"All of us ",0,"o3 b4. a8 b4","o2 p4 ml b8>mne8< mlb8>mne8","o2 g#2.",00
DATA "un-der its ",0,"o4 c#4. <b8 a4","o3 p4 mlc#8mne8 mlc#8mne8","o2 f#2.",00,"spell, We ",0,"o3 e2 e4","o2 p4 mla8>mnc#8< mla8>mnc#8","o2 e2.",00,"know that it's ",0,"o3 f#4. g#8 a4","o2 p4 mla8>mne8< mla8>mne8","o2 d2.",00
DATA "prob-ab-ly ",0,"o3 e4. f#8 a8","o2 p4 mla8>mnc#8< mla8>mnc#8","o2 c#2.",00,"",2,"v11","v12","v13",00,"ma-",0,"o3 b2.","o3 mlf#8mna8 mld8mnf#8 mlf#8mna8","o1 e2.",00,"",2,"v12","v13","v14",00,"gic.",0,"o4 mlc2."
DATA "o3 mlg8mnb-8 mle-8mng8 mlb-8mnb-8","o1 f2.",05,"",1,"o4 c4 p4 p4","o3 mlg8mna8 mlc8mng8 mlf8mna8","o2 f2.",00,"Have you been ",0,"o3 d4 f4 b-4","o2 p4 mlb-8mn>d8< mlb-8>mnd8","o2 b-4 f4 f4",00,"half a-sleep and ",0
DATA "o4 c8 d8 d4. <d8","o3 a4 mld8mnf8 mld8mnf8","o2 g4 b-4 b-4",00,"have you heard ",0,"o3 e-4 f4 b-4","o2 p4 mlb-8mn>e-8< mlb-8>mne-8","o2 c4 g4 g4",00,"voic-es?",1,"o3 b-4 >c2","o3 g4 f4 c4","o2 f4 >c4 <a4",08,"I've heard them "
DATA 0,"o3 d4 f4 a4","o3 p4 mlb-8>mnd8 mlc8mnf8","o1 b-4 f4 a4",00,"call-ing my ",0,"o3 b-4 b-4 f4","o3 p4 mld8mnf8 ml<b-8>mnd8","o2 g2 f4",00,"name.",0,"o3 mlg2.","o2 p4 mlb-8>mnf8< mlb-8>mnf8","o2 e-2.",09
DATA "",1,"o3 mng2 p4","o2 p4 mlb-8>mnf8< mlb-8>mnc8","o2 f2 f4",00,"Is this the ",0,"o3 d4 f4 b-4","o2 p4 mlb-8mn>d8< mlb-8>mnd8","o2 b-4 f4 f4",00,"sweet sound, that ",0,"o4 c8 mld8 mnd4. <d8","o3 a4 mld8mnf8 mld8mnf8","o2 g4 b-4 b-4",10
DATA "calls the young ",0,"o3 e-4 f4 b-4","o2 p4 mlb-8mn>e-8< mlb-8>mne-8","o2 c4 g4 g4",00,"sail-ors? the ",0,"o3 b-4 >c2","o3 g4 f4 c4","o2 f4 >c4 <a4",00,"voice might be ",0,"o3 d4 f4 a4","o3 p4 mlb-8>mnd8 mlc8mnf8","o1 b-4 f4 a4",00
DATA "one and the ",0,"o3 b-4 b-4 f4","o3 p4 mld8mnf8 ml<b-8>mnd8","o2 g2 f4",00,"same.",0,"o3 mlg2.","o2 p4 mlb-8>mnf8< mlb-8>mnf8","o2 e-2.",07,"",1,"o3 mng2 p4","o2 p4 mlb-8>mnf8< mlb-8>mnf8","o2 e-2.",00
DATA "I've heard it ",0,"o3 g4 >d4 <g4","o3 p8 d8 <b-8 g8 b-8 g8","o2 e-2.",00,"too man-y ",0,"o4 d4 <g4 >d4 ","o3 p8 d8 <b-8 g8 b-8 g8","o2 e-2.",00,"times to ig-",0,"o3 g4 >d4 <g4","o3 p8 d8 <b-8 g8 b-8 g8","o2 e-2.",00
DATA "nore it. It's ",0,"o4 d4 <g4. g8 ","o3 p8 d8 <b-8 g8 b-8 g8","o2 e-2.",00,"some-thing that ",0,"o3 a4 a4 a4","o3 p8 e8 c8< a8 >c8< a8","o2 d2.",00,"I'm s'posed to ",0,"o4 c4 <a4 f4","o3 p8 e8 c8< a8 >c8< a8","o2 d2.",00
DATA "be.",0,"o3 mla2.","o3 p8 e8 c8< a8 >c8< a8","o2 d2.",00,"",1,"o3 mna2.","o3 p8 e8 c8< a8 >c8< a8","o2 d2.",00,"Some-day we'll ",0,"o3 e-4 g4 b-4","o2 p4 mlb-8mn>e-8< mlb-8mn>e-8","o2 c4 g4 g4",00,"find it, The "
DATA 0,"o3 a4 b-4. f4","o2 p4 mlb-8mn>e-8< mlb-8mn>e-8","o2 f4 g4 g4",00,"Rain-bow Con-",0,"o3 f4 a4 >c4","o3 p4 mlc8mnf8 mlc8mnf8","o2 d4 a4 a4",00,"nec-tion, the ",0,"o3 a4 b4. d8","o3 f4 mld8mnf8 mld8mnf8","o2 g2 p8 b8",06
DATA "lov-ers, the ",0,"o3 e-8 mlg8mng4. b-8","o2 p4 mlb-8mn>e-8< mlb-8mn>e-8","o2 c4 g4 g4",00,"dream-ers, and ",0,"o4 d8 mld8mnd4 c8","o3 p4 mle-8mnf8 mle-8mnf8","o2 f2.",00,"me.",0,"o3 b-2.","o3 p4 mld8mnf8 mld8mnf8","o2b-2.",00
DATA "",2,"o4 c4. <b-8> c4","o3 p4 mlc8mnf8 mlc8mnf8","o2 a2.",00,"",2,"o4 d4. c8 <b-4","o3 p4 mld8mnf8 mld8mnf8","o2 g2.",00,"",2,"o3 f2 f4","o2 p4 mlb-8mn>d8< mlb-8mn>d8","o2 f2.",00,"",2,"o3 g4. a8 b-4","o2 p4 mlb-8mn>f8< mlb-8mn>e-8"
DATA "o2 e2.",00,"",2,"o3 f4 b-4 a4","o2 p4 mlb-8mn>c8< mla8mn>e-8","o2 f2.",00,"",2,"o4 p4 mld8mnf8 mld8mnb-8","o3 mlb-2.","o1 mlb-2.",00,"",2,"o5 mld2<mnb-1","o3 mlb-1.","o1 mlb-1.",00,"",2,"v10","v11","v12",00
DATA "",0,"","","",0

data_rbow_bmp:
DATA 32094,2984,-1
DATA "eNokyTUBAkAUBuAPWdActEB2RtZrQqFXA011/uTX2z09gYQTLgv+WFgDeB/nb80v5dG2YYMQQwilD0YbES2u1NZBjqMwEAXQbPp+vfnGHMB1Awvl"
DATA "AEgsZ4Na3Hb85VIJ5DgmA6QzP0qFDot+qpiy/784CYAIP0VSyZf6Fgl2D78TgYMLLjmwKvlrBFnd+y0fgsPGRwrfovqGr7vat6Jpv+DMJ01fjJcJ"
DATA "CSl9IsLLnb7IXOor1p+90F5/XYf0ipf6uAIhQbQ4BL6zz+7VfIq8KhRQ6UQLbE1y3sDuPfPhQh8BVXo9XXyPzyE88UndNwwU9rjYB6n6XMO30LeY"
DATA "75NC37IsH+gbwBC29vWfYuTvOpuPUe2MGE88s+g2IYGF13qSCQgt352mwrf8YMBZEVDkVjubbWgtH+6KWjTsJvJX8USf2/pAGH2u4TNX6TuvgcS4"
DATA "sPU59UljJPdbnv7YZHaIJ/rgpPRxUaKaIdZ9YE7zSdE/fvCC9KqPQDz0zfnZOXHTJYUX4tTqEBq+Lm8Zhc+PyOlO9IE9lFR1tGQsU5/M5BS+aRph"
DATA "vu40X3EKbCUNZtJSWQWbzH1EynCaT17yEVTF2WPSDRHH4vh8rH2yy3dfD73+8WjsuQHSiHfFVv2GhwlF+MOj/0m+gcb3xMYK+hXPT766sQyRZ9cD"
DATA "ZwOI5PrCUW9Wn/JGjCNg8aZL+RkOtU+wmsntcNO4EwUjkDd5ayDSgFk2YfuO+8DsHSs2+ChNPFj//ASjWwdx3CfYl8WiYcdg68/OL+tk3+12yGdD"
DATA "5uXzlGf/9JF56JtB3e0r1QPrz+3yldttBiqq5vtOvlS+/sknpAXXfG5rPkwU1X3k0Xd72ecgyEcXNNvX3RfzbTl+mp76Mu8rVaSksst5g/mwJx3/"
DATA "0wMfM0KDra9PSfUPfSSCrcR3i6f9ZtPEveAj8JHPQ6NSu+u95x/0MQDXoC1DQktYfpjUx8dW/jJvBy9uG1EYwNcH/QEquNCrjGnv2kCPOkx6rp19"
DATA "i3ItxLnnsL6nDEyPXdr/t/qY8ce4z7OS8OSRDyQEYdFvvzcz3iTsTR++Ww7i0Ip8jJ5rH1HLfHj/dBGTvy3xmulOXzHpQEhLZivtNk3231vLT5b5"
DATA "GsGd9fGBPH4PMbNLIH2hHLaHFj4VAc/LQl96Mwg0oQG2lnYRM18gbhhvS5+uT8Y530OMkDddaTkmkdD+kEWa282xwNS4tAAWfB9+henK91fuY30p"
DATA "jaTO+I5k1Gnyvf4gMfh6FphOhfZ2gSLwvVPz9blvUC/lWS0Pc2kkbRyMMrHSI+4xccDbgm+X+3y8f+SfivLxrJ6hcd5ppsmXHrki6GsPV7bXruui"
DATA "T7KMyfePc05i3MM9abi14y5KJyhU9G1FWuSnjNdN2cuUI33ZfMVNeV/Jx2FGIKunr4UPyWz0oUXteyLwyQ13+xqoCFTbabOVlsC/2/Yt34gLqgRE"
DATA "k3f7wMp9TPK1ckjASUcfYOErlMoHFhIf7iow/+hJUpW2hY/5IfnwyXakLyXI6Kv7ONJ0fCofon0i2icBPHmirxKQqubWgBf6mMyH1CiQT7O+Nt8f"
DATA "s777C1SjruV7X9+H/D4/4FmfZL4pVX3NGt9xxvdkUOD9vroF6pAWs85nANwoH7LGN9j5OGBBFvrcd+oTxwItF+AKn22BaoP4pb7B0Pe61ofYLsAF"
DATA "PnftG6wX4Fu+R+1z37vPWQ+Yf6XU6eEJAT6bCa/zfYCPC5ExH3DZ9+j4g6BJgZsFPp/5eqEvi+UCVBtk9HJJ37/jOWMEfNvnr33gqfqQwXABcoPQ"
DATA "R2/PY1oDjQasfYHIZ1H1MZYDlkvGcOXzpfoQwwHvIw03XJcSQ7E+ZLAbMHwSok3oG68+5HSMF6AH6eJDkZ6HoLMD6gHTN5lgC/CFIIG8/tFZTnhT"
DATA "9PkRrujjdPspzgyofa88YICLPjiF9akCGasB7yGBLCBeQvT5yDMDlv+hUpDx4hvhiycOcIgrxGgHQ4SpMh5a8soFDhYDDjo+kGdeoBqwBiLklQtE"
DATA "jI7ojDUGZkGBg8GAkV8uvAy4qMDBYMAEiuC0icA/abMGbnSBESjHDgGQPMaVYlEgEjx4iHC4qkAT4Oa2T/ifhmPY9cuBg82A96gvRr52vY4rxmLA"
DATA "eyEP1DUFusGgwMj7+Xyx9vZA7WOBIIH3pQOwE1WgLVD5IJryBRcL1HFGQMo44Fjf5Qbfzh5YHvAEkiyoc+WE3TctUEa5ipeuMGEb4GaJb7cSaOo7"
DATA "Fgp8tAH+36cCHwu0B26W+Lp+5YSdsc8eyCzz7ayBhQK3BV/Xr12C1Q7qGR9wLNAcqArEbyAqH9IbAwu+588EcryrgUz9Af/4+Xw68ZfVWB8nvBI4"
DATA "VC4QvhcUKOC9fEJ9qkBr4JXvdD5H3+l0fvlE3GogU7NA+KbA93yamvwDrNKEGfd2hqoFwifwoUj6WOBqIPJbzRUIHnyAwlcDWNHHQxo+mPSE1wNr"
DATA "DhiBrwOvErD2j6n/FUsHNBBDIQyGi4Q+CUzC5l/bGbisGQH6K/hSIJn/qwHRPSB58n93BQj4B7wnfWAD8BG+5gFPHxCbA+atgf2+qF9YA9EQCxf+"
DATA "05gvBoEYGpBZAD7KtzBg3m/N+MAxIMYGZJaAz4QPLAPFhBgc8BSBT78PLAG1EJMDMqvAu9sHNgPvZl98BV5S+ChfA/AIoKjRB04AAd+F81r1gQNA"
DATA "NBbfgbnpA/uBsAOvBZ+68Mm3tM8MvNZ8YAmYa74oAq8lH1gEpvaZgdeOL8rAXPGBdeAlfAagEGKg0MCXtM8MzGvaB76Un4RwA4UQRqBo1Bck9RPq"
DATA "EeEGijAWX/P7BPDYfdEBhA9It08Cj9kHqtZ8UVuQR/rMCwoh/EBafQjqnD6QumP0gawL4QYKIXaBIpcPQdZGhBWoR4QbKIjYi586Wz4BFEgsFvwe"
DATA "3EARdvP7VP0+qxCGwu8T9ftcQLjy+0TR7zMIYa3ZZxDCnt+nCr9P5ffJ/D6d2VdQ/gDyjts/"

' Converts a base64 string to a normal string or binary data
FUNCTION Base64_Decode$ (s AS STRING)
    DIM srcSize AS _UNSIGNED LONG: srcSize = LEN(s)
    DIM buffer AS STRING: buffer = SPACE$((srcSize \ 4) * 3) ' preallocate complete buffer
    DIM j AS _UNSIGNED LONG: j = 1
    DIM AS _UNSIGNED _BYTE index, char1, char2, char3, char4

    DIM i AS _UNSIGNED LONG: FOR i = 1 TO srcSize STEP 4
        index = ASC(s, i): GOSUB find_index: char1 = index
        index = ASC(s, i + 1): GOSUB find_index: char2 = index
        index = ASC(s, i + 2): GOSUB find_index: char3 = index
        index = ASC(s, i + 3): GOSUB find_index: char4 = index

        ASC(buffer, j) = _SHL(char1, 2) OR _SHR(char2, 4)
        j = j + 1
        ASC(buffer, j) = _SHL(char2 AND 15, 4) OR _SHR(char3, 2)
        j = j + 1
        ASC(buffer, j) = _SHL(char3 AND 3, 6) OR char4
        j = j + 1
    NEXT i

    ' Remove padding
    IF RIGHT$(s, 2) = "==" THEN
        buffer = LEFT$(buffer, LEN(buffer) - 2)
    ELSEIF RIGHT$(s, 1) = "=" THEN
        buffer = LEFT$(buffer, LEN(buffer) - 1)
    END IF

    Base64_Decode = buffer
    EXIT FUNCTION

    find_index:
    IF index >= 65 AND index <= 90 THEN
        index = index - 65
    ELSEIF index >= 97 AND index <= 122 THEN
        index = index - 97 + 26
    ELSEIF index >= 48 AND index <= 57 THEN
        index = index - 48 + 52
    ELSEIF index = 43 THEN
        index = 62
    ELSEIF index = 47 THEN
        index = 63
    END IF
    RETURN
END FUNCTION

' Loads a binary file encoded with Bin2Data
' Usage:
'  1. Encode the binary file with Bin2Data
'  2. Include the file or it's contents
'  3. Load the file like so:
'      Restore label_generated_by_bin2data
'      Dim buffer As String
'      buffer = LoadResource  ' buffer will now hold the contents of the file
FUNCTION Base64_LoadResourceData$
    DIM ogSize AS _UNSIGNED LONG, resize AS _UNSIGNED LONG, isComp AS _BYTE
    READ ogSize, resize, isComp ' read the header

    DIM buffer AS STRING: buffer = SPACE$(resize) ' preallocate complete buffer

    ' Read the whole resource data
    DIM i AS _UNSIGNED LONG: DO WHILE i < resize
        DIM chunk AS STRING: READ chunk
        MID$(buffer, i + 1) = chunk
        i = i + LEN(chunk)
    LOOP

    ' Decode the data
    buffer = Base64_Decode(buffer)

    ' Expand the data if needed
    IF isComp THEN buffer = _INFLATE$(buffer, ogSize)

    Base64_LoadResourceData = buffer
END FUNCTION