Blame platform-demos/cs/guitar-tuner.js.page

Packit 1470ea
Packit 1470ea
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" type="guide" style="task" id="guitar-tuner.js" xml:lang="cs">
Packit 1470ea
  <info>
Packit 1470ea
  <title type="text">Kytavorá ladička (JavaScript)</title>
Packit 1470ea
    <link type="guide" xref="js#examples"/>
Packit 1470ea
    <revision version="0.1" date="2012-03-09" status="stub"/>
Packit 1470ea
Packit 1470ea
    <credit type="author copyright">
Packit 1470ea
      <name>Susanna Huhtanen</name>
Packit 1470ea
      <email its:translate="no">ihmis.suski@gmail.com</email>
Packit 1470ea
      <years>2012</years>
Packit 1470ea
    </credit>
Packit 1470ea
Packit 1470ea
    <desc>Používá GTK+ a GStreamer k sestavení jednoduché aplikace pro GNOME s funkcionalitou kytarové ladičky.</desc>
Packit 1470ea
  </info>
Packit 1470ea
Packit 1470ea
  <title>Kytarová ladička</title>
Packit 1470ea
Packit 1470ea
    <synopsis>
Packit 1470ea
      

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ší.

Packit 1470ea
   <list>
Packit 1470ea
      <item>

<link xref="#gstreamer">Roury systému GStreamer</link>

</item>
Packit 1470ea
      <item>

<link xref="#script">Skript pro spuštění aplikace</link>

</item>
Packit 1470ea
      <item>

<link xref="#imports">Importované knihovny</link>

</item>
Packit 1470ea
      <item>

<link xref="#mainwindow">Vytvoření hlavního okna pro aplikaci</link>

</item>
Packit 1470ea
      <item>

<link xref="#buttons">Tlačítka pro ladění</link>

</item>
Packit 1470ea
      <item>

<link xref="#playSound">Vyluzování zvuků systémem GStreamer</link>

</item>
Packit 1470ea
      <item>

<link xref="#connecting">Napojení tlačítek na playSound</link>

</item>
Packit 1470ea
      <item>

<link xref="#guitarjs">Celý program</link>

</item>
Packit 1470ea
      <item>

<link xref="#terminal">Spuštění aplikace z terminálu</link>

</item>
Packit 1470ea
    </list>
Packit 1470ea
  </synopsis>
Packit 1470ea
  

Po přečtení této lekce byste měli na obrazovce dostat toto:

Packit 1470ea
  <media type="image" mime="image/png" src="media/guitar-tuner.png"/>
Packit 1470ea
  <section id="gstreamer">
Packit 1470ea
    <title>Roury systému GStreamer</title>
Packit 1470ea
    

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

Packit 1470ea
    

Koncepčně GStreamer funguje následovně: Vytvoříte rouru (pipeline) obsahující různé prvky zpracující směrem od zdroje (source) do cíle (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.

Packit 1470ea
    

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

Packit 1470ea
    <media type="image" mime="image/png" src="media/guitar-tuner-pipeline.png">
Packit 1470ea
      

Příklad roury systému GStreamer.

Packit 1470ea
    </media>
Packit 1470ea
  </section>
Packit 1470ea
  <section id="script">
Packit 1470ea
    <title>Skript pro spuštění aplikace</title>
Packit 1470ea
    
Packit 1470ea
  #!/usr/bin/gjs
Packit 1470ea
    

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.

Packit 1470ea
  </section>
Packit 1470ea
  <section id="imports">
Packit 1470ea
    <title>Importované knihovny</title>
Packit 1470ea
    
Packit 1470ea
var Gtk = imports.gi.Gtk;
Packit 1470ea
var Gst = imports.gi.Gst;
Packit 1470ea
Packit 1470ea
const Mainloop = imports.mainloop;
Packit 1470ea
    

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

Packit 1470ea
    </section>
Packit 1470ea
  <section id="mainwindow">
Packit 1470ea
    <title>Vytvoření hlavního okna pro aplikaci</title>
Packit 1470ea
    
Packit 1470ea
Gtk.init(null, 0);
Packit 1470ea
Gst.init(null, 0);
Packit 1470ea
Packit 1470ea
var guitarwindow = new Gtk.Window({type: Gtk.WindowType.TOPLEVEL, border_width: 100});
Packit 1470ea
guitarwindow.title = "Guitar Tuner";
Packit 1470ea
guitarwindow.connect("destroy", function(){Gtk.main_quit()});
Packit 1470ea
Packit 1470ea
guitarwindow.show();
Packit 1470ea
Gtk.main();
Packit 1470ea
    

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 Gtk.main().

Packit 1470ea
  </section>
Packit 1470ea
  <section id="buttons">
Packit 1470ea
   <title>Tlačítka pro ladění</title>
Packit 1470ea
   
Packit 1470ea
var guitar_box = new Gtk.ButtonBox ({orientation: Gtk.Orientation.VERTICAL, spacing: 10});
Packit 1470ea
Packit 1470ea
var E = new Gtk.Button({label: "E"});
Packit 1470ea
var A = new Gtk.Button({label: "A"});
Packit 1470ea
var D = new Gtk.Button({label: "D"});
Packit 1470ea
var G = new Gtk.Button({label: "G"});
Packit 1470ea
var B = new Gtk.Button({label: "B"});
Packit 1470ea
var e = new Gtk.Button({label: "e"});
Packit 1470ea
Packit 1470ea
guitar_box.add(E);
Packit 1470ea
guitar_box.add(A);
Packit 1470ea
guitar_box.add(D);
Packit 1470ea
guitar_box.add(G);
Packit 1470ea
guitar_box.add(B);
Packit 1470ea
guitar_box.add(e);
Packit 1470ea
Packit 1470ea
guitarwindow.add(guitar_box);
Packit 1470ea
Packit 1470ea
guitar_box.show_all();
Packit 1470ea
   

Protože Gtk.Window 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 Buttonbox (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.

Packit 1470ea
   

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.

Packit 1470ea
  </section>
Packit 1470ea
  <section id="playSound">
Packit 1470ea
   <title>Vyluzování zvuků systémem GStreamer</title>
Packit 1470ea
   
Packit 1470ea
var frequencies = {E: 329.63, A: 440,	D: 587.33,	G: 783.99,	B: 987.77,	e: 1318.5}
Packit 1470ea
Packit 1470ea
function playSound(frequency){
Packit 1470ea
  var pipeline = new Gst.Pipeline({name: "note"});
Packit 1470ea
  var source = Gst.ElementFactory.make("audiotestsrc","source");
Packit 1470ea
  var sink = Gst.ElementFactory.make("autoaudiosink","output");
Packit 1470ea
Packit 1470ea
  source.set_property('freq', frequency);
Packit 1470ea
  pipeline.add(source);
Packit 1470ea
  pipeline.add(sink);
Packit 1470ea
  source.link(sink);
Packit 1470ea
  pipeline.set_state(Gst.State.PLAYING);
Packit 1470ea
Packit 1470ea
  Mainloop.timeout_add(500, function () {
Packit 1470ea
    pipeline.set_state(Gst.State.NULL);
Packit 1470ea
	  return false;
Packit 1470ea
  });
Packit 1470ea
}
Packit 1470ea
   

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 playSound. 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 Mainloop k zastavení roury po 500 ms.

Packit 1470ea
   

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.

Packit 1470ea
  </section>
Packit 1470ea
  <section id="connecting">
Packit 1470ea
   <title>Napojení tlačítek na playSound</title>
Packit 1470ea
   
Packit 1470ea
E.connect("clicked", function() {
Packit 1470ea
  playSound(frequencies.E);
Packit 1470ea
});
Packit 1470ea
A.connect("clicked", function(){
Packit 1470ea
  playSound(frequencies.A);
Packit 1470ea
});
Packit 1470ea
D.connect("clicked", function(){
Packit 1470ea
  playSound(frequencies.D);
Packit 1470ea
});
Packit 1470ea
G.connect("clicked", function(){
Packit 1470ea
  playSound(frequencies.G);
Packit 1470ea
});
Packit 1470ea
B.connect("clicked", function(){
Packit 1470ea
  playSound(frequencies.B);
Packit 1470ea
});
Packit 1470ea
e.connect("clicked", function(){
Packit 1470ea
  playSound(frequencies.e);
Packit 1470ea
});
Packit 1470ea
   

Způsob propojení kliknutí na tlačítko a funkce playSound se správným tónem se provede pomocí metody connect widgetu tlačítka. Zvolíme napojované tlačítko a napíšeme E.connect("clicked", function(){playSound(frequencies.E);});. Metoda connect říká, že když se zmáčkne E, má se něco stát. Řetězec "clicked" říká, o jaký typ signálu se u tlačítka jedná a funkce function(){}; volá playSound se správnou notou, která k tlačítku patří.

Packit 1470ea
  </section>
Packit 1470ea
  <section id="guitarjs">
Packit 1470ea
    <title>Celý program</title>
Packit 1470ea
    

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

Packit 1470ea
      
Packit 1470ea
#!/usr/bin/gjs
Packit 1470ea
var Gtk = imports.gi.Gtk;
Packit 1470ea
var Gst = imports.gi.Gst;
Packit 1470ea
Packit 1470ea
const Mainloop = imports.mainloop;
Packit 1470ea
Packit 1470ea
Gtk.init(null, 0);
Packit 1470ea
Gst.init(null, 0);
Packit 1470ea
Packit 1470ea
var guitarwindow = new Gtk.Window({type: Gtk.WindowType.TOPLEVEL, border_width: 100});
Packit 1470ea
guitarwindow.title = "Guitar Tuner";
Packit 1470ea
guitarwindow.connect("destroy", function(){Gtk.main_quit()});
Packit 1470ea
Packit 1470ea
var guitar_box = new Gtk.ButtonBox ({orientation: Gtk.Orientation.VERTICAL, spacing: 10});
Packit 1470ea
Packit 1470ea
var E = new Gtk.Button({label: "E"});
Packit 1470ea
var A = new Gtk.Button({label: "A"});
Packit 1470ea
var D = new Gtk.Button({label: "D"});
Packit 1470ea
var G = new Gtk.Button({label: "G"});
Packit 1470ea
var B = new Gtk.Button({label: "B"});
Packit 1470ea
var e = new Gtk.Button({label: "e"});
Packit 1470ea
Packit 1470ea
var frequencies = {E: 329.63, A: 440,	D: 587.33,	G: 783.99,	B: 987.77,	e: 1318.5}
Packit 1470ea
Packit 1470ea
Packit 1470ea
function playSound(frequency){
Packit 1470ea
  var pipeline = new Gst.Pipeline({name: "note"});
Packit 1470ea
Packit 1470ea
  var source = Gst.ElementFactory.make("audiotestsrc","source");
Packit 1470ea
  var sink = Gst.ElementFactory.make("autoaudiosink","output");
Packit 1470ea
Packit 1470ea
  source.set_property('freq', frequency);
Packit 1470ea
  pipeline.add(source);
Packit 1470ea
  pipeline.add(sink);
Packit 1470ea
  source.link(sink);
Packit 1470ea
  pipeline.set_state(Gst.State.PLAYING);
Packit 1470ea
Packit 1470ea
  Mainloop.timeout_add(500, function () {
Packit 1470ea
    pipeline.set_state(Gst.State.NULL);
Packit 1470ea
	  return false;
Packit 1470ea
});
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
E.connect("clicked", function() {
Packit 1470ea
  playSound(frequencies.E);
Packit 1470ea
});
Packit 1470ea
A.connect("clicked", function(){
Packit 1470ea
  playSound(frequencies.A);
Packit 1470ea
});
Packit 1470ea
D.connect("clicked", function(){
Packit 1470ea
  playSound(frequencies.D);
Packit 1470ea
});
Packit 1470ea
G.connect("clicked", function(){
Packit 1470ea
  playSound(frequencies.G);
Packit 1470ea
});
Packit 1470ea
B.connect("clicked", function(){
Packit 1470ea
  playSound(frequencies.B);
Packit 1470ea
});
Packit 1470ea
e.connect("clicked", function(){
Packit 1470ea
  playSound(frequencies.e);
Packit 1470ea
});
Packit 1470ea
Packit 1470ea
guitar_box.add(E);
Packit 1470ea
guitar_box.add(A);
Packit 1470ea
guitar_box.add(D);
Packit 1470ea
guitar_box.add(G);
Packit 1470ea
guitar_box.add(B);
Packit 1470ea
guitar_box.add(e);
Packit 1470ea
Packit 1470ea
guitarwindow.add(guitar_box);
Packit 1470ea
Packit 1470ea
guitar_box.show_all();
Packit 1470ea
guitarwindow.show();
Packit 1470ea
Gtk.main();
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
<section id="terminal">
Packit 1470ea
  <title>Spuštění aplikace z terminálu</title>
Packit 1470ea
  

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

<screen> <output style="prompt">$ </output><input> GJS_PATH=`pwd` gjs guitarTuner.js</input> </screen>
Packit 1470ea
    </section>
Packit 1470ea
Packit 1470ea
<section id="impl">
Packit 1470ea
 <title>Ukázková implementace</title>
Packit 1470ea
 

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

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
Packit 1470ea
</page>