2011年9月20日 星期二

valgrind 的其他用途

valgrind 是一個常被 programmer 拿來偵測 memory leaks 的利器。不過除了偵測記憶體錯誤以外,其實它還提供了其他有用的工具,只是 valgrind 以 memcheck 作為預設工具。

以下是 valgrind 提供的工具清單:

  1. memcheck
    偵測 runtime 記憶體錯誤與 memory leaks。
  2. callgrind
    提供類似 gprof 的 profiling 功能,記錄函數被呼叫的次數。不同的是它可以在 runtime 即時監控。
  3. cachegrind
    快取命中的 profiler,改善快取失誤可以提昇程式效能。
  4. massif
    heap 的 profiler,記錄記憶體使用量。
  5. helgrind
    thread 的 debugger,主要是用來偵測資料的 race condition。


2011年8月25日 星期四

ALSA 音量控制 sample code

以下是一段 ALSA 的程式碼片段,目的是調整某個音效卡的音量。我們會先開啟預設的 mixer,然後列舉所有的控制項並且找出 Master、將音量調整為 100%。

snd_mixer_elem_t* elem = NULL;
snd_mixer_t* mixer;

snd_mixer_open(&mixer, 0);
snd_mixer_attach(mixer, "default");
snd_mixer_selem_register(mixer, NULL, NULL);
snd_mixer_load(mixer);

for(elem=snd_mixer_first_elem(mixer);elem;elem=snd_mixer_elem_next(elem))
{
	if(!strcmp(snd_mixer_selem_get_name(elem), "Master"))
		break;
}

snd_mixer_selem_set_playback_volume_range(elem, 0, 100);  // range : 0 ~ 100
snd_mixer_selem_set_playback_switch_all(elem, 1);

下面的程式碼則是找出錄音來源的控制項並將它切換到編號一所對應的選項。這種控制項和上面的音量控制不同,它沒有百分比計和靜音開關,只能從幾個 options 中挑一個來用。

snd_mixer_elem_t* elem = NULL;
snd_mixer_t* mixer;

snd_mixer_open(&mixer, 0);
snd_mixer_attach(mixer, "default");
snd_mixer_selem_register(mixer, NULL, NULL);
snd_mixer_load(mixer);

for(elem=snd_mixer_first_elem(mixer);elem;elem=snd_mixer_elem_next(elem))
{
	if(!strcmp(snd_mixer_selem_get_name(elem), "Input Source"))
		break;
}

snd_mixer_selem_set_enum_item(elem, SND_MIXER_SCHN_MONO, 1);

2011年8月16日 星期二

PulseAudio 永遠低延遲播放來自線路輸入的訊號

像音效卡的 line-in、麥克風或 SPDIF等訊號輸入,除非你讓音效卡直接輸出錄音,不然平常應該聽不到輸入訊號才對。讓音效卡永遠播放來自錄音裝置的訊號有一些好處,這樣可以把系統播放的聲音和錄音裝置的訊號合在一起。譬如說實況 console game 的時候加入 PC 端播放的音樂,上一篇錄音的文章雖然也可以做到,但是會有只能兩邊挑一個聽的問題,不是聽音樂犧牲音效不然就是聽音效不聽音樂,對玩家來說頗不方便。不過讓音效卡永遠播放來自錄音裝置的訊號也不是沒有缺點,像 SE200PCI 這種麥克風和線路輸入混合的硬體就會有麥克風訊號被播放的問題。

底下的設定請寫到 /etc/pulse/default.pa

load-module module-loopback source=alsa_input.pci-0000_05_07.0.analog-stereo sink=alsa_output.softvol

其中 alsa_intput 是你的錄音裝置,alsa_output 是輸出(播放)裝置。如果播放有延遲的問題,請修改 /etc/pulse/daemon.conf 內的 default-fragment 系列參數。
default-fragments = 8
default-fragment-size-msec = 1

2011年7月27日 星期三

VirtualBox 自訂視窗解析度與隱藏選單、狀態列

VirtualBox 在裝了 Extension pack 以後雖然可以隨意調整解析度,但在某些時候就是想用固定解析度,偏偏可以選的標準解析度最高只有到 1280x1024(而且還沒寬螢幕可以選)。

這個時候就可以靠以下的指令指定你想要的解析度:

vboxmanage controlvm "Windows 7 x86-64" setvideomodehint "1280" "720" "32"

其中 "Windows 7 x86-64" 是虛擬機器的名稱,解析度會被設定為 1280x720 32bits。

另外,如果想要把那礙眼的選單列與狀態列隱藏、只留下純畫面的話,可以輸入下列指令:

VBoxManage setextradata global GUI/Customizations noMenuBar,noStatusBar

這樣以後啟動虛擬機器就可以得到乾淨的畫面。

VirtualBox USB隨身碟異常

正常來說 Linux user 只要確定帳號有加到 vboxusers 群組,guest OS 有裝 extension pack 的話,照理說 USB 2.0 應該是能正常工作的。但很不幸的是,在我的系統上即使照官方手冊的指示去做還是無法讓 guest OS 辨識 USB 儲存裝置。每次插上 USB 隨身碟、PSP、外接硬碟,Windows 就回我驅動程式安裝失敗,然後 USB 就掛在那裡。奇怪的是如果我是把其他 USB 裝置掛進去的話又一整個正常,像是 USB 滑鼠掛進去的話,X window 的滑鼠會消失。

經過幾天的實驗最後終於發現問題的關鍵。在實驗中我發現由官方發佈的 Linux kernel 可以正確找到 USB 儲存裝置,只有我自己編譯的 kernel 會有這樣的問題。經過 kernel configure 的交叉比對後,最後發現是 CONFIG_USB_DEBUG (USB verbose debug messages) 的問題,把它關掉以後 USB 就正常了。

說也奇怪,一樣的 kernel configure 對 VMware player 就沒影響,搞不好是 VirtualBox 的 bug   XD

2011年7月17日 星期日

FFmpeg GTK+ frontend like Flash Media Live Encoder (gtk-fmle)

這是一個簡易的 FFmpeg 前端程式,主要是針對 Twitch.tv 或 Ustream 這種實況應用而設計的。你可以用它來做 Screencast,將螢幕上的內容編碼傳送到 Flash Media Server。目前的版本算是雛型,未來也許會加入檔案、Video4Linux2 等輸入,以及檔案輸出等功能。

github 網頁: https://github.com/ryuanlu/gtk-fmle


介面:


Twitch.tv 實況測試(初音ミク Project DIVA F - Freely Tomorrow)


編碼參數:640x360@60, crf=23, preset=medium

2011年7月2日 星期六

[PATCH] Added analog video input support for Compro E650F

Compro E650(F) 是一張基於 Conexant 23885 晶片的數位/類比電視卡,它同時支援 DVB-T 數位電視、類比電視和類比端子輸入,板子上有 AV 端子、S 端子、色差端子、FM 天線輸入和紅外線接收器,和 E800(F) 差了一顆硬壓晶片,是一張軟壓的電視卡。

這張卡在 Linux 上有被支援,但僅限於 DVB-T 數位電視的部份能用。為了讓它的輸入端子能用,筆者參考了前人的實驗寫了以下的 patch:
0001-Added-analog-video-input-support-for-Compro-E650F.patch
※ 本 patch 適用於 Linux kernel 版本 2.6.35.0 ~ 3.6.11,3.7 以上使用以下 patch
0001-Added-analog-video-input-support-for-Compro-E650F-for-linux-3.10+.patch
這個 patch 可以啟用 E650(F) 的類比輸入功能,建立 /dev/video0 device node。以下是筆者用色差端子接 PS3 所擷取到的畫面: