2012年1月16日 星期一

Genie 程式語言

Genie 程式語言是 GNOME 計畫下的一個新的程式語言,跟 Vala 一起開發的,語法類似 Python,跟 Vala 一樣都是借助 GObject 來實現物件導向程式設計,也跟 Vala 一樣都是產生出 C 的程式碼,而且也因為 GObject 的關係可以輕易地產生其它程式語言的 binding。
例如:輸入以下的程式碼儲存成 hello.gs
init
        print "Hello World"
然後再執行以下的指令就可以看到結果了。
$ valac hello.gs
$ ./hello
如果說要看到中間轉譯出來的 C 語言程式碼可以輸入以下指令:
$ valac -C hello.gs
於是就可以看到 hello.c 產生出來了。
/* hello.c generated by valac 0.14.0, the Vala compiler
 * generated from hello.gs, do not modify */

#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>

void _vala_main (gchar** args, int args_length1);

void _vala_main (gchar** args, int args_length1) {
        g_print ("Hello World\n");
}

int main (int argc, char ** argv) {
        g_type_init ();
        _vala_main (argv, argc);
        return 0;
}
看看裡面的內容是不是一般所熟悉的 C 語言程式碼。:)
參考資料:Genie - GNOME Live!

AMD Graphics Drivers 非官方 PPA - ppa:fourdollars/fglrx

因為我自己工作上的需要所以偶而會測試 AMD 官方最新 release 出來的 Graphics Drivers
剛剛更新了 ppa:fourdollars/fglrx 給 Ubuntu 10.04/10.10/11.04/11.10 使用
目前使用的是 AMD 在 12/13/2011 釋出的 AMD Catalyst™ 11.11 Proprietary Linux x86 Display Driver
最新的 AMD Graphics Drivers 可以參考 http://support.amd.com/us/gpudownload/linux/Pages/radeon_linux.aspx
有 AMD Graphics Drivers 使用問題的網友可以試試看,另外要特別聲明這只是使用 AMD 官方釋出的套件產生出來的,因此有問題找我也解決不了。:P

2012年1月13日 星期五

betaradio v1.4 released

BetaRadio 是一款使用 Vala 程式語言寫出來的網路收音機程式,專門用來收聽台灣的網路電台。

專案網址:
http://code.google.com/p/betaradio/

新功能:
1. 改善 Unity 整合性
2. 使用多執行緒改善回應速度

錯誤修正:
1. 修正右鍵點擊無法使用的問題

原始碼下載:
http://code.google.com/p/betaradio/downloads/detail?name=betaradio-1.4.tar.bz2

2011年11月21日 星期一

Ubuntu 11.10 繁體中文全新安裝後手動修正問題

共同的部份

1. 系統語言變數設定錯誤
直接修改 /etc/default/locale 內容改成
LANG="zh_TW.UTF-8"
LANGUAGE="zh_TW:en"
然後再執行
$ sudo update-grub
2. fontconfig 字型設定錯誤
正常的設定會是以下的結果
$ fontconfig-voodoo -c
Current config: zh_TW
如果不正常就執行以下命令修正
$ sudo fontconfig-voodoo -a
修正完畢後,重新開機應該就會正常了。

Xubuntu 11.10

1. ibus 導致程式崩潰的問題
$ sudo apt-get install ibus-gtk ibus-gtk3
$ cd /usr/lib/gtk-2.0/2.10.0/
$ sudo ln -s /usr/lib/i386-linux-gnu/gtk-2.0/2.10.0/immodules
如果是使用 AMD64
$ sudo ln -s /usr/lib/x86_64-linux-gnu/gtk-2.0/2.10.0/immodules

2011年11月20日 星期日

在 Sony Ericsson Xperia™ X8 刷 MiniCM7

MiniCM 是一個特別為 Sony Ericsson Xperia  X10 mini / X8 製作 Android 的 CyanogenMod 客製化的計畫



以下是筆者的安裝步驟筆記,自行刷客製的 Android ROM 有一定的風險,請讀者自行負擔風險,筆者不擔保過程中發生的問題。
  1. 首先需要在 Windows 下載安裝 Sony Ericsson PC Companion 2.0 用來升級跟還原出廠預設版本(安裝過程中有任何問題都可以還原手機上的系統)
  2. 如果 [設定] -> [關於手機] 裡面的 [基頻版本] 不是 015 結尾的話,需要下載 Baseband 015 的 firmware 回來使用 Flashtool 來更新,然後重新啟動手機
  3. 在 Windows 上面安裝使用 SuperOneClick 來取得手機上的 root 權限,然後重新啟動手機
  4. 利用 Android Market 安裝 Apk Installer 用來安裝 Root Explorer,然後重新啟動手機
  5. 然後再將 Xrecovery.zip 裡面的三個檔案利用 Root Explorer 複製到手機系統裡的 /system/bin 底下
  6. 重新啟動系統,看見手機畫面上出現 Sony Ericsson 字樣時不斷地連擊手機上的 Back 鍵,順利的話就可以進入 Xrecovery
  7. 在 Xrecovery 裡面安裝 MiniCM7-2.0.7-X8.zip 跟 gapps-gb-20110828-signed.zip,然後再執行 factory reset 再重新啟動手機就大功告成啦!^o^

PS. 筆者所使用的手機型號是 X8i(E15i)

2011年9月26日 星期一

在 Ubuntu 10.10 上修正 NVidia 的 HDMI audio 支援問題

首先要裝上 ppa:fourdollars/nvidia 上面的 nvidia proprietary driver
還要裝上 ppa:diwic/dkms 上面的 alsa-hda-dkms
還要裝上 ppa:ubuntu-audio-dev/ppa 上面的 pulseaudio
然後重新啟動
接下來看看 HDMI 接在哪裡
$ for i in /proc/asound/NVidia/eld*; do echo "<<$i>>"; cat $i; done
<</proc/asound/NVidia/eld#0.0>>
monitor_present		0
eld_valid		0
<</proc/asound/NVidia/eld#1.0>>
monitor_present		1
eld_valid		1
monitor_name		CHIMEI 22SH-L
connection_type		HDMI
eld_version		[0x2] CEA-861D or below
edid_version		[0x3] CEA-861-B, C or D
manufacture_id		0x73b
product_id		0x2d22
port_id			0x10000
support_hdcp		0
support_ai		0
audio_sync_delay	0
speakers		[0x1] FL/FR
sad_count		1
sad0_coding_type	[0x1] LPCM
sad0_channels		2
sad0_rates		[0xe0] 44100 48000 88200
sad0_bits		[0xe0000] 16 20 24
<</proc/asound/NVidia/eld#2.0>>
monitor_present		0
eld_valid		0
<</proc/asound/NVidia/eld#3.0>>
monitor_present		0
eld_valid		0
從上面的紀錄可以看出在 /proc/asound/NVidia/eld#1.0 上面
不過可能會看到都是靜音的狀態
$ amixer -D hw:NVidia
Simple mixer control 'IEC958',0
  Capabilities: pswitch pswitch-joined penum
  Playback channels: Mono
  Mono: Playback [off]
Simple mixer control 'IEC958',1
  Capabilities: pswitch pswitch-joined penum
  Playback channels: Mono
  Mono: Playback [off]
Simple mixer control 'IEC958',2
  Capabilities: pswitch pswitch-joined penum
  Playback channels: Mono
  Mono: Playback [off]
Simple mixer control 'IEC958',3
  Capabilities: pswitch pswitch-joined penum
  Playback channels: Mono
  Mono: Playback [off]
就可以執行
$ alsamixer -D hw:NVidia
在 CUI 設定畫面中全部取消靜音,接下來執行
$ pasuspender -- speaker-test -D hdmi:NVidia,1 -c 2 -t sine -l 1
應該就可以聽到聲音了,確定裝置之後就可以修改 /usr/share/pulseaudio/alsa-mixer/profile-sets/default.conf 當中的
[Mapping hdmi-stereo]
device-strings = hdmi:%f
channel-map = left,right
priority = 4
direction = output
改成
[Mapping hdmi-stereo]
device-strings = hdmi:%f,1
channel-map = left,right
priority = 4
direction = output
再重新啟動後應該就可以聽到 HDMI audio 的聲音了。

其它幫助除錯的方法還有

2011年8月31日 星期三

Project Euler - Problem 12

昨天在 TOSSUG 聚會上 Choupi 提到這個問題 Project Euler - Problem 12 於是就寫了以下的 Vala 程式碼來解這個問題
void main()
{
    int i = 0, number = 0;
    // 用來儲存質數分解的結果
    HashTable<string, int*> factors = null;

    do {
        // 逐個取出三角數
        number = triangle_number(++i);
        // 算出所有因數的個數直到比 500 還要大為止
    } while (factor_number_of(number, out factors) < 500);

    // 把算出來的答案印出來
    stdout.printf("Answer: %d\n", number);

    // 將答案驗算一遍
    print_factors(factors);
}

void print_factors(HashTable<string, int*> factors)
{
    int number = 1;

    List<unowned string> keys = factors.get_keys();
    // 把質因數表的鍵值依照數值大小重新排序
    keys.sort( (a, b) => {
        int num1 = int.parse(a);
        int num2 = int.parse(b);
        if (num1 < num2 ) {
            return -1;
        }
        else if (num1 > num2) {
            return 1;
        }
        else {
            return 0;
        }
    });

    // 驗算過程
    foreach (unowned string key in keys) {
        int* count = (int*) factors.lookup(key);
        int prime = int.parse(key);
        if (*count > 1) {
            stdout.printf("%d^%d*", prime, *count);
        }
        else {
            stdout.printf("%d*", prime);
        }
        // 重覆乘上質因數出現的次數
        for (int i = 0; i < *count; i++) {
            number = number * prime;
        }
        free(count);
    }

    stdout.printf("\b=%d\n", number);
}

// 三角數的計算
int triangle_number(int num)
{
    return num * (num + 1) / 2;
}

// 找出某數值的質因數分解
int factor_number_of(int number, out HashTable<string, int*> table)
{
    table = new HashTable<string, int*>(str_hash, str_equal);
    do {
        // 找出該數值的平方根
        int root = sqrt_floor_of(number);
        int previous = number;

        // 從小到大用質因數去整除直到超過平方根
        for (int i = 0; prime_number_of(i) <= root; i++) {
            int prime = prime_number_of(i);
            if (number % prime == 0) {
                // 遞增質因數表的數值
                int* count = (int*) table.lookup(prime.to_string()) ?? malloc0(sizeof(int));
                *count = *count + 1;
                table.replace(prime.to_string(), count);
                number = number / prime;
                break;
            }
        }

        // 如果 number 沒有變動過,number 就是質數。
        if (number == previous) {
            // 遞增質因數表的數值
            int* count = (int*) table.lookup(number.to_string()) ?? malloc0(sizeof(int));
            *count = *count + 1;
            table.replace(number.to_string(), count);
            break;
        }
    } while (number != 1);

    int result = 1;

    // 計算所有因數的個數
    foreach (int* count in table.get_values()) {
        result = result * (*count + 1);
    }

    return result;
}

// 計算平方根
int sqrt_floor_of(int num)
{
    return (int) Math.sqrt((double) num);
}

// 準備一個用來 cache 計算過的質數表
static List<int> prime_table = new List<int>();

// 質數計算
int prime_number_of(uint index)
{
    if (index < prime_table.length()) {
        // 直接從 cache 中取出
        return prime_table.nth_data(index);
    }

    // 第一個質數為 2
    if (index == 0) {
        prime_table.append(2);
        return 2;
    }
    // 第二個質數為 3
    else if (index == 1) {
        prime_table.append(3);
        return 3;
    }
    // 第三個後的質數計算
    else {
        int candidate = prime_table.nth_data(prime_table.length() - 1) + 2;
        do {
            bool is_prime = true;
            foreach (int number in prime_table) {
                if (candidate % number == 0) {
                    is_prime = false;
                    break;
                }
            }
            if (is_prime) {
                prime_table.append(candidate);
                return candidate;
            }
            candidate = candidate + 2;
        } while (true);
    }
}
將以上程式碼儲存成 p12.vala 或是直接從 gist: 1182715 下載 然後編譯執行
$ valac p12.vala -X -lm && ./p12
Answer: 76576500
2^2*3^2*5^3*7*11*13*17=76576500