Linux çalıştıran bilgisayarınızın performansını müzikal olarak gözetleyin
Açık kodlu FluidSynth ve Perl'i kullanarak basit tonal besteler yaratın ve bunu bilgisayarınızın durumunu dinlemek için kullanın
Düzey: Orta
Nathan Harrington (harrington.nathan@gmail.com), Programcı, IBM
14 Kasım 2006
Perl ve FluidSynth kullanarak sistem durumunuzu müzikal olarak gözetleyin. çeşitli sistem performans istatistiklerini kullanarak armonik ve MIDI kontrollü ses sentezleme deneyimleri yaşayın. Bilgi işlem ortamınızdaki veriyi işitsel olarak nasıl ele alabileceğinizi keşfedin.
Bilgisayarınızın sağlıklı çalışıp çalışmadığını görsel olarak size sunan pek çok yazılım mevcuttur. Basit metin tabanlı göstergelerden tutun gerçek zamanlı ve 3 boyutlu grafiklere kadar kişisel bilgisayarınız, sunucu sistemleriniz veya ağ bağlantı cihazlarınızın durumuna dair detaylı raporlar alabilirsiniz. chordStats bilgisayarınızın durumuna dair sizi biraz farklı şekilde bilgilendirmektedir: tonları, tınıları ve armoniyi kullanarak.
1998 yılında, Peep! Ağ Seslendiricisi sistem yöneticilerine, sorumlu oldukları ağın durumu ve olası problemlerle ilgili çevreyi saran seslerle (ambient) uyarıda bulunmak için tasarlanmıştı. Belli olaylara bağlı olarak çıkan ses efektleri sayesinde sistem yöneticileri kendilerini bir tür ses uzayını dinlerken buluyor (normal ağ yükü için akan su sesi, bazı ağ olayları için kuş ötüşleri, vb.) ve sesteki dikkat çekici değişimlerden hemen bir ağ ortamında değişiklik olduğunu anlıyorlardı.
chordStats yazılımı da benzer bir ses ortamı yaratmakta ve sistem yükünü inceleyerek bu sayısal veriye dayanan farklı tonlar, değişik enstrüman özellikleri ve armonik ses dizileri kullanmaktadır. Bu makalede Perl programlama dilini kullanarak FluidSynth sistemine notalar göndereceğiz ve çeşitli sistem olaylarının armonik aralıklar olarak nasıl kullanılabileceğini gösterdikten sonra müzikal gözetleme sisteminizin nasıl geliştirilebileceği üzerinde duracağız.
Bu makale kısmen bir 256 MB ana hafızalı Intel® Pentium® 4 bilgisayar ile geliştirildi. FluidSynth MIDI yazılım sentezlemesi epey kaynak tükettiğinden buradaki programları en az 256 MB ana hafızalı bir Pentium III'ten daha düşük bir makinada denememenizde fayda var. Aynı zamanda bir ses kartına gerek var. Bu makalenin amaçları doğrultusunda okurun donanım tabanlı bir MIDI dalga tablosu sentezleyicisi olmadığını ve dolayısı ile yazılım tabanlı bir ses sentezleyici kullanılacağını var sayıyoruz. Eğer ses kartınızda donanım tabanlı bir ses sentezleyici varsa ya da chordStats'ı harici bir donanım ile kullanmak istiyorsanız lütfen Kaynaklar bölümüne göz atın.
En az 2.4 ya da daha üzeri bir Linux® çekirdeği, Perl ve FluidSynth tavsiye edilir. FluidSynth uygulaması için lütfen Kaynaklar bölümüne başvurun. Ayrıca isteğinize uygun "SoundFont"lar da tavsiye edilir. Dosyalar bölümünde piyano, xylophone gibi enstrümanlar için hazırlanmış "SoundFont"ları bulabilirsiniz. Internet'te de pek çok farklı SoundFont mevcuttur, detaylar için Kaynaklar bölümüne bakabilirsiniz.
Sistem durum gözetlemesi için vmstat programını kullanacağız. Pek çok Linux dağıtımı ile gelen vmstat üç farklı CPU yükü, genelleştirilmiş disk blok bilgisi üzerinden giriş ve çıkış verisi sunar, bunlara ek olarak başka sistem işlevlerinin de gözetlenmesini sağlar.
Örnek bir kurulum ve yapılandırma
FluidSynth kurulum ve ayarlaması
FluidSynth programını yükleyip örnek SoundFont'u da kurduktan sonra fluidsynth Hammered_Instruments.sf2
komutu ile FluidSynth'i başlatın. Aşağıdakine benzer bir çıktı ile karşılaşacaksınız:
Liste 1. FluidSynth çıktısı
lash_open_socket: could not look up host 'localhost': \ Servname not supported for ai_socktype lash_open_socket: could not connect to host 'localhost', service '14541' lash_comm_connect_to_server: could not create server connection lash_init: could not connect to server 'localhost' - disabling LASH lash_init: LASH_START_SERVER unset, not attempting to start server automatically fluidsynth: warning: Failed to pin the sample data to RAM; swapping is possible. ALSA lib timer_hw.c:269:(snd_timer_hw_open) \ extended read is not supported (SNDRV_TIMER_IOCTL_TREAD) fluidsynth: warning: Requested a period size of 64, got 940 instead fluidsynth: ALSA driver: Using format s16, rw, interleaved FluidSynth version 1.0.7 Copyright (C) 2000-2006 Peter Hanappe and others. Distributed under the LGPL license. SoundFont(R) is a registered trademark of E-mu Systems, Inc. Type 'help' for information on commands and 'help help' for help topics. > |
Bu uyarı iletilerini dert etmeyin. Eğer >
sembolünü görüyorsanız
FluidSynth ses üretmeye hazır demektir. noteon 5 77 100
yazıp
5. kanaldan 77 hızında ve 100 ses seviyesinde bir ses üretmeyi deneyin. Eğer
elektronik bir piyano tonu duyarsanız bir sonraki adıma geçmeye hazırsınız demektir.
çıkmak için quit
yazın ya da Ctrl+C
tuş kombinasyonuna basın.
Eğer ses duyamaz ya da bir hata mesajı ile karşılaşırsanız ses
sunucunuzun başlatıldığından emin olun ve mixer ayarlarınızın da
düzgün olup olmadığını kontrol
edin.
FluidSynth'e birden fazla nota gönderdiğinizde seste bir aksama fark edebilirsiniz -- tıpkı
bozuk ve atlayarak çalınan bir CDde olduğu gibi. Bunu düzeltmek için
fluidsynth Hammered_Instruments.sf2 -c10000 -z10000
komutu ile
ses arabelleklerini ve her arabelleğin boyunu artırın. Bu komut FluidSynth'i
herbiri 10.000'lik 10.000 ses arabelleği ile başlatacaktır, bu da ses kalitesi için
yeterli kaynak demektir.
Tempo, tını, akorlar ve nota hızının seçilmesi bu makaleyi aşan bir sanat ve bilim konusudur. Geliştirmenin basitliğini ve asıl derdimizin bir şekilde veriyi temsil etmek olduğunu göz önünde bulundurarak bu programda 1 Hz frekansında oktav tabanlı nota gamları kullanılacaktır. vmstat programı gerekli temel sistem verisini sunacak ve aynı zamanda bizim tempomuza dayanak teşkil edecek 1 Hz'lik "nabız" sinyalini sağlayacaktır.
Liste 2. Ana program parametreleri
#!/usr/bin/perl -w # chordStats.pl - create music based on system status use strict; my $vmStatCmd = "vmstat 1"; # run vmstat every second my $totalPackets = 0; # total of packets received and transmitted my $lineCount = 0; # count number of vmstat output lines my %fields = (); my $count = 0; # the field headers in the vmstat output, useful for referring to them by name for( split " ", "r b swpd free buff cache si so bi bo in cs us sy id wa" ){ $fields{$_} = $count; $count++; } # buffering output must be turned off because fluidsynth does not appear to # accept buffered input from stdin $|=1; |
Yukarıdaki betiğin başlangıcında her saniyede bir çalıştırılacak komut olarak vmstat 1
komutunu
seçtik. Her okumadaki toplam paket sayısını tutacak ve vmstat programından gelecek satırların
sayısını kaydedece değişkenleri ayarladıktan sonra başlık tanımlamalarına geçtik. Alan başlıkları olan
bi
(blocks in), bo
(blocks out), ve us
(user CPU usage - kullanıcı CPU
kullanımı) verileri saniyede bir okunmaktadır. "Hash" veri yapısı sayesinde bunlara
daha sonra isimlerini kullanarak erişmek mümkün olacaktır. $|=1
satırına dikkat edin.
Eğer bu satırı kaldırırsanız teşhis etmesi güç ve kaynağı arabellekleme olan hatalarla karşılaşabilirsiniz
Liste 3. Ana program başlangıcı
# open the vmstat program to read from open( INPIPE, "$vmStatCmd |" ) || die "can't read from vmstat"; # wait while the fluidsynth program opens sleep(3); while(my $statLine = <INPIPE> ){ # ignore the header display, and the fieldname display lines if( $statLine !~ /\-\-\-\-/ && $statLine !~ /swpd/ ){ # the first line of vmstat data is a recent average, ignore if( $lineCount > 2 ){ |
Programın yukarıda görünen ikinci kısmı vmstat komutuna bir boru (pipe) açmaktadır ve bunun üzerinden saniyede 1 kere veri okunmaktadır. FluidSynth programının çalışması için birkaç saniye bekledikten sonra vmstat çıktısını işlemeye başlayabiliriz. vmstat çıktısının ilk üç satırı görmezden gelinir çünkü bu satırlar ayrıştırıcıları, başlık bilgilerini ve kısa süre önceki ortalamayı göstermektedir.
Liste 4. Ana programda nota işleme
# reset wavetable synthesis if( $totalTime % 10 == 0 ){ print "reset\n" } $totalTime ++; my $note = ""; my @currLine = split " ", $statLine; # user cpu usage $note = $currLine[ $fields{us} ]; sendNote( $note, 14, 12, 96 ); # conglomerate disk i/o fields to one stat $note = $currLine[ $fields{bi} ] + $currLine[ $fields{bo} ]; if( $note > 1000 ){ $note = 1000; } $note = $note/10; sendNote( $note, 8, 12, 96 ); # network throughput on eth0 $note = getNetworkStats(); sendNote( $note, 5, 12, 84 ); }#if not first 3 lines to ignore }#if not a header line $lineCount++; }#while reading the pipe close(INPIPE); |
Yukarıdaki kod bloğunda ilk yapılan şey eğer 10 saniye geçti ise FluidSynth'e bir yeniden başlatma
emri göndermektir. Bu halihazırda işlenmekte olan son nota kırıntılarını iptal edecektir
(bu notalar işitilemeyecek bir ses düzeyinde mevcut olsalar bile). Gerekli değişken ilklendirilmesinden
sonra us
(user CPU usage - kullanıcı CPU kullanım miktarı) ile ilgili nota sendNote
komutu ile çalınacaktır. us
alanı daima 0 ile 100 arasında
bir değer olduğu için daha fazla veri işlemeye gerek yoktur. Basitçe sendNote
altrutinini kullanarak 14. kanala minimum 12, maksimum 96 arasında olan bir hızda gerekli
notayı yollamaktayız.
İlk nota gönderme işinden sonra yine vmstat'tan gelen bi
(blocks in) ve bo
(blocks out) bilgileri
birleştirilmekte ve 0 ile 1000 arasında bir değer elde edilmektedir. Bu
değerlerin makinanın IDE
ayarlarını test etmek için de kullanılabileceği dikkatinizi
çekebilir. Eğer çok yüksek ya da çok
düşük performanslı bir disk altsisteminiz varsa maksimum
değeri mevcut bantgenişliğini daha
hassas olarak gösterecek şekilde ayarlamanız gerekebilir. Toplam
disk kullanımı
0 ile 1000 arasındaki bir değere karşılık gelecek şekilde
ölçeklendikten sonra
bu sayı 10'a bölünür ve 0 ile 100 arasında bir değer
elde edilir. Ardından bu değer
8. kanala her zamanki minimum ve maksimum aralığında olacak şekilde
gönderilir.
getNetworkStats
kısmı görebileceğiniz gibi biraz daha karmaşıktır,
veri değeri 0 ile 100 arasında alınır ve bir başka noteon
komutu gönderilir.
Bu son nota gönderimindeki maksimum değerin 84 oluşuna dikkat edin. Bunun sebebi SoundFont'un
5. kanalda sadece 0 ile 84 arasında duyulabilir ses üretiyor olmasıdır. Bu durum, müzik konusunda
eğitimli olan ve armonideki küçük farklardan bile duruma dair bilgi çıkarabilecek olanları
biraz rahatsız edebilir.
Döngü parantezlerini kapatıp zamanlama kodunu tamamladıktan sonra şimdi de sıra altruinlerde.
Liste 5. sendNote altrutini
sub sendNote { my( $noteVal, $noteChan, $min, $max ) = @_; if( $noteVal < $min ){ $noteVal = $min; }else{ # divide it into twelve parts $noteVal = sprintf( "%0.0f", $noteVal/12); # reduce the note to 12 at the very least; $noteVal = ($noteVal * 12); if( $noteVal > $max ) { $noteVal = $max } }#if note is > minimum print "noteon $noteChan $noteVal 100\n"; }#sendNote |
sendNote
altrutini 0-100 arasında bir nota değeri alır ve
bunu taban notaya göre en yakın 12-notalık aralıktan birine
dönüştürür. Taban
notamız 12'dir ve tüm notalar bu değeri 0
durumu olarak kullanır.
Böylece sistem düşük yükte çalışırken düşük frekanslı hoş bir ses elde
ederiz. Tüm notalar basitlik namına 100 ses şiddettinde basılır. Diğer
sistem parametrelerine göre ses şiddeti seviyesini ayarlamak
notaların kendisi ile yahut armonik değişimlerle oynamadan veri temsilini
geliştirmek için güzel ve sezgisel bir yöntem olarak düşünülebilir.
Liste 6. getNetworkStats altrutini
sub getNetworkStats { my $networkCmd = "/sbin/ifconfig eth0 | grep 'RX bytes'"; $networkCmd = `$networkCmd`; my $rxBytes = 0; my $txBytes = 0; chomp($networkCmd); for( $networkCmd ){ $rxBytes = substr($_, 19); $rxBytes = substr($rxBytes,0,index($rxBytes," ")); $txBytes = substr($_, 52); $txBytes = substr($txBytes,0,index($txBytes," ")); my $bothBytes = $rxBytes + $txBytes; if( $totalPackets == 0 ){ $totalPackets = $bothBytes; }else{ # find the difference between measurements, set maximum difference to # 1Mbit, which works well for `saturated' on a 100Mbit/sec network # reduce the value by a factor of 10000, which spreads the usage # nicely over 1-100 my $diffRX = $bothBytes - $totalPackets; if( $diffRX > 1000000 ){ $diffRX = 1000000 } $diffRX = ($diffRX / 10000); $totalPackets = $bothBytes; return( $diffRX ); }# if not first packet check }# packet count check }#getNetworkStats |
Yukarıdaki kod basit bir yöntemle Ethernet kartınızdaki hareketliliğin bir
ölçüsünü verir. /sbin/ifconfig/eth0
komutu alınan ve yollanan
tüm paketlerin sayısını listeler. Test makinalarında 100 Mbit/saniye
kapasiteli ağda, 1 milyonun alınan ya da gönderilen paket tam
doygunluk anlamına gelmektedir. Bu değer daha sonra 0 ile 100 arasındaki
bir değere dönüştürülür ve bir elektronik piyano notası olarak çalınır.
chordStats programı vmstat'ı okuyacak ve arabellekleme yapmadan FluidSynth'e stdin
standart giriş kanalı üzerinden veri gönderecektir. Programı
perl chordStats.pl |fluidsynth Hammered_Instruments.sf2 -c10000 -z10000 >/dev/null
komutu ile başlatabilirsiniz. Unutmayın ki -c
ve -z
parametreleri
ses arabellekleme ile ilgilidir ve sizin sisteminize göre ince ayar çekilmesi gerekebilir.
Şimdi chordStats'ı çalıştırdığınıza göre Mozilla web tarayıcısını çalıştırın. CPU kullanımı
ve disk giriş/çıkış durumundaki artışı zil ve "celesta" sesleri olarak fark ettiniz mi?
Eğer Mozilla ile çok veri içeren bir sayfaya bakar yahut wget
ile büyük
bir dosya indirirseniz ağ kapasitenizi kullanmaya başladıkça gittikçe artan bir piyano
sesi duyacaksınız.
Temel sistem yüküne ek olarak, chordStats programını başka şeyleri "dinlemek" için
de kolayca modifiye edebilirsiniz. vmstat 1
komutu her saniye
bir dizi bilgi sunmaktadır. Bu bilgiler nota değerleri üretmek ve temel tempoyu
belirlemek için kullanılmaktadır. chordStats'ı değiştirmek isterseniz yapabileceğiniz
ilk şeylerden biri vmstat
komutunu başka bir şeyle değiştirmektir. Söz gelimi
buradaki kaynak kodların arasında görebileceğiniz fastUpdate.pl
programı mevcut boş hafızayı, mevcut süreçleri, Ethernet
bağlantılarını her 0.2 saniyede bir
göstermektedir. Eğer chordStats.pl'yi fastUpdate.pl'yi kullanacak
şekilde düzenlemek
isterseniz şunu yapın:
Aşağıdaki komutu:
my $vmStatCmd = "vmstat 1"; |
şöyle değiştirin:
my $vmStatCmd = "./fastUpdate.pl 0.2 " |
Ve şu satırı da
for( split " ", "r b swpd free buff cache si so bi bo in cs us sy id wa" ){ |
şu şekilde değiştirin:
for( split " ", "memFree ethInt proc" ){ |
Ana program döngüsünde başlık satırlarını ve ilk 2 satırı görmezden gelen koda burada ihtiyaç
yoktur. Eğer isterseniz koşul satırlarını kaldırabilirsiniz. fastUpdate.pl çıktısı 0 ile 100
arasında değer üretecek şekilde ayarlanmıştır, dolayısı ile sendNote
altrutininde
de şu bölümü:
# user cpu usage $note = $currLine[ $fields{us} ]; sendNote( $note, 14, 12, 96 ); # conglomerate disk i/o fields to one stat $note = $currLine[ $fields{bi} ] + $currLine[ $fields{bo} ]; if( $note > 1000 ){ $note = 1000; } $note = $note/10; sendNote( $note, 8, 12, 96 ); # network throughput on eth0 $note = getNetworkStats(); sendNote( $note, 5, 12, 84 ); |
şu şekilde değiştirmelisiniz:
$note = $currLine[ $fields{memFree} ]; sendNote( $note, 14, 48, 96 ); $note = $currLine[ $fields{ethInt} ]; sendNote( $note, 8, 48, 96 ); $note = $currLine[ $fields{proc} ]; sendNote( $note, 5, 48, 96 ); |
Bu durumda minimum değerin 48'e çıktığına dikkat edin. Bunun
sebebi seçilmiş olan SoundFont ile ilgilidir
(Electronic_Sounds.sf2). chordStats'ın bu güncellenmiş halini
perl chordStats.pl | fluidsynth Electronic_Sounds.sf2 -c10000 -z10000 >/dev/null
komutu ile çalıştırabilir 1960'lı yılların bilimkurgu filmlerinin tadını yakalayabilirsiniz.
Bu örneği kullanarak bilgisayarınızdaki istediğiniz şeyi, istediğiniz parametrelere göre "dinlemek" için
chordStats'ı değiştirebilirsiniz. fastUpdate
'i de mesela strace
ya da gprof
çıktısını kullanacak şekilde değiştirebilirsiniz. Böylece program derleme
işlerinden log dosyalarına çeşitli makinaların performans istatistiklerinden ağ hareketlerine, problemlerine
dek pek çok şeyi "dinleyebilirsiniz".
Farklı denemeler için başka verilere göre ses şiddetini değiştirmeyi de düşünebilirsiniz. örneğin eğer veri paketlerinin sayısı sabit kalıyor fakat Ethernet kesmelerinin sayısı artıyorsa ağ ile ilgili notanın şiddetini artırabilirsiniz. Ya da tam oktavlık hareketler yerine üçte birlik aralıklarla hareket etmeyi ya da büyük değişimler arasında ses boşlukları bırakmayı deneyebilirsiniz.
Tanım | İsim | Büyüklük | İndirme yöntemi |
---|---|---|---|
Kaynak kod | os-linuxmusic_chordStats-0.1.zip | 10MB | HTTP |
öğrenin
-
chordStats Enstrüman örneklerini çekin.
-
Bilimkurgu Electronik örneğine bakın.
-
Peep! The Network Auralizer hakkında SourceForge'dan bilgi alın.
-
Linux'taki MIDI donanım ve yazılımları ile ilgili mükemmel bir kaynak: Advanced PC sound cards for MIDI.
-
HammerSound.net adresinden SoundFonts ile ilgili bilgi edinin.
-
Bedava SoundFont'larını indirin.
-
developerWorks Linux zone'u ziyaret edip Linux geliştiricileri için sunulan
kaynaklara göz atın.
-
developerWorks Open source zone'u
ziyaret edin açık kodlu araçları kendi projelerinizde IBM
ürünleri ile nasıl kullanabilceğinize dair bilgi sahibi olun.
-
developerWorks technical events and webcasts sayfasından son gelişmeleri takip edin.
-
Safari Books Online sayfasını ziyaret edin ve açık kod teknolojileri ile ilgili pek çok bilgiye erişin.
-
developerWorks podcasts sayfasından yazılım geliştiricileri ilgilendiren röportajları ve
tartışmaları dinleyin.
ürünler ve teknolojileri edinin
-
FluidSynth'i indirin.
-
Bir sonraki açık kodlu projeniz için Internet'ten erişilebilir ya da DVD'de sunulan
IBM deneme yazılımlarını kullanın..
Discuss
- Get involved in the developerWorks community by participating in developerWorks blogs.
Nathan Harrington, IBM'de çalışan bir programcıdır ve bugünlerde Linux, WatchPad 1.5 ve kaynak tespit etme teknolojileri üzerinde çalışmaktadır. |