/usr/share/help/cs/gnome-devel-demos/guitar-tuner.c.page is in gnome-devel-docs 3.28.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | <?xml version="1.0" encoding="utf-8"?>
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" type="topic" id="guitar-tuner.c" xml:lang="cs">
<info>
<title type="text">Kytarová ladička (C)</title>
<link type="guide" xref="c#examples"/>
<desc>Jak použít GTK+ a GStreamer k sestavení jednoduché aplikace pro GNOME fungující jako kytarová ladička. Předvedeme si, jako používat návrhář rozhraní.</desc>
<revision pkgversion="0.1" version="0.1" date="2010-12-02" status="review"/>
<credit type="author">
<name>Dokumentační projekt GNOME</name>
<email its:translate="no">gnome-doc-list@gnome.org</email>
</credit>
<credit type="author">
<name>Johannes Schmid</name>
<email its:translate="no">jhs@gnome.org</email>
</credit>
<credit type="editor">
<name>Marta Maria Casetti</name>
<email its:translate="no">mmcasetti@gmail.com</email>
<years>2013</years>
</credit>
</info>
<title>Kytarová ladička</title>
<synopsis>
<p>V této lekci vytvoříme program, který přehrává tóny, které můžete použít k ladění kytary. Naučíte se, jak udělat tyto věci:</p>
<list>
<item><p>Vytvořit základní projekt ve studiu Anjuta.</p></item>
<item><p>Vytvořit jednoduché GUI v návrháři GUI ve studiu Anjuta.</p></item>
<item><p>Použít GStreamer k přehrání zvuku.</p></item>
</list>
<p>Abyste mohli pokračovat v této lekci, budete potřebovat následující:</p>
<list>
<item><p>Nainstalovanou kopii <link xref="getting-ready">IDE Anjuta</link></p></item>
<item><p>Základní znalosti programovacího jazyka C</p></item>
</list>
</synopsis>
<media type="image" mime="image/png" src="media/guitar-tuner.png"/>
<section id="anjuta">
<title>Vytvoření projektu ve studiu Anjuta</title>
<p>Než začnete s kódováním, musíte ve studiu Anjuta vytvořit nový projekt. Tím se vytvoří všechny soubory, které budete později potřebovat k sestavení a spuštění kódu. Je to také užitečné kvůli udržení všeho pohromadě.</p>
<steps>
<item>
<p>Spusťte IDE Anjuta a klikněte na <guiseq><gui>Soubor</gui> <gui>Nový</gui> <gui>Projekt</gui></guiseq>, aby se otevřel průvodce projektem.</p>
</item>
<item>
<p>Na kartě <gui>C</gui> zvolte <gui>GTK+ (jednoduchý)</gui>, klikněte na <gui>Pokračovat</gui> a na několika následujících stránkách vyplňte své údaje. Jako název projektu a složky použijte <file>guitar-tuner</file>.</p>
</item>
<item>
<p>Ujistěte se, že <gui>Konfigurovat externí balíčky</gui> je přepnuto na <gui>Zapnuto</gui>. Na následující stránce vyberte v seznamu <em>gstreamer-0.10</em>, aby se knihovna GStreamer zahrnula do vašeho projektu.</p>
</item>
<item>
<p>Klikněte na <gui>Použít</gui> a vytvoří se vám projekt. Otevřete <file>src/main.c</file> na kartě <gui>Projekt</gui> nebo <gui>Soubor</gui>. Měli byste vidět kód, který začíná řádky:</p>
<code mime="text/x-csrc">
#include <config.h>
#include <gtk/gtk.h></code>
</item>
</steps>
</section>
<section id="build">
<title>Prvotní sestavení kódu</title>
<p>C je celkem „upovídaný“ jazyk, takže nebuďte překvapeni, že soubor obsahuje poměrně hodně kódu. Většina toho je kód šablony. Načte (prázdné) okno ze souboru s popisem uživatelského rozhraní a zobrazí jej. Dále to podrobněji rozebereme. Pokud jste již pochopili základy, tak tento seznam můžete přeskočit:</p>
<list>
<item>
<p>Tři řádky <code>#include</code> na začátku vkládají knihovny <code>config</code> (užitečné definice pro sestavení pomocí autotools), <code>gtk</code> (uživatelské rozhraní) a <code>gi18n</code> (internacionalizace). Funkce z těchto knihoven se používají ve zbytku kódu.</p>
</item>
<item>
<p>Funkce <code>create_window</code> vytvoří nové okno ze souboru GtkBulder (<file>src/guitar-tuner.ui</file>, definováno o pár řádků výše), připojí jeho signály a zobrazí jej v okně. Soubor GtkBuilder obsahuje popis uživatelského rozhraní a jeho prvků. K návrhu uživatelského rozhraní GtkBuilder můžete použít editor přímo ve vývojářském studiu Anjuta.</p>
<p>Napojení signálu je způsob, jak definovat, co se má stát, když zmáčknete tlačítko nebo se prostě něco přihodí. Zde je zavolána metoda <code>destroy</code> (a ukončení aplikace) při zavření okna.</p>
</item>
<item>
<p>Funkce <code>main</code> se spustí jako výchozí, když spustíte aplikaci napsanou v jazyce C. Volá pár funkcí, které nastaví a spustí aplikaci. Funkce <code>gtk_main</code> spustí hlavní smyčku GTK, která spustí uživatelské rozhraní a začne naslouchat událostem (jako je kliknutí nebo zmáčknutí klávesy).</p>
</item>
<item>
<p>Podmíněná definice <code>ENABLE_NLS</code> nastavuje <code>gettext</code>, což je základní konstrukce pro překládání aplikací do národních jazyků. Tyto funkce určují, jak mají překladové nástroje pracovat s vaší aplikací za běhu.</p>
</item>
</list>
<p>Kód je připravený k použití, takže jej můžete zkompilovat kliknutím na <guiseq><gui>Sestavit</gui> <gui>Sestavit projekt</gui></guiseq> (nebo zmáčknutím <keyseq><key>Shift</key> <key>F7</key></keyseq>).</p>
<p>V následujícím okně zmáčkněte <gui>Spustit</gui>, aby se nakonfigurovalo ladicí sestavení. Stačí to udělat jen jednou, pro první sestavení.</p>
</section>
<section id="ui">
<title>Vytvoření uživatelského rozhraní</title>
<p>Popis uživatelského rozhraní se nachází v souboru GtkBuilder. Když chcete uživatelské rozhraní upravit, otevřete <file>src/guitar_tuner.ui</file>. Přepnete se tím do návrháře rozhraní. Navrhované okno je uprostřed, widgety a jejich vlastnosti jsou nalevo a paleta dostupných widgetů je napravo.</p>
<p>Rozvržení každého uživatelského rozhraní v GTK+ je provedeno pomocí boxů a mřížek. Zde použijeme svislý <code>GtkButtonBox</code>, do kterého přiřadíme šest <code>GtkButtons</code>, jedno pro každou z kytarových strun.</p>
<media type="image" mime="image/png" src="media/guitar-tuner-glade.png"/>
<steps>
<item>
<p>Vyberte <gui>GtkButtonBox</gui> z oddílu <gui>Kontejnery</gui> v <gui>Paletě</gui> napravo a vložte jej do okna. V panelu <gui>Vlastnosti</gui> nastavte počet prvků na 6 (pro 6 strun) a orientaci na svislou.</p>
</item>
<item>
<p>Nyní v paletě zvolte <gui>GtkButton</gui> a vložte jej do první části boxu.</p>
</item>
<item>
<p>Zatímco je tlačítko stále vybráno, změňte vlastnost <gui>Popisek</gui> na kartě <gui>Widgety</gui> na <gui>E</gui>. Bude se jednat o spodní strunu E.</p>
</item>
<item>
<p>Přepněte se na kartu <gui>Signál</gui> (uvnitř karty <gui>Widgety</gui>) a podívejte se po signálu <code>clicked</code> tlačítka. Můžete jej použít k napojení na obsluhu signálu, která bude volána, když uživatel na tlačítko klikne. Provede se to kliknutím na signál a vepsáním <code>on_button_clicked</code> do sloupce <gui>Obslužná rutina</gui> a zmáčknutím <key>Enter</key>.</p>
</item>
<item>
<p>Zopakujte předchozí kroky pro ostatní tlačítka, takže přidáte následujících 5 strun s názvy <em>A</em>, <em>D</em>, <em>G</em>, <em>B</em> a <em>e</em>.</p>
</item>
<item>
<p>Návrh uživatelského rozhraní uložte (kliknutím na <guiseq><gui>Soubor</gui> <gui>Uložit</gui></guiseq>) a ponechte jej otevřený.</p>
</item>
</steps>
</section>
<section id="signal">
<title>Vytvoření obsluhy signálů</title>
<p>V návrháři uživatelského rozhraní můžete nastavit to, že všechna tlačítka budou při kliknutí volat stejnou funkci <gui>on_button_clicked</gui>. Tuto funkci musíme přidat do zdrojového kódu.</p>
<p>K tomu otevřete <file>main.c</file> a soubor s uživatelským rozhraním při tom ponechte stále otevřený. Přepněte se na kartu <gui>Signály</gui>, kterou jste již použili pro nastavení názvu signálu. Nyní chytněte řádek, na kterém jste nastavili signál <gui>clicked</gui> a přetáhněte jej do zdrojového kódu na místo mimo kteroukoliv funkci. Do zdrojového kódu se přidá následující kód:</p>
<code mime="text/x-csrc">
void on_button_clicked (GtkWidget* button, gpointer user_data)
{
}</code>
<p>Obsluha signálu má dva argumenty: ukazatel na <code>GtkWidget</code>, který funkci zavolal (v našem případě vždy <code>GtkButton</code>) a ukazatel na nějaká „uživatelská data“, která si můžete nadefinovat, ale zde je nebudeme chtít použít. (Uživatelská data můžete nastavit zavoláním <code>gtk_builder_connect_signals</code>. Normálně se použivá k předání ukazatele na datovou strukturu, ke které můžete potřebovat přístup uvnitř obsluhy signálu.)</p>
<p>Prozatím ponecháme obsluhu signálu prázdnou a budeme pracovat na psaní kódu pro vyluzování zvuků.</p>
</section>
<section id="gstreamer">
<title>Roury systému GStreamer</title>
<p>GStreamer je základní multimediální rámec GNOME. Můžete jej použít k přehrávání, nahrávání a zpracování videa, zvuku, vysílání z webové kamery a podobně. Zde jej použijeme ke generování tónu s jednou frekvencí.</p>
<p>Koncepčně GStreamer funguje následovně: Vytvoříte <em>rouru</em> (pipeline) obsahující různé prvky zpracující směrem od <em>zdroje</em> (source) do <em>cíle</em> (sink), tj. výstupu. Zdrojem může být například soubor s obrázkem, videosoubor nebo hudební soubor, výstupem pak widget nebo zvuková karta.</p>
<p>Na cestě mezi zdrojem a cílem můžete použít různé filtry a převodníky k vytvoření efektů, převodníky formátů atd. Každý prvek roury má vlastnosti, které můžete použít ke změně jeho chování.</p>
<media type="image" mime="image/png" src="media/guitar-tuner-pipeline.png">
<p>Příklad roury systému GStreamer.</p>
</media>
</section>
<section id="pipeline">
<title>Vytvoření roury</title>
<p>V tomto příkladu použijeme jako zdroj tónový generátor nazývaný <code>audiotestsrc</code> a výstup pošleme do výchozího systémového zvukového zařízení <code>autoaudiosink</code>. Nastavit potřebujeme jen frekvenci tónového generátoru. Ta je přístupná přes vlastnost <code>freq</code> zmíněného <code>audiotestsrc</code>.</p>
<p>Vložte do <file>main.c</file> následující řádek, hned pod řádek <code>#include <gtk/gtk.h></code>:</p>
<code mime="text/x-csrc">#include <gst/gst.h></code>
<p>Tímto se vloží knihovna GStreamer. Potřebujete také přidat řádek inicializující GStreamer. Vložte následující kód na řádek nad volání <code>gtk_init</code> do funkce <code>main</code>:</p>
<code>gst_init (&argc, &argv);</code>
<p>Pak nakopírujte následující funkci do <file>main.c</file> nad prázdnou funkci <code>on_button_clicked</code>:</p>
<code mime="text/x-csrc">static void
play_sound (gdouble frequency)
{
GstElement *source, *sink;
GstElement *pipeline;
pipeline = gst_pipeline_new ("note");
source = gst_element_factory_make ("audiotestsrc",
"source");
sink = gst_element_factory_make ("autoaudiosink",
"output");
/* nastaví frekvenci */
g_object_set (source, "freq", frequency, NULL);
gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL);
gst_element_link (source, sink);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* zastaví to po 500 ms */
g_timeout_add (LENGTH, (GSourceFunc) pipeline_stop, pipeline);
}</code>
<steps>
<item>
<p>Prvních pět řádků vytvoří prvky GStreamer typu zdroj a cíl (<code>GstElement</code>) a prvek typu roura (který bude použit jako kontejner pro první dva prvky). Roura dostane název „note“. Zdroj je pojmenován „source“ a je nastaven jako <code>audiotestsrc</code>. Cíl je pojmenován „output“ a je nastaven jako <code>autoaudiosink</code> (výchozí výstup zvukové karty).</p>
</item>
<item>
<p>Volání <code>g_object_set</code> nastaví vlastnost <code>freq</code> zdrojového prvku na <code>frequency</code>, která byla předána jako argument funkci <code>play_sound</code>. Jedná se o frekvenci tónu v hertzích. Správné frekvence nadefinujeme později.</p>
</item>
<item>
<p><code>gst_bin_add_many</code> vloží zdroj a cíl do roury. Roura je <code>GstBin</code>, což je zase jen prvek, který může obsahovat více dalších prvků GStreamer. Obecně můžete přidat tolik prvků, kolik chcete, pomocí předáním více argumentů do <code>gst_bin_add_many</code>.</p>
</item>
<item>
<p>Následně je <code>gst_element_link</code> použito k propojení prvků navzájem, takže výstup prvku <code>source</code> (tón) putuje do vstupu prvku <code>sink</code> (což je výstup do zvukové karty). <code>gst_element_set_state</code> je použito ke spuštění přehrávání nastavením stavu roury na přehrávání (<code>GST_STATE_PLAYING</code>).</p>
</item>
</steps>
</section>
<section id="stop">
<title>Zastavení přehrávání</title>
<p>Nechceme ale hrát nějaký tón navždycky, takže poslední věcí, kterou <code>play_sound</code> udělá, je, že zavolá <code>g_timeout_add</code>. Tím se nastaví časový limit pro zastavení zvuku. Čeká v délce <code>LENGTH</code> milisekund a pak zavolá funkci <code>pipeline_stop</code>, která vrátí <code>FALSE</code>, jinak by se v jejím volání pokračovalo.</p>
<p>Nyní budeme psát funkci <code>pipeline_stop</code>, která je volána z <code>g_timeout_add</code>. Vložte následující kód <em>nad</em> funkci <code>play_sound</code>:</p>
<code mime="text/x-csrc">
#define LENGTH 500 /* Délka přehrávání v ms */
static gboolean
pipeline_stop (GstElement* pipeline)
{
gst_element_set_state (pipeline, GST_STATE_NULL);
g_object_unref (pipeline);
return FALSE;
}</code>
<p>Zavolání <code>gst_element_set_state</code> zastaví přehrávání roury a <code>g_object_unref</code> zruší odkazy na rouru, zlikviduje ji a uvolní její paměť.</p>
</section>
<section id="tones">
<title>Definice tónů</title>
<p>Když uživatel klikne na tlačítko, chceme zahrát správný zvuk. Nejdříve ze všeho potřebujeme znát frekvence pro šest kytarových strun, které jsou definovány (na začátku <file>main.c</file>) následovně:</p>
<code mime="text/x-csrc">
/* Řetězce pro jednotlivé frekvence */
#define NOTE_E 329.63
#define NOTE_A 440
#define NOTE_D 587.33
#define NOTE_G 783.99
#define NOTE_B 987.77
#define NOTE_e 1318.5</code>
<p>Nyní oživíme obsluhu signálu, kterou jsme zadeklarovali již dříve po názvem <code>on_button_clicked</code>. Mohli bychom mít napojená všechna tlačítka na různé obslužné funkce, ale to by vedlo ke zbytečné duplicitě kódu. Místo toho použijeme popisek každého z tlačítek ke zjištění, na které tlačítko bylo kliknuto:</p>
<code mime="text/x-csrc">
/* Zpětná volání pro tlačítka */
void on_button_clicked (GtkButton* button,
gpointer user_data)
{
const gchar* text = gtk_button_get_label (button);
if (g_str_equal (text, _("E")))
play_sound (NOTE_E);
else if (g_str_equal (text, _("A")))
play_sound (NOTE_A);
else if (g_str_equal (text, _("G")))
play_sound (NOTE_G);
else if (g_str_equal (text, _("D")))
play_sound (NOTE_D);
else if (g_str_equal (text, _("B")))
play_sound (NOTE_B);
else if (g_str_equal (text, _("e")))
play_sound (NOTE_e);
}
</code>
<p>Ukazatel na <code>GtkButton</code>, na které bylo kliknuto je předán jako argument (<code>button</code>) do <code>on_button_clicked</code>. Text tohoto tlačítka můžeme získat pomocí <code>gtk_button_get_label</code>.</p>
<p>Text se porovnává s notami, které máme pomocí <code>g_str_equal</code> a <code>play_sound</code> je voláno s příslušnou frekvencí odpovídající notě. Tím se zahraje tón a my máme konečně fungující kytarovou ladičku!</p>
</section>
<section id="run">
<title>Sestavení a spuštění aplikace</title>
<p>Celý kód by nyní měl být připravený k fungování. Klikněte na <guiseq><gui>Sestavit</gui> <gui>Sestavit projekt</gui></guiseq>, aby se vše znovu sestavilo a pak na <guiseq><gui>Spustit</gui> <gui>Spustit</gui></guiseq>, aby se aplikace spustila.</p>
<p>Pokud jste tak ještě neučinili, zvolte aplikaci <file>Debug/src/guitar-tuner</file> v dialogovém okně, které se objeví. Nakonec klikněte na <gui>Spustit</gui> a užijte si ji!</p>
</section>
<section id="impl">
<title>Ukázková implementace</title>
<p>Pokud v této lekci narazíte na nějaké problémy, porovnejte si svůj kód s tímto <link href="guitar-tuner/guitar-tuner.c">ukázkovým kódem</link>.</p>
</section>
<section id="next">
<title>Další postup</title>
<p>Zde je pár nápadů, jak byste mohli tuto jednoduchou ukázku rozšířit:</p>
<list>
<item>
<p>Přidat do programu možnost cyklicky procházet tóny.</p>
</item>
<item>
<p>Naučit program přehrávat nahrávky vybrnkání jednotlivých reálných kytarových strun.</p>
<p>Abychom to mohli udělat, potřebujeme sestavit mnohem složitější rouru GStreamer, která umožní načíst a přehrát hudební soubory. Budete muset zvolit prvky GStreamer typu <link href="http://gstreamer.freedesktop.org/documentation/plugins.html">dekodér a demultiplexor</link> podle formátu souborů s vašimi zvukovými nahrávkami – například MP3 používá jiné prvky než Ogg Vorbis.</p>
<p>Můžete také potřebovat prvky propojit mnohem komplikovanějším způsobem. Toho lze dosáhnout pomocí <link href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-intro-basics.html">konceptů GStreamer</link>, které jsme v této lekci neprobírali. Mezi ně patří například <link href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-intro-basics-pads.html">přípojné body</link>. Hodit se vám může také příkaz <cmd>gst-inspect</cmd>.</p>
</item>
<item>
<p>Automaticky analyzovat tóny, které uživatel zahraje.</p>
<p>Mohli byste připojit mikrofón a nahrávat z něj zvuky pomocí <link href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good-plugins/html/gst-plugins-good-plugins-autoaudiosrc.html">vstupního zdroje</link>. Zjistit, který tón je přehráván, by vám možná pomohla <link href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good-plugins/html/gst-plugins-good-plugins-plugin-spectrum.html">spektrální analýza</link>.</p>
</item>
</list>
</section>
</page>
|