Monday, 27 April 2020

Hangkeltés a régi számítógépek basicjében

Régi számítógépeken zenét programozni legegyszerűbben a beépített basic programozási nyelven lehet. A hangchip négyszögjelét a legtöbb számítógépen a SOUND utasítással szólaltathatjuk meg, egyes gépeken a SOUND mellett vagy helyett más utasítás is rendelkezésre áll.

A SOUND utasítás

A SOUND utasításnak megadhatunk paramétereket. Így állíthatjuk be elsősorban a hang magasságát, hosszát, egyes számítógépeken a hang más tulajdonságait is, pl. hangerejét. Néhány gépen az egyes paramétereknek külön nevük is van, ilyenkor a paraméterek sorrendje tetszőleges. Más gépeken nincs külön nevük a paramétereknek, ilyenkor a paraméterek sorrendje kötött, az adott sorszámú paraméterrel lehet az adott hangtulajdonságot állítani.

Enterprise-on már a korábbi Enterpress számokból ismerhetjük a SOUND utasítás rejtelmeit. Az alap, hogy a PITCH paraméter után a hangmagasságot, a DURATION után a hosszt adhatjuk meg, de ezeken kívül is még sok paraméter megadható (LEFT, RIGHT, STYLE, SYNC, ENVELOPE, INTERRUPT):

   SOUND PITCH [hangmagasság],DURATION [hossz], ... 

      [hangmagasság] - 0 és 127 közötti érték

Hangmagasságból az 1 jelenti a legmélyebb C hangot, és félhangonként a magasabb hangok felé haladva eggyel növelni kell a szám értékét. Így a 2 Cisz, a 3 D, a 4 Disz, az 5 E, a 6 F hangot jelöl, és így tovább. A normál C hangot a 37 jelöli. Mindig 12-t kell hozzáadni az értékhez, ha egy oktávval magasabb hangot akarunk megszólaltatni. (Így a C hangot az egyes oktávokban a következő számok jelölik: 1, 13, 25, 37, 49, 61, 73, 85.) A legmagasabb hangot 127-tel érhetjük el elméletileg, gyakorlatilag azonban nem használunk ilyen magas hangokat a zenében.
A SOUND paramétereinek sorrendje Enterprise-on tetszőleges, hiszen a paraméter neve egyértelműen utal arra.
Burkológörbét is megadhatunk az ENVELOPE NUMBER utasítással. Ennek használatát biztos mindenki ismeri, a gépkönyvben részletesen le van írva.
Egyedülálló Enterprise-on a PING parancs, mely nem paraméterezhető, és egy magas, lecsengő hangot ad ki. Hasonló, mint amikor írógéppel a sor végére értünk.
Videoton TVC-n egyetlen hangcsatornát használhatunk. Ez azt jelenti, hogy lényegében csak egyetlen egy szólamban szólaltathatunk meg zenét, egyidejűleg több hang nem szólhat egyszerre. (Azonban megoldható, hogy két hang egymást nagyon gyorsan váltva szóljon párhuzamosan, így hasonló érzetet kelt, mintha egyszerre szólnának.)
TVC-n egy sound utasítás a következőképpen néz ki:

   SOUND; PITCH [hangmagasság],DURATION [hossz],VOLUME [hangerő]

      ; - nincs interrupt
      [hangmagasság] - 0 és 4095 közötti érték
      [hangerő] - 0 és 15 közötti érték

A DURATION után 1/50 másodpercben adhatjuk meg a hang hosszát, akárcsak Enterprise-on, tehát az 50-es érték 1 másodperc hosszú hangot eredményez. (Azonban TVC-n a DURATION 1 rövidebb hangot eredményez, mint EP-n, így TVC-n ezt kihasználva alaphelyzetben változatosabb hangzások állíthatók elő egyetlen hangcsatornán.)
A PITCH paramétere az azonos szavak ellenére teljesen más, mint Enterprise-on. A legmélyebb elérhető zenei hangot a 110 adja, ez egy G hang. Megadható ennél kisebb szám is, de még a 0 sem mélyebb annyival, hogy fél hanggal nagyobb legyen az eltérés a G-hez képest. A legmagasabb elérhető zenei hang a dokumentáció szerint 4047, ez egy H hang. (A dokumentáció pdf formátumban letölthető, annak az 57. oldalán található meg, milyen zenei hanghoz milyen PITCH érték tartozik.) Megadható ennél nagyobb szám is, azonban ilyen magas hangok esetében kevesebb frekvenciát tud a TVC hangchipje megszólaltatni, mint az alacsonyabb frekvenciáknál, és nem jelöl egyik egész érték sem olyan frekvenciát, amely adott zenei hangnak megfelelne, törteket pedig nem támogat a TVC PITCH paramétere (az Enterprise-é igen). Mély hangokból többet tud a gép megszólaltatni, mint magasból, egy mély G hangnak 110  felel meg, míg az emelletti Gisz-nek 334, tehát 224-et kell a 110-hez hozzáadni, hogy annál egy félhanggal magasabb hangot kapjunk, a többi szám köztes hangmagasságot jelöl. A 4047-tel jelölt H hangnál egy félhanggal mélyebb hangot a 4044-gyel adhatjuk meg, tehát itt már csak 3 a különbség, ami lefedi a köztes hangokat. A két félhang közötti PITCH-beli különbség fokozatosan csökken, ahogy a mély hangok felől a magas hangok felé haladunk. Bonyolult képlettel számítható ki, hogy egyes zenei hangokhoz milyen PITCH érték tartozik, így a leginkább az használható, hogy az előre elkészített táblázatból (lásd a fent linkelt dokumentációt) mindig megnézzük, milyen PITCH érték tartozik a kívánt zenei hanghoz.
TVC-n a SOUND utasítás alapból mindig megszakítja azt a hangot, amely korábban megszólalt, de még szól. (Olyan, mintha EP-n kiadnának a sound mellé az interrupt paramétert is.) Így alapból eléggé gyorsan „ledarálna" egy zenét a gép, ha sosem várná meg az előző hang végét. Hogy kikapcsoljuk ezt, meg kell adni egy pontosvesszőt a SOUND után, így az adott hang mindenképpen addig fog szólni, amekkora hosszúság meg van adva.
TVC-n a hangerőt a SOUND utasítás VOLUME paraméterével adhatjuk meg. A SOUND VOLUME 0 nem ad ki hangot, a VOLUME 1 a leghalkabb, a VOLUME 15 a leghangosabb. A SOUND VOLUME 16 nem ad ki hangot (tehát olyan, mintha 0-át adtunk volna meg), a SOUND 17 olyan, mint az 1, és ez így megy egészen 255-ig. A SOUND VOLUME n+(m*16) ugyanazt a hangerőt eredményezi, mint ha csak n lenne megadva, de csak amíg 256 alatt van az eredmény, mert a 256 már hibát okoz. (Enterprise-on a hangerőt a LEFT és a RIGHT paraméterekkel állíthatjuk, külön a bal és a jobb csatornán 0 és 255 számot megadva, 0 értékre nincs hang, 255 a leghangosabb. Enterprise-on sem adhatunk meg 255-nél nagyobb számot, és megadhatunk negatív számokat -256-ig: a -1 a leghangosabb, a -256-ra pedig nincs hang.)

A Plus 4 két hangcsatornát kezel, ezek közül az egyiken csak tiszta négyszögjel, a másikon vagy zaj, vagy tiszta négyszögjel szólaltatható meg, zenéhez inkább a tiszta négyszögjel praktikus, bár dobszerű effektekhez a zaj is használható lehet. Plus 4-en nem kell a SOUND utasítás mellett PITCH és DURATION szavakat megadni, hanem a hangmagasságot és hanghosszt jelölő számot egymástól vesszővel elválasztva adhatjuk meg, és a csatorna számát is mindig meg kell adni. Egyik paraméter sem hagyható el, sorrendjük kötött, mivel csak a sorrendjükből derül ki, mit jelölnek, hiszen PITCH és egyéb szavak nem utalnak a paraméterre:

   SOUND [csatorna száma],[hangmagasság],[hossz]

      [hangmagasság] - 0 és 1022 közötti érték

A csatorna száma 1, 2 vagy 3 lehet, attól függően, hogy melyik csatornát akarjuk megszólaltatni, ill. tiszta négyszögjelet vagy zajt akarunk-e hallani. Hangmagasságnak 0 és 1023 közötti szám adható meg, 0 a legmélyebb, 1022 a legmagasabb hang, 1023 pedig szintén a legmélyebb hang. A legmélyebb hang egy 2. oktávbeli A hang, ezt PAL rendszerben a 16-os szám jelöli. (Plus 4-en más hangmagasság-értékek tartoznak PAL és NTSC rendszerhez. Az egyszerűség kedvéért mi csak a PAL-lal foglalkozunk.) A 16-os A-nál egy félhanggal magasabb hangra, az Asz-ra a 73-as számmal hivatkozhatunk. A dokumentált elérhető legmagasabb zenei hang a 6. oktávbeli A hang, erre 961-gyel hivatkozhatunk. Az ennél egy félhanggal mélyebb hang száma 957. (A plus4world oldalán megtekinthető, mely zenei hangokhoz milyen értéket kell megadnunk.)
A hang hosszát az Enterprise-hoz és TVC-hez hasonlóan 1/50 másodpercekben adhatjuk meg, így az 50-es szám egy másodperc hosszúságú hangot eredményez. (NTSC rendszer esetén 50 helyett 60 jelöli az 1 másodperc hosszúságú hangot.)
A hangerőt nem a SOUND paramétereként adhatjuk meg, hanem külön utasítással állíthatjuk a globális hangerőt. A VOL után 0 és 8 közötti szám adható meg, 0 értékre csend van, 1 a leghalkabb, 8 pedig a leghangosabb hangerő. A VOL mindkét csatornára kifejti hatását, tehát nem állítható a két csatorna hangereje külön-külön.
Plus4-en tehát feltétlenül mind a 3 paramétert meg kell adni, és szigorúan a fenti sorrendben, hiszen a PITCH, DURATION, stb. szavak nem utalnak a paraméterre. Ennél több paramétere nincs ezen a gépen a SOUND utasításnak. Ehhez képest Enterprise-on és TVC-n tetszőleges sorrendben adhatjuk meg a hanghosszt, hangerőt, hangmagasságot, vagy akár el is hagyhatjuk egyik-másik paramtétert, vagy akár az összeset, mert minden paraméternek van alapértelmezése, így önmagában egy SOUND utasítás is eredményez hangot. Plus4-en ez nem lehetséges.

Videoton és Plus/4 gépen bonyolult képlettel számítható ki, hogy egy adott zenei hanghoz milyen hangmagasság-értéket kell megadnunk a SOUND utasításban. Bár az Enterprise-on csak 0 és 127 között vannak a hangmagasság értékei, ez a gép tudja a három közül a legtöbb hangmagasságot megszólaltatni, részben azért, mert törteket is megadhatunk PITCH értéknek, részben pedig azért, mert az egész PITCH értékeket használva is a hangterjedelem 8 oktáv. Az Enterprise a PITCH értékeket felhasználóbarát módon kezeli, az egész értékek mindig konkrét zenei hangokat jelentenek. Azonban magas hang kevesebb van Enterprise-on is, mint mély, bár a PITCH értékek eloszlása látszólag egyenletes. Ennek ellenére kb. 100 fölött több egymás melletti PITCH érték is ugyanazt a hangot jelöli, és a törtek is. Így ha lefuttatunk egy FOR ciklust, mely a gép egész hangterjedelmét megszólaltatja, Enterprise-on a magas hangok tartományában hosszabb ideig fogjuk hallani ugyanazt a hangot többször is, míg TVC-n és Plus/4-en ilyenkor gyorsabban követik egymást a hangok, mivel utóbbi gépeknél a hangmagasság-értékek mind konkrét, különböző hangokat jelölnek.

Egy normál C hangot a következő utasítással tudunk megszólaltatni a három gépen egy másodpercig:

   Enterprise:
     SOUND PITCH 37,DURATION 50

   Videoton TVC:
     SOUND PITCH 3349,DURATION 50

   Commodore Plus 4:
     SOUND 1,600,50

A következő basic programok a Boci-boci tarka című világhírű dalt játsszák le a három gépen:

Enterprise:
Videoton TVC:
Commodore Plus 4:


A 264-es családba tartozik a Plus/4-gyel együtt a Commodore 16 és Commodore 116 is többek között, ezek egymással kompatibilisek (megfelelő memóriabővítés esetén), a basic-jük is teljesen ugyanaz, a SOUND utasítás mindegyikben ugyanazon az elven működik.
A régi számítógépek basic-je nagyon hasonló módon kezeli a hangkeltést. Mindegyiknek az a lényege, hogy a hangot kiadó utasítás (a legtöbb esetben SOUND) után számokkal kell megadni a hangmagasságot és a hosszt, csak az egyes hangmagasságokat gépenként eltérő számok jelölik. Az eddig tárgyalt gépeknél a hossz hasonló elven adható meg, 1/50-ed másodpercben.
Az Amstrad CPC sound utasításának felépítése nagyon hasonló a Plus/4-eséhez, egymástól vesszővel elválasztva kell megadni első helyen a csatorna számát, utána a hangmagasságot, végül a hanghosszt. További paraméterek is megadhatóak itt, többek között a hangerő, de ezek a paraméterek elhagyhatók, akárcsak a hanghossz, csak az első két paraméter kötelező. Így egy minimalista sound utasítás CPC-n minimum két paraméterrel rendelkezik, pl.

   SOUND 1,239

ahol csak a csatorna számát és a hangmagasságot adtuk meg, a többi paraméter alapértelmezés szerinti.
CPC-n három csatorna létezik, ezeket A, B és C betűjellel jelölik. Az A csatorna balról, a B csatorna jobbról, a C középről szól. Az A csatornához a SOUND utasításban az 1, a B csatornához a 2, a C-hez a 4-es számot kell megadni. Ha egy hangot egyszerre több csatornán is meg akarunk szólaltatni, akkor a megfelelő csatornák számjegyét (1, 2 ill. 4) össze kell adni. A 3-as szám tehát nem a C csatornát jelöli, hanem azt, hogy az 1-es és a 2-es csatorna is aktív. (Enterprise-on hasonló elven működik a joy függvény, ahol a megfelelő irányok értékeit kell összeadnunk azok kombinációjának eléréséhez.) A csatorna számához különböző értékek hozzáadásával az egyes csatornákat összehangolhatjuk, késleltethetjük, vagy az Enterprise-on ismert CLEAR SOUND utasításéhoz hasonló hatást élhetünk el. A késleltetett hangokat a RELEASE paranccsal szólaltathatjuk meg.
Hangmagasságnak 0 és 4095 közötti szám adható meg a TVC-hez hasonlóan, azonban minél kisebb ez a szám, annál magasabb hangot jelöl, a legmélyebb hang pedig a 4095. (Ezzel szemben Enterprise-on, TVC-n és Plus/4-en is minél kisebb a szám, annál mélyebb a hang.) A hangterjedelem itt 8 oktáv. Hanghossznak 100-at megadva kapunk 1 másodperces hangot.
Egy egy másodperces, normál C hang:

   SOUND 1,239,100

A cpcpwiki oldalon egy PDF fájlban megtalálható a gép dokumentációja, melyben a 7. fejezet 24. oldalán megtalálható a táblázat, hogy melyik zenei hangnak milyen szám felel meg. Tehát, a TVC-hez és a Plus4-hez hasonlóan bonyolult képlettel számítható ki CPC-n is, hogy mely zenei hangnak milyen érték felel meg. A hanghosszt jelölő szám pont fele olyan hosszú hangot jelöl, mint Enterprise-on, TVC-n vagy Plus/4-en, ott az 50 jelöli az 1 másodperc hosszúságú hangot, míg CPC-n a 100. Ha nem adjuk meg a hanghosszt, az alapértelmezés 20 lesz (0.2 másodperc).
A SOUND első két paraméterét (csatorna és hangmagasság) CPC-n kötelező megadni. A harmadik paramétert, a hosszt nem kötelező megadni, és a további paraméterek sem kötelezőek. Összesen 7 paraméter adható meg:

   SOUND [csatorna száma],[hangmagasság],[hossz],[hangerő],[volume envelope],[tone envelope],[zaj típusa]

A Plus/4-gyel párhuzamba állítható a csatornaszám, hangmagasság, hanghossz megadása. Utána sorrendben következik a hangerő, utána a hangerő burkolójának (envelope) azonosítója, a hangmagasság burkolójának azonosítója, végül a zaj típusa.
A hangerő a TVC-hez hasonlóan 0 és 15 közötti szám lehet.
Míg Enterprise-on az ENVELOPE NUMBER paranccsal definiálhatunk burkológörbét, melyben a hangmagasság és a hanghossz változásait is megadhatjuk, CPC-n külön kell definiálnunk burkológörbét a hangerőnek és a hangmagasságnak. Az előbbit az ENV paranccsal (V mint Volume), az utóbbit az ENT paranccsal (T mint Tone) hozhatjuk létre. Például az ENV 1,50,20,20 parancsban az 1. szám jelzi a burkológörbe azonosítóját (hasonlóan az ENVELOPE NUMBER esetéhez), ezt az azonosítót kell megadni a SOUND utasítás 5. paramétereként. Az ENT 2,10,-4,20 olyan burkológörbét definiál, melynél a hang lejátszása során a hangmagasság fog változni. Ennek a burkolónak a bekapcsolásához itt a SOUND utasítás 6. paraméterében 2-t kell megadni.
Az utolsó paraméterrel megadhatjuk, hogy akarunk-e zajt megszólaltatni az adott csatornán, és ha igen, akkor mi legyen a frekvenciája. A zaj paramétere 0 és 31 közötti szám lehet, 0-ra nincsen zaj, az 1 a legmélyebb, a 31 a legmagasabb hangú zajt eredményezi. A zaj hasonló, mint Enterprise-on a magas torzításnál megadott PITCH értékek, csak jóval kisebb a zaj frekvenciatartománya. CPC-n tehát egyetlen csatornán egyszerre szólhat zaj és tiszta hang is, a SOUND második paramétereként a tiszta hang frekvenciáját, a 7. paramétereként a zaj frekvenciáját adhatjuk meg, a két frekvencia tehát egymástól független. Ha az adott csatornán a tiszta hangot vagy a zajt ki akarjuk kapcsolni, akkor az adott paraméterbe nullát kell megadni, illetve  a zaj paraméterét a legvégéről el is hagyhatjuk.
CPC-n a paraméterek sorrendje a SOUND parancsban kötött. Ha nem akarjuk megadni valamelyik paramétert, de a következő paramétert igen, akkor egyszerűen ki kell hagynunk, ilyenkor vesszők kerülnek egymás mellé. Ha például nem adunk meg sem a hangerőhöz, sem a hangmagassághoz burkológörbét, de zajt meg akarunk adni, akkor így nézhet ki egy SOUND utasítás:

   SOUND 1,300,100,7,,,10

A CPC dokumentációjában (linket lásd feljebb) bővebben olvashatunk a SOUND utasításról és a burkológörbék működéséről az 1. fejezet 65. oldalától kezdődően, valamint a 8. fejezet 35. oldalától kezdődően.

A BEEP utasítás és egyebek

ZX Spectrumon sem túlságosan eltérő a helyzet. Ott azonban a BEEP utasítást használhatjuk hangkeltésre. A paraméterek sorrendje kötött, de eltér a Plus/4-től vagy a CPC-től, először kell megadni a hanghosszt másodpercekben, utána a hangmagasságot:

    BEEP [hanghossz másodpercekben],[hangmagasság]

A 0 jelöli a normál C hangot, és félhangonként felfele haladva mindig egyet kell ehhez hozzáadni, hasonlóan az Enterprise-hoz. (Így pl. Cisz 1, D 2, Disz 3, E 4.) Azonban az Enterprise-nál az 1 a legmélyebb C hangot jelöli, és nem a normál C hangot, mint Spectrumon. Ha a normál C hangnál mélyebb hangokat akarunk, akkor negatív számokat kell megadni (pl. -1 lesz a H). Továbbá, Enterprise-on az 1-es szám jelöl C hangot (a 0 egy H hangot jelöl), Spectrumon pedig a 0 jelöl C hangot. Így, ha a BEEP-ben megadott hangmagasságot számoljuk át SOUND PITCH értékre, 1-et hozzá kell adnunk (illetve ezen kívül még 3*12-t is hozzá kell adnunk, hogy ugyanabban az oktávban legyen az adott hang).
Spectrumon egy másodperces normál C hang így fest:

   BEEP 1,0

Tehát az 1 utal az egy másodpercre, a 0 pedig a C hangra. A BEEP 1,12 egy oktávval magasabb C hangot eredményez. A Worldofspectrum oldalán bővebben olvashatunk a BEEP utasítás használatáról, illetve a Sam Coupé felhasználói kézikönyve (lásd lejjebb) is elég bőven kifejti, hogy mely zenei hangok milyen BEEP értékekkel érhetők el.

Spectrum 128k-n a BEEP mellett a PLAY utasítás áll még rendelkezésre. Ezzel az utasítással sokkal könnyebben írhatunk zenét, mint a többi gépen, ahol az egyes zenei hangokhoz tartozó számokban nem mindig van sok logika. Három szöveges változót adhatunk meg a PLAY utasítás után, melyekben a három csatorna hangjait adhatjuk meg:

    PLAY a$,b$,c$

A hangokra a zenében is használt nevükkel hivatkozhatunk. A hangok nevei mellett természetesen egyéb karaktereket is elhelyezhetünk, melyekkel a hang hosszát, az oktávot, a tempót és egyéb paramétereket állíthatjuk. Egy C hang így szólaltatható meg:

   PLAY "c"

A PLAY utasításról bővebben a World of Spectrum oldalán lehet olvasni, illetve a Spectrum Világ 5. számában.

Sam Coupén is használható a BEEP, ezen kívül létezik SOUND utasítás is. Utóbbi használata kissé bonyolult, mivel közvetlenül a hangchip regisztereit piszkálhatjuk vele. Egyedülálló ezen a géptípuson a ZAP, POW, ZOOM, BOOM parancs, melyek négy különböző hangeffektet szólaltatnak meg. Ez a megoldás kissé az Enterprise PING utasítására emlékeztet. A speccy.cz oldalán megtalálható a Sam Coupé felhasználói kézikönyve, ebben a 93. oldalon kezdődik a hangkeltéssel foglalkozó fejezet.

Commodore 64-en a hangkeltéshez használható basic utasítás a poke, ez egy külön világ.

Összegzésként, a hangmagasság paraméterezésében megkülönböztethetünk felhasználóbarát és nem felhasználóbarát megoldásokat. Felhasználóbarát az Enterprise SOUND, és a ZX Spectrum ill. számos más gép BEEP utasítása. Ezeken a gépeken aránylag könnyen kiszámolható, hogy adott zenei hanghoz milyen értéket kell megadnunk, míg pl. TVC-n, Plus/4-en és CPC-n egy átlagos, zenéhez értő felhasználó számára nem mondható egyszerűnek a hangmagasság értékeinek a kiszámolása. A  BEEP utasítás és az Enterprise SOUND utasítása annyiból is előnyös, hogy adott számú félhangnak megfelelő számjegy hozzáadásával egy dallam valamennyi hangmagasság-értékéhez könnyen transzponálhatjuk a dallamot. Például, 12-t hozzáadva a hangmagasságot jelölő változóhoz egy oktávval magasabb hangon játszhatjuk le a dallamot, bármilyen hangmagasságról legyen is szó. Más gépeken ez nem lehetséges.
A legemberbarátibb a Spectrum 128 PLAY utasítása, mivel maguknak a zenei hangoknak a nevét adhatjuk meg.

No comments:

Post a Comment