MusicBox2

Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Music

MusicBox2 is a BASIC music player that stores and plays eight folk and popular songs using the BEEP command, with each piece encoded as paired frequency-and-duration values in DATA statements starting at line 1000 and spaced 200 lines apart. Songs include “On Top of Old Smokey,” “Greensleeves,” “Waltzing Matilda,” and “The Tavern in the Town,” among others. A special data value of 100 acts as a control code, triggering chord-name display from a pre-built string array when followed by an index, or a PAUSE (rest) when followed by a duration value of 99. The program uses ON ERR to detect the end of each song’s data, with a looping option (triggered by Z$=”2″) that restarts the data pointer mid-song. Tempo is user-adjustable via a multiplier (TT, default 10) applied to all note durations.


Program Structure

The program is organized into a front-end menu/display section (lines 10–90), a playback engine (lines 100–170), a post-play options menu (lines 180–300), an initialization subroutine (lines 310–350), and eight song data blocks beginning at lines 1000, 1200, 1400, 1600, 1800, 2000, 2200, and 2400. Each song block is exactly 200 lines wide, which the program exploits for indexed access.

Song Selection and DATA Addressing

The program uses a clever indexing scheme to locate song data. Given a user selection N (1–8), the DATA pointer is set with RESTORE N*200+800, which maps selections to line numbers 1000, 1200, 1400, and so on. Each song block begins with a string (the song title) and a base rate value R, followed by pairs of frequency and duration values used by BEEP.

Playback Engine and Control Codes

The core playback loop at lines 130–160 reads pairs F,V from DATA. Three cases are handled:

  • If F=100: display a chord name from A$(V) at a fixed screen position and loop back — this is an annotation mechanism, not a sound event.
  • If F=99: insert a rest using PAUSE T/V*60, then loop.
  • Otherwise: play a note with BEEP T/V, F where T is the scaled tempo value and F is the semitone offset.

The effective note duration is T/V, where T = R * TT and TT defaults to 10. Smaller values of TT produce faster tempos; larger values slow the piece down.

ON ERR Usage

End-of-song detection relies on ON ERR GO TO 170 set at line 130. When RESTORE exhausts the current song’s data and a READ fails, execution jumps to line 170. There, ON ERR RESET clears the error trap, and the program checks whether Z$="2" (continuous play mode); if so, it restores the data pointer to N*200+810 (skipping the title/rate header) and resumes playback, creating a seamless loop.

Chord Name Array

The subroutine at lines 310–350 initializes a string array A$ dimensioned as DIM A$(17,5), holding 17 chord names of up to 5 characters each. These are displayed at screen position AT 5,13 whenever a F=100 control code is encountered in the data stream, providing a chord-chart overlay synchronized with the music.

IndexChordIndexChord
1A10Gm
2C11A7
3D12C7
4F13D7
5G14E7
6Am15F7
7Cm16G7
8Dm17Bflat
9Fm

Post-Play Options

After a song ends (or is stopped), lines 180–300 present four options keyed by INKEY$ after a PAUSE 0:

  • "1" — Play again from the beginning.
  • "2" — Play continuously (loops via the ON ERR handler).
  • "3" — Adjust tempo (prompts for a new TT value).
  • "0" — Return to the song selection menu.

Notable Techniques and Anomalies

  • Line 230 begins with two raw character codes (\{16}\{0}), which are INK color control characters embedded directly in the line — likely a screen attribute reset artifact.
  • Line 320 contains a lowercase a$ in LET a$(8)="Dm", which is inconsistent with A$ used elsewhere; most Spectrum-family BASICs treat variable names as case-insensitive after tokenization, so this is not functionally a bug but is a visual anomaly in the listing.
  • The title screen at lines 10–20 prints “MUSIC BOX 2” repeatedly in two ink colors across 13 rows to create a decorative banner effect before the prompt appears.
  • Tempo is applied as a multiplier to the stored reciprocal-duration values, meaning the DATA values for duration are divisors rather than absolute durations — a compact encoding that avoids floating-point scaling in the data itself.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   10 BORDER 4:PAPER 6:CLS :FOR A=0 TO 12
   20 PRINT TAB 3; INK 1;"MUSIC BOX 2"; TAB 18; INK 3;"MUSIC BOX 2":NEXT A
   30 PRINT AT 15,0; PAPER 5;''"THIS IS YOUR MUSIC BOX 2.  PRESS ""ENTER"" TO SEE THE CONTENTS."
   40 PAUSE 0:GO SUB 310
   50 CLS :PRINT PAPER 5;"********* BOX CONTENTS *********":PRINT ''
   60 FOR I=1 TO 8:RESTORE I*200+800:READ N$:PRINT I; TAB 4;N$:NEXT I
   70 PRINT PAPER 5; AT 20,0;"ENTER THE NUMBER OF THE COMPOSI-TION THAT YOU WANT TO PLAY      " 
   80 INPUT N:CLS :LET TT=10:LET Z$=""
   90 RESTORE N*200+800:READ N$,R:LET T=R*TT
  100 CLS :PRINT PAPER 5;" *********NOW PLAYING **********"; AT 21,0;"********* NOW PLAYING **********"
  110 PRINT AT 10,(31- LEN N$)/2;N$
  120 PRINT PAPER 3; INK 7; AT 20,0;"TO STOP, PRESS ""SHIFT"" + ""BREAK"""
  130 READ F,V:ON ERR GO TO 170:IF F=100 THEN PRINT AT 5,13; PAPER 5;A$(V):GO TO 130
  140 IF F <>99 THEN GO TO 160
  150 PAUSE T/V*60:GO TO 130
  160 BEEP T/V,F:GO TO 130
  170 ON ERR RESET :IF Z$="2" THEN RESTORE N*200+810:GO TO 130
  180 CLS :PAPER 7:PRINT AT 7,0;"PRESS ""1"" TO PLAY AGAIN.        "
  190 PRINT "PRESS ""2"" TO PLAY CONTINUOUSLY. "
  200 PRINT ;"PRESS ""3"" TO PLAY DIFFERENTLY.  "
  210 PRINT ;"PRESS ""0"" TO PLAY ANOTHER       "
  220 PRINT "COMPOSITION.":PAPER 6
  230 \{16}\{0} PAUSE 0:LET Z$= INKEY$:IF Z$="1" OR Z$="2" THEN GO TO 90
  240 IF Z$="0" THEN GO TO 50
  250 CLS :PRINT AT 6,0;"INPUT A NUMBER FOR THE DESIRED"
  260 PRINT "TEMPO.  THE PROGRAMMED TEMPO IS"
  270 PRINT "10. A SMALLER NUMBER WILL MAKE"
  280 PRINT "THE TEMPO FASTER; A LARGER"
  290 PRINT "NUMBER WILL MAKE IT SLOWER."
  300 INPUT TT:GO TO 90
  310 DIM A$(17,5):LET A$(1)="A":LET A$(2)="C":LET A$(3)="D":LET A$(4)="F":LET A$(5)="G"
  320 LET A$(6)="Am":LET A$(7)="Cm":LET a$(8)="Dm":LET A$(9)="Fm":LET A$(10)="Gm"
  330 LET A$(11)="A7":LET A$(12)="C7":LET A$(13)="D7":LET A$(14)="E7":LET A$(15)="F7":LET A$(16)="G7"
  340 LET A$(17)="Bflat"
  350 RETURN 
  390 SAVE "BOX 2"
 1000 DATA "ON TOP OF OLD SMOKEY",.08
 1010 DATA 0,4,100,2,0,4,4,4,7,4,100,4,12,1.33,9,.8,9,4,5,4,7,4,9,4,100,2,7,.5,0,4,0,4,4,4,7,4,100,16,7,1.33,2,.8,2,8,4,8,5,4,4,4,2,4,100,2,0,.5
 1200 DATA "THE SAINTS",.08
 1210 DATA 0,4,4,4,5,4,100,2,7,.8,0,4,4,4,5,4,7,.8,0,4,4,4,5,4,7,2,4,2,0,2,4,2,100,16,4,4,2,1,4,4,4,4,2,4
 1220 DATA 100,2,0,2,0,2,100,12,4,2,7,4,7,4,7,4,100,4,5,1,4,4,5,4,100,2,7,2,4,2,100,16,0,2,2,2,100,2,0,.8
 1400 DATA "CARELESS LOVE",.08
 1410 DATA 100,2,4,1.33,0,4,100,16,-1,4,-5,4,-1,4,2,4,100,2,0,.5,4,1.33,5,4,100,11,7,4,7,4,9,4,7,4,100,13,2,.5,100,2,4,1.33,5,4,100,12,7,1.33,7,4,100,4,9,2,5,2
 1420 DATA 100,9,0,1.33,5,4,100,2,4,1.33,0,4,100,16,-1,4,-5,4,-1,4,2,4,100,2,0,.5
 1600 DATA "OH! NO JOHN, NO",.09
 1610 DATA -5,4,100,2,0,4,0,4,100,16,2,4,2,4,100,2,7,4,7,8,5,8,100,16,4,4,2,4,100,2,-5,4,0,4,100,5,2,4,2,4,100,2,7,4,5,4,100,16,2,2,100,2,7,4,7,8,5,8
 1620 DATA 100,6,4,4,0,4,100,8,5,4,2,8,0,8,100,16,-1,4,-5,4,100,2,0,4,4,4,100,4,-3,4,0,4,100,16,-1,4,-5,4,-5,2,100,2,7,2,100,4,5,4,2,4,100,2,4,4,0,4,100,16,-1,8,-3,8,-5,4,100,2,0,1.33
 1800 DATA "AURA LEE",.12
 1810 DATA 100,17,5,4,10,4,9,4,10,4,100,7,12,4,7,4,12,2,100,15,10,4,9,4,7,4,9,4,100,17,10,2,100,15,5,2,100,17,5,4,10,4,9,4,10,4,100,12,12,4,7,4,12,2
 1820 DATA 100,15,10,4,9,4,7,4,9,4,10,17,10,1,100,3,9,2.66,9,8,9,2,100,10,10,2.66,10,8,10,2,100,17,14,2.66,12,8,10,4,100,4,12,4,100,17,14,1,14,4,100,13,14,4,100,5,15,2.66,14,8
 1830 DATA 100,12,12,2.66,7,8,12,4,10,4,100,15,9,8,9,2.66,14,4,12,4,100,17,10,1
 2000 DATA "GREENSLEEVES",.2
 2010 DATA 2,4,100,8,5,2,7,4,9,2.67,10,8,9,4,100,2,7,2,4,4,0,2.67,2,8,4,4,100,8,5,2,2,4,2,2.67,1,8,2,4,100,1,4,2,1,4,-3,2,2,4
 2020 DATA 100,8,5,2,7,4,9,2.67,10,8,9,4,100,2,7,2,4,4,0,2.67,2,8,4,4,100,8,5,2.67,4,8,2,4,100,11,1,2.67,-2,8,1,4,100,8,2,.67,100,4,12,1.33,12,2.67,11,8
 2030 DATA 9,4,100,2,7,2,4,4,0,2.67,2,8,4,4,100,8,5,2,2,4,2,2.67,1,8,2,4,100,1,4,2,1,4,-3,1.33,100,4,12,1.33,12,2.67,11,8,9,4,100,2,7,2,4,4
 2040 DATA 0,2.67,2,8,4,4,100,8,5,2.67,4,8,2,4,100,11,1,2.67,-2,8,1,4,100,3,2,.8
 2200 DATA "WALTZING MATILDA",.2
 2210 DATA 100,2,4,8,4,8,4,8,4,8,100,14,2,4,2,4,100,6,0,8,2,8,4,8,0,8,100,4,-3,8,-1,8,0,4,100,2,-5,4,0,8,4,8,7,4,7,8,7,8,7,8
 2220 DATA 7,8,5,8,4,8,100,16,2,4,0,8,2,8,100,2,4,4,4,8,4,8,100,14,2,4,2,4,100,6,0,8,2,8,4,8,0,8,100,4,-3,8,-1,8,0,4,100,2,-5,4,0,8
 2230 DATA 4,8,7,4,5,8,4,8,100,16,2,4,2,8,2,8,100,2,0,2,7,4,7,8,7,8,100,12,7,4,4,4,100,4,12,4,12,8,12,8,11,4,9,4,100,2,7,4,7,8
 2240 DATA 7,8,9,4,7,8,7,8,9,4,5,8,4,8,100,16,2,4,0,8,2,8,100,2,4,4,4,8,4,8,100,14,2,4,2,4,100,6,0,8,2,8,4,8,0,8,100,4,-3,8
 2250 DATA -1,8,0,4,100,2,-5,4,0,8,4,8,7,4,5,8,4,8,100,16,2,4,2,8,2,8,100,2,0,2
 2400 DATA "THE TAVERN IN THE TOWN",.08
 2410 DATA 7,4,100,2,7,1.33,7,4,9,4,7,4,6,4,7,4,4,2,7,2.67,7,8,7,1,7,1.33,7,4,9,4,7,4,6,4,7,4,100,5,2,2,7,2.67,7,8
 2420 DATA 7,4,5,4,4,4,2,4,100,2,0,2,4,2,7,2,12,2,100,4,14,4,12,4,11,4,12,4,9,1.33,12,4,100,16,11,1.33,11,4,11,4,7,4,9,4,11,4
 2430 DATA 100,2,12,2,12,2.67,12,8,12,2,7,4,6,4,100,5,5,4,11,4,11,4,11,4,11,4,7,4,5,4,2,4,100,2,0,4,12,4,12,4,12,4,12,4,7,4
 2440 DATA 4,4,0,4,100,5,-1,4,11,4,11,2.67,11,8,11,4,7,4,9,4,11,4,100,2,12,2,100,4,9,2,100,2,7,1.33,7,4,7,1.33,7,4,9,4,7,4,6,4,7,4
 2450 DATA 4,4,7,4,7,4,7,4,7,1.33,7,4,7,1.33,7,4,9,4,7,4,6,4,7,4,100,5,2,2,7,2.67,7,8,7,4,5,4,4,4,2,4,100,2,0,2
 2460 DATA 4,2,7,2,12,2.67,12,8,100,4,14,4,12,4,11,4,12,4,9,1.33,12,4,100,16,11,1.33,11,4,11,4,7,4,9,4,11,4,100,2,12,2,12,2.67,12,8,12,1.33

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top