Lekce 3 - Zvukový výstup v C# Konzoli
V předchozí lekci, Analýza dat ze vstupu z klávesnice v C# Konzoli, jsme se dozvěděli, co vše lze zjistit ze zadávaných dat z klávesnice a ukázali jsme si postupy, jak lze tyto informace získat a nakládat s nimi.
V dnešním C# tutoriálu se seznámíme s možnostmi, jak ovládat
zvukový výstup u konzolových aplikací. Po pravdě řečeno,
moc těch možností není (prakticky jsou jen tři) a jsou velmi omezené. Při
chytrém použití umožní aplikacím zahrát jednoduché
melodie, nebo třeba vítěznou fanfáru.
Abychom mohli nechat zahrát melodii, musíme naši aplikaci naučit
noty, resp. musíme zadat frekvence a
dobu trvání jednotlivých tónů. V krátké odbočce do
hudební teorie se dozvíme, že s použitím správného algoritmu to není
nijak složité.
Výpis tónu
Nejjednodušší možností, jak naučit náš program vyluzovat zvuky, je
vypsat zvukový znak. Jeden takový zvukový znak nabízí
ASCII tabulka , a to ASCII znak 7
(BEL
). Přestože metoda Write()
slouží hlavně k
výpisu znaků do okna konzole, při výpisu znaku BEL
se ozve
zvuk. Pro výpis použijeme přetypování ASCII hodnoty
7
na znak:
Console.Write((char)7);
Pípnutí
Druhou jednoduchou možností pro zadání tónu je použití
bezparametrické metody Beep()
:
Console.Beep();
Při zadání tohoto příkazu konzole provede krátké pípnutí, které má pevně nastavenu frekvenci 800 Hz po dobu 200 milisekund.
Zahrání tónu zadané frekvence a doby trvání
Nejzajímavější možností pro zahrání tónů je použití metody
Beep()
se dvěma parametry typu int
. První parametr
udává frekvenci tónu, druhý parametr určuje dobu
trvání tónu v milisekundách, který nesmí být menší, nebo roven
0.
Při použití této metody můžeme naše aplikace naučit přehrávat jednoduché melodie. K tomu ale potřebujeme do kódu zadat frekvence jednotlivých tónů, které odpovídají tónům tónové osnovy, resp. notám v notovém zápisu. Abychom nemuseli každý tón zadávat ručně podle tabulkových hodnot, je možné použít algoritmus pro rovnoměrné temperované ladění. V tomto algoritmu frekvence mezi sousedními půltóny tvoří geometrickou posloupnost a mohou se snadno spočítat.
Frekvenční omezení
Frekvence přehrávaných tónů má svá omezení:
- softwarové možnosti. Metodou
Beep()
můžeme definovat tóny v rozsahu od 37 Hz do 32.767 Hz. - hardwarové možnosti. Kvalita zvukové karty a použitého výstupního zařízení. Na něm závisí, v jakém rozsahu frekvencí dokáže zvuk reprodukovat.
- možnosti lidského sluchu. Nemá smysl přehrávat frekvence, které člověk neslyší (samozřejmě pokud se nebavíme o aplikacích pro ultra a infra zvuk). Oblast slyšitelných tónů pro zdravého člověka se obecně udává od 20 Hz do 20.000 Hz.
Průnikem těchto tří oblastí omezení se dostáváme k prakticky využitelnému pásmu frekvencí, které je však poměrně široké. Běžně se v životě setkáváme s frekvenčním pásmem mnohem užším, které pokrývá zhruba rozsah šesti oktáv od 60 Hz do 4.000 Hz a zahrnuje rozsah většiny hudebních nástrojů. Pro zajímavost uveďme, že lidský hlas se pohybuje přibližně od 90 Hz (bas) po 1.100 Hz (soprán).
Krátce z hudební teorie
Tónová stupnice je rozdělena na oktávy. Mezi oktávami platí jednoduchá matematická závislost: Zdvojnásobíme-li frekvenci jakéhokoliv tónu, dostaneme týž tón, ale o oktávu vyšší.
Tóny každé oktávy mají dvojnásobnou frekvenci oproti stejným tónům předcházející oktávy.
Základní tón
Pro naše programátorské potřeby si zvolme tón c velké oktávy za základní tón. Tón c velké oktávy má frekvenci 65,406 Hz. Pro nás to bude nejnižší tón, jaký budeme používat. To je tón na spodní hranici prakticky využitelného frekvenčního pásma. Od tohoto tónu budeme počítat všechny ostatní tóny. Mohli bychom si samozřejmě zvolit za základní tón jakýkoliv jiný tón.
Oktávy
Každá oktáva je souborem 12 tónů, počínaje tónem c. V tabulce si ukažme tóny c šesti oktáv, jak jdou za sebou. Těchto šest oktáv pokrývá námi požadované běžné frekvenční pásmo zhruba od 65 Hz do 4,200 Hz:
- V 1. sloupci je oficiální název oktávy v hudební terminologii.
- Ve 2. sloupci je označení tónu c dané oktávy opět v hudební terminologii.
- Ve 3. sloupci je frekvence tónu c.
- Ve 4. sloupci je násobek příslušného tónu c oproti námi zvolenému "základnímu tónu".
Oktáva | Označení tónu "c" | Frekvence (Hz) | Násobek základního tónu |
---|---|---|---|
Velká | C | 65,406 | 20 = 1 (základní tón) |
Malá | c | 130,81 | 21 = 2 |
Jednočárková | c1 | 261,63 | 22 = 4 |
Dvojčárková | c2 | 523,25 | 23 = 8 |
Tříčárková | c3 | 1046,50 | 24 = 16 |
Čtyřčárková | c4 | 2093,00 | 25 = 32 |
Přesnost frekvence zvoleného základního tónu je zde uvedena na tři desetinná místa, protože základní tón bereme za základ pro výpočty. Vidíme, že frekvence tónu c každé následující oktávy je dvojnásobkem tónu c předcházející oktávy. Frekvence vypočtených tónů je informativně zaokrouhlena na dvě desetinná místa, což je pro naše účely postačující.
Tóny v oktávě
Dvanáct tónů v oktávě jde po řadě za sebou takto, počínaje tónem c:
Označení tónu v oktávě: | c | cis | d | dis | e | f | fis | g | gis | a | b | h |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Pořadí tónu v oktávě: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
Pro lepší představu o tónové řadě se podívejme na obrázek níže. Jednu oktávu si můžeme představit jako část klaviatury klavíru:
Frekvenční vzdálenost mezi tóny
Pro jednotlivé tóny v oktávě platí, že jejich frekvence je rovna frekvenci tónu předcházejícího vynásobeného dvanáctou odmocninou čísla 2. Dvanáctá odmocnina ze dvou se nazývá půltónový krok a u rovnoměrného temperovaného ladění jde o konstantu stejnou pro všechny tóny. A protože tónů v oktávě je 12, pak platí, že po dvanácti krocích se dostaneme na frekvenci prvního tónu následující oktávy, která musí být dvojnásobná oproti prvnímu tónu naší oktávy. Platí, že:
( 2 ^ 1/12 ) ^ 12 = 2
Vezměme tedy frekvenci tónu c a vynásobme ji dvanáctou odmocninu čísla 2. Tak dostaneme následující tón cis:
cis = c × 2 ^ 1/12
Nyní vezměme vypočítaný tón cis a vynásobme jej dvanáctou odmocninou čísla 2. Tak dostaneme následující tón d. Toto provedeme i pro ostatní tóny:
d = cis × 2 ^ 1/12
, dis = d × 2 ^ 1/12
,
e = dis × 2 ^ 1/12
, a tak dále...
Tento postup můžeme zobecnit tak, že platí:
Frekvence hledaného tónu = c × ( 2 ^ 1/12 ) ^ i.
kde i je pořadí hledaného tónu v oktávě, počínaje
c = 0
, cis = 1
, d = 2
,
dis = 3
, atd.
Praktická ukázka
Vypočítáme frekvenci tónů dvojčárkové oktávy:
- Definujeme si frekvenci základního tónu. Zvolíme si
například tón C velké oktávy:
zakladniTon = 65,406
- Vypočítáme první tón c2 požadované
dvojčárkové oktávy. Vezmeme tedy základní tón a podle
výše uvedené tabulky s pořadím oktáv jej vynásobíme koeficientem
2^3
:c2 = zakladniTon × 2 ˄ 3
- Vypočítáme frekvenci všech 12 tónů v oktávě a tón
c^3
následující oktávy tak, že v cyklu, kdei = 0
až12
vypočítáme:frekvenceTonu [ i ] = c2 × ( 2 ˄ 1/12 ) ˄ i
- Pro uložení vypočtených hodnot použijeme kvůli jednoduchosti dvě jednorozměrné pole. V jednom poli budou uloženy názvy tónů. V druhém poli budou vypočtené frekvence. Indexy prvků obou polí odpovídají pořadí tónu v oktávě.
- Nakonec každý tón vypíšeme a zahrajeme. Pro kontrolu
správnosti výpočtu si můžeme ověřit, že frekvence tónu
c^3
je dvojnásobná oprotic^2
.
Kód je následující:
double zakladniTon = 65.406; string[] nazevTonu = { "c2", "cis2", "d2", "dis2", "e2", "f2", "fis2", "g2", "gis2", "a2", "b2", "h2", "c3" }; int[] frekvenceTonu = new int[13]; double c2 = zakladniTon * Math.Pow(2, 3); for (int i = 0; i <= 12; i++) { frekvenceTonu[i] = (int)Math.Round(c2 * Math.Pow((Math.Pow(2, (1.0 / 12.0))), i)); Console.WriteLine("Tón {0,-4} o frekvenci {1,4} Hz", nazevTonu[i], frekvenceTonu[i]); Console.Beep(frekvenceTonu[i], 500); } Console.ReadKey();
Vypočtenou frekvenci tónu jsme zaokrouhlili, protože
frekvenci tónu v parametru příkazu Beep()
je nutno zadat jako
celé číslo.
Zobrazovaný výstup:
Konzolová aplikace
Tón c2 o frekvenci 523 Hz
Tón cis2 o frekvenci 554 Hz
Tón d2 o frekvenci 587 Hz
Tón dis2 o frekvenci 622 Hz
Tón e2 o frekvenci 659 Hz
Tón f2 o frekvenci 698 Hz
Tón fis2 o frekvenci 740 Hz
Tón g2 o frekvenci 784 Hz
Tón gis2 o frekvenci 831 Hz
Tón a2 o frekvenci 880 Hz
Tón b2 o frekvenci 932 Hz
Tón h2 o frekvenci 988 Hz
Tón c3 o frekvenci 1046 Hz
Každý výpis tónu je také slyšitelně přehrán.
V následujícím cvičení, Řešené úlohy k 1.-3. lekci Konzole C# .NET , si procvičíme nabyté zkušenosti z předchozích lekcí.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 13x (147.63 kB)
Aplikace je včetně zdrojových kódů v jazyce C#