1. Bevezető
Egy korábbi posztban szó volt arról, hogyan szólaltathatunk meg zenét ill. hangeffektet néhány régi számítógép basic programozási nyelvének segítségével. A továbbiak erre épülnek: most bemutatom, egy hagyományos, PC-s, szintetizátoros midi fájlból hogyan tudjuk a zenei hangokat kinyerni és a zenét így basic programmal szólaltatni meg. Egy Enterprise-ra írt basic programot mutatok majd be, amely egy midi fájlt beolvas, és hangjaiból basic programot állít elő. Ez az előállított basic program Enterprise-on lesz futtatható, de röviden kitérek majd arra, hogyan lehet más gépeken is zenét facsarni a midi fájlból beolvasott adathalmazból.
A régi számítógépek nagy része négyszögjel kiadására alkalmas chipet tartalmaz. A négyszögjel egy sajátos számítógépes hangzás, melyet sok számítógép képes kiadni, és más eszközök is, például régebbi játékautomaták. A négyszögjel onnan kapta a nevét, hogy oszcilloszkópos képén négyszögekhez hasonló hullámforma jelenik meg. (Szemben például a szinuszrezgéssel, melyhez a hangvilla hangja áll a legközelebb.) Elektronikus eszközökkel ez a fajta hangzás állítható elő a legegyszerűbben.
Jelentősebb különbségek vannak a régi retro számítógéptípusok hangzásbeli képességeiben. Például a Primo-n egyáltalán nem lehet zenét és hangeffekteket megszólaltatni. A TVC egyetlen hangot tud megszólaltatni egyszerre, a Plus4 két szólamot is kezelhet, az Enterprise három hangot tud megszólaltatni egyszerre és egy zajcsatornát. A Commodore 64 legfeljebb három szólamot tud kezelni, és a négyszögjelen kívül más hullámformák is előállíthatók. (Ezek a paraméterek persze csak alapesetben igazak. Bonyolultabb programozással pl. TVC-n is megszólaltatható több hang is egyszerre, például digitális hangmintákkal.
2. Zeneszerkesztés régen és most. Vagy akár egyszerre mindkettőt?
A midi egy általánosan elterjedt zenei formátum, mely gyakorlatilag a kottát tárolja. Többek között arra jó, hogy ha szintetizátoron játszunk valamit, azt midi formátumba rögzíthetjük, amit később PC-n is vissza tudunk hallgatni (ha a kottához a megfelelő hangszerhangokat is biztosítani tudjuk) vagy átszerkeszthetjük. A netről számos könnyűzenei és komolyzenei darab letölthető midi formátumban, amiket a zenészek különféleképpen hasznosítani tudnak. Szinte minden PC-s program, amivel elektronikus zenét lehet szerkeszteni, támogatja a midi formátumot. Léteznek külön midi fájlok szerkesztéséhez szoftverek, amelyekkel pl. zenét írhatunk kotta formájában, meg tudhatjuk jeleníteni egy midi fájl kottáját, vagy a PC-vel összekötött szintetizátorról vagy midi billentyűzetről játszott zenét rögzíthetjük midi fájlba.
Mire lehet jó midi fájlokat basic programmá alakítani? Mint írtam, a netről sok zene letölthető midi formátumban, és így ezeket könnyen meg lehet szólaltatni a régi számítógépeken is. A másik, amire jó lehet ez, hogy ha valaki maga akar zenét írni egy játékhoz, DATA sorok után számok formájában kéne a hangmagasságot és a hanghosszt beírni. Nem feltétlen könnyen megjegyezhető, hogy melyik hangot melyik szám jelzi. Így jóval egyszerűbb lehet PC-n midi szerkesztővel megszerkeszteni egy zenét, és azt konvertálni át régi számítógépbe, és ott végül basic játékprogramba beilleszteni. Erről fog szólni ez az írás, hogy egy midi formátumú zenét vagy annak részét hogyan lehet átalakítani Enterprise-on (vagy némi átalakítással akár más gépen) megszólaló basic programmá. Videoton és Plus4 gépen bonyolult képlettel számítható ki, hogy egy adott zenei hanghoz milyen értéket kell megadnunk a SOUND utasításban. Zenészek számára ez nem ideális. Enterprise-on még csak-csak ki lehet számolni, hogy hány félhanggal térünk el a 37-es C hanghoz képest, de akinek nincs ebben gyakorlata, annak ez sem túl jó módszer. Zenészek sokkal könnyebben írnak kottát.
Éppen ezért lehet célszerű egy olyan program, mely a midi fájlban található zenét átalakítja SOUND utasítások sorozatává.
Mire lehet jó midi fájlokat basic programmá alakítani? Mint írtam, a netről sok zene letölthető midi formátumban, és így ezeket könnyen meg lehet szólaltatni a régi számítógépeken is. A másik, amire jó lehet ez, hogy ha valaki maga akar zenét írni egy játékhoz, DATA sorok után számok formájában kéne a hangmagasságot és a hanghosszt beírni. Nem feltétlen könnyen megjegyezhető, hogy melyik hangot melyik szám jelzi. Így jóval egyszerűbb lehet PC-n midi szerkesztővel megszerkeszteni egy zenét, és azt konvertálni át régi számítógépbe, és ott végül basic játékprogramba beilleszteni. Erről fog szólni ez az írás, hogy egy midi formátumú zenét vagy annak részét hogyan lehet átalakítani Enterprise-on (vagy némi átalakítással akár más gépen) megszólaló basic programmá. Videoton és Plus4 gépen bonyolult képlettel számítható ki, hogy egy adott zenei hanghoz milyen értéket kell megadnunk a SOUND utasításban. Zenészek számára ez nem ideális. Enterprise-on még csak-csak ki lehet számolni, hogy hány félhanggal térünk el a 37-es C hanghoz képest, de akinek nincs ebben gyakorlata, annak ez sem túl jó módszer. Zenészek sokkal könnyebben írnak kottát.
Éppen ezért lehet célszerű egy olyan program, mely a midi fájlban található zenét átalakítja SOUND utasítások sorozatává.
3. Hogyan alakítható át a midi fájlban lévő zene SOUND utasítások sorozatává?
Zenét tehát úgy érhetünk el a legegyszerűbben a régi számítógépeken, hogy sound utasítások sorozatát adjuk meg, eltérő hangmagasság és hanghossz értékekkel. Azonban a megadható hangmagasság-értékekkel zsonglőrködni nem túl egyszerű. Hogyan lehetne írni programot, mely a midi fájlban lévő dallamot sound utasítások sorozatává alakítja? Először is, hozzunk létre egy üres midi fájlt, írjunk bele egymás után egy C, E, G hangjegyet azonos hanghosszokkal! Mentsük el, majd nyissuk meg egy hex editorral! Mit látunk?
Feltűnő, hogy a fájl vége felé három rövid, egymáshoz nagyon hasonló bájtsorozat ismétlődik, a képen a 90-nel jelölt érték után. (A 90h (decimálisan 144) az 1. midi csatorna kezdetét jelzi. A 91h (145) a 2. midi csatorna kezdete, a 92h (146) a 3.-é, és így tovább.) Nyilván ezekben tárolódik a három hang, amit a fájlba beírtunk. Mindegyik bájtsorozat 4 elemből áll és a középső két elem mindegyiknél ugyanaz. Ez a két középső elem jelöli a hangerőt és a hanghosszt, ezeket nem állítottuk külön, tehát mindhárom hangnál egyformának kell lenniük. A bájtsorozatok első és utolsó bájtja viszont mind a három esetben eltér, ez jelöli a hangmagasságot, hiszen mindegyik hangnak más hangmagasságot adtunk meg. Ez az első és utolsó bájt mindegyik bájtsorozatnál ugyanaz, az első a hang megszólalását (note on), az utolsó a hang elhallgatását (note off) jelenti. Tehát a kép alapján a 3C jelöli a C hangot, a 40 az E hangot, a 43 pedig a G hangot. Milyen logika alapján tárolódhat itt a hangmagasság? A 3Ch tízes számrendszerben 60, a 40h 64, a 43h pedig 67. Az Enterprise PITCH paraméterénél a C hangnak 37, az E hangnak 41, a G hangnak 44 felel meg. Nézzük csak... 60, 64, 67 és 37, 41, 44. Látható, hogy két szomszédos hangot jelölő szám különbsége a midi fájlban és az Enterprise PITCH értékében is ugyanaz! Lehetséges, hogy ugyanazon az elv alapján működnek az Enterprise PITCH értékei, mint a midiben a hangmagasságot jelölő szám? Bizony ám! A midiben szereplő 60-ból (tízes számrendszerbe átszámolva) előállíthatjuk a 37-et, ha 23-at kivonunk belőle. Tehát, a midi fájlban tárolt hangmagasság-értékekből 23-at kell kivonni ahhoz, hogy az Enterprise sound utasításának a megfelelő PITCH értékét megkaphassuk! A hangmagasság konvertálásához nincs más dolgunk, mint egy programmal beolvasni a midi fájlt, megkeresni benne azt a részt, ahol a hangok kezdődnek, ezt általában 90h jelzi, ahogy a képen is, és utána a hangmagasságok értékéből 23-at ki kell vonni, a kapott értékeket pedig elmenteni, amit aztán egy Enterprise basic program be fog olvasni és a PITCH paramétereként meg fog szólaltatni.
Na, de a hangmagasság önmagában még kevés, a hang hosszára is szükség van. Ez hogyan tárolódhat a midi fájlban? Nyissunk meg újra egy üres midi fájlt, írjunk bele 3 azonos magasságú, de eltérő hosszú hangot, és nézzük meg, hogyan fest ez hex editorban! Próbaképp egy negyed, nyolcad és egy tizenhatod hosszúságú C hangot írtam bele a midi fájlba:
Láthatjuk, hogy a három bitsorozatnál most mindhárom esetben azonos a hangmagasságot jelölő szám, ez 3Ch. Ami különbözik, az az utolsó előtti szám lesz, az első hangnál ez 78h, a következőnél 3Ch, az utolsónál pedig 1Eh. Tízes számrendszerbe átszámolva: 120 (negyed), 60 (nyolcad) és 30 (tizenhatod). Tehát fele olyan hosszú hangot fele akkora számmal tárol a midi fájl. A három kedvenc számítógépem is ugyanezen az elven határozza meg a hang hosszát. Hogy mi lesz egy másodperc hosszú (50-es duration érték), az már attól függ, hogy tempónak mennyi van beállítva a midi fájlban. A midi fájl tempójával nem feltétlen kell foglalkoznunk, mert a konvertáló programban megadhatjuk mi magunk is, hogy a lehető legrövidebb hanghosszoknak (az egészre, félre, negyedre, stb. megadva) hányszorosát akarjuk hallani. Így kísérletezhetünk, hogyan kapjuk a számunkra legmegfelelőbb tempót. Az egyszerűség kedvéért attól is eltekintünk most, amikor a dallam közben a tempó dinamikusan változik.
Nézzük meg, mi történik, ha szüneteket szúrunk be a hangok közé! Ha például az első
és második hang közé nyolcad hosszúságú szünetet teszünk, hex editorban
akkor a két hang között nem 00 00 fog megjelenni, hanem 00 3C. A
00 tehát azt jelenti, hogy szünet van ott, az ezt követő szám pedig a szünet hosszát jelenti. Ha 00 00 áll ott, akkor nincs szünet.
Ha a negyed kétszeresét (felet) adjuk meg hanghossznak, akkor azt a hex editorban már két bájton ábrázolva láthatjuk. Ez lenne „midis értelmezésben" a duration 240, ezt 81 70-nek ábrázolja a hex editor, azaz 129 112 szerepel. Hogyan lesz ebből 240? Ha 127-nél hosszabb hangot adunk meg, akkor azt már nem tudja egy bájton tárolni, a 128-nak például 81 00 lesz az értéke. A hanghosszt jelölő bájtok első bitje mindig jelzőbit. Ha az értéke 1, akkor az adott bájt feldolgozása után még nem értünk az
érték beolvasásának végére, a következő bájt is a hanghossz kifejezéséhez kell. Ha az értéke 0, akkor az adott bájt
feldolgozása után elértük az érték beolvasásának végét.
Ha a midi fájlban tárolt hanghosszokat basic duration értékekké akarjuk átszámolni, akkor valami hasonló algoritmust lehet elképzelni:
- Nullázzuk az értéket tároló változót. (pl.: LET HOSSZ = 0)
- Beolvassuk a soronkövetkező bájtot. (pl.: beolvassuk a C$ nevű változóba)
- Ha nagyobb az értéke 127-nél, akkor a tárolt értéket megszorozzuk 128-cal és hozzáadjuk az alsó hét bit értékét. (pl.: LET HOSSZ = HOSSZ * 128 + ORD(C$) - 128)
- Ha kisebb az értéke 128-nál, akkor a tárolt értéket megszorozzuk 128-cal és hozzáadjuk az alsó hét bit értékét. (pl.: LET HOSSZ = HOSSZ * 128 + ORD(C$))
- Ha nagyobb az értéke 127-nél akkor folytatjuk a 2. ponttól.
Köszönjük ErgoGnomik segítségét a hanghossz kiolvasását elvégző programrész megírásában!
A fenti ábrákon is látható bájtsorozatokban, melyekből most a hangmagasságot és az időtartamot olvastuk ki, a hangerő is megtalálható. Ez a bájtsorozatoknak a második eleme. A fenti ábrákon ez mindig 64h volt. Semmi akadálya, hogy ezt is kiolvassuk, és a basic program a midi fájlhoz hasonlóan változtassa a hangerőt is, de az egyszerűség kedvéért most csak a hangmagassággal és a hanghosszal foglalkozunk.
Tegyük hát át gyakorlatba az eddigieket!
Írjunk a fentiek alapján egy programot, mely egy midi fájl sávját basic programmá alakítja, mely az adott dallamot lejátssza! Ahogy láthattuk a fenti ábrákon, a midi fájl eleje fejléc, csak a 90h-val jelölt bájttól kezdődik maga a dallam. Így az első bájtokat elég csak beolvasnunk, és keresni kell azt a bájtot, ahol 90h (144) áll, például így:
Írjunk a fentiek alapján egy programot, mely egy midi fájl sávját basic programmá alakítja, mely az adott dallamot lejátssza! Ahogy láthattuk a fenti ábrákon, a midi fájl eleje fejléc, csak a 90h-val jelölt bájttól kezdődik maga a dallam. Így az első bájtokat elég csak beolvasnunk, és keresni kell azt a bájtot, ahol 90h (144) áll, például így:
100 OPEN #1:"dallam.mid" ACCESS INPUT
110 DO
120 GET #1:A$
130 LOOP UNTIL A$=CHR$(144)
Hozzunk létre egy-egy tömböt a leendő basic programban tárolt dallam hangjainak, egyet a hangmagasságnak, egyet a hossznak!
140 NUMERIC TRACK(1 TO 3,1 TO 500),DUR(1 TO 500)
Feltételezzük, hogy az adott midi sávban csak egyetlen szólam lesz, tehát nem szólal meg egyszerre két hang. Egyelőre maximum 500 hangból álló dallam konvertálására készülünk fel. Szükség esetén ezt a számot megnövelhetjük 500-nál nagyobbra. A TRACK tömb kétdimmenziós, az első paraméter a sáv (szólam) számát jelöli. Egyelőre egyetlen szólam konvertálásával fogunk foglalkozni, később megnövelhetjük a szólamok számát. A szólam (aktuális midi sáv) száma lehetne Enterprise esetén 1 és 3 közötti szám, vagy akár 4 is, ha a zajcsatorna hangjait is valamilyen módon a midi fájlban adjuk meg. Ennek értékét a LAYER nevű változóban adom meg, esetünkben ez mindig 1 lesz. A konvertáló programrészt többször is meg kell hívni több szólam esetén, más LAYER értékekkel. TVC-n elvileg csak egy szólam lehet, Plus/4-en kettő, azonban ha nagyon gyorsan (1/50 másodpercenként) váltogatunk két (vagy akár több) hangot, akkor többszólamú hangzáshoz hasonlót kaphatunk, így TVC-n is érdemes legalább két szólamot fenntartani. Plus/4-en pedig akár a zaj megszólaltatásához használhatunk egy külön midi sávot, ami gyakorlatilag harmadik szólamnak számít, csak nem szólhat egyszerre a másodikkal, hiszen ugyanaz a hangcsatorna állítja elő a kettőt.
A fenti hexdumpokon látható, hogy a sáv végét FFh 2Fh 00h (255, 47, 0) bájtsorozat jelzi. A basic programban addig kell konvertálni a hangmagasságot és a hanghosszt, amíg ezt a bájtsorozatot nem találjuk. Beolvassuk tehát azt a négy bájtot, mely a hangmagasságot, hangerőt, hanghosszt tárolja. A bájtsorozatokat nem FOR, hanem DO ciklussal fogjuk kiolvasni, ezért előtte megadunk egy ciklusváltozót, ez legyen mondjuk SG nevű:
LET SG=1
DO
GET #1:A$
GET #1:B$
GET #1:C$
IF A$=CHR$(255) AND B$=CHR$(47) AND C$=CHR$(0) THEN EXIT DO
GET #1:D$
...
LET SG=SG+1
LOOP
Az A$-ban megtalálható a hangmagasság, a B$-ban a hangerő, a C$-ban a hanghossz, és a D$-ban újra a hangmagasság (note off esemény). Lehetséges, hogy a hang hosszabb annál, mint amit egyetlen bájton lehet tárolni, így még utána nem a note off esemény jön, hanem még mindig a hanghosszt jelölő bájt. Ehhez meg kell nézni a C$-ban beolvasott bájt jelzőbitjének az értékét, és ha az 1, akkor még a D$ beolvasása előtt egy másik, a hanghosszt definiáló bájtot is be kell olvasnunk, vagy nagyon hosszú hang esetében többet is.
555 LET HOSSZ=0
556 IF C$>CHR$(127) THEN
557 LET HOSSZ=HOSSZ*128+ORD(C$)-128
558 GET #1:C$
559 GOTO 556
560 END IF
561 LET HOSSZ=HOSSZ*128+ORD(C$)
Ahogy szó volt róla, a midi fájlban tárolt hangmagasság 23-mal nagyobb szám (decimálisba átszámolva), mint az annak megfelelő pitch érték Enterprise-on. Így a megfelelő pitch értéket könnyen előállíthatjuk:
610 LET TRACK(1, SG)=ORD(A$)-23
A hanghossz adott esetben akár ugyanannyi is maradhat, mint amennyit a midi fájl megadott, de ez általában hosszabb hangot eredményez, ez csak nagyon lassú zenéknél lehet jó. Legegyszerűbb, ha ezt az értéket elosztjuk mondjuk 5-tel. A végén előállított basic programban még úgyis szerkeszthetjük ezt is ízlés szerint. Persze lenne itt is több lehetőség is, hogy például a lehető legrövidebb hangnak valahányszorosát vegyük, de az egyszerűség kedvéért maradjunk az 5-tel osztásnál:
612 LET DUR(SG)=HOSSZ/5
A hangjegyet leíró négy bájt után ki kell olvasni a következő két bájtot: GET #1:E$ és GET #1:F$. Az E$-ban 00 lesz, az F$-ban pedig vagy szintén 00, vagy pedig, ha szünet következik, akkor a szünet hosszát leíró bájt. Hosszú szünet esetén a következő bájtok is a szünet hosszát írják le. Szünetnek célszerű hangmagasságnak Enterprise-on 127-et adni meg, ami a legmagasabb hang, olyan magas, hogy már nem hallatszik. Ennek annyi ideig kell szólnia, amíg a 00h utáni hanghossz jelzi. Mivel már az előbb szerepelt az a rész, mely a hanghosszt jelölő bájtokat értelmezi, és a szünet hosszát is ugyanúgy tárolja a midi fájl, érdemes lenne előbb megvizsgálni, szünet jön-e, és ha igen, akkor simán továbbmenne a program a hossz generálására. Tegyük az esetleges szünetet tartalmazó bájtok kiolvasásáért felelős részt rögtön a ciklus elejére! Először megvizsgálja a program, 00 00 áll-e a két bájtban. Ha igen, akkor nincs mit tenni, újra be kell olvasni a két bájtot. Ha azonban a két bájt közül csak az első 00, akkor szünetet kell letárolni hangmagasságként, és a következő bájtokból generálni kell a szünet hosszát. Ha pedig éppen nem 00 áll az első bájtban, hanem hangmagasságot jelölő bájt, akkor utána ugyanúgy annak a hosszát kell kiolvasni és értelmezni:
510 DO
520 GET #1:A$
530 GET #1:B$
535 IF ORD(A$)=0 AND ORD(B$)=0 THEN GOTO 520 !00 00, újra elölről
536 IF ORD(A$)=0 THEN C$=B$:GOTO 555 ! Szünet lesz, a hangerő nem releváns, annak kiolvasását át kell ugrani, jöhet a hossz, amit C$-ban tárolunk.
540 GET #1:C$ ! Ha nem szünet volt, akkor most olvassuk be a hosszt.
550 IF A$=CHR$(255) AND B$=CHR$(47) AND C$=CHR$(0) THEN EXIT DO ! Ez a 3 bájt jelzi a sáv végét. Ha ezek jönnek, befejezzük az átalakítást, kilépünk a ciklusból.
555 LET HOSSZ=0 ! Elkezdjük a hossz generálását, ehhez kiindulásként 0-ról indulunk.
...
600 IF ORD(A$)<>0 THEN GET #1:D$ ! Ha nem szünet volt (00h), akkor még van itt egy note off jelzés, ennek a bájtját is be kell olvasni.
610 LET TRACK(LAYER,SG)=ORD(A$)-23 ! A PITCH értékét állítjuk elő az aktuális hangjegynek. A midi bájt decimális alakjából 23-at kell levonni, lásd fent.
611 IF ORD(A$)=0 THEN LET TRACK(LAYER,SG)=127 ! Ha 00h volt az elején, azaz szünet, akkor hangmagasságnak 127-et célszerű megadni, lásd fent.
612 IF LAYER=1 THEN LET DUR(SG)=HOSSZ/5 ! Átszámítjük a midiben tárolt hosszt a DURATION-ban megadható értékre. Ennél elegánsabb módszerrel is lehetne, egyelőre beérjük ezzel.
613 LET SG=SG+1 ! A ciklusváltozót növeljük.
670 LOOP
Ha több szólamot akarunk beolvasni, akkor a következő midi sáv(ok) elejéről is el kell kezdeni az adatok beolvasását, a LAYER változó értéket előtte eggyel megnövelni, így a TRACK tömb első dimenziójának következő értéktartományába kerülhetnek a következő szólam(ok) hangjai.
Több szólam esetén is a hanghosszt csak egyszer kell beolvasni. Ez azt jelenti, hogy akárhány szólam van, azok összes párhuzamos hangja teljesen egyszerre szólal meg és hallgat el, hiszen egy hanghosszt rendelünk akár több szólamhoz is. Tehát, nem tehetjük azt, hogy míg pl. az első szólamban egyetlen hang szól, addig a második szólamban egymás után több hang is megszólal, hanem ilyen esetben az első szólamban is a második szólam minden egyes hangjával párhuzamosan meg kell szólaltatni ugyanazt a hangot. Erre a basic nyelv korlátai miatt van szükség. Így nem is lehet olyan midi fájlt helyesen konvertálni, ahol az egyes szólamok párhuzamos hangjainak hossza nem egyezik meg. Tehát nekünk kell megszerkeszteni úgy a midi fájlt, hogy az megfelelően szóljon majd, ha több szólamot is konvertálni akarunk. Ezért ugyan kiolvassuk több szólamhoz is a hangok hosszát, de elég csak egyszer letárolni, amikor a legelső szólam hangjait olvassuk ki. Ezért is van a 612-es sor elején az IF, hogy csak az első szólam konvertálásakor vegye figyelembe a gép a hang hosszát.
Ezzel tehát kiolvastuk a midi fájlból a hangjegyek magasságának és hosszának az értékeit, átalakítottuk Enterprise PITCH és DURATION paraméterekkel értelmezhető számokká, letárolva mindent a TRACK és a DUR tömbökben.
Ha nem Enterprise, hanem TVC vagy Plus/4 (C16) gépre akarjuk átkonvertálni a midi fájlt, akkor a hanghosszhoz nem kell más módszer, viszont más számokat kell az egyes PITCH értékekhez hozzárendelni. Ez nem is olyan bonyolult:
1. A dokumentációból ki kell másolni DATA sorokba az egyes hangmagasságoknak megfelelő értékeket a legmélyebbtől a legmagasabb felé haladva.
2. Létre kell hozni egy tömböt (pl. NOTE(31 TO 110), amelybe majd beolvassuk a DATA sorokból az egyes TVC-s ill. Plus 4-es PITCH értékeket, amit hozzárendelhetünk egy-egy midis hangmagasság értékhez.
3. A 610-es sorban nem LET TRACK(LAYER,SG)=ORD(A$)-23 lesz, hanem LET TRACK(1,SG)=NOTE(ORD(A$))
4. A szünetet nem 127-tel jelöljük, így TVC-n 4095-öt, Plus/4-en pedig 1022-t kell megadni a 611. sorban.
A TVC hangtartománya kisebb, mint az EP-é, a Plus/4 hangtartománya pedig még kisebb. Ezeken a gépeken kevesebb a mély és a magas hang is, nagyon mély és nagyon magas hangok kibocsátására már nem alkalmasak. Így a nagyon mély és nagyon magas hangokhoz érdemes lehet szünetet hozzárendelni, hogy konvertálásnál ne legyen hibaüzenet a nem létező hangmagasság érték miatt, ha esetleg túl magas vagy túl mély hang fordulna elő a midi fájlban.
Végezetül pedig létre kell hozni egy kimeneti fájlt, és abba szöveges formátumban kinyomtatni a basic programot, először a lejátszó részt, majd DATA sorokba rendezve a TRACK és a DUR tömb elemeit. Lejátszó résznek megadhatunk több lehetőséget is, amihez a konvertálás elején megkérdezzük a felhasználót, hogy melyiket szeretné választani. Bár ez nem olyan fontos, valószínűleg úgyis később kísérletezéssel fogjuk beállítani a legmegfelelőbb hangzást és azzal fogjuk végül elmenteni a programot.
Ez a módszer persze nem igazán kifinomult. Lehetne DO helyett FOR ciklusba is tenni a bájtsorozatok kiolvasását, és ehhez előtte kiolvassuk a midi fájl elejéről, hogy milyen hosszú a sáv, mennyit kell a FOR változóba írni. Igaz, végeredmény szempontjából ennek nincs jelentősége, mert az FF 2F 00 mindig jelzi a sáv végét, ahol abba kell hagyni.
Egy midi fájl a hangjegyek hangmagasságán, időtartamán, hangerején kívül sok más információt is tárolhat, amire a konvertáló program nincs felkészítve, így ilyen esetben a konvertálás nem sikerül. Az általam ismertetett módszer nem arra való, hogy tetszőleges midi fájlból kinyerjük a dallamot és basic programmá alakítsuk, hanem hogy mi magunk midi formátumban szerkesszük meg a zenét a basic programba az elejétől kezdve, így eleve nem is teszünk olyat a midibe, ami a basic program létrehozásához nem szükséges. Lehet netről letöltött midiket is konvertálni, csak előbb egy midi szerkesztővel át kell nézni azt és törölni kell belőle a számunkra felesleges információkat (pl. vezérlőket, hajlításokat). Arra is ügyelni kell, hogy egy midi sávon belül egyszerre mindig csak egy hang szólhasson. Ahol több hang van, csak az egyiket kell meghagyni, a többinek esetleg külön midi sávokat hozhatunk létre.
Több szólam esetén problémát okozhat az a jelenség, amikor nem szól egyszerre mindegyik szólamon zene, hanem valamelyik szólamon szünetek vannak. Ez azért problémás, mert a szünetet is fel kellene osztani olyan részletekre, mind ahogy a másik szólamon a hangok követik egymást. Erre egy megoldás lehet, ha olyan hangokat írunk a midi szerkesztővel a szünet helyére, melyek máshol nem fordulnak elő a zenében, így akár konvertálás után a txt fájlban ezeket az értékeket átírhatjuk a szünetet jelölő számokra. Ha pl. TVC-n a gyorsan, felváltva szólnak a két szólam hangjai lehetőséget választjuk, akkor a szünetet tartalmazó helyekre a másik szólam hangjait kell bemásolni.
Egy midi fájl a hangjegyek hangmagasságán, időtartamán, hangerején kívül sok más információt is tárolhat, amire a konvertáló program nincs felkészítve, így ilyen esetben a konvertálás nem sikerül. Az általam ismertetett módszer nem arra való, hogy tetszőleges midi fájlból kinyerjük a dallamot és basic programmá alakítsuk, hanem hogy mi magunk midi formátumban szerkesszük meg a zenét a basic programba az elejétől kezdve, így eleve nem is teszünk olyat a midibe, ami a basic program létrehozásához nem szükséges. Lehet netről letöltött midiket is konvertálni, csak előbb egy midi szerkesztővel át kell nézni azt és törölni kell belőle a számunkra felesleges információkat (pl. vezérlőket, hajlításokat). Arra is ügyelni kell, hogy egy midi sávon belül egyszerre mindig csak egy hang szólhasson. Ahol több hang van, csak az egyiket kell meghagyni, a többinek esetleg külön midi sávokat hozhatunk létre.
Több szólam esetén problémát okozhat az a jelenség, amikor nem szól egyszerre mindegyik szólamon zene, hanem valamelyik szólamon szünetek vannak. Ez azért problémás, mert a szünetet is fel kellene osztani olyan részletekre, mind ahogy a másik szólamon a hangok követik egymást. Erre egy megoldás lehet, ha olyan hangokat írunk a midi szerkesztővel a szünet helyére, melyek máshol nem fordulnak elő a zenében, így akár konvertálás után a txt fájlban ezeket az értékeket átírhatjuk a szünetet jelölő számokra. Ha pl. TVC-n a gyorsan, felváltva szólnak a két szólam hangjai lehetőséget választjuk, akkor a szünetet tartalmazó helyekre a másik szólam hangjait kell bemásolni.
5. Zárszó
--
A midibe konvertálásról a Plus4-re vonatkozó ismeretek a 264-es család minden tagjára érvényesek. Semmi akadálya, hogy a midiből basicbe konvertáló programban a DATA sorokat átírjuk úgy, hogy a CPC-nek megfelelő hangmagasság értékek szerepeljenek benne.
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, ezeket kell beírni a DATA sorokba, de a legnagyobb számtól a legkisebb felé haladva! A NOTE() tömb tartományát is kibővítjük, hogy 8 oktávnyi hangjegyek férjenek bele, és be kell állítani a szünetet jelölő számot is megfelelően. Mivel a hanghosszt jelölő szám pont fele olyan hosszú hangot jelöl, mint a másik három gépen, a hanghosszok átszámítását is kicsit módosítani kell.
Így aztán Spectrumra sem túl bonyolult átkonvertálni a hangmagasságot midiből, csak nem 23-at kell kivonni a midiben tárolt bájt értékéből, hanem kicsit többet, kb. 60-at, hogy a BEEP paraméterének megfelelő értéket megkapjuk. A hanghossz konvertálásánál persze be kell vetni valami praktikát, hiszen az 1-es BEEP érték és mondjuk a midiben megadott 120-as érték (negyed hosszúságú hang) nincsenek túlzottan köszönőviszonyban egymással. Talán a legjobb, ha 120-szal elosztjuk azt, ami a midi fájlban szerepel hanghosszként - adott tempó esetében...



No comments:
Post a Comment