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