<?xml version="1.0" encoding="utf-8"?>
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" type="guide" style="task" id="guitar-tuner.js" lang="cs">
  <info>
  <title type="text">Kytavorá ladička (JavaScript)</title>
    <link type="guide" xref="js#examples"/>
    <revision version="0.1" date="2012-03-09" status="stub"/>

    <credit type="author copyright">
      <name>Susanna Huhtanen</name>
      <email its:translate="no">ihmis.suski@gmail.com</email>
      <years>2012</years>
    </credit>

    <desc>Používá GTK+ a GStreamer k sestavení jednoduché aplikace pro GNOME s funkcionalitou kytarové ladičky.</desc>
  </info>

  <title>Kytarová ladička</title>

    <synopsis>
      <p>V této lekci sestavíme malou aplikaci, kytarovou ladičku, pomocí jazyka JavaScript a knihoven GTK+ a GStreamer. Abyste tak mohli učinit a spustit si kód z příkladu, budete potřebovat nainstalovaný editor pro psaní kódu, terminál a GNOME 3.0 nebo novější.</p>
   <list>
      <item><p><link xref="#gstreamer">Roury systému GStreamer</link></p></item>
      <item><p><link xref="#script">Skript pro spuštění aplikace</link></p></item>
      <item><p><link xref="#imports">Importované knihovny</link></p></item>
      <item><p><link xref="#mainwindow">Vytvoření hlavního okna pro aplikaci</link></p></item>
      <item><p><link xref="#buttons">Tlačítka pro ladění</link></p></item>
      <item><p><link xref="#playSound">Vyluzování zvuků systémem GStreamer</link></p></item>
      <item><p><link xref="#connecting">Napojení tlačítek na playSound</link></p></item>
      <item><p><link xref="#guitarjs">Celý program</link></p></item>
      <item><p><link xref="#terminal">Spuštění aplikace z terminálu</link></p></item>
    </list>
  </synopsis>
  <p>Po přečtení této lekce byste měli na obrazovce dostat toto:</p>
  <media type="image" mime="image/png" src="media/guitar-tuner.png"/>
  <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="script">
    <title>Skript pro spuštění aplikace</title>
    <code mime="application/javascript" style="numbered">
  #!/usr/bin/gjs</code>
    <p>Tento řádek říká, jak spustit skript. Musí být prvním řádek v souboru s kódem a soubor musí být spustitelný. Abyste získali práva na spuštění, jděte do terminálu a ve správné složce spusťte: chmod +x název_skriptu. Nebo můžete použít grafického správce souborů. Přejděte do správné složky s vašim kódem, klikněte na soubor s kódem pravým tlačítkem, zvolte vlastnosti, klikněte na kartu oprávnění a zaškrtněte políčko, které povoluje spuštění souboru jako programu.</p>
  </section>
  <section id="imports">
    <title>Importované knihovny</title>
    <code mime="application/javascript" style="numbered">
var Gtk = imports.gi.Gtk;
var Gst = imports.gi.Gst;

const Mainloop = imports.mainloop;</code>
    <p>Abychom dostali fungující program, potřebujeme naimportovat pár GObject Introspection, tj. knihoven, pro naše použití. Pro fungující uživatelské rozhraní potřebujeme Gtk a pro GStreamer potřebujeme Gst. Import se provádí hned na začátku, takže budou fungovat všude. Na začátku také naimportujeme konstrukt Mainloop, který se bude starat o časové omezení při vydávání ladicích tónů.</p>
    </section>
  <section id="mainwindow">
    <title>Vytvoření hlavního okna pro aplikaci</title>
    <code mime="application/javascript" style="numbered">
Gtk.init(null, 0);
Gst.init(null, 0);

var guitarwindow = new Gtk.Window({type: Gtk.WindowType.TOPLEVEL, border_width: 100});
guitarwindow.title = "Guitar Tuner";
guitarwindow.connect("destroy", function(){Gtk.main_quit()});

guitarwindow.show();
Gtk.main();</code>
    <p>Jen naimportovat Gtk a Gst nestačí, je třeba je inicializovat, aby fungovaly. Když jsou Gtk a Gst nastavené a běží, potřebujeme vytvořit okno pro aplikaci. Později do tohoto okna vložíme všechna tlačítka pro vydávání tónů. Aby se okno zobrazilo, musíme mu říci, ať se zobrazí, a také musíme spustit kód s <code>Gtk.main()</code>.</p>
  </section>
  <section id="buttons">
   <title>Tlačítka pro ladění</title>
   <code mime="application/javascript" style="numbered">
var guitar_box = new Gtk.ButtonBox ({orientation: Gtk.Orientation.VERTICAL, spacing: 10});

var E = new Gtk.Button({label: "E"});
var A = new Gtk.Button({label: "A"});
var D = new Gtk.Button({label: "D"});
var G = new Gtk.Button({label: "G"});
var B = new Gtk.Button({label: "B"});
var e = new Gtk.Button({label: "e"});

guitar_box.add(E);
guitar_box.add(A);
guitar_box.add(D);
guitar_box.add(G);
guitar_box.add(B);
guitar_box.add(e);

guitarwindow.add(guitar_box);

guitar_box.show_all();</code>
   <p>Protože <code>Gtk.Window</code> může obsahovat jen jediný widget, potřebujeme vytvořit nějaký další podkladový, který bude schopný do sebe přidat všechna tlačítka. V tomto příkladu použijeme <code>Buttonbox</code> (box na tlačítka). Po jeho vytvoření vytvoříme tlačítka s patřičnými popisky. Když máme tlačítka, musíme je přidat do kontejneru Buttonbox a ten musíme přidat do Gtk.Window a vše v boxu na tlačítka se musí zobrazit.</p>
   <p>Po této fázi byste měli mít okno, které se ukáže na obrazovce a zobrazí šest tlačítek. Je v pořádku, že tlačítka nic nedělají, to budeme řešit později. Než vůbec můžeme někam napojit signály tlačítek, musíme ono „někam“ nejdříve naprogramovat.</p>
  </section>
  <section id="playSound">
   <title>Vyluzování zvuků systémem GStreamer</title>
   <code mime="application/javascript" style="numbered">
var frequencies = {E: 329.63, A: 440,	D: 587.33,	G: 783.99,	B: 987.77,	e: 1318.5}

function playSound(frequency){
  var pipeline = new Gst.Pipeline({name: "note"});
  var source = Gst.ElementFactory.make("audiotestsrc","source");
  var sink = Gst.ElementFactory.make("autoaudiosink","output");

  source.set_property('freq', frequency);
  pipeline.add(source);
  pipeline.add(sink);
  source.link(sink);
  pipeline.set_state(Gst.State.PLAYING);

  Mainloop.timeout_add(500, function () {
    pipeline.set_state(Gst.State.NULL);
	  return false;
  });
}</code>
   <p>Nejprve se musíme rozhodnout, jaké tóny chceme při zmáčknutí tlačítka vyloudit. O to se postará seznam frekvencí. Tím se dostáváme k tomu, jak vydat zvuk ve funkci <code>playSound</code>. Té jako vstup předáváme frekvenci (ty jsme právě nadefinovali do proměnné). Jako první musíme sestrojit rouru, zdroj a cíl. Zdroji nastavíme frekvenci. K rouře přidáme zdroj i cíl a pak řekneme, ať to hraje. Jako poslední věc použijeme objekt <code>Mainloop</code> k zastavení roury po 500 ms.</p>
   <p>Nyní máme způsob, jak přehrát tón při kliknutí na tlačítko. Takže jako další krok propojíme zmáčknutí tlačítka s přehráním správného tónu.</p>
  </section>
  <section id="connecting">
   <title>Napojení tlačítek na playSound</title>
   <code mime="application/javascript" style="numbered">
E.connect("clicked", function() {
  playSound(frequencies.E);
});
A.connect("clicked", function(){
  playSound(frequencies.A);
});
D.connect("clicked", function(){
  playSound(frequencies.D);
});
G.connect("clicked", function(){
  playSound(frequencies.G);
});
B.connect("clicked", function(){
  playSound(frequencies.B);
});
e.connect("clicked", function(){
  playSound(frequencies.e);
});</code>
   <p>Způsob propojení kliknutí na tlačítko a funkce <code>playSound</code> se správným tónem se provede pomocí metody <code>connect</code> widgetu tlačítka. Zvolíme napojované tlačítko a napíšeme <code>E.connect("clicked", function(){playSound(frequencies.E);});</code>. Metoda <code>connect</code> říká, že když se zmáčkne E, má se něco stát. Řetězec <code>"clicked"</code> říká, o jaký typ signálu se u tlačítka jedná a funkce <code>function(){};</code> volá <code>playSound</code> se správnou notou, která k tlačítku patří.</p>
  </section>
  <section id="guitarjs">
    <title>Celý program</title>
    <p>Takže všechny části spojené dohromady vypadají takto. Když spustíte tento kód, měli byste být schopni naladit si svoji kytaru (pokud máte správně zkalibrované reproduktory).</p>
      <code mime="application/javascript" style="numbered">
#!/usr/bin/gjs
var Gtk = imports.gi.Gtk;
var Gst = imports.gi.Gst;

const Mainloop = imports.mainloop;

Gtk.init(null, 0);
Gst.init(null, 0);

var guitarwindow = new Gtk.Window({type: Gtk.WindowType.TOPLEVEL, border_width: 100});
guitarwindow.title = "Guitar Tuner";
guitarwindow.connect("destroy", function(){Gtk.main_quit()});

var guitar_box = new Gtk.ButtonBox ({orientation: Gtk.Orientation.VERTICAL, spacing: 10});

var E = new Gtk.Button({label: "E"});
var A = new Gtk.Button({label: "A"});
var D = new Gtk.Button({label: "D"});
var G = new Gtk.Button({label: "G"});
var B = new Gtk.Button({label: "B"});
var e = new Gtk.Button({label: "e"});

var frequencies = {E: 329.63, A: 440,	D: 587.33,	G: 783.99,	B: 987.77,	e: 1318.5}


function playSound(frequency){
  var pipeline = new Gst.Pipeline({name: "note"});

  var source = Gst.ElementFactory.make("audiotestsrc","source");
  var sink = Gst.ElementFactory.make("autoaudiosink","output");

  source.set_property('freq', frequency);
  pipeline.add(source);
  pipeline.add(sink);
  source.link(sink);
  pipeline.set_state(Gst.State.PLAYING);

  Mainloop.timeout_add(500, function () {
    pipeline.set_state(Gst.State.NULL);
	  return false;
});
}

E.connect("clicked", function() {
  playSound(frequencies.E);
});
A.connect("clicked", function(){
  playSound(frequencies.A);
});
D.connect("clicked", function(){
  playSound(frequencies.D);
});
G.connect("clicked", function(){
  playSound(frequencies.G);
});
B.connect("clicked", function(){
  playSound(frequencies.B);
});
e.connect("clicked", function(){
  playSound(frequencies.e);
});

guitar_box.add(E);
guitar_box.add(A);
guitar_box.add(D);
guitar_box.add(G);
guitar_box.add(B);
guitar_box.add(e);

guitarwindow.add(guitar_box);

guitar_box.show_all();
guitarwindow.show();
Gtk.main();</code>
  </section>

<section id="terminal">
  <title>Spuštění aplikace z terminálu</title>
  <p>Pro spuštění aplikace otevřete terminál, přejděte do složky, kde je vaše aplikace uložená a pak ji spusťte</p> <screen> <output style="prompt">$ </output><input> GJS_PATH=`pwd` gjs guitarTuner.js</input> </screen>
    </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.js">ukázkovým kódem</link>.</p>
</section>


</page>
