歪林網誌

本來這個blog是記錄開發輸入法的點滴的,後來越來越雜,現在什麼都記錄了。

2011年2月9日星期三

C++ program to remove C/C++ style comments, while keep string content intact and line numbers of code unchnaged...

#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string>
#include <iostream>
#include <vector>
#include <string>

int my_fgets(std::string &str, FILE *fp, unsigned char to_remove_comments) {
    // read one line from file. if end of file return 0 otherwise return 1
    int ret=1;
    static unsigned char prev_linebreak;
    unsigned char ch;

    str.clear();

    while(1) {
        ch = fgetc(fp);

        if (feof(fp)) {
            prev_linebreak='\0';
            if (str.empty())
                ret=0;
            break;
        }

        if (ch=='\r') {
            prev_linebreak='\r';
            break;
        }

        if (ch=='\n') {
            if (prev_linebreak=='\r') {
                prev_linebreak='\0';
                continue;
            } else {
                prev_linebreak='\n';
                break;
            }
        }
        str+=ch;
    }

    if (to_remove_comments)
    {
        std::string tmpstr=str;
        
        static enum IN_COMMENT_T {
            IN_COMMENT_NOT,
            IN_COMMENT_WAIT_FOR_STAR_SLASH,
            IN_COMMENT_DOUBLE_QUOTE,
        } in_comment = IN_COMMENT_NOT;
        const char *p, *p_limit, *p_start;
        
        str.clear();
        p_start = tmpstr.c_str();
        p_limit = p_start + tmpstr.length();
        
        for(p=p_start; p<p_limit; p++) {
            switch(in_comment) {
            case IN_COMMENT_NOT:
                if (strncmp(p, "//", 2)==0) {
                    p=p_limit-1;
                    continue;
                } else if (strncmp(p, "/*", 2)==0) {
                    in_comment=IN_COMMENT_WAIT_FOR_STAR_SLASH;
                    p+=(sizeof("/*")-1)-1;
                } else if (*p=='"') {
                    // avoid case like '"'
                    if (p==p_start || *(p-1)!='\'')
                        in_comment=IN_COMMENT_DOUBLE_QUOTE;
                }
                break;
            case IN_COMMENT_WAIT_FOR_STAR_SLASH:
                if (strncmp(p, "*/", 2)==0) {
                    in_comment=IN_COMMENT_NOT;
                    p+=sizeof("*/")-1;
                }
                break;
            case IN_COMMENT_DOUBLE_QUOTE:
                if (*p=='"') {
                    // need to count how many '\' in the front. If it is even number then end of quote!
                    const char *q;
                    for(q=p-1; q>=p_start && *q=='\\'; q--);
                    if ((p-q)&1) {
                        // note (p-q)-1 is the number of '\\' before '"'.
                        // if ((p-q)-1) is odd, the " is escaped.
                        // if ((p-q)-1) is even, the " is a real close quotoation.
                        in_comment=IN_COMMENT_NOT;
                    }
                }
                break;
            default:
                break;
            }
        
            if (in_comment==IN_COMMENT_NOT || in_comment==IN_COMMENT_DOUBLE_QUOTE)
                str = str+*p;
        }
        
        if (ret==0)
            in_comment = IN_COMMENT_NOT;
    }

    return ret;
}

int 
main(int argc, char **argv) {
    FILE *fp=NULL;
    std::string str;

    if (argc!=2) {
        fprintf(stderr, "remove C style comment in a text file and show in stdout\n");
        fprintf(stderr, "usage: %s file\n", argv[0]);
        goto MAIN_ERROR;
    }

    fp=fopen(argv[1], "rb");

    if (fp==NULL)  {
        fprintf(stderr, "error in open %s\n", argv[1]);
        goto MAIN_ERROR;
    }

    while(my_fgets(str, fp, 1))
        fprintf(stderr, "%s\n", str.c_str());

                    
MAIN_ERROR:
    if (fp)
        fclose(fp);

    return 0;

}

2011年1月23日星期日

how to download audio from rthk server using wget?

wget --user-agent="NSPlayer/4.1.0.3938" --header="Pragma: \
no-cache,\
rate=1.000000,\
stream-time=240800,\
stream-offset=4294967295:4294967295,\
request-context=4,\
max-duration=2151082448,\
xPlayStrm=1,\
xClientGUID={3300AD50-2C39-46c0-AE0A-6420211E86C2},\
stream-switch-count=1,\
stream-switch-entry=ffff:1:0" \
http://202.177.192.111/rthk/radio1/20110122/2011012214.asf

2010年11月2日星期二

iPod HID Report Descriptor, what exactly is the content?

I am working on iPod HID interface recently.

As the first thing to do when working on HID interface, the lsusb -vv is used.

Here is the result:
Bus 002 Device 005: ID 05ac:1291 Apple, Inc. iPod Touch 1.Gen
...
Interface Descriptor:
  bLength                 9
  bDescriptorType         4
  bInterfaceNumber        2
  bAlternateSetting       0
  bNumEndpoints           1
  bInterfaceClass         3 Human Interface Device
  bInterfaceSubClass      0 No Subclass
  bInterfaceProtocol      0 None
  iInterface              0
    HID Device Descriptor:
      bLength                 9
      bDescriptorType        33
      bcdHID               1.11
      bCountryCode            0 Not supported
      bNumDescriptors         1
      bDescriptorType        34 Report
      wDescriptorLength     208
     Report Descriptors:
       ** UNAVAILABLE **

It seems to me that wDescriptorLength is 208. I am not sure why the Report Descriptors is UNAVAILABLE.

According to this link: which somehow make the Report Descriptors available, the 208 bytes are:
06 00 ff 09 01 a1 01 75 08 26 80 00 15 00 09 01 85 01 95 05 82 02 01 09 01 85 02
95 09 82 02 01 09 01 85 03 95 0d 82 02 01 09 01 85 04 95 11 82 02 01 09 01 85 05
95 19 82 02 01 09 01 85 06 95 31 82 02 01 09 01 85 07 95 5f 82 02 01 09 01 85 08
95 c1 82 02 01 09 01 85 09 96 01 01 82 02 01 09 01 85 0a 96 81 01 82 02 01 09 01
85 0b 96 01 02 82 02 01 09 01 85 0c 96 ff 02 82 02 01 09 01 85 0d 95 05 92 02 01
09 01 85 0e 95 09 92 02 01 09 01 85 0f 95 0d 92 02 01 09 01 85 10 95 11 92 02 01
09 01 85 11 95 19 92 02 01 09 01 85 12 95 31 92 02 01 09 01 85 13 95 5f 92 02 01
09 01 85 14 95 c1 92 02 01 09 01 85 15 95 ff 92 02 01 c0

With the hidrd-convert tool, the above is parsed as shown below:
Usage Page (FF00h), ; FF00h, vendor-defined
Usage (01h),
Collection (Application),
 Report Size (8),
 Logical Maximum (128),
 Logical Minimum (0),
 Usage (01h), ReportID( 0x1), ReportCount(  5),  Input(Variable, Buffered Bytes),
 Usage (01h), ReportID( 0x2), ReportCount(  9),  Input(Variable, Buffered Bytes),
 Usage (01h), ReportID( 0x3), ReportCount( 13),  Input(Variable, Buffered Bytes),
 Usage (01h), ReportID( 0x4), ReportCount( 17),  Input(Variable, Buffered Bytes),
 Usage (01h), ReportID( 0x5), ReportCount( 25),  Input(Variable, Buffered Bytes),
 Usage (01h), ReportID( 0x6), ReportCount( 49),  Input(Variable, Buffered Bytes),
 Usage (01h), ReportID( 0x7), ReportCount( 95),  Input(Variable, Buffered Bytes),
 Usage (01h), ReportID( 0x8), ReportCount(193),  Input(Variable, Buffered Bytes),
 Usage (01h), ReportID( 0x9), ReportCount(257),  Input(Variable, Buffered Bytes),
 Usage (01h), ReportID( 0xa), ReportCount(385),  Input(Variable, Buffered Bytes),
 Usage (01h), ReportID( 0xb), ReportCount(513),  Input(Variable, Buffered Bytes),
 Usage (01h), ReportID( 0xc), ReportCount(767),  Input(Variable, Buffered Bytes),

 Usage (01h), ReportID( 0xd), ReportCount(  5), Output(Variable, Buffered Bytes),
 Usage (01h), ReportID( 0xe), ReportCount(  9), Output(Variable, Buffered Bytes),
 Usage (01h), ReportID( 0xf), ReportCount( 13), Output(Variable, Buffered Bytes),
 Usage (01h), ReportID(0x10), ReportCount( 17), Output(Variable, Buffered Bytes),
 Usage (01h), ReportID(0x11), ReportCount( 25), Output(Variable, Buffered Bytes),
 Usage (01h), ReportID(0x12), ReportCount( 49), Output(Variable, Buffered Bytes),
 Usage (01h), ReportID(0x13), ReportCount( 95), Output(Variable, Buffered Bytes),
 Usage (01h), ReportID(0x14), ReportCount(193), Output(Variable, Buffered Bytes),
 Usage (01h), ReportID(0x15), ReportCount(255), Output(Variable, Buffered Bytes),
End Collection

However, with a 3rd party library that I used for the embedded system I am working on, I got a completely different result.

The size of descriptor is 96 bytes!!!!!!!!!!! (but not 208 bytes for lsusb -vv):
0600 ff09 01a1 0175 0826 8000 1500 0901
8501 950c 8202 0109 0185 0295 0e82 0201
0901 8503 9514 8202 0109 0185 0495 3f82
0201 0901 8505 9508 9202 0109 0185 0695
0a92 0201 0901 8507 950e 9202 0109 0185
0895 1492 0201 0901 8509 953f 9202 01c0

After parsing:
Usage Page (FF00h),                     ; FF00h, vendor-defined
Usage (01h),
Collection (Application),
  Report Size (8),
  Logical Maximum (128),
  Logical Minimum (0),

  Usage (01h), Report ID (1), Report Count (12), Input  (Variable, Buffered Bytes),
  Usage (01h), Report ID (2), Report Count (14), Input  (Variable, Buffered Bytes),
  Usage (01h), Report ID (3), Report Count (20), Input  (Variable, Buffered Bytes),
  Usage (01h), Report ID (4), Report Count (63), Input  (Variable, Buffered Bytes),

  Usage (01h), Report ID (5), Report Count (8),  Output (Variable, Buffered Bytes),
  Usage (01h), Report ID (6), Report Count (10), Output (Variable, Buffered Bytes),
  Usage (01h), Report ID (7), Report Count (14), Output (Variable, Buffered Bytes),
  Usage (01h), Report ID (8), Report Count (20), Output (Variable, Buffered Bytes),
  Usage (01h), Report ID (9), Report Count (63), Output (Variable, Buffered Bytes),
End Collection

Which one should I believe???????

2009年10月3日星期六

歪林輸入法和 google 更緊密的整合

歪林輸入法 已加入了 Goggle Suggest Goggle 拼音Goggle 翻譯 的功能。

下載及安裝歪林輸入法後,可以按 Ctrl + W / E (先按 Ctrl 鍵,然後按 W 鍵 或 E 鍵),就可以啟動上述的功能。

那麼加入上面三個功能有什麼好處呢? 以下是加入上面三個功能的介紹:


Google Suggest:

Google Suggest 是當你在 Google 網頁輸入搜尋字的期間,Google 提出的建議字。舉個例子:

在 2009年7月尾,Google 為了配合香港人語言的需要,首創可以支援廣東話拼音的搜尋建議,這亦是 Google 香港首次為廣東話用戶特別推出的功能,讓大家的搜尋更得心應手。下面提供了一些範例,大家可以參考:

想搵 輸入

娛樂名人

劉德華 lau tak wa
lautakwa
ltw
陳奕迅 chan yik shun
chanyikshun
cys
張學友 cheung hok yau
cheunghokyau
chy
卡通劇集 巾幗裊雄 gun kok hiu hung
gunkokhiuhung
gkhh
老婆大人 lo po tai yan
lopotaiyan
lpty
海賊王 hoi chak wong
hoichakwong
hcw
想搵 輸入
資訊話題 電車男 din che nam
dinchenam
dcn
金融海嘯 kam yung hoi siu
kamyunghoisiu
kyhs
地方景點 北海道 pak hoi dou
pakhoidou
phd
馬爾代夫 ma yi doi fu
mayidoifu
mydf
太平山頂 tai ping shan dang
taipingshandang
tpsd

歪林輸入法已經將這功能整合了. 以下是 示範:


Google 拼音

Google 提供了拼音漢字轉換

Google 運用智慧軟體系統對拼音關鍵字能進行自動中文轉換並提供相應提示(此功能只適用於台灣以外地區)。例如:輸入“shang wu tong”, Google 能自動提示 “您是不是要查:商務通”。如果您點選“商務通”,Google 將以“商務通”作為關鍵字進行搜尋。對於拼音和中文混和關鍵字,系統也能做有效轉換。對於拼音“lü”, “lüe”, “nü” 或 “nüe”,您可輸入 “lv”, “lve”, “nv” 或 “nve”。如果拼音中沒有空格,例如 “shangwutong”,Google 也會做相應處理,但是在多個拼音中加空格能提高轉換準確率和速度。

由於漢語的多音字和方言眾多,常用發音與實際發音常常有出入,更不用說拼音輸入中可能出現的錯誤了。Google 的拼音漢字轉換系統能支援模糊拼音搜尋,為用戶提示最符合的中文關鍵字,具有容錯和改正的功能。例如:輸入 “wan luo xing wen”, Google 會提示 “您是不是要查:萬羅興文 蔓羅興文 網絡新聞”, 其中 “網(wang)絡新(xin)聞” 是系統參考了可能會有的拼音錯誤後自動轉換的。點選其中任一提示,Google 將以其作為關鍵字進行搜尋。


 

2009年5月31日星期日

怎樣在 Linux 環境下,透過網絡共享數碼電視廣播 (DMB-TH 香港制式) ?

  1. 購買 ASUS 華碩 My Cinema-U3100 Mini USB 2.0 高清數碼電視接受棒
  2. 在某電腦,安裝 Ubuntu 9.0.4。建立一個用戶(以下假設是 yylam)
  3. 插入接收棒後,打 lsusb,看看 USB Vendor ID / Product ID 是否如下:

    Bus 001 Device 005: ID 0b05:1721 ASUSTek Computer, Inc.

  4. 下載 v4l-dvb
  5. Check if successfully loaded the driver:
    • Unplug the DMT-TH USB stick.
    • Restart the PC.
    • Plug the DMB-TH USB stick. Wait a little while
    • type lsmod to see if you see the following lines:

    dib3000mc 24452 2 dvb_usb_dibusb_common
    dibx000_common 11524 1 dib3000mc

    • also see if /dev/dvb/adapter0 is created
       
  6. Quick check if can play using mplayer:
     
    • Create a file channels.conf with the following content:
    J2:586000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:821:823:82
    iNews:586000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:831:834:83
    HDJade:586000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:851:853:85
    Jade:482000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:811:813:1
    Pearl:482000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:841:843:2
    Home:482000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:111:113:11
    World:482000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:161:163:16
    His:602000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:131:133:13
    Her:602000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:141:143:14
    News:602000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:121:123:12
    Plus:602000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:151:153:15
    CCTV:602000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:171:172:17
    HDTV:602000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:92:82:19

            Please note that: for Jade, Pearl, Home, Word, please change the frequency according to your district
    慈雲山 482 000 000
    青山 650 000 000
    飛鵝山 562 000 000
    金山 626 000 000
    九龍坑山 546 000 000
    南丫島 546 000 000
    聶高信山 634 000 000

    • sudo apt-get install dvb-apps
    • sudo tzap -r -c channels.conf His
      (of course you should choose, instead of His, Jade etc)

      you should be see the following:

      tuning to 602000000 Hz
      video pid 0x0083, audio pid 0x0085
      status 1f | signal b9f0 | snr 0000 | ber 10000000 | unc 00000000 | FE_HAS_LOCK
      status 1f | signal b9f0 | snr 0000 | ber b7f3914c | unc b7efb780 | FE_HAS_LOCK
      status 1f | signal b9f0 | snr 0000 | ber b7f3914c | unc b7efb780 | FE_HAS_LOCK
      status 1f | signal b9f0 | snr 0000 | ber b7f3914c | unc b7efb780 | FE_HAS_LOCK
      status 1f | signal b9f0 | snr 0000 | ber b7f3914c | unc b7efb780 | FE_HAS_LOCK
      status 1f | signal b9f0 | snr 0000 | ber b7f3914c | unc b7efb780 | FE_HAS_LOCK
       

    • sudo apt-get install mplayer
    • mplayer /dev/dvb/adapter0/dvr0
    • You should be able to watch TVB now.
       
  7. Using VLC to share the video:

    sudo chown yylam /dev/dvb/adapter0/frontend0
    sudo chown yylam /dev/dvb/adapter0/
    vlc dvb:// :dvb-frequency=482000000 --programs=11 -I dummy --sout '#standard{access=http,mux=ts}'    (ATV Home)
    vlc dvb:// :dvb-frequency=482000000 --programs=16 -I dummy --sout '#standard{access=http,mux=ts}'    (ATV World) 
    vlc dvb:// :dvb-frequency=482000000 --programs=1   -I dummy --sout '#standard{access=http,mux=ts}'    (TVB Jade)
    vlc dvb:// :dvb-frequency=482000000 --programs=2   -I dummy --sout '#standard{access=http,mux=ts}'    (TVB Pearl) 

        Then you should be able to watch the TV at http://192.168.0.2:8080 using Windows Media Player Classic.

        To stream in Windows Media Player:

        vlc dvb:// :dvb-frequency=482000000 --programs=11 -I dummy --sout '#transcode{vcodec=WMV1,vb=350,acodec=mp3,ab=32,channels=1}:duplicate{dst=std{access=http,mux=asf,dst=:1234}}}'

        However, you need a special version of ffmpeg.