JAK NAUČIT KVÁKAČ ZPÍVAT
[o úroveň výše]
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 úroveň výše]
|