!0.......^.........^.........^.. !B \H11\H07\H10\H00 PLAY IT AGAIN, SAM !2.......^.........^.........^.........^.........^.........^.... A big noise in programming, Tony Samuels, has composed a zippa- de-do-da of a music package that'll set your Speccy buzzin'. You're not going to believe your ears! !1.......^.........^.........^.........^........ OK, I've got to admit that the Speccy's not exactly famed for its outstanding sound facili- ties. But I've just about had it up to here, what with Commie 64 owners (Wash your mouth out! Ed.) shunning my Speccy's burping sounds and Amstrad owners laughing at its chesty cough. So, to turn the tables on them all, I've written a program that'll transform the Speccy's humble BEEP statements into the most mega- amazing music you've ever heard a machine utter. Well, I'd rather listen to it than to an Amstrad hi-fi system let alone one of their crummy computers! (You tell 'em, Tone! Ed.) What we have here is a program that'll replace the boring bip, bip, bip of the BEEP with a full warp effect. It really does produce synthesised sound! It works by using two sawtooth waveforms in anti-phase with each other - and though even I don't really understand what that means, it doesn't half impress those thicko 64 owners. Still, the mechanics aren't important - all you need to know is how to construct data statements for the BEEP command using length of note followed by pitch of note. Just remember that this program outclasses the sound system in professional Speccy software and now you can include it in your own programs. Roll over Beethoven! !0.......^.........^.........^.. !B SOUND TRACKIN' !1.......^.........^.........^.........^........ Now the first thing you'll presumably want to do is start using synthesised tunes in your own programs, so here goes. First enter and synthe- sise a tune using Samsynth. Then save the compiled tune and write down the number of bytes used and how many notes there are in it. Next load in the synthesiser routine using LOAD "" CODE - the routine is 270 bytes long and loads at location 64750. Right, now load in the comp- iled tune code at an address of your choice, remembering, of course, to clear enough space using the CLEAR command. To play your tune is as simple as POKEing the number of notes and the start address of the tune code into the synthe- siser routine and typing RANDOMIZE USR 64750. Now, don't panic if you haven't quite got all that 'cos I'm going to run through it using a concrete example. Load in Samsynth and then mess about with the tune until it's playing to your tastes. And before you ask, no, I'm not going to tell you what the tune is - you'll only solve that mystery by typing the program! Right, done that? Now save it using option I. Load in the synthesiser routine and clear enough memory for it: !3.......^.........^.........^.........^.. CLEAR 61999: LOAD "" CODE !1.......^.........^.........^.........^........ Now load in the tune code - and don't forget to specify an address: !3.......^.........^.........^.........^.. LOAD "" CODE 62000 !1.......^.........^.........^.........^........ OK, let's put the show on the road: !3.......^.........^.........^.........^.. LET addrs=62000: POKE 64758,addrs-256*INT (addrs/256): POKE 64759,INT (addrs/256): LET notes=137: POKE 64756,notes-256*INT (notes/256): POKE 64757,INT (notes/256) !1.......^.........^.........^.........^........ Finally, pin 'em back and play the tune with: !3.......^.........^.........^.........^.. RANDOMIZE USR 64750 !0.......^.........^.........^.. !B !P\H11\H07\H10\H00\H13\H00 GET NOTED! !2.......^.........^.........^.........^.........^.........^.... Unless you're a budding Beethoven, you're going to want to add a touch of class to your programs using tried and tested pieces of music. Well, it's quite possible to transfer anything from Dvorak to Duran Duran using Samsynth, provided you've got the sheet music in front of you. And what's more, you don't have to read a note of music - though it'll help! First, you must learn to recognise the comparative lengths of each note and be able to work out their pitches. Take a look at the illustration below - it'll help you to work out the data statements for transcribing almost any piece of music. Remember that they take the form, length of note followed by pitch of note. You'll also have to watch out for sharp (#) notes which raise the pitch by a value of one and flat (\H91) notes that decrease it by the same amount. !SYR20_251 Now take a look at this snatch of our mystery tune and practise turning the notes here into data statements. With a bit of trial and error, you should soon have it cracked and you can move on to the music of your choice. !SYR20_252 !SYR20_253 !0.......^.........^.........^.. !B !P\H11\H07\H10\H00\H13\H00 MUSICAL MENU !1.......^.........^.........^.........^........ !P\H11\H07\H10\H00\H13\H00 Here are the full details of all the options offered to you on the menu. !2.......^.........^.........^.........^.........^.........^.... S Lets you change the speed that the synthesised tune is played at. A Compiles the BEEP values in the data statements into a form that can be used by the synthesiser routine. W Lets you change the wave length and depth values. These really determine the synthesised sound effects that the routine can produce. P This is the play option. You'll find that certain wave- lengths and depths will cause a clicking sound - when this happens just return to the menu and change the values. C Now you can really drive 'em up the wall. This option plays the tune over and over and over ... I You'll find this the most important option when you come to incorporate synthesized tunes in your own programs. Select it and you'll be told how many notes in your tune and how many bytes it uses. Write them down for reference later. Next enter the name you want the block of code to be saved as - you'll be returned to the menu as soon as it's saved. U This option saves the Basic loader with your tune data and the synthesizer routine. To load it back in, just type LOAD "". Easy innit? B For all you nostalgia freaks, this lets you hear Speccy music as it used to be played - in glorious Beeps! Oh, they don't write 'em like they used to - thank goodness. !0.......^.........^.........^.. !B SAMSYNTH !1.......^.........^.........^.........^........ Yep, it's our ol' friend the Hex loader. What more is there to say but type it in and run it. 'Way you go then ... !0.......^.........^.........^.. 10 CLEAR 62199 20 INPUT "START LOCATION >";sl 40 LET a=10: LET b=11: LET c=1 2: LET d=13: LET e=14: LET f=15 50 LET cq=0 60 LET t=0 100 INPUT h$ 105 IF LEN h$<>2 THEN GO TO 10 0 107 IF h$="XX" OR h$="xx" THEN GO TO 200 110 LET h=0 120 LET h=h+16*VAL h$(1) 130 LET h=h+VAL h$(2) 140 POKE sl,h: LET sl=sl+1 145 LET cq=cq+h 150 PRINT TAB (t);h$;: LET t=t+ 3: IF t=33 THEN LET t=0: PRINT 160 GO TO 100 200 INPUT "CHECKSUM >";cs 210 IF cs<>cq THEN PRINT : PRI NT "DATA ENTRY ERROR": STOP 220 PRINT : PRINT "DATA OKAY" !1.......^.........^.........^.........^........ !B With the Hex loader in, it's time to tackle the code. Type it in one byte at a time until you're asked for the checksum at the end. If it's wrong, you'll be given an error report and you'll just have to go back and re-check your typing. Once it's correct, save it to tape. !0.......^.........^.........^.. C3 A9 FD C3 03 FD 6B 00 02 80 0C 00 55 0A 00 00 0A 00 0A 00 00 F3 21 00 00 E5 2A F8 FC 2B 22 F8 FC 3E 00 BC C2 1C FD BD C2 1C FD E1 FB C9 2A FA FC ED 5B FC FC ED 52 11 01 00 CD B5 03 2A FC FC 11 01 00 CD B5 03 3E 7F DB FE FE FE CA 19 FD 2A FC FC ED 4B FE FC 09 22 FC FC E1 23 3A FF FC BC C2 07 FD 3A 00 FD BD C2 07 FD E5 2A F8 FC 2B 22 F8 FC 3E 00 BC C2 6D FD BD C2 6D FD E1 FB C9 2A FA FC ED 5B FC FC ED 52 11 01 00 CD B5 03 2A FC FC 11 01 00 CD B5 03 3E 7F DB FE FE FE CA 19 FD 2A FC FC ED 4B FE FC ED 42 22 FC FC E1 2B 3E 00 BC C2 58 FD BD C2 58 FD C3 04 FD 2A F4 FC ED 4B F6 FC 0A 32 F8 FC 03 0A 32 F9 FC 03 0A 32 FA FC 03 0A 32 FB FC 03 0A 32 FC FC 03 0A 32 FD FC 03 0A 32 FE FC 03 0A 32 FF FC 03 0A 03 32 00 FD C5 E5 CD F1 FC CD 8E 02 7B FE FF E1 C1 CA F0 FD 3E 64 C9 2D 3E 00 BD C8 C3 B0 FD 00 00 00 00 !1.......^.........^.........^.........^........ !B Do I hear music? Not yet - just type in the Basic loader and save it in front of the code on your tape. Then load the whole kaboodle back in again - Basic plus code. The Basic listing already has an example tune in it, so run the program and choose the Synthesise routine. Then pin back your lugholes. If you want to put your tune into the program then you must enter it as data statements using the BEEP command format (length of note, pitch of note) between lines 1-8999. !0.......^.........^.........^.. 10 DATA 2,7,3,12,1,14,1,16,1,1 4,1,12,1,11,4,9,4,21,2,19,2,16,1 ,17,1,16,1,14,1,12,6,14 20 DATA 2,7,2,12,1,12,1,14,1,1 6,1,14,1,12,1,11,4,9,4,21,2,19,2 ,16,1,17,1,16,1,14,1,16,6,12 30 DATA 1,19,1,19,2,12,1,12,1, 14,1,16,1,14,1,12,1,11,4,9,4,21, 2,19,2,16,1,17,1,16,1,14,1,12,6, 14 40 DATA 2,7,2,12,1,12,1,14,1,1 6,1,14,1,12,1,11,4,9,4,21,2,19,2 ,16,1,17,1,16,1,14,1,16,6,12 50 DATA 2,19,3,24,1,26,1,28,1, 26,1,24,1,23,2,24,6,19,2,24,2,16 ,1,17,1,16,1,14,1,12,6,14,2,7,2, 12,1,12,1,14,1,16,1,14,1,12,1,11 ,4,9,4,21,2,19,2,16,1,17,1,16,1, 14,1,16,6,12,2,19,2,24,1,24,1,26 ,1,28,1,26,1,24,1,23,1,24,1,23,2 ,21,3,19,1,19,2,24,2,16,1,17,1,1 6,1,14,1,12,6,14 60 DATA 2,12,1,12,1,14,1,16,1, 14,1,12,1,11,4,9,4,21,2,19,2,16, 1,17,1,16,1,14,1,16,12,12 !2.......^.........^.........^.........^.........^.........^.... Lines 10-60 These lines contain the data for your music. This is the area that you'll need to store your own music data in. !0.......^.........^.........^.. 9000 DATA 9999,9999: RESTORE 1 !2.......^.........^.........^.........^.........^.........^.... Line 9000 This line marks the end of your music data. !0.......^.........^.........^.. 9005 CLEAR 32759 : LET e=0 !2.......^.........^.........^.........^.........^.........^.... Line 9005 This clears some space in memory for the machine code routine, plus a bit of room for your tune (hey, lyrics already!). !0.......^.........^.........^.. 9010 LET speed=PEEK 32760: LET d epth=PEEK 32762: LET wavel=PEEK 32761 !2.......^.........^.........^.........^.........^.........^.... Line 9010 The values of Speed, Depth and Wavelength are stored in high memory so that they're not lost when the program's run. !0.......^.........^.........^.. 9015 INK 7: PAPER 1: BORDER 1: C LS 9020 PRINT " **** SAMSYNTH ****" 9025 PRINT : PRINT : PRINT : PRI NT 9030 PRINT "PRESS :- S TO CHANGE SPEED A TO SYNTHE SIZE W TO CHANGE WAVE EFFECT": PRINT 9035 PRINT " P TO PLAY C FOR CONTI NUOUS PLAY" 9036 PRINT '" I SAVE COM PILED TUNE U SAVE DAT A AND PROG" 9037 PRINT '" B TO PLAY TUNE IN BEEPS" !2.......^.........^.........^.........^.........^.........^.... Lines 9015-9037 This routine prints the menu. !0.......^.........^.........^.. 9040 LET a$=INKEY$ 9041 IF a$<>"b" AND a$<>"B" THEN GO TO 9045 9042 RESTORE : INPUT "SPEED ";sp p 9043 READ b1,b2: IF b1=9999 OR b 2=9999 THEN GO TO 9045 9044 BEEP b1/spp,b2: GO TO 9043 9045 IF a$="s" OR a$="S" THEN C LS : PRINT " PRESENT SPEED I S=";speed: INPUT "TYPE IN NEW SP EED=";speed: POKE 32760,speed: G O TO 9015 9046 IF a$="U" OR a$="u" THEN I NPUT "FILE NAME>";f$: SAVE f$ LI NE 9999: SAVE "SAMSYNTHC"CODE 64 750,270 9047 IF e<>0 THEN IF a$="I" OR a$="i" THEN CLS : PRINT "TUNE L ENGTH ";e;" NOTES"''e*9;" BYTES USED": INPUT "FILENAME>";f$: SAV E f$CODE 32770,e*9: GO TO 9000 9048 IF a$="I" OR a$="i" AND e=0 THEN CLS : PRINT "YOU MUST SYN THESIZE THE TUNE BEFORE YOU C AN SAVE IT": PAUSE 0: PAUSE 0: G O TO 9000 9050 IF a$="W" OR a$="w" THEN C LS : PRINT " PRESENT DEPTH I S=";depth: PRINT : PRINT " PRE SENT WAVE LENGTH IS=";wavel: INP UT "TYPE IN NEW DEPTH=";depth: I NPUT "TYPE IN NEW WAVE LENGTH="; wavel: POKE 32761,wavel: POKE 32 762,depth: GO TO 9015 9055 IF a$="A" OR a$="a" THEN C LS : GO TO 9075 9060 IF a$="p" OR a$="P" THEN C LS : PRINT "CERTAIN VALUES FOR W AVELENGTH, DEPTH AND SPEED WILL PRODUCE A CLICKING SOUND,IF TH IS HAPPENS, PRESS ANY KEY TO RET URN TO MENU": RANDOMIZE USR 6475 0: GO TO 9015 9065 IF a$="c" OR a$="C" THEN C LS : PRINT "TO ESCAPE,PRESS BREA K": PRINT : PRINT : PRINT "THEN TYPE GOTO 9000 TO CONTINUE": RAN DOMIZE USR 64750: PAUSE 50: GO T O 9065 9070 GO TO 9040 !2.......^.........^.........^.........^.........^.........^.... Lines 9040-9070 This section reads the keyboard and performs the appropriate function. !0.......^.........^.........^.. 9075 LET d=32770 !2.......^.........^.........^.........^.........^.........^.... Line 9075 This line sets a counter to be used in the main loop following. !0.......^.........^.........^.. 9080 RESTORE : DIM n(150,2): FOR f=1 TO 150: READ x,z: IF x=9999 AND z=x THEN GO TO 9090 9085 LET n(f,1)=x: LET n(f,2)=z: NEXT f: STOP 9090 LET f=f-1: PRINT AT 8,0;"No te # " 9095 FOR e=1 TO f 9100 PRINT AT 8,8;e 9105 LET freq=(1.0594631^n(e,2)) *100 9110 LET len=INT (freq*(n(e,1)/s peed)) 9115 POKE d,len-(INT (len/256)*2 56) 9120 LET d=d+1 9125 POKE d,INT (len/256) 9130 LET pit=INT ((466432/freq)- 128) 9135 LET d=d+1 9140 POKE d,pit-(INT (pit/256)*2 56) 9145 LET d=d+1 9150 POKE d,INT (pit/256) 9155 LET d=d+1 9160 POKE d,0 9165 LET d=d+1 9170 POKE d,0 9175 LET d=d+1 9180 LET w=wavel: LET di=depth 9185 POKE d,w 9190 LET d=d+1 9195 POKE d,INT (di/256) 9200 LET d=d+1 9205 POKE d,di-(INT (di/256)*256 ) 9210 LET d=d+1 9215 NEXT e 9220 LET e=e-1 !2.......^.........^.........^.........^.........^.........^.... Lines 9080-9220 This is the main loop, which puts the ordinary Speccy BEEP values through the mangle of Tony's equation crunching. The remains are POKEd into memory. If you find that you have a tune longer than 150 notes, then change the value of N() and the size of the F loop in line 9080 to the required length. !0.......^.........^.........^.. 9225 POKE 64758,32770-256*INT (3 2770/256) 9230 POKE 64759,INT (32770/256) 9235 POKE 64756,e-256*INT (e/256 ) 9240 POKE 64757,INT (e/256) 9245 GO TO 9015 !2.......^.........^.........^.........^.........^.........^.... Lines 9225-9245 These lines POKE the start location of the compiled music, plus the number of notes used, into the synth routine ready for play. Line 9245 sends the action back to the main menu. !0.......^.........^.........^.. 9999 CLEAR 32759: LOAD "SAMSYNTH C"CODE !2.......^.........^.........^.........^.........^.........^.... Line 9999 When you save the program, use the format SAVE "SAMSYNTH" LINE 9999 and save the code directly after with SAVE "SAMSYNTHC" CODE 64750,270. Or, alternatively, you could use option 'U' from the main menu. !1.......^.........^.........^.........^........ !B -- from Your Spectrum #20 (Nov.1985) -- !$ ..................... Look to see which key the tune is played in. Here it's C Major - you can tell by the absence of sharps and flats, so you don't have to worry about altering the pitch values. ..................... Though this note has a value of four in length, you'll have to extend it to six to account for the rest that follows it. To give you a start, we'll give you this one - it's BEEP value is 6,14. Check it out on the chart. ..................... Don't be put off by the double tail. It just means that the note is in both the melody and harmony lines. You should still include it because it has an upward pointing tail, the symbol of a melodic note. ..................... This is the bass clef but don't let it bother you. Most of the time it only holds the harmony while we're concerned with the notes that play the melody. They're the ones on the upper stave, the treble clef, with their tails pointing upwards. ..................... Take a rest - you deserve it! Here the rest symbol is worth one beat out of the whole bar but, as Samsynth has no rest facilities (Unlike its half-awake programmer! Ed.), it's better to extend the length of the previous note by the length of the rest. ..................... When two or more notes are joined together, they lose none of their indi- vidual values. These two and the four following still count as one each.