SewiGの日記
2006-05-27 [土]
■ [Programming] X11プログラミングメモ(1)
とりあえず、ウィンドウを開いてみる。
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
Display *display;
Window root, window;
int screen;
XEvent event;
int main(int argc, char *argv[]) {
display = XOpenDisplay(NULL);
screen = DefaultScreen(display);
root = RootWindow(display, screen);
window = XCreateSimpleWindow(display, root, 100, 100, 640, 480, 4, BlackPixel(display, screen), WhitePixel(display, window));
XStoreName(display, window, "Hello, X11 world");
Atom atom1, atom2;
atom1 = XInternAtom(display, "WM_PROTOCOLS", False);
atom2 = XInternAtom(display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(display, window, &atom2, 1);
XMapWindow(display, window);
XFlush(display);
XSelectInput(display, window, ExposureMask | ButtonPressMask | UnmapNotify);
for(;;) {
XNextEvent(display, &event);
switch (event.type) {
case Expose:
break;
case ButtonPressMask:
if (event.xbutton.button == 1) {
XDestroyWindow(display, window);
XCloseDisplay(display);
exit(0);
}
break;
case ClientMessage:
if (event.xclient.message_type == atom1 && event.xclient.data.l[0] == atom2) {
XDestroyWindow(display, window);
XCloseDisplay(display);
exit(0);
}
}
}
}
まず、#include <X11/Xlib.h>と#include <X11/Xutil.h>は、お ま じ な い。Xプログラミングでは、XOpenDisplay()によりXサーバに接続するという一見すると大掛かりなことをします。でも複数のDisplayが扱えて弁理だったりします。接続したらディスプレイのIDを取得します。ハンドルみたいなもんです。使い終わったらXCloseDisplay()で閉じます。
そして、Window型にrootとwindowと2つありますが、XにはDisplayごとに1つrootwindowという一番親となるウィンドウがあります。GNOMEや、KDEなんかはrootwindow上でうまく動いています。なのでウィンドウもrootwindowから作成できます。XCreateSimpleWindow()でウィンドウを作成してウィンドウのIDを取得します。
作成したウィンドウはXMapWindow()で表示準備をして、XFlush()でバッファに溜まったメッセージを送信します。
あとはプログラムが終了するまでメッセージ処理をするだけです。使用しないメッセージまで受信したら無駄なのでXSelectInput()で受信したいメッセージを選択します。Exposeでウィンドウの再描画をしたり、ButtonPressMaskでマウスの処理をしたり、ClientMessageでウィンドウに関する処理をします。ほかにもいろんなメッセージがあります。終了するときは、XDestroyWindow()とXCloseDisplay()を使用します。残りのコードは、クローズボックスをクリックされたときの処理です。これが意外に面倒。
2007-05-27 [日]
■ [MATLAB] リサンプリング (1)
最近、プログラミング関連のネタを扱ってこなかったので、たまにはネタ投下。
ダウンサンプリング
ダウンサンプリングとは、ある周波数でサンプリングされた信号をそれよりも低い周波数でリサンプリングすることです。例えば、48kHzでサンプリングされた信号を24kHzでリサンプリングすることです。
ダウンサンプリングの原理はデータの間引き。例えば、偶数サンプルのみを間引くと、サンプリング周波数は半分になります。しかし、サンプリング周波数が半分になったのにスペクトル成分はそのままなので、折り返しが発生してしまいます。なので、サンプリング周波数の1/4を遮断周波数とするローパスフィルタ(LPF)を通して、高周波を遮断すればこうしたエイリアシングを防ぐことができます。
clear;
% 入力信号
[x,fs,bits]=wavread('input.wav');
fc=fs/4;
% 入力信号の波形
figure(1);
plot(x(1:100));
% LPF作成
[b,a]=butter(2,fc/(fs/2));
% LPFの周波数特性
figure(2);
freqz(b,a,fs,fs/4);
% 入力信号をLPFに通す
x2=filter(b,a,x);
% LPFに通した信号の表示
figure(3);
plot(x2(1:100));
% ダウンサンプリング(fsを半分に)
length_y=floor(length(x2)/2);
y=zeros(1,length_y);
for n=1:length_y
y(n)=x2(n*2-1);
end
% ダウンサンプリングした信号
figure(4);
plot(y(1:50));
% 書き出し
wavwrite(y,fs/2,'output.wav');
とここまで、説明してきたダウンサンプリングですが、実際にはMATLABのSignal Processing Toolboxに既にリサンプリングできる関数が用意されているので使いましょう。詳しくはhelpで確認を。
clear;
% 入力信号
[x,fs,bits]=wavread('input.wav');
fc=fs/4;
% 入力信号の波形
figure(1);
plot(x(1:100));
% リサンプリング
y = resample(x,1,2)
% ダウンサンプリングした信号
figure(2);
plot(y(1:50));
% 書き出し
wavwrite(y,fs/2,'output.wav');
● かおるくん [俺が春休みにインターンで行った会社は、運送業者のトラックやタクシーの配車システムなんかを管理するシステムを販売してた..]