QUICK Ecke 27 von Harald Schönfeld Hallo allerseits! Nach leichten Verwirrungen geht es nun also weiter mit der QUICK Ecke. Vorweg ein Wort zu QUICK: QUICK hat nun den Sprung über den Kanal und über den großen Teich geschafft! Das heißt es ist nun auch in Großbritannien und in den USA in entsprechenden inter- natioalen Versionen zu erhalten. Ich bin sicher daß es somit bald einige interessante neue Programme die in QUICK geschrieben wurden, geben wird... Melodien für Millionen Naja, eine Million 8 Bitter gibt's wohl nicht ganz :-) Es geht heute also um Melodien, genauer gesagt darum wie man diese in QUICK abspielen kann. QUICK ist zwar für seine Möglichkeit digitalisierte Sounds erklingen zu lassen bekannt, aber daß man auch herkömmliche 4-stimmige Töne erzeugen kann hat bisher niemand so richtig wahrgenommen. Auf jeden Fall ist mir nicht bekannt, daß es einen Musikplayer für QUICK gibt. Anm: steht für den Unterstrich. Der SOUND Befehl In QUICK steht der selbe Befehl zum einschalten der 4 Soundkanäle zur Verfügung wie in BASIC. Auch seine Parameter sind fast die selben: SOUND(K,H,V,L) K ist der Kanal 0 bis 3 H ist die Tonhöhe 0 bis 255 L ist die Lautstärke 0 bis 15 und die Verzerrung entspricht dem halben Wert, den man in BASIC verwenden würde. V von 0 bis 7 Ich denke, jeder weiß, wie man diesen Befehl grundsätzlich benutzt um Melodien abzuspielen. Es gibt aber einige Dinge zu beachten: Die Verzerrung sollte 5 sein, damit man einen reinen Rechteckton hört ( kein Sinus wie meist behauptet ). Den Noten, die man vorspielen will muß man die richtige Tonhöhe zuordnen. Dazu sollte man nicht die Tabellen verwenden, die im Handbuch des Computers oder im Profibuch angegeben sind. Diese sind nämlich falsch. Statt dessen sollte man die Werte verwenden, wie sie im QUICK Quelltext definiert werden. Das Vorgehen Eingentlich ist es ja ganz einfach: Man legt in einem Speicherbereich die Melodie in Form von Werten ab. Pro Note sollte man die gewünschte Tonhöhe, Lautstärke und Länge angeben. Dann liest man diese Werte aus, schaltet den Sound mit der richtigen Tonhöhe und Lautstärke an und schaltet ihn aus, wenn die richtige Zeit abgelaufen ist. Es geht um Zeit und regelmäßiges Vorspielen von Noten. Also was kommt jetzt? Richtig, der VBI :-) Das Vorspielen im VBI Der VBI wird 50 mal pro Sekunde aufgerufen, somit könnte man bis zu 50 Noten pro Kanal pr Sekunde vorspielen. Das reicht vermutlich auch für sehr schnelle Lieder. Im VBI werden also die Melodiedaten aus dem Speicher gelesen und der zugehörige Sound wird eingeschaltet. Nun wird jedesmal wenn der VBI wieder aktiv ist, die Notenlänge um eins erniedrigt. Irgendwann ist sie dann Null. Das ist der Zeitpunkt, wo die nächsten Daten gelesen werden müssen. Irgendwann sind dann keine Daten mehr da. Dieses Melodieende muß natürlich gekennzeichnet werden. Dazu wird einfach in die Lautstärke der zugehörigen Note 128 dazuaddiert. Liest der VBI dann einern Wert >127 weiß er, daß dies die letzte Note war und setzt den Melodiezeiger wieder auf den Anfang der Daten. Die Daten Es gibt viele Molichkeiten, wie man die Daten zum Vorspielen bereitstellen könnte: - Daten von Disk laden: Für später wohl praktisch, aber wie erzeugt man sie? - Daten mit dem DATA-Befehl an eine freie Stelle im Speicher kopieren: Einfach, aber man verschenkt viel Platz, weil die Daten im Programm ja auch schon stehen! :-( - Den INLINE-Befehl benutzen. Genau das machen wir! Man definiert z.B. einfach ein Unterprogramm, das nur einen INLINE-Befehl enthält, der die gesamte Melodie enthält. Mit PADR(Name) erhält man dann die Adresse des Unterprogramms und weiß somit wo die Daten liegen. Tricky aber wahr! Die Noten Um ein paar Noten einzugeben (z.B. 2 Stück) würde der INLINE Befehl grundsätzlich so aussehen: INLINE(+ (+ 121,15,8 96,15,4 )+ Das ist eine Note mit der Tonhöhe 50, der Lautstärke 15 und der Länge 8 Einheiten und eine Note der Höhe 60, Lautstärke 15 und Länge 4. Die Routine zum Vorspielen beherrscht als kleinste Einheit 1/16 Note. Damit ist oben also eine 1/2 und eine 1/4 Note angegeben. Sehr schön ist diese Darstellungsweise aber nicht. Besser ist doch sicher das: INLINE (+ C1,15,T12 E1,15,T14 )+ Und es ist auch ganz einfach zu verwirklichen. Man braucht sich nur eine Reihe von Variablen definieren, die so heißen wie all die verschiedenen Noten und Längen. Diese Variablen werden einer bestimmten Adresse zugeweisen und diese Adresse wird dann automatisch bei INLINE anstelle des Namens eingesetzt. Netterweise wird bei Zeropagevariablen auch nur ein Byte als Adresse verwendet, nicht 2 wie sonst. Die Definitionen für den obigen Fall sind also vorher so vorzunehmen: BYTE (+ C1=121,E1=96 T12=8,T14=4 )+ Natürlich muß man alle Noten von C0 bis C3 und alle Längen von T11 bis T116 definieren. Auch Pausen sind nötig. Dazu benutzt man die Tonhöhe 0 und Lautstärke 0. 2 Problemfälle Tritt 2 mal hintereinander die selbe Tonhöhe auf, so muß man eine kurze Tonpause einlegen, damit das Ohr hört, daß ein neuer Ton begonnen hat. Es gibt aber sog. Haltebögen zwischen 2 gleichen Noten. In so einem Fall darf diese Pause dann nicht erfolgen. Haltebögen werden durch die Addition von 16 zur Lautstärke gekennzeichnet. Somit kann der VBI erkennen, ob er die Note mit oder ohne Pause anspielen soll, wenn sie die selbe Tonhöhe wie die vorige hat. Ein kleiner Trick Das Auslesen der Daten aus dem Melodiefeld in die Variablen, die dann im VBI gebraucht werden könnte man natürlich mit PEEK(ADR,V) machen. Da man aber 3 Werte holen muß, dauert das doch eine ganze Weile (PEEK ist relativ aufwendig). Die Daten, die eine Note beschreiben, liegen ja direkt hintereinader im Speicher. Was liegt also näher, auch die benötigten Variablen hintereinander anzuordnen und dann die Daten aus dem Speicher in die Variablen in einem Rutsch zu kopieren: PLAYER(ADR,0,3,VADR) Das kopiert 3 Datenbytes von ADR nach VADR. Wobei bei VADR die 3 Variablen stationiert sein müssen. Und noch ein Zähler Um die Abspielgeschwindigkeit insgesamt regeln zu können, braucht man nun auch noch einen Zähler, der festlegt, wie oft der VBI auftreten soll, bevor er die Länge der aktuellen Note erniedrigt. All das zeigt das folgende Listing: * MusicPlay * VBI Sound Routine * fuer UserMag * Teil 1 * (c) H. Schoenfeld * NOTENBEZEICHNUNG MIT TONHOEHE BYTE (+ C0=243,C1=121,C2=60,C3=29 CIS0=230,CIS1=114,CIS2=57 DES0=230,DES1=114,DES2=57 D0=217,D1=108,D2=53 DIS0=204,DIS1=102,DIS2=50 ES0=204,ES1=102,ES2=50 E0=193,E1=96,E2=47 F0=182,F1=91,F2=45 FIS0=173,FIS1=85,FIS2=42 GES0=173,GES1=85,GES2=42 G0=162,G1=81,G2=40 GIS0=153,GIS1=76,GIS2=37 AS0=153,AS1=76,AS2=37 A0=144,A1=72,A2=35 AIS0=136,AIS1=68,AIS2=33 B0=136,B1=68,B2=33 H0=128,H1=64,H2=31 P=0 )+ *NOTENLAENGE IN 1/16 BYTE (+ T11=16 T12P=12 T12=8 T14P=6 T14=4 T18P=3 T18=2 T116=1 )+ * VARIABLEN FUER 4 SOUNDKANAELE * DIREKT HINTEREINANDER BYTE (+ TH0=1536 V0=1537 L0=1538 )+ BYTE (+ * TEMPO TEMPO,TEMPZ * ALTE TONHOEHE ATH0 )+ WORD (+ PDR=208 * AKTUELLE ADRESSE DER NOTENDATEN NP0 * ANFANGSADRESSE SNP0 )+ MAIN * ZEIGER AUF NOTENFELD SETZEN PADR(N0) SNP0=PDR NP0=SNP0 * TEMPO EINSTELLEN TEMPO=5 TEMPZ=TEMPO * INITIALISIEREN L0=0 * VBI ZUM VORSPIELEN EINSCHALTEN VBI(PLAY) REPEAT ?(TH0) UNTIL 1=0 ENDMAIN INTER PLAY BEGIN * TEMPOZAEHLER HAT TEMPO ERREICHT? IF TEMPZ=TEMPO * DANN RUECKSETZEN TEMPZ=0 * NOTENLAENGE ABGELAUFEN? IF L0=0 * NEUE MELODIEDATEN IN TH0,L0,V0 * KOPIEREN PLAYER(6,0,3,NP0) * MELODIEDATENZEIGER ERHOEHEN ADD(NP0,3,NP0) * WENN DATENENDE, DANN ZUM ANFANG IF V0>127 NP0=SNP0 ENDIF * WENN KEIN HALTEBOGEN AND(V0,31,V0) IF V0<16 IF ATH0=TH0 * DANN KURZE PAUSE WENN NEUER TON * MIT GLEICHER TONHEOHE SOUND(0,TH0,5,0) ELSE * SONST GLEICH NEUER TON SOUND(0,TH0,5,V0) ENDIF ELSE * MIT HALTEBOGEN GLEICHER TON * OHNE PAUSE AND(V0,15,V0) SOUND(0,TH0,5,V0) ENDIF * ALTE TONHOEHE MERKEN ATH0=TH0 ELSE * TON WIEDER EINSCHALTEN SOUND(0,TH0,5,V0) ENDIF * LAENGE ERNIEDRIGEN L0- ENDIF * TEMPOZAEHLER ERHOEHEN TEMPZ+ ENDVBI * MELODIE FUER "POPCORN" PROC N0 BEGIN INLINE (+ A2,15,T18 G2,15,T18 A2,15,T18 E2,15,T18 C2,15,T18 E2,15,T18 A1,15,T14 A2,15,T18 G2,15,T18 A2,15,T18 E2,15,T18 C2,15,T18 E2,15,T18 A1,15,T14 A2,15,T18 H2,15,T18 C3,15,T18 H2,15,T18 C3,15,T18 A2,15,T18 H2,15,T18 A2,15,T18 H2,15,T18 G2,15,T18 A2,15,T18 G2,15,T18 A2,15,T18 H2,15,T18 C3,143,T14 )+ ENDPROC So, eine Stimme alleine ist ja schon ganz nett. Das nächste Mal wird das Ganze auf 4 Kanäle ausgebaut. P.S.: Wer kennt die Smilies nicht? Kopf um 90 Grad nach links drehen, dann wird alles klar :-)