NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

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:

Konzole C# .NET a její možnosti

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:

  1. Definujeme si frekvenci základního tónu. Zvolíme si například tón C velké oktávy:

    zakladniTon = 65,406

  2. 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

  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, kde i = 012 vypočítáme:

    frekvenceTonu [ i ] = c2 × ( 2 ˄ 1/12 ) ˄ i

  4. 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ě.
  5. 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á oproti c^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#

 

Předchozí článek
Analýza dat ze vstupu z klávesnice v C# Konzoli
Všechny články v sekci
Konzole C# .NET a její možnosti
Přeskočit článek
(nedoporučujeme)
Řešené úlohy k 1.-3. lekci Konzole C# .NET
Článek pro vás napsal Luděk Novotný
Avatar
Uživatelské hodnocení:
6 hlasů
Autor je technik, má rád stručné a jasné texty, a tak se také snaží psát články pro vás.
Aktivity