C 64
Musik

Sound Machine

Mit Sound Machine können nun auch Sie, wie in professionellen Spielen, unabhängige Hintergrundmusik programmieren.

Sound Machine besteht aus zwei Programmen, einem Maschinenprogramm, das die Musik später spielt, und einem Basic-Programm, mit dem Sie die Melodie einfach eingeben können.

Das Maschinenprogramm Sound Machine (Listing 1) belegt den Speicherplatz von dezimal 53004 bis 53187. Nach dem Abtippen mit dem MSE kann es mit »LOAD "SOUND MACHINE",8,1« jederzeit geladen werden. Es benutzt nur die erste Stimme des SID, die anderen bleiben für Geräuscheffekte frei. Eine Melodie wird mit SYS 53004 gestartet.

Die Noten müssen ab 49152 im Speicher stehen. Zur Noteneingabe können Sie Listing 2 verwenden.

Die Melodie kann mit SYS 53027 gestoppt werden.

Bevor man das Programm Noteneingabe startet, muß sich Sound Machine schon im Speicher befinden.

Das Programm Noteneingabe löscht als erstes den Notenspeicher. Es fragt dann nach der Zeit, die eine Viertelnote gespielt werden soll. Durch diesen Wert wird also die Geschwindigkeit ihrer Melodie festgelegt.

Jetzt kann die eigentliche Noteneingabe beginnen:

Auf die Frage »NOTE : ?«gibt man zuerst die Notenbezeichnung, dann die Oktave ein. Einige Beispiele wären: »C5«, »A#3«. Erniedrigte Noten können nicht direkt eingegeben werden. Hb3 muß also als »A#3« eingegeben werden. Pausen gibt man mit »P« oder »PAUSE« ein.

Als Antwort auf die Frage »ZEIT: ?« gibt man die Notenlänge im Format x/y ein. Zwei Beispiele: Eine ganze Note wird als »1/1«, eine punktierte halbe als »3/4« eingegeben, x kann maximal doppelt so groß wie y sein, für y sind die Werte 1, 2, 4, 8, 16, 32 und 64 erlaubt.

Aus jeder der gewählten Funktionen kommt man mit »↑« zurück ins Hauptprogramm. Das Programm geht davon aus, daß ein Floppy-Laufwerk 1541 am seriellen Bus angeschlossen ist. Beabsichtigt man, das Programm mit einer Datasette zu betreiben, so sind einige Zeilen wie folgt zu ändern:

1130 1130 OPEN 1,1,1,A$
1185 1185 CLOSE 1
1190 1190 PRINT:PRINT »TASTE DRUECKEN«
2050 2050 REM
2055 2055 OPEN 1,1,0,A$
2180 2180 REM
2185 2185 PRINT:PRINT »TASTE DRUECKEN«
(Arno Muhr/bs)
10 rem *******************************
20 rem *       'sound-machine'       *
30 rem *  fuer den c64               *
40 rem *  von:    arno muhr          *
50 rem *          unterstr. 32       *
60 rem *          5176 inden-frenz   *
70 rem *******************************
80 :
100 for i=53004 to 53187
110 read d:k=k+d:poke i,d
120 next
130 if k<>22158 then print"fehler in datas !":end
140 print "starten mit 'sys 53004'"
150 :
32000 data169,0,141,0,212,141,1,212,141,7,220,32,49,207,32,89,207,169,89,141
32001 data15,220,96,169,8,141,15,220,169,0,141,4,212,141,24,212,96,169,32,141
32002 data2,212,169,8,141,3,212,169,24,141,5,212,169,82,141,6,212,169,33,141
32003 data4,212,169,15,141,24,212,162,0,160,192,134,164,132,165,88,96,120,169
32004 data103,141,20,3,169,207,141,21,3,88,96,234,120,173,13,220,41,2,240,3,32
32005 data119,207,88,76,49,234,234,169,0,141,7,220,169,24,141,15,220,169,16,141
32006 data4,212,160,0,177,164,141,0,212,200,177,164,141,1,212,240,5,169,65,141
32007 data4,212,200,177,164,141,6,220,240,20,234,24,165,164,105,3,133,164,144
32008 data2,230,165,169,89,141,15,220,234,96,234,169,0,133,164,169,192,133,165
32009 data169,89,141,15,220,96
Listing 1. Das Maschinenprogramm »Sound Machine« muß mit dem MSE eingegeben werden.
100 rem *******************************
110 rem * + -    noteneingabe     - + *
120 rem * zum programm 'sound-machine'*
130 rem * fuer den c64                *
140 rem * von:   arno muhr            *
150 rem *        unterstr. 32         *
160 rem *        5176 inden-frenz     *
170 rem *******************************
180 poke 53280,9:poke 53281,5:print"{blk}"
190 print"{clr}{dish}{down}{swlc}{rght}bitte ca. 13  sekunden warten"
200 na=49152:for i=na to na+3000:pokei,0:next
210 dim nw(5,203),t(5,203):gosub 320
220 input"{clr}{down}{rght}zeit fuer 1/4 note (1-120):";gt
230 gt=int(gt):gt=gt/120*32:if gt<=0 or gt>32 then 220
240 print chr$(147)
250 print chr$(19);c/3+1"{left} . note : ":n$=""
260 input "note  : ";n$
270 goto 610
280 w=1
290 for i=1 to 98:if n$=n$(i) then w=w(i)
300 next
310 return
320 rem *** notenwerte einlesen ***
330 dim n$(98),w(98)
340 for i=1 to 98:read n$
350 n$(i)=n$:next
360 for i=1 to 98:read w
370 w(i)=w:next
380 return
390 rem *** notendatas ***
400 data c0,c#0,d0,d#0,e0,f0,f#0,g0,g#0,a0,a#0,h0
410 data c1,c#1,d1,d#1,e1,f1,f#1,g1,g#1,a1,a#1,h1
420 data c2,c#2,d2,d#2,e2,f2,f#2,g2,g#2,a2,a#2,h2
430 data c3,c#3,d3,d#3,e3,f3,f#3,g3,g#3,a3,a#3,h3
440 data c4,c#4,d4,d#4,e4,f4,f#4,g4,g#4,a4,a#4,h4
450 data c5,c#5,d5,d#5,e5,f5,f#5,g5,g#5,a5,a#5,h5
460 data c6,c#6,d6,d#6,e6,f6,f#6,g6,g#6,a6,a#6,h6
470 data c7,c#7,d7,d#7,e7,f7,f#7,g7,g#7,a7,a#7,h7
480 data pause,p
490 data 268,284,301,318,337,358,379,401,425,451,477,506,536,568,602,637,675
500 data 716,758,803,851,902,955,1012,1072,1136,1204,1275,1351,1432,1517,1607
510 data 1703,1804,1911,2025,2145,2273,2408,2551,2703,2864,3034,3215,3406,3608
520 data 3823,4050,4291,4547,4817,5103,5407,5728,6069,6430,6812,7217,7647,8101
530 data 8583,9094,9634,10207,10814,11457,12139,12860,13625,14435,15294,16203
540 data 17167,18188,19269,20415,21629,22915,24278,25721,27251,28871,30588
550 data 32407,34334,36376,38539,40830,43258,45830,48556,51443,54502,57743
560 data 61176,64814,0,0
570 :
580 rem   ******************
590 rem   *+- funktionen -+*
600 rem   ******************
610 :
620 if n$="-" and c=>3 then c=c-3:goto 250
630 if n$="-"      then print "erste note !  ":goto 250
640 if n$="+"      then c=c+3:goto 250
650 if n$="save"   then 1120
660 if n$="load"   then 1870
670 if n$="def."   then 1280
680 if n$="copy"   then 1650
690 if n$="insert" then 1470
700 if n$="quit"   then 1040
710 if n$="on"     then sys 53004:goto 250
720 if n$="off"    then sys 53027:goto 250
730 if n$="new"    then c=0:goto 240
740 if n$="clear"  then run
750 if n$="set end"then 1060
760 gosub 280
770 input "zeit  : ";t$:t$=t$+"  "
780 print "                          {left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}";
790 if w=1 then print "noten fehler!":if zz<>1 goto 250
800 if w=1 then return
810 hb=int(w/256):lb=w-256*hb
820 a=val(t$):aa=3:if a>9 then aa=4
830 a$=mid$(t$,aa,2):t=0
840 a1=val(a$)
850 if a1=64 then t=2
860 if a1=32 then t=4
870 if a1=16 then t=8
880 if a1=08 then t=16
890 if a1=04 then t=32
900 if a1=02 then t=64
910 if a1=01 then t=127
920 if t=0 then print" zeit fehler!":if zz<>1 then goto 250
930 if t=0 then return
940 t=t/32*gt:t=t*a
950 if t>255 then print " zeit zu lang !":if zz<>1 goto 250
960 if t>255 then return
970 if zz=1 then return
980 poke 49152+c,lb
990 poke 49153+c,hb
1000 poke 49154+c,t
1010 c=c+3
1020 goto 250
1030 :
1040 for i=0 to 9:poke 49152+c+i,0:next
1050 end
1060 rem *** set end ***
1070 rem -ende des stueckes makieren
1080 poke na+c,0
1090 poke na+c+1,0
1100 poke na+c+2,0
1110 goto 250
1120 rem *** save ***
1130 rem -abspeichern von musikstuecken
1140 sys 53027
1150 i=0:print "{clr}{down}{rght}abspeichern "
1160 input "{clr}{down}{rght}titel ";a$
1170 if len(a$)>16 then 1150
1180 if a$="^" then 240
1190 open 1,8,1,a$
1200 print#1,chr$(0);chr$(192);
1210 :np=peek(49152+i)
1220 :print#1,chr$(np);
1230 :i=i+1:if i<=c then 1210
1240 print#1,chr$(0);chr$(0);chr$(0)
1250 close 1:gosub 2380
1260 print"{down}{rght}";e;z$:print"{down}{rght}taste druecken "
1270 poke 198,0:wait 198,1:poke198,0:goto 240
1280 rem *** def. ***
1290 rem -definieren einer notenfolge
1300 print "{clr}":nn=0
1310 if ns>5 then print"es bestehen schon 6 ":fori=0to999:next:print"{clr}":goto250
1320 print"{home}{down}{rght}definitionfile nr.";ns:print nn+1;"{left} . note"
1330 input "{down}note  : ";n$
1340 if n$="end" then 1430
1350 if n$="^" then 240
1360 if n$="-" then nn=nn-1:goto 1320
1370 if n$="+" then nn=nn+1:goto 1320
1380 gosub 280:zz=1:gosub 770:zz=0
1390 if t=0 or t>255 or w=1 then 1320
1400 nw(ns,nn)=w:t(ns,nn)=t
1410 nn=nn+1:if nn<201 then 1320
1420 print "definitionfile is voll!"
1430 w=0:t=0:for i=1 to 2:nn=nn+1:nw(ns,nn)=0:t(ns,nn)=0:next
1440 for i=1 to 999:next:print"{clr}"
1450 ns=ns+1:goto 250
1460 :
1470 rem *** insert ***
1480 rem -einfuegen einer definition
1490 :
1500 print "{clr}{down}{rght}definitionfile einfuegen"
1510 print "{down}{rght}nr. 0-5 oder ^"
1520 poke 198,0:wait 198,1:get a$
1530 if a$="^" then 1630
1540 if a$<"0" or a$>"5" then 1520
1550 ni=val(a$):a=0
1560 if ni>ns then 1630
1570 :p2=int(nw(ni,a)/256):p1=nw(ni,a)-256*p2:p3=t(ni,a)
1580 :poke 49152+c,p1
1590 :poke 49153+c,p2
1600 :poke 49154+c,255-p3
1610 a=a+1:c=c+3:if p3<>0 then 1570
1620 c=c-3
1630 print "{clr}":goto 250
1640 :
1650 rem *** copy ***
1660 rem -kopieren von notenreihen
1670 :
1680 print "{clr}{down}{rght}copy"
1690 input "{down}{rght}erste note  :";a$
1700 a=val (a$)
1710 input "{rght}letzte note :";b
1720 a=int(a):b=int(b)
1730 if a<1 or b<1 then 240
1740 x=1:if a>b then x=-1
1750 if a>c/3 or b>c/3 then 240
1760 if a<b then a=a-x:b=b-x
1770 if a>b then a=a+x:b=b+x
1780 :
1790 for i=a to b step x
1800 :poke 49152+c,peek(49152+i*3)
1810 :poke 49153+c,peek(49153+i*3)
1820 :poke 49154+c,peek(49154+i*3)
1830 :c=c+3
1840 next
1850 goto 240
1860 :
1870 rem *** load ***
1880 rem -laden von musikstuecken und $
1890 sys 53027
1900 print "{clr}{down}{rght}load song oder directory"
1910 input "{down}{rght}titel :";a$
1920 if a$="$" then 2150
1930 if a$="^" then 240
1940 input "{down}{rght}anhaengen (j/n) :";b$
1950 if b$="^" then 240
1960 open 1,8,0,a$:gosub 2380:if e<>0 then 2120
1970 open 1,8,0,a$
1980 get#1,c$,c$
1990 if b$<>"j" and b$<>"ja" then c=0
2000 a=1
2010 :get#1,c$
2020 :a2=a1:a1=a
2030 :if c$<=chr$(0) then a=0:goto 2050
2040 :a=asc(c$)
2050 :poke 49152+c,a
2060 :c=c+1
2070 :if a=0 and a1=a and a2=a then 2090
2080 :goto 2010
2090 c=c-3
2100 close 1
2110 gosub 2380
2120 print"{down}{rght}";e;z$:print"{down}{rght}taste druecken "
2130 poke 198,0:wait 198,1:poke198,0:goto 240
2140 :
2150 rem --- directory anzeigen ---
2160 :
2170 open 1,8,0,"$":kv=0
2180 for i=0 to 30:get#1,a$:b$=b$+a$:next
2190 print"  ";b$
2200 get#1,a$,b$,e$,f$,g$:for i=0 to 26:get#1,d$:c$=c$+d$:next
2210 if f$<=chr$(0) then a=0:goto 2230
2220 a=asc(f$)
2230 if g$<=chr$(0) then b=0:goto 2250
2240 b=asc(g$)
2250 d=a+256*b
2260 if c$="GGGGGGGGGGGGGGGGGGGGGGGGGGG" then c$="":goto 2340: rem -27 shift g-
2270 print d;c$:c$=""
2280 kv=kv+1:if kv=22 then 2300
2290 goto 2200
2300 kv=0:print "{down}{rght}taste druecken"
2310 poke 198,0:wait 198,1
2320 print"{up}                    ":print"{up}{up}{up}"
2330 goto 2200
2340 kv=0:print "{down}{rght}taste druecken"
2350 poke 198,0:wait 198,1
2360 close 1:poke 198,0:goto 1870
2370 :
2380 rem +++ fehlerkanal abfragen +++
2390 open 2,8,15
2400 input#2,e,z$,t,s
2410 close 1
2420 close 2
2430 return
Listing 2. Mit diesem Programm können einfach Musikstücke programmiert werden
PDF Diesen Artikel als PDF herunterladen
Mastodon Diesen Artikel auf Mastodon teilen
← Vorheriger ArtikelNächster Artikel →