JAK NAUČIT KVÁKAČ ZPÍVAT Jistě každý z vás zkoušel na počítači pracovat se zvukem. Úplně nejjednodušší způsob, jak dostat z PC jiný zvuk, než je bzučení pevného disku, vrčení diskety, cvakání klávesnice či pískání monitoru je tento: begin Write(#7); {Zapíše přes MS-DOS znak číslo 7, který vyvolá pípnutí} end. Turbo Pascal nabízí poněkud méně krkolomný a nepoměrně flexibilnější způsob vydávání skřeků pomocí procedur Sound, NoSound a Delay. Principem je přibližně toto: Nějaký obvod, který je připojen na PC speaker začne rytmicky kmitat v určité, předem dané, frekvenci, nějakou dobu se v tomto kmitání udrží a pak kmitat přestane. begin Sound(200); {Začne hrát tón o frekvenci 200 Hz} Delay(500); {Bude ho hrát 0.5 sekundy} NoSound; {Pak přestane} end. K tomu, abychom si vysvětlili jak se pracuje se zvukem na vyšší úrovni si musíme říci něco teorie zvuku. To, že vůbec nějaký zvuk vnímáte je způsobeno dopadem zvukových vln na ušní bubínek a následné silové působení bubínku na kostěnné orgány ve vašem uchu a nakonec i na sluchový nerv. Zvukové vlny se přenášejí pomocí neustálého zhušťování a zřeďování vzduchu mezi vysílačem a příjemcem. Pokud je vysílačem reproduktor (PC speaker je jednoduchý reproduktor, ve sluchátkách jsou reproduktorky, i u HiFi věžě bývají reproduktory...), zhušťování se provádí pomocí velmi rychlých pohybů membránou reproduktoru k příjemci a od něj. To, jak funguje reproduktor tady, doufám, vysvětlovat nemusím, jenom se zmíním o tom, že to, jak se vysune či zasune membrána reproduktoru je dáno proudem protékajícím cívkou reproduktoru. Když je tento proud velký a kladný, je membrána vychýlena značně směrem ven, když je menší, ale stále kladný, je vychýlena méně, ale stále směrem ven, když je nulový, je v prostřední pozici, když je protékající proud záporný, je vychýlena směrem dovnitř reproduktoru (od příjemce). To, jaký proud bude protékat skrz cívku můžeme programově ovládat pomocí hodnot, které posíláme na určité porty. Maximální hodnota, jakou se ještě to které zvukové zařízení dá ovládat určuje, kolika bitové je. Speaker je 6 bitový, takže největší hodnota, kterou na jeho port můžeme poslat je 2^6, čili 64. Takže pokud chceme, aby nám kvákač vyloudil zvuk přibližně "TRRRRRRRRRR", tak pošleme na port speakeru nejdříve nulu, a pak 64. Membrána se "vcucne" dovnitř, a v zápětí zase vytlačí úplně ven. Prográmek na to je asi tento: var x:word; begin port[61]:=port[61] or 2; {Bit číslo 1 (počítáno od 0) na portu 61h povoluje výstup do reproduktoru} for x:=0 to 50000 do begin Port[42]:=0; {Membrána je "vcucnuta" dovnitř} Port[42]:=64; {Membrána je vytlačena úplně ven} end; end. Zde je ještě třeba poznamenat, že poměrem rozdílu mezi nejvyšší a nejnižší hodnotou, kterou na port 42h posíláme můžeme regulovat hlasitost - pokud jsme posílali 0 a 64, pak jejich rozdíl je 64, to děleno maximální hodnotou 64 dává 1, což znamená 100 % hlasitost. Pokud bychom posílali hodnoty 16 a 48, rozdíl mezi nimi je 32 a to děleno 64 dává 0.5 = 50 % hlasitost. Stejným způsobem můžeme přehrát na speakeru i nějaký zvukový soubor (nejlépe WAV či VOC). Zde vyvstává problém "vzorkovací frekvence". To je frekvence, se kterou výrobce toho kterého zvuku opakovaně snímal úroveň zvuku na mikrofonu. Typické vzorkovací frekvence jsou 8000, 11025, 22050 a 44100 vzorků za sekundu (Hertzů). Jak však zaručit, aby hodnota zvuku byla poslána na reproduktor právě 11025 krát, 22050 krát ... za sekundu? Zde máme dvě možnosti: Buď budeme hodnoty posílat v cyklu, kde si mezi nimi necháme čekat počítač právě dobu 1/vzorkovací_frekvence sekund, což přináší řadu nevýhod, např. na různě rychlých počítačích bude zvuk přehráván různě rychle, nebo využijeme časovače 8253, který má ve svém PC snad každý. První možnost vypadá přibližně takto: var zvuk:Array[0..50000] of byte; x: Word; begin Nacti_zvuk('soubor.wav',zvuk); {Jakákoliv procedura, která načte data ze souboru do pole} port[61]:=port[61] or 2; for x := 0 to SizeOf(zvuk) do begin Port[42]:=zvuk[x]; Pockej_chvili; {Jakási neurčitá procedura na čekání, kterou nemohu jen tak napsat, protože nevím, jak rychlý máte počítač} end; end. Při použití té druhé možnosti musíme pracovat s přerušením od časovače. To je sice o něco složitější, nicméně zvuk bude znít stejně i na různě rychlých počítačích nebo můžete hrát i na pozadí běžící aplikace. Toho docílíme několika kroky: 1. Nainstalujeme svoji obsluhu vektoru přerušení INT 08, který je vyvolán při každém tiku časovače. Obsluha by mohla spočívat třeba i v poslání určitého byte na port speakeru, ale bezpečnější bude, když obsluha nastaví pouze určitou vlajku do stavu, že již přerušení prošlo a hlavní program se postará o to, že tuto vlajku schodí. 2. Přeprogramujeme časovač na hodnotu vzorkovací frekvence. Prakticky to provedeme tak, že na řídící port časovače (43h) pošleme řídící slovo 36h, a na port 40h pošleme nejdříve dolní a poté horní byte dělící konstanty. Tu vypočteme jednoduchým poddělením 1193180 / vzorkovací_frekvence. 3. V programu v každý vhodný okamžik zkontrolujeme vlajku a pokud je nastavena, tak na port speakeru pošleme konkrétní hodnotu zvuku, posuneme ukazatel na další byte a vymažeme vlajku. 4. Po přehrání celého zvuku přeprogramujeme časovač stejným způsobem, jako v bodě 2, jen jako dělící konstantu použijeme číslo 0. 5. Odinstalujeme obsluhu přerušení a nainstalujeme původní. A to je vše. O tom, jak hrát zvuky přes Sound Blaster napíšu příště. Bernie výheň