Przenosiny!

Cześć!

Chciałbym przeprosić wszystkich za ostatni brak postów i w zamian za to dać wam coś nowego. Zupełnie nie chodzi mi o nowe obietnice, że posty będą się pojawiać częściej. Wręcz przeciwnie – tutaj posty nie będą się pojawiać w ogóle!

Postanowiłem zmienić coś w swoim życiu pod względem blogowania i utworzyłem całkiem nowy blog. Aktualnie publikuję swoje myśli pod adresem:

http://blog.radoszewski.pl

Każdy z bystrym okiem od razu zauważy, że nowy blog jest w nieco innym języku. No cóż… Chciałbym aby moje publikacje były dostępne dla wszystkich, a język angielski jest na tyle uniwersalny, że wydaje się świetnie nadawać do takiego zastosowania 🙂

Zapraszam!

Jak wywołać z Javy konkretną funkcję skryptu JavaScript

Wczoraj opisałem trochę w jaki sposób można wykonać skrypt JS używając silnika Mozilla Rhino. Wczoraj byłem tak podekscytowany tym, że wreszcie mi się udąło, że zapomniałem napisać z czego właściwie korzystałem 😉

Tak czy inaczej samo wykonanie skryptu to jeszcze nie wszystko. Gdybyśmy chcieli mieć w grze wiele różnych obiektów wykonujących kilka zadań w zależności od potrzeb to musielibyśmy dla każdej funkcji pisać osobny plik skryptu. Ani to wygodne, ani eleganckie dlatego też warto było poświęcić wczoraj kilka chwil na zastanowienie się w jaki sposób wywoływać po nazwie funkcje JS z kodu Javy.

Aby to osiągnąć najpierw trzeba załadować skompilowany skrypt tak jak w ostatnim poście.

URL[] urls;
urls = new URL[] { new File('/home/morti/NetBeansProjects/RhinoJS/scripts').toURI().toURL() };
URLClassLoader loader = new URLClassLoader(urls);
Class cl = Class.forName('Base', true, loader);

Script scr = (Script) cl.newInstance();

Następnie należy utworzyć/pobrać kontekst wykonywania oraz przestrzeń:

Context cx = Context.enter();
Scriptable scope = cx.initStandardObjects();

Na stronie o silniku RhinoJS nie rozwodzili się przesadnie nad tym czym jest kontekst ale dość jasno zaznaczyli, że ma on występować jeden na wątek. Na szczęście funkcja enter() załatwia wszystko za nas. Jeżeli w tym wątku nie ma jeszcze kontekstu to zostanie utworzony a jeśli jest to zostanie pobrany i zwiększony jego licznik referencji. Skoro jest licznik referencji to pewnie trzeba też jakoś informować o oddaniu obiektu no i rzeczywiście: mamy metodę Context.exit().

A do czego te przestrzenie? No cóż. Służą one głównie do przechowywania środowiska wykonywania skryptu (np. zdefiniowanych zmiennych oraz ich wartości). Możemy mieć takich przestrzeni ile dusza zapragnie no i dobrze 🙂 Cała sztuczka polega na tym, że dla każdego obiektu w grze będziemy mieli jedną przestrzeń, która będzie przechowywała stan zmiennych oraz treści funkcji. Za chwilę postaram się wytłumaczyć dlaczego tyle tych scopów będziemy potrzebować. Najpierw jednak dam następny fragmencik kodu:

scr.exec(cx, scope);

Być może dla niektórych jest już jasne dlaczego potrzebujemy wiele przestrzeni. Napiszę jednak, aby wszyscy mogli wyciągnąć z tego tekstu wartościowe informacje 🙂 Jak widzimy powyżej należy wykonać załadowany skrypt. Trzeba wykonać ten krok aby zdefiniować w przestrzeni funkcje. Jeśli będziemy mieli wiele obiektów używających skryptów tej samej postaci (z tymi samymi nazwami funkcji) to gdybyśmy zdefinoiwali je wszystkie w jednej przestrzeni to tylko funkcje ostatniego skryptu byłyby wykonywane dla wzsystkich gdyż nadpisałyby one definicje poprzednich skryptów. Dlatego każdy obiekt w grze powinien mieć włąsną przestrzeń wykonywania skryptu.

Jak dotąd w sumie zrobiliśmy to samo co w ostatnim poście z tą różnicą, że dziś na tym nie skończymy 😉 No i oczywiście opisałem nieco znaczenie kilku wymaganych linijek. W całym kodzie trzeba oczywiście jeszcze umieścić odpowiednie bloki try{..} catch(…) ale nie używam tego tutaj ponieważ utrudniłoby to tylko czytanie przykładów.

Ostatnią rzeczą, którą trzeba wykonać jest pobranie obiektu funkcji z przestrzeni oraz wywołanie jej z podaniem parametrów:

Object fObj = scope.get('NazwaFunkcji', scope);
if(fObj instanceof Function) {
	Function f = (Function)fObj;

	result = f.call(cx, scope, scope, new Object[] {'Argument1', new Integer(44), arg3});
	System.out.println('Result: ' + result);
}

Powstaje naturalne pytanie dlaczego podajemy aż 2 razy scope skoro na zdrowy rozum możnaby go nie podawać wcale! Pobraliśmy przecież obiekt z tej przestrzeni więc o co tu chodzi. No cóż. chcąc być do końca szczerym to powiem, że nie zagłębiałem się w te przestrzenie tak mocno aby potrafić udzielić zadowalającej odpowiedzi. Mogę jedynie wkleić opis z dokumentacji:

java.lang.Object call(Context cx,
                      Scriptable scope,
                      Scriptable thisObj,
                      java.lang.Object[] args)

    Call the function. Note that the array of arguments is not
    guaranteed to have length greater than 0.

    Specified by:
        call in interface Callable

    Parameters:
        cx - the current Context for this thread
        scope - the scope to execute the function relative to. 
                This is set to the value returned by getParentScope() 
                except when the function is called from a closure.
        thisObj - the JavaScript this object
        args - the array of arguments 
    Returns:
        the result of the call

Być może komuś pryda się opisany tutaj sposób na wywołanie funkcji ze skompilowanych skryptów JavaScript. Może ktoś wie coś więcej i potrafi dodać coś do tematu? Ja z pewnością skorzystam z umiesczenia tutaj tego przykładu bo nie będę musiał go szukać w kodzie 😉

Pan… z dyplomem.

Ostatnimi czasy pisałem niewiele. Nie. Nie chcę powiedzieć, że teraz zacznę pisać więcej, choć oczywiście chciałbym. Problem w tym, że aby pisać trzeba mieć o czym. Pisanie, żeby pisać jest słabym pomysłem. Dlaczego więc teraz piszę?

Powód nie-pisania ostatnio oraz tego, że piszę teraz jest w zasadzie ten sam – egzamin dyplomowy. Dziś miałem okazję przystąpić do ustnej wersji egzaminu licencjackiego z wynikiem całkiem zadowalającym – 4,5. Egzamin taki jest moim zdaniem strasznie dziwnym tworem ponieważ powodzenie i porażka zależą tylko i wyłącznie od naszego szczęścia w losowaniu pytań. U mnie nawet nie było losowanie. W zasadzie po wejściu do sali otrzymywało się kartkę z trzema pytaniami. Jakkolwiek dziwny i niesprawiedliwy system oceny wiedzy by nie był to na (nie)szczęście do gry wchodziła jeszcze średnia z całych studiów.

Ostatecznie nie taki diabeł straszny… Choć spędziłem ostatnie dwa tygodnie siedząc całe dnie i powtarzając 3 lata nauki. Na szczęście teraz mam już wreszcie zasłużone (mam nadzieję, że nikt nie ma innego zdania) wakacje 🙂 A po wakacjach na studia drugiego stopnia i znów cyrk 😉

Chciałbym wam obiecać, że będę pisał częściej ale nie jestem pewien czy nie byłoby to okrutne kłamstwo dlatego też nic nie napiszę 😛 Mam trochę rzeczy do nadrobienia przez ostatnią nieobecność w życiu publicznym i prywatnym na rzecz wzorów i definicji.

Uf.

C++ oraz instanceof

Jak wszyscy wiemy, Java jest językiem programowania, który nie leżał nawet koło języków tak "niskopoziomowych" jak C czy C++. Dzięki temu zawiera pewne niesamowite konstrukcje. No… niesamowite są dopóki człowiek się do nich nie przyzwyczai…

Jedną z takich konstrukcji jest tytułowe instanceof. Użycie tego słowa kluczowego pozwala na sprawdzenie czy obiekt jest instancją danej klasy. Użycie tego wynalazku wygląda w Javie tak:

if(foo instanceof Bar) {
/* ... */
}

Jest to ogromna wygoda, a jak wiemy – do wygód człowiek przyzwyczaja się szybko. Dlatego ubolewałem jakiś czas nad brakiem możliwości sprawdzenia czy dany obiekt jest instancją jakiejś klasy w C++…

Zaraz, zaraz. Nie da się? Dziś poczytując blog Xion’a wpadłem na szatański plan zmuszenia C++ do wykrycia klasy obiektu. Jak się okazało mechanizm działa nawet "lepiej" niż w Javie 😉 Najpierw zaprezentuję kod:

class Foo {};
class Bar : public Foo {};
// ...

Bar bar;
try { throw bar; }
catch(Foo f) { cout << "Obiekt jest klasy foo!" << endl; }

Jak widać po powyższym kawałku kodu – możemy wykryć klasę obiektu nawet jeśli jest to pochodna jakiejś klasy bazowej!

Ale to jeszcze nie wszystko. Mówiłem, że to nawet lepsze niż instanceof. Tak na prawdę możemy użyć tego mechanizmu jako swego rodzaju switch dla wykrywania klasy obiektu – nawet jeśli klasy które sprawdzamy są całkowicie ze sobą niezwiązane:

class Foo{};
class Bar{}; // brak zależności pomiędzy klasami!
//...
Bar bar;
try { throw bar; }
catch(Foo f) { cout << "Foo" << endl; }
catch(Bar b) { cout << "Bar" << endl; }

Wszystko za sprawą niekonfliktowości kompilatorów C++. W Javie niestety taki numer nie przejdzie z dwóch powodów. Po pierwsze – nie można rzucać wszystkimi obiektami (możemy rzucać tylko klasy implementujące interfejs Throwable). Po drugie – nie możemy łapać wyjątków, których nie rzucamy w sekcji try.

Jak się okazuje czytanie blogów zamiast uczenia się do kolokwium może przynieść trochę pożytku 😉

Rozpoznawanie dźwięku

Po ostatnim wpisie o IMARE Reg zapytał o szczegóły techniczne rozpoznawania.

Postanowiłem więc odpowiedzieć w tym wpisie. Sprawa jest dość skomplikowana. Na początek trzeba zastanowić się nad tym co mamy i co chcemy osiągnąć. Otóż mamy sygnał:

No i już tutaj zaczyna być ciekawie ponieważ sygnał zapisany w postaci cyfrowej jest niekompletny. W celu zapisania cyfrowej informacji o dźwięku musimy przeprowadzić próbkowanie sygnału. Polega ono po prostu na pomiarze poziomu badanego sygnału w określonych odstępach czasu:

Jeżeli częstotliwość próbkowania wybierzemy zbyt dużą to pomiar będzie za rzadki i w przypadku gdzie sygnał będzie mocno zróżnicowany możemy po prostu pominąć jego istotne części:

Widzimy tutaj, że sygnał dyskretny nie odpowiada sygnałowi oryginalnemu. Z drugiej strony jeśli wybierzemy zbyt wysoką częstotliwość to będziemy mieli całe mnóstwo próbek i szybko skończy nam się dostępna pamięć.

Dodatkowo w grę wchodzi rozdzielczość pojedynczej próbki, czyli ilość poziomów kwantyzacji. Zmierzona wartość może być zapisana np. przy pomocy 1 bajta wówczas mamy 256 poziomów kwantyzacji. Zazwyczaj jednak operujemy plikami WAVE, w których próbki mają 2 lub 3 bajty. Zdarzają się także próbki 4-bajtowe. Prawdopodobne jest również istnienie większych rozdzielczości, ale nie jestem pewien czy będzie to robiło istotną różnicę…

W IMARE naszym celem było wykrycie nut (dźwięków) czających się w tych wszystkich próbkach i zapisanie ich w postaci nut na pięciolinii. Pierwsze próby polegały na wykorzystaniu transformacji Fouriera w celu wykrycia siedzących w samplach częstotliwości. Transformata liczona była dla małych przedziałów czasowych. Takie podejście było jednak niewystarczające ze względu na fakt gęstego upakowania dźwięków o niskiej częstotliwości w transformacie Fouriera. Nie pozwalało to odróżnić ich od siebie wystarczająco dobrze i w efekcie skłoniło nas do szukania alternatywy.

Kolega, który był głównym twórcą modułu rozpoznawania wynalazł w sieci informacje o transformacji Constant Q. Pozwala ona utrzymać stałą jakość transformaty dla każdej częstotliwości z danego przedziału. W wynikowym widmie częstotliwości następnie wyszukiwane są maksima. Wyznaczają one częstotliwości dominujące. Po przeliczeniu ciągu takich transformacji dla kolejnych kawałków pliku audio otrzymujemy różne ciągi częstotliwości.

Tutaj zaczyna się dopiero jazda bez trzymanki. Algorytm rozpoznawania jest odpowiedzialny za wyznaczenie dla każdego dźwięku jaki potencjalnie znaleźliśmy częstotliwości podstawowej. Następnie eliminuje wielokrotności tej częstotliwości, które przeszkadzają w dalszej pracy. Później podobne kawałki częstotliwości (z ciągu transformat ConstQ) łączone są w dłuższe fragmenty.

Po tym wszystko trafia do modułu transkrypcji, który na podstawie zadanych łańcuchów częstotliwości tworzy informacje o dźwięku oraz jego czasie początkowym i długości. Na koniec zostaje wybrana „najodpowiedniejsza” zdaniem algorytmu (bo zdarza się, że można wybrać lepiej) tonacja. Ostatecznie wszystko wędruje na panel wyświetlający nuty.

Opisałem tutaj sposób ogólny działania tego modułu. Gdyby chcieć opisać to nieco dokładniej i poprzeć kilkoma wzorami i rozważaniami powstałaby zacna książeczka 😉 Jeśli chodzi o przetwarzanie plików MP3 – program radzi sobie całkiem nieźle jednak wynik jest słabszy niż w przypadku plików WAVE. Głównie dlatego, że MP3 nie zawiera wszystkich częstotliwości i jest ogólnie kiepskie do takich zabaw 😛

Reg: Mam nadzieję, że zaspokoiłem chociaż troszkę Twoją ciekawość w tej kwestii? Jeśli ktoś ma jeszcze jakieś pytania to proszę śmiało je zadawać w komentarzach – jeśli wystarczy mi czasu to postaram się odpowiedzieć. Oczywiście o ile moje zorientowanie w temacie będzie wystarczające 😉

KDE 4.4 – wrażenia

Początkowo było ciężko 🙂

Po kilkugodzinnej kompilacji pakietów nowego KDE zrestartowałem komputer i moim oczom ukazało się…. niewiele nowych rzeczy 😛 Oczywiście nowa wersja respektowała moje ustawienia zapisane w katalogu domowym i właściwie odnośnie pulpitu nic się nie zmieniło, ale…

Czarny ekran… jedno okno – raportowanie błędów. *westchnienie*. Restartuję KDE, chcę coś zrobić iiii… [patrz początek akapitu; jeśli przeczytałeś to już 5 razy – przejdź do następnego akapitu 😉 ].

Postanowiłem więc zresetować moje ustawienia KDE w nadziei, że to one były problemem.

mv ~/.kde4 ~/.kde4_old
/etc/init.d/xdm restart

O! Moim oczom ukazał się całkowicie nowy ekran startowania sesji, po którym na monitorze wyświetlił się sterylnie wręcz czysty pulpit. Okazało się, że w ten sposób żadne raporty błędów nie są generowane a plasma workspace się nie wywraca.

Rozpocząłem więc testy i okazuje się, że faktycznie usprawniono conieco, chociaż pewnie większości nowości jeszcze nie zbadałem. Zmianom uległo sporo okienek konfiguracyjnych. W większości są teraz znacznie czytelniejsze i łatwiejsze w obsłudze. Poniżej widać zupełnie przeprojektowany interfejs ustawień pulpitu:

Okno ustawień pulpitu KDE 4.4

Oprócz zmian estetycznych chłopcy z KDE popracowali również nad łatwością zarządzania okienkami – głównie implementując rozwiązania podobne do znanych z Windows 7 🙂 O takich rzeczach nie powinno się mówić – takie rzeczy najlepiej obejrzeć dlatego proponuję obejrzeć dwa filmiki na stronie http://www.kde.org/announcements/4.4/.

Jak dotąd wszystko jest super i pięknie. Pierwsze wrażenie jest na prawdę bardzo pozytywne. Jest tylko jedna rzecz, która mnie denerwuje od dawna, a miałem nadzieję, że ją poprawią. Chodzi mi o pokazywanie ilości czasu pozostałego przy pracy bez zasilania na laptopie. Niestety wskaźnik za to odpowiedzialny pozwala jedynie zobaczyć stan procentowy baterii – czyli właściwie nic nie mówiący… Może kiedyś uda się to panom z KDE wprowadzić – będę trzymać kciuki 😉

A teraz pójdę dalej grzebać i odkrywać nowości 😛

KDE 4.4!

Dziś w moim czytniku RSS (oczywiście Akregator 😉 ) pojawił się wpis informujący mnie o tym, że wyszło nowe KDE 4.4. Pomyślałem, że to fajnie ale początkowo nie zdawałem sobie sprawy z tego jak dużo zyska względem wersji 4.3. Ostatnio przez jakiś czas używałem Windows 7 w celach poznawczych. Odkryłem tam mnóstwo świetnych rozwiązań dotyczących pracy z komputerem i zarządzaniem okienkami które Win7 ma cudowne!

Nie mniej jednak, wciąż jest to Windows i wciąż nie jest wolny od swoich liczbych denerwujących problemów (nie wymienię ich ponieważ nie chodzi mi znów o zwalczanie się wzajemne – zresztą to kwestia gustu). Po przejrzeniu pewnych wodotrysków wprowadzonych w KDE 4.4 okazuje się, że programiści dodali pewne rozwiązania z Windows 7 do zarządzania okienkami dodatkowo je ulepszając/rozwijając/zmieniając.

Efekt jest taki, że po obejrzeniu ogłoszenia na stronie KDE (http://www.kde.org/announcements/4.4/) czym prędzej postanowiłem sprawdzić czy w moim Gentoo mogę to sobie zainstalować. Jak się okazało – mogłem już we wtorek 🙂

W tej chwili trwa kompilacja i instalacja pakietów nowego KDE 4.4. Prawdopodobnie potrwa to jeszcze kilka godzin (jak to w Gentoo przy dyżych aktualizacjach ^^ ) ale po zainstalowaniu i wytestowaniu tych nowości postaram się opisać czy jest to tak samo dobre jak Win7, a może lepsze? Wszystko okaże się za kilka godzin, kiedy wszystkie pakiety zostaną już skompilowane i zainstalowane.