Jak prawdopodobnie zauważyliście, bądź nie, zmieniłem nieco wygląd strony. Niestety z dostępnych tematów na WordPressie ten chyba jest jednym z fajniejszych. Zastanawiam się, kto je wybiera…

Tak czy inaczej, mam nadzieję, że się wam choć trochę podoba bo poprzedni zaczał mnie już nudzić. Chciałbym również częściej pisać, ale tutaj niestety jest problem. Teraz, jak wszyscy wiemy, jest sesja, ale to mogłaby być tylko wymówka ;) Każdy kto chociaż trochę śledzi mojego  bloga wie, że przerwa trwała już wcześniej. No i prawda. W tym semestrze bowiem miałem całkiem niezłe urwanie głowy.

Przytłaczała mnie bowiem masa przedmiotów, a do tego dołożyły się jakieś wyjścia z dziewczyną czy zwykłe sobotnie (trwające pół dnia) zakupy… Z tego co się orientuję, w przyszłym semestrze powinno być lepiej z wolnym czasem i powinienem poświęcać go więcej na pewien projekt programistyczny, który tworzymy z kolegami w ramach przedmiotu Programowanie Zespołowe. Z tego względu postaram się czasem napisać coś interesującego, ale częstotliwość oczywiście może być niewielka :)

Proszę zatem o uzbrojenie się w cierpliwość i w międzyczasie czytanie blogów moich znajomych, które znajdują się w sekcji Linki.

Ostatni przez podejrzanie długi czas nie pojawiły się w moim pięknym linuksie żadne problemy. Czasem jakieś drobne niedogodności po aktualizacji danego pakietu, ale nie było to nic specjalnie wyzywającego, ani tym bardziej pilnego.

Ostatnio jednak po aktualizacji “zepsuło” się wyłączanie systemu. Efekt był taki, że kiedy chciałem uruchomić ponownie, bądź wyłączyć komputer system wyłączał się w miarę normalnie, aż do pokazania komunikatu:

INIT: No more processes left in this runlevel.

Ten komunikat pojawia się zawsze i to nie jest problem. Problemem było to, że nie działo się nic później – normalnie powinno nastąpić uruchomienie ponowne/wyłączenie komputera. Jedyne co mi pozostawało to wyłączyć komputer “z palca” ;)

Jak się okazało – aktualizacja nic nie popsuła, ale nowa wersja oprogramowania wymagała specyficznych zapisów w odpowiednim pliku konfiguracyjnym i stąd wziął się problem.

Sprawa wyjaśniła się, gdy dzisiaj po raz kolejny zasiadłem aby pozbyć się tego denerwującego “błędu”. Rozwiązanie znalazłem zaledwie w kilka chwil,podczas gdy poprzednio przekopywałem tony stron.

Oczywiście nie byłem jedynym człowiekiem z tą dolegliwością więc nie powinno być dla nikogo zaskoczeniem, że instrukcje naprawy tego stanu rzeczy znalazłem tu: http://bugs.gentoo.org/show_bug.cgi?id=251024#c10.

Wychodzi na to, że brakowało mi po prostu dwóch linijek w /etc/inittab:

l0s:0:wait:/sbin/halt -dhip l6r:6:wait:/sbin/reboot -dk

Po ich dodaniu problem znikł i mam nadzieję, że już nigdy więcej nie wróci :)

Ostatnio zostałem postawiony przed ciekawym problemem zamiany częstotliwości dźwięku na nutę. Przez nutę rozumiem “nazwę” dźwięku (jak. C, D, E, itd.) oraz oktawę.

Po krótkim używaniu Google i przyglądaniu się różnym stronom Wikipedii okazało się to być prostsze niż się na początku zdawało. Funkcja konwertująca wygląda następująco:

f(x) = log2(x/440)*12 + 57

Wzór ten zwraca jak widać jedną liczbę w której zakodowany jest numer dźwięku oraz oktawa. Aby wydostać te informacje wystarczy kawałek kodu:

int tmp = (int)(log( freq / 440 ) / log(2) * 12 + 57.5);
int note = tmp % 12;
int octave = tmp / 12;

W powyższym przykładzie dodałem 57.5 zamiast 57. Jest to spowodowane potrzebą zaokrąglenia. Jeśli przy konwersji na typ int zostanie obcięta część ułamkowa to dodanie 0.5 pozwoli zaokrąglić wartość matematycznie bez używania dodatkowych funkcji.

W wyniku działania kodu otrzymujemy dwunastostopniową skalę dla zmiennej note, w której numery 0, 1, 2… odpowiadają kolejno dźwiękom C, C#, D, D#, …

Jeśli natomiast chcielibyśmy  zrobić coś odwrotnego – zamienić nutę (na częstotliwość) to wystarczy znaleźć funkcję odwrotną do podanej powyżej. Czyli coś takiego:

f^(-1)(x) = 440 * 2^((x-57)/12)

double getFrequency(int note, int octave) {
return 440 * pow(2,  (octave*12+note-57)/12 );
}

Tym sposobem mamy funkcje do zamiany częstotliwości dźwięków na nuty i odwrotnie :) Nie jest to specjalnie odkrywcze gdyż podobne wzory podane są na wikipedii. Jedyna różnica jest taka, że tam wzór jest trochę inny gdyż odpowiada tej tablicy. U mnie natomiast dźwięk 0 częstotliwości 12.352 (C0) będzie miał numer 0 (a nie -48). Wszystko to kwestia dostosowania wartości 57 z powyższych wzorów do własnych potrzeb.

Wreszcie będzie coś dla prorgamistów, po całej serii postów o różnych linuksach. Doszedłem do wniosku, że za dużo już pisałem o systemach i wypadałoby wreszcie wziąć się za programowanie. Z pomocą przyszła mi pani prowadząca zajęcia ze Wstępu do Przetwarzania Sygnałów i Obrazów. Moim zadaniem było zapoznanie się z techniką generowania obrazu metodą półtonów i napisania odpowiedniego programu na tę okoliczność.

Obraz ma być w skali szarości ale system powinien zadziałać również dla normalnych obrazków RGB jeśli zastosujemy sposób do każdego kanału osobno. Efekt działania takiego algorytmu wygląda następująco:

Z lewej obraz oryginalny, z prawej przetworzony

Cały pomysł na zamianę polega na tym, aby podzielić obraz źródłowy na małe kwadraty pikseli (u mnie 3×3 piksele), a następnie dla każdego z tych pikseli wybrać czy ma on być zamalowany na czarno czy na biało. W jaki sposób określić, który piksel ma być jaki?

Na stronie http://wwwhome.cs.utwente.nl/~schooten/graphics/ opisany jest sposób dla bloków 2×2 piksele oraz skali szarości w przedziale od 0 do 1. Autor sugeruje stworzenie macierzy 2×2 zawierającej… hmm… odchylenie? Zachęcam do zapoznania się z jego artykułem gdyż chciałbym jedynie przedstawić ten sposób dla bloku 3×3 piksele oraz skali szarości od 0 do 255.

Jeśli mamy blok 3×3 piksele to jeśli zamalujemy wszystkie na biało to oczywiście otrzymamy kolor biały (tu akurat łatwo wszystkich przekonać ;) ). Jeśli zamalujemy wszystkie piksele na czarno to będziemy mieli kolor czarny. Jeśli zamalujemy jeden z pikseli na czarno, a resztę na biało to patrząc z daleka będzie nam się wydawało, że blok jest troszeczkę szary. W ten sposób (zamalowując kolejne piksele na czarno) możemy stworzyć 10 poziomów szarości dla bloku 3×3. Poniżej przedstawiam przykładową reprezentacje poziomów 1, 5 oraz 9:

Poziomy 1, 5 i 9

Teraz należy stworzyć tablicę odchylenia dla pikseli z danego bloku. Aby to zrobić trzeba najpierw rozłożyć naszą skalę szarości (0-255) na 9 przejść pomiędzy poziomami. Dla N poziomów mamy N-1 przejść – jeśli ktoś ma problem ze zrozumieniem dlaczego to niech narysuje sobie 10 słupków od ogrodzenia i policzy ile jest potrzebnych części płotu pomiędzy słupkami ;) – te części to przejścia. Wykonajmy dzielenie: 255/9 = 28,(3).  Ten wynik nie jest zbyt piękny, ale wystarczy, że zaokrąglimy sobie do dwóch miejsc po przecinku. Otrzymaliśmy zatem 28,33.

Teraz jest najciekawiej. Jeśli narysujemy sobie wszystkie możliwe poziomy szarości dla bloku 3×3 i odrzucimy skrajne (tzn. cały czarny i cały biały) to łatwo będzie stworzyć tablicę odchyleń. Patrzymy zatem na poziomy 1-8. Tablica odchyleń oczywiście też musi być wielkości 3×3. Teraz patrzymy na pierwszy piksel po lewej na górze (poziom 1). Co w tym miejscu wpisać w tablice odchyleń? Wystarczy policzyć na ilu poziomach ten piksel jest czarny (oczywiście patrząc wyłącznie na poziomy pośrednie [1-8]) . W przypadku lewego górnego – jest on czarny na wszystkich 8 poziomach zatem w tablicę odchyleń wpisujemy dla niego wartość ~(8*28.33). Warto ją zaokrąglić :) Podobnie postępujemy dla kolejnych pikseli. W końcu otrzymujemy macierz postaci:

Macierz odchyleń

Mając taką macierz wystarczy już tylko do każdego piksela dodać odpowiadającą mu wartość z powyższej macierzy i później sprawdzić czy ma on wartość większą niż 255. Jeśli tak to ustawiamy ten piksel na kolor biały (255) jeśli nie to ustawiamy go na kolor czarny (0). W ten sposób otrzymaliśmy dość ciekawy obraz oraz zmniejszyliśmy ilość potrzebnych kolorów do dwóch (biały i czarny) zachowując przy tym 10 poziomów szarości.

Nie jest to może najpiękniejszy obraz ale efekt powinien być dobrze znany starszym graczom, którzy w dzieciństwie na takie cuda się napatrzyli :)

Na koniec podam jeszcze ostateczny algorytm w pseudokodzie w C++:

int bias[3][3] = {
   { 227, 198, 170 },
   { 142, 113, 85  },
   { 57 , 28 , 0   }
};
int value;
for(int y=0; y < in.height(); y++) {
   for(int x=0; x < in.width(); x++) {
      value = in.pixel(x,y) + bias[y%3][x%3];
      if(value > 255) value = 255;
      else value = 0;
      out.setPixel(x, y, value);
   }
}

Podczas pracy algorytmu dość istotne jest w jakim formacie jest zapisany obraz. Powyżej założyłem, że do zapisu każdego piksela wykorzystane zostało 8 bitów informujących o skali wartości w skali szarości.

Jako, że bardzo lubię Google Chrome od czasu kiedy zostało wypuszczone na Windowsie, bardzo ubolewałem, że nie ma odpowiednika na Linuxa.

Ostatnio jednak ukazała się wczesna wersja działająca w systemie Linux. Dopóki korzystałem z Ubuntu wszystko było dobrze ponieważ developerzy dali paczę DEB. Teraz zachciało mi się posiadać możliwość uruchomienia Chrome’a w systemie Gentoo.

Z pomocą przyszli niezawodni internauci, którzy mieli podobne zachcianki. Jeden z nich opisał proces instalacji przeglądarki z paczki DEB w systemie Gentoo na swoim blogu: http://blog.andreaolivato.net/open-source/google-chrome-natively-running-on-gentoo-linux.html.

A Flash?

No właśnie. Tutaj pojawiły się problemy.  W katalogu /usr/lib/nsbrowser/plugins znalazłem plugin którego potrzebowałem: libflashplayer.so. Jeśli go tam nie ma to pewnie trzeba go zainstalować poleceniem:

emerge www-plugns/adobe-flash

Jak już go tam mamy to flash będzie działał w przeglądarce Epiphany. To już nieźle ;) . Kombinowałem z linkami do tego pliku w różnych miejscach aby chrome widział plugin jednak nic nie przynosiło efektu. W końcu wykorzystałem ostatnie drewno ratunku i postanowiłem udawać, że mam Firefoxa i tam zainstalować wtyczkę:

mkdir ~/.mozilla
ln -s /usr/lib/nsbrowser/plugins ~/.mozilla/plugins

W ten sposób utworzyłem katalog .mozilla w moim katalogu domowym (tam firefox trzyma swoje śmieci), a później w tym katalogu stworzyłem link do katalogu zawierającego wtyczki Epiphany. Link ten z punktu widzenia programów jest widziany jako zwykły katalog i nawet nie podejrzewają jak bardzo je oszukujemy :)

Tak czy inaczej teraz Google Chrome po uruchomieniu obsługuje już flasha.

Życzę miłego oglądania jutuba ;)

Info: To nie jest informacja jak kompilować kernel – to raczej informacja jak go nie kompilować :)

Największym problemem okazała się dla mnie kompilacja kernela 2.6.30. Początkowo podczas instalacji użyłem narzędzia genkernel ponieważ było wygodne. Jednak tak stworzone jądro trochę długo się uruchamiało (około 1 minuty 15 sek. od GRUBA do ekranu logowania). Wszystko dlatego, że na początku uruchamiany był obraz initrd i on ładował do dużo modułów których nawet nie potrzebowałem! Pomijam już fakt, że kompilacja takiego jądra z milionem modułów trwała około 20 minut.

Postanowiłem więc wziąć sprawy w swoje ręce i zmodyfikować nieco ustawienia jądra tak aby nie musiało korzystać z initrd. Dodatkowo chciałem aby jądro obsługiwało system plików ext4, abym mógł pracować na partycji gdzie zainstalowałem Ubuntu (bo ono też jeszcze jest ;) ).

Zatem poszedłem do źródeł gentoo-sources które były już na dysku od czasu gdy instalowałem system:

cd /usr/src/linux

I rozpocząłem konfigurowanie:

make menuconfig

Początkowo ogrom opcji jakie się cisną do oczu jest porażający. Po kilku nieudanych kompilacjach (tzn takich, że jądro po uruchomieniu dawało KERNEL PANIC). Postanowiłem zacząć całkowicie od nowa. W katalogu /usr/src/linux wydałem polecenie:

rm .config

Co oznacza, że usunąłem starą konfigurację (jeszcze wygenerowaną przez genkernel – stąd pewnie były problemy). Po tej operacji program do konfiguracji jądra wczytał podstawowe ustawienia, które są bardzo minimalistyczne. Bałem się czy takie jądro w ogóle poradzi sobie w życiu codziennym, ale postanowiłem spróbować.

Jedyne rzeczy jakie zmieniłem to dodałem obsługę ext4 oraz zaznaczyłem kilka opcji graficznych dla kart NVIDIA i mojej karty bezprzewodowej.

Kompilacja nowego jądra trwała mniej niż 2 minuty. Wygenerowanych zostało zaledwie 12 modułów, z których łatwo było wybrać te interesujące :)

Jak się okazało jądro poradziło sobie i uruchomiło się w około 30 sekund (gdyby nie konfigurować sieci to nawet kilka sekund szybciej). Widać zatem, że w prosty sposób można znacznie przyspieszyć ładowanie systemu operacyjnego.

Teraz jeśli zauważę, że potrzebuję dodatkowej opcji w jądrze to dodanie jej zajmuje tylko kilka minut. Ma to ogromne zalety w stosunku do tego, ze w Ubuntu właściwie wszystko działo się samo i nawet nie wiedziałem skąd, po co i dlaczego :) A ja lubię wiedzieć dlaczego.

Wniosek

Jeśli kompilowałeś jądro przy użyciu genkernela lub w jakiś inny automatyczny sposób to najlepiej usuń tę konfigurację i zacznij od nowa.

W internecie jest bardzo wiele przewodników dotyczących konfiguracji i kompilacji jądra Linux. TA STRONA jest jednym z przykładów. Najważniejszą rzeczą podczas szukania informacji jest wiedza o tym, że informacje te mogą być przestarzałe – dlatego należy ostrożnie podchodzić do znalezionych informacji.

Ostatnio siedząc sobie spokojnie i przeglądając zasoby internetu wymyśliłem mroczny plan. Znużony tym, że w Ubuntu działa wszystko od ręki oraz faktem, że jest nieco przeładowane przez co trochę powolne postanowiłem zainstalować sobie system Gentoo Linux.

[ Tutaj następuje efekt dźwiękowy:  http://www.dramabutton.com/ ]

Jak się okazało – nie taki diabeł straszny… Na stronie domowej Gentoo znajdują się poradniki dotyczące instalacji tegoż systemu. Są nawet w języku polskim ale nie polecam tychże ponieważ są stare i czasem nie zgadzają się z rzeczywistością.

Piękno tej dystrybucji polega na tym, że system budujemy sami od podstaw. Zajmuje to co prawda znacznie więcej czasu (kilka[naście] godzin za pierwszym razem ;) ) niż zainstalowanie Ubuntu (~ 15-20 min ). W zamian za poświęcony czas dostajemy system, w którym panujemy nad wszystkim i w którym dokładnie wiemy co gdzie należy zmienić lub dodać aby osiągnąć to co chcemy.

W następnym poście opiszę moją przygodę z kompilacją kernela ;)

Dziś przez przypadek (podczas różnych kombinacji w Ubuntu) odkryłem, że jest niesamowicie prosty sposób na stworzenie paczki DEB zawierającej cokolwiek tak, aby możliwa była instalacja tego na dysku.

Aby stworzyć archiwum z katalogu, który mamy już stworzony (wraz z plikami które chcemy umieścić w paczce)  wystarczy stworzyć w tym katalogu kolejny folderek nazwany DEBIAN, a w środku plik control. Do tego pliku należy wpisać kilka informacji podstawowych o pakiecie. Listę możliwych pól można znaleźć TUTAJ.

Kiedy już mamy stworzony plik ./<katalog>/DEBIAN/control to wówczas wydajemy polecenie:

dpkg-deb --build ./<katalog>

Po chwili będziemy mieli paczkę <katalog>.deb

Stworzony w taki sposób pakiet jest dość ubogi ale wystarczy żeby zainstalować/odinstalować w systemie program lub jakieś inne pliki. Jeśli kogoś zainteresował taki “ręczny” sposób tworzenia archiwów to proponuję lekturę TEGO dokumentu. (Podany wcześniej link jest tylko częścią większej części opisującej archiwa debianowe)

Przeczytałem artykuł mówiący, że Linux nie jest dla wszystkich. Rozważałem przez cwhilę czy dodać komentarz czy też opisać sprawę szerzej u siebie. Efekt tych przemyśleń macie przed sobą więc nie będę pisać, którą opcję wybrałem :)

Przechodząc do sedna sprawy – autor artykułu najmocniej ubolewa nad tym, że użytkownicy nie potrafią zachwycić się bardziej zaawansowanymi opcjami systemu niż zmiana tapety czy upięknianie okienek i to za darmo… Trudno oczekiwać od dotychczasowych użytkowników Windowsa aby potrafili dostrzec coś jeszcze. Przecież ich system nie pozwalał na nic więcej…

Poza tym… jak reklamował się Windows Vista? Wszyscy chyba najbardziej oczekiwali tego trójwymiarowego przełączania okien i innych bajerów graficznych. Jak się nad tym teraz zastanawiam to kutek (autor wspomnianego arta) ubolewa nad podobnymi rzeczami jak wielu starych graczy, którzy narzekają, że teraz grafika jest na pierwszym miejscu, a grywalność kiepska…

Wracając jednak do tematu – uważam, że Linux jest dla każdego bo każdy powinien widzieć w systemie to co mu odpowiada. Przecież nie ma znaczenia z jakiego powodu Pan Stefan używa jakiegoś tam systemu. Przynajmniej mnie osobiście to zupełnie nie obchodzi. Dopóki jest mu z tym dobrze. Przykładowo jeśli ktoś lubi być narażony na kradzież wszelkich danych – instaluje Windowsa i używa IE. Jeśli ktoś lubi pomęczyć się z instalacją jakiegokolwiek programu aby później narzekać, że Linux jest kiepski – instaluje Slax albo inne Gentoo (oczywiście bez znajomości słów kluczowych: kompilacja, linkowanie itp. ).

Na koniec powiem, że Linux faktycznie nie jest dla wszystkich. Nie jest to system dla ludzi, którzy oczekują, że sposób w jaki działa i zachowuje się Windows jest jedynym słusznym (zwłaszcza jeśli instalują inną dystrybucję niż Ubuntu ;) ). Będą jedynie zawiedzionymi użytkownikami więc szkoda ich czasu i nerwów.

Ostatnio postanowiłem wypróbować nowe dziecko Microsoftu. Poprzez uczelnię mam dostęp do wydania Windows 7 Professional, dlatego chciałem dać mu szansę do zaprezentowania się i może nawet zastąpienia Linuxa (sic!) na moim dysku na stałe.

Mój zapał dotyczący nowego systemu trwał kilka godzin. Były to godziny poświęcone na ściągnięcie i nagranie na płytę odpowiedniego obrazu…

Po zbootowaniu z płyty ujrzałem piękne okienko ze sporym przyciskiem na środku “Install now…”. Pomyślałem, że to dobry punkt wyjścia więc klikąłem ów przycisk. Pojawił się wówczas napis “Setup is starting…”. To by się nawet zgadzało z intuicją. Niestety później było już tylko gorzej.

Po ostatniej informacji o startowaniu instalatora pojawiło się nowe okienko wraz z informacją, że nie mam sterownika CD/DVD i jeśli mam płytę/pendrive/cokolwiek ze sterownikami to mam to wykorzystać i załadować go.

Zadanie to nie wydaje się przesadnie trudne jeśli się nad nim głębiej nie zastanowić. Hej, czy ja nie bootowałem systemu z płyty? To teraz nagle odkrył, że nie może z niej czytać? Jeśli dodać do tego fakt, że przy poszukiwaniach sterownika mogę przeglądać sobie płyty, pendrive’y i zawartość dysku twardego to ktoś tu zmyśla.

Zacząłem poszukiwania internetowe dotyczące feralnego komunikatu. Jak się okazało nie byłem odosobnionym przypadkiem. Niektórzy sobie z tym poradzili i znalazłem kilka zaleceń how-to. Jedno z nich dotyczyło pogmerania przy ustawieniach RAID dla SATA w BIOSie. Niestety BIOS w moim laptopie (Acer Aspire 5610Z) pozwala jedynie zmienić kolejność bootowania…

Później ktoś poradził, aby zainstalować system z pendrive’a. Nagrałem więc obraz Win7 na 4GB patyk i zbootwałem z niego system. Podbudowała mnie szybkość bootowania ale dzięki niej o wiele prędzej dowiedziałem się, że nic to nie dało.

Kolejną poradą było załadowanie sterowników SATA z dysku lub pendrive’a. Próbowałem to na kilka sposobów i również się nie udało.

Ostatnia moja próba wynikająca już mojej własnej inwencji twórczej polegała na wymontowaniu napędu CD z laptopa. Jako, że nigdy tego nie robiłem to rozmontowałem wszystko co się dało, żeby odkryć, że wystarczyło wykręcić jedną śrubkę i po prostu napęd wyjąć. To było pouczające.

Tak czy inaczej – po wyjęciu napędu CD/DVD problem dotyczący sterowników nadal występował.

Spróbowałem zainstalować Windows Vista, który dostałem razem z laptopem i uruchomić z płyty instalator i po prostu zupgradować system z Visty do 7. To również nie dało efektu ponieważ 2 pliki DLL ( spwizeng.dll i wdscore.dll ) sprawiają problemy i nie daje się uruchomić instalacji pod Win Vista.

Wydaje mi się, że to nie jest dobry start dla Windowsa, aby przekonać mnie o swojej wyższości…

Jeśli ktoś ma jeszcze jakiś pomysł w jaki sposób można zmusić ten…. system do działania to proszę się nie ograniczać i napisać w komentarzach swoje przemyslenia.