2010年11月13日土曜日

EDIROL FA-66 ドライバのインストールでハマッた

FA-66 ドライバの再インストールをしようとして、ちょっとハマッたので、備忘録として書き残す。

検証環境
  • Windows Vista Business (64ビット) SP2
  • EDIROL FA-66
  • IEEE1394 拡張ボード(Texas Instruments 製チップ)

インストールしたバージョンは、EDIROL FA-66 Driver Ver.1.0.6 for Windows Vista 64ビット版 (2008.03.25 公開)(FA66_Vis64Drv106J.zip)。

再インストールなので、zip ファイルを解凍し、その中の UnInstall.exe を実行する。
再起動後、setup.exe を実行する。手順通りに進め、FA-66 の電源を入れるところまで進める。
ここからが重要。
FA-66 の電源を入れる前に、FA-66 背面の「SAMPLE RATE」スイッチを”44.1”または”48”に設定する。”96”または”192”に設定しておくと、「FA-66 を使用する準備をしています。しばらくお待ちください。」から進まなくなる。場合によっては、強制リセットで再起動してしまう。
マニュアルにも、インストール手順にもそれらしい記述は無いので、環境依存なのか・・・

2010年11月1日月曜日

MeCab を MinGW-w64 でビルド。ついでに、Java バインディングもビルド

MeCab をビルドしたくなった。ついでに Java からも使いたい。そしてそれは、64ビット版でなくてはならない。

環境


MinGW 環境は、これまで色々ビルドしているので、他にも必要なライブラリなどがあるかもしれないが、今回やった手順しか書かないので注意。

libiconv のビルド
tar zxvf libiconv-1.13.1.tar.gz
cd libiconv-1.13.1
./configure --prefix=/mingw --enable-static --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32
make
make install
libiconv のビルドは、スンナリできた。

MeCab 用 IPA 辞書のビルド
tar zxvf mecab-ipadic-2.7.0-20070801.tar.gz
cd mecab-ipadic-2.7.0-20070801
./configure --prefix=/mingw --with-charset=utf-8
make

MeCab のビルド
パッチファイル(MeCab_0.98_MinGW.patch)については後述する。
以下の手順でビルドすると、 libgcc_s_sjlj-1.dll が実行時に必要となる。このファイルは MinGWディレクトリの ”x86_64-w64-mingw32/bin/”に入っている。パスを通すか、実行ファイルと同じディレクトリにコピーしておく必要がある。依存を無くそうと悶絶してみたが、私のレベルでは、どうしてもできなかった。ちなみに私のレベルは5である。スライムぐらいには勝てる・・・・
tar zxvf /f/Archive/mecab-0.98.tar.gz
cd mecab-0.98
patch -p0 < MeCab_0.98_MinGW.patch
CPPFLAGS='-I/mingw/include' LIBS=-liconv ./configure --prefix=/mingw --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --enable-utf8-only --with-charset=utf8
make

MeCab のパッチファイル
このパッチファイルこそが、今回の血と汗と涙の結晶。若干の説明をおこなう。

【config.h.in】
49 行目
#undef HAVE_PTHREAD_H
↓
//#undef HAVE_PTHREAD_H
これは、pthread を利用しないようにするため。インストールされていなければいらない。うちの環境では、以前 pthread をインストールしていて、それを使うと MeCab.exe 実行して、1行入力後に固まるようなので、利用しないようにした。pthread を利用しない場合は、WindowsAPI の同様の機能を利用するようだ。

【src/feature_index.cpp】
311 行目
case 't':  os_ << (size_t)path->rnode->char_type;     break;
↓
case 't':  os_ << static_cast<unsigned int>((size_t)path->rnode->char_type);     break;
あいまいなキャストだったので、修正。これが正しいのかは神のみぞ知る・・・

【src/libmecab.cpp】
53 行目
#ifdef __cplusplus
↓
#if defined(__cplusplus) && !defined(__MINGW32__)

65 行目
#ifdef __cplusplus
↓
#if defined(__cplusplus) && !defined(__MINGW32__)
ここは、偉大なる先人の知恵。

【src/Makefile.in】
260 行目
INCLUDES = -DDIC_VERSION=$(DIC_VERSION) $(MECAB_WITHOUT_SHARE_DIC) $(MECAB_WITHOUT_MUTEX_LOCK) $(MECAB_USE_UTF8_ONLY) -DMECAB_DEFAULT_RC="\"$(MECAB_DEFAULT_RC)\""
↓
INCLUDES = -DDIC_VERSION=$(DIC_VERSION) $(MECAB_WITHOUT_SHARE_DIC) $(MECAB_WITHOUT_MUTEX_LOCK) $(MECAB_USE_UTF8_ONLY) -DMECAB_DEFAULT_RC='"$(MECAB_DEFAULT_RC)"'
ここの修正は、苦肉の策。どうもうちの環境では、変数の展開に問題があるらしく、思ったようにならない(バックスラッシュだらけになり、バックスラッシュの個数も1個足りないとか・・・)。よって、この値を利用している、src/utils.cpp を修正した。ここは、コンパイルが通るようにしただけで、理想の対処とは程遠い。

【src/mecab.h】
131 行目
#ifdef _WIN32
↓
#if defined(_WIN32) && !defined(__MINGW32__)

254 行目
#ifndef SIWG
↓
#ifndef SWIG
ここも、偉大なる先人の知恵。

【src/utils.cpp】
282 行目
if (rcfile.empty()) rcfile = MECAB_DEFAULT_RC;
↓
if (rcfile.empty()) rcfile = "C:\\appli\\MeCab_utf8\\etc\\mecabrc";
ここは、mecabrc ファイル格納デフォルトディレクトリをハードコーディングした。各自の環境に合わせて、変更する必要がある。
ソースを読むと、ホームディレクトリの”.mecabrc”か、MECABRC 環境変数の値か、レジストリ”HKEY_LOCAL_MACHINE\software\mecab”の”mecabrc”の値か、レジストリ”HKEY_CURRENT_USER\software\mecab”の”mecabrc”の値か、MeCab.dll と同じディレクトリの”mecabrc”を探すらしい。それでも見つからないときにこの値を利用するようだ。
本来的には、Make の変数展開を何とかするべきなんだろうが、LV5 ではなんとも・・・

【src/writer.cpp】
236 行目
case 'L': *os << std::strlen(sentence); break;
↓
case 'L': *os << static_cast<unsigned int>(std::strlen(sentence)); break;
あいまいなキャストってコンパイラに怒られたので、適当にキャストしてみた(おいっ)。いいのかなぁいいのかなぁ。

MeCab Java バインディングのビルド
tar zxvf mecab-java-0.98.tar.gz
cd mecab-java-0.98

先ほどビルドした MeCab から必要なファイルを Java バインディングのディレクトリにコピーする。
cp ../mecab-0.98/src/mecab.h .
cp ../mecab-0.98/src/.libs/libmecab.a .

Java の bin ディレクトリをパスに追加
export PATH=/c/appli/Java/jdk1.6/bin:$PATH

Makefile を修正
TARGET=MeCab
JAVAC=javac
JAVA=java
JAR=jar
CXX=c++
INCLUDE=c:/appli/Java/jdk1.6/include

PACKAGE=org/chasen/mecab

LIBS=-L. -L/mingw/lib -lmecab -liconv
INC=-I$(INCLUDE) -I$(INCLUDE)/win32

all:
    $(CXX) -O3 -c -fpic $(TARGET)_wrap.cxx  $(INC)
    $(CXX) -shared -static $(TARGET)_wrap.o -o $(TARGET).dll $(LIBS)
    $(JAVAC) -encoding utf-8 $(PACKAGE)/*.java
    $(JAVAC) -encoding utf-8 test.java
    $(JAR) cfv $(TARGET).jar $(PACKAGE)/*.class

test:
    LD_LIBRARY_PATH=. MECABRC=./mecabrc $(JAVA) -Djava.file.encoding=euc-jp test

clean:
    rm -fr *.jar *.o *.dll *.class $(PACKAGE)/*.class
    
cleanall:
    rm -fr $(TARGET).java *.cxx


java のコンソール出力が文字化けするので、ファイルにログを吐いておく。、
make > build.log 2>&1

出来上がったもののテストをしてみる。
設定ファイルを作る
cp ../mecab-0.98/mecabrc .

コピーした mecabrc を修正する。辞書ディレクトリを指定する部分に、先ほどビルドした辞書のディレクトリを設定する。
dicdir =  ..\mecab-ipadic-2.7.0-20070801

テストを実施
コンソール出力は、文字化けするのでファイルに吐いて確かめる。
make test > test.log 2>&1

テスト結果
LD_LIBRARY_PATH=. MECABRC=./mecabrc java -Djava.file.encoding=euc-jp test
0.98
太郎 名詞,固有名詞,人名,名,*,*,太郎,タロウ,タロー
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
二郎 名詞,固有名詞,人名,名,*,*,二郎,ジロウ,ジロー
に 助詞,格助詞,一般,*,*,*,に,ニ,ニ
この 連体詞,*,*,*,*,*,この,コノ,コノ
本 名詞,一般,*,*,*,*,本,ホン,ホン
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
渡し 動詞,自立,*,*,五段・サ行,連用形,渡す,ワタシ,ワタシ
た 助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
。 記号,句点,*,*,*,*,。,。,。
EOS

 BOS/EOS,*,*,*,*,*,*,*,*
EOS

ちなみに、辞書を指定せずに実行すると、以下のようなログが出力される。
LD_LIBRARY_PATH=. MECABRC=./mecabrc java -Djava.file.encoding=euc-jp test
0.98
Exception in thread "main" java.lang.RuntimeException: tagger.cpp(151) [load_dictionary_resource(param)] param.cpp(71) [ifs] no such file or directory: ./mecabrc
    at org.chasen.mecab.MeCabJNI.new_Tagger__SWIG_1(Native Method)
    at org.chasen.mecab.Tagger.<init>(Tagger.java:128)
    at test.main(test.java:17)
make: *** [test] Error 1

文字コードの違う辞書を指定してしまうと、文字が化け化けになる。指定しているつもりが無くとも、MeCab をインストーラーでインストールしたことがあると、レジストリに設定ファイルの場所が設定されてしまうので、こういう事態に陥りやすいので注意。

MeCab の設定ファイルの指定方法は複数あるが、今回は、環境変数で指定してある。DLL と同じディレクトリに入れる方法もあるのだが、レジストリでの指定より優先順位が低いので、環境によって問題がある。

これでめでたく Java から MeCab を利用することが出来る。
いや、長かった・・・・この手順も長いが、実はかなり遠回りをしてしまい、実際にはここに書かれていない作業を延々としてしまった。GLib コンパイルしたりとか、gettext コンパイルしたりとか・・・
まあ、いろんな意味でレベルは上がった。怪我の功名というやつですな。次は Python バインディングか・・・・

2010年10月31日日曜日

Eclipse CDT と MinGW (64ビット環境)で JNI のデバッグ

ふと、Eclipse で JNI 呼び出し DLL のデバッグがしたくなった。
つまんない事で嵌ったので、備忘録として書いておく。

検証環境:
  • Windows Vista Business (64ビット) SP2
  • Eclipse classic 3.6.1(64ビット) Build id: M20100909-0800
  • Eclipse CDT 7.0.1.201009141542
  • JDK 1.6.0_16(64ビット)
  • MinGW-w64 (mingw-w64-bin_i686-mingw_20100702_sezero.zip)
  • GDB (x86_64-w64-mingw32-gdb-7.1.90.20100730.zip)
  • Make (make-3.82-20100827.zip)

以前に、CDT の設定をして、うまく動いていたと思ったのに、久しぶりに Eclipse を起動したら、MinGW を認識してくれなった。CDT のアップデートを行ったからだろうか?
しょうがないので、サポート外Toolchain から MinGW を選択した。path に MinGW/bin が設定されていれば、デフォルトの include ディレクトリや lib ディレクトリは自動的に設定されるようだ。
まあ、ここら辺の調査は宿題としておこう。

まあ、何事にも共通するが、初めてやるものは、最小限の状態から試すことが大事。

JNI で Java ソースと C++ のソースを作成済みとする。
プロジェクトは、Java と C++ で分ける必要がある。Java プロジェクトには、JNI インターフェースを作成するソースを格納。これは、そのままテスト駆動用とする。C++ プロジェクトには、JNI インターフェースのヘッダファイルと、ヘッダに定義されている関数の実装を記述したソースを格納。

C++ プロジェクトの設定

C++ プロジェクトのプロパティを開く
「C/C++ Build」-「Settings」で「Tool Settings」タブを開く

「GCC C++ Compiler」で以下を設定
  • 「Preprocessor」の「Defined symbols(-D)」に”_JNI_IMPLEMENTATION_”を追加。これは、jni.h の中に定義されている。未設定でも動いたが、ヘッダの該当箇所あたりに記述してあるメソッドを利用するときは設定する必要があるのかもしれない。
  • 「Includes」の「Include paths(-I)」に JDK をインストールしたディレクトリの include と include/win32 を追加。
  • 「Debugging」の「Debug Level」を”Default(-g)”に設定。

「All options」を見るとこんな感じ
-D_JNI_IMPLEMENTATION_ -I"C:\appli\Java\jdk1.6\include" -I"C:\appli\Java\jdk1.6\include\win32" -O2 -g -Wall -c -fmessage-length=0


「MinGW C++ Linker」で以下を設定
  • 「Miscellaneous」の「Linker flags」に”-static”と”--kill-at”を追加。static は、静的リンクをしたい場合につける。kill-at はシンボルの後ろに @ を付けたくないときに付ける。両方とも無くてもかまわない。たぶん。
  • 「Shared Library Settings」の「Shared(-shared)」チェックボックスをチェック

「All options」を見るとこんな感じ
-static --kill-at -shared


「Settings」画面の「Build Artifact」タブで以下を設定
  • 「Artifact Type」を”Shared Library”を設定。ただ、この設定がどこに影響があるのか不明。
  • 「Artifact name」を”${ProjName}”に設定。出力ファイルのベースファイル名になる。
  • 「Artifact extension」を”dll”に設定。出力ファイルの拡張子になる
  • 「Output prefix」を空にする。出力ファイル名の先頭に付加される。

以上で C++ プロジェクトへの設定は完了
ビルドすると、Default ディレクトリに dll ファイルが生成されるはず。

Java デバッグの設定
  • DLL 読み込みのために以下のいずれかのように DLL のディレクトリを設定する。
    • 「VM arguments」に”-Djava.library.path=../hello-jni/Default”のように指定。
    • 「Environment」に”PATH”を追加して、”../hello-jni/Default”のように指定。


C++ アタッチデバッグの設定
  • C++ プロジェクトをクリックして、選択状態にする。
  • 「Run」メニューから「Debug Configurations...」を選択。
  • 「C/C++ Attach to Application」 を右クリックして、コンテキストメニューから「New」を選択。
  • 作成されたデバッグ設定をクリック。
  • 「Main」タブの「C/C++ Application」が”Default\ DLL ファイル名”、「Project」がC++ プロジェクト名になっていることを確認。
  • 「Close」ボタンを押す。

デバッグ開始


デバッグを開始する手順は次のようにする。
  • Javaのソースにブレイクポイントを設定。ただし、 System.loadLibrary で 作成した DLL のロード後の場所に設定すること。
  • Java のデバッグを開始。
  • C++ のデバッグを開始。アタッチするプロセス ID を設定するダイアログが開くので、上で実行したプロセス(javaw.exe)の ID を tasklist コマンドか、タスクマネージャで調べて入力する。javaw.exe プロセスは、eclipse 本体もあるので、間違って eclipse 本体のプロセスを指定しないこと。
  • C++ ソースにブレイクポイントを設定する。ここ重要、必ず C++ デバッグ開始直後の状態(GDB が起動して、一時停止の状態)でブレイクポイントを設定すること。ブレイクポイントを解除しなくても無効にして有効にすれば問題ない。ブレイクポイントのマークをよく見ると、有効な場合は、丸の上にチェックが付いている。無効な場合には、丸だけ。さらに、ソース上のブレイクポイント行に!マークが付き”Breakpoint attribute problem: installation failed”と表示される。
  • C++ デバッグを再開(Resume(F8))する。再開後に C++ のブレイクポイントの設定はできない。C++ のブレイクポイントで一時停止した状態にならないとブレイクポイントの設定はできない。
  • Java デバッグを再開すると C++ のブレイクポイントで停止する。はず。


いろいろやってると、eclipse が反応しなくなるときがある。そんなときは、GDB のプロセスが残ってる場合があるので、taskkill コマンドかタスクマネージャから gdb.exe プロセスを停止するといい。

2010年7月16日金曜日

Google ツールバーでマウスオーバー翻訳ができなくなった

気が付いたら、Google ツールバーのマウスオーバー翻訳が動作しなくなっていた。
Google ツールバー オプション画面を開く。
「ツール」タブで、「翻訳する」項目の「編集」を開く。
「翻訳する言語を選択してください:」で、なぜか”中国語(簡体字)”から、”日本語”に変更して、保存しても、変更できない。

設定を、どう変更しても反映されないので、しかたなく「デフォルトに戻す」ボタンをポチッとなっ!
そしたら、正常に動作するようになったとさ。めでたしめでたし。

Eclipse CDT と MinGW(64bit版)でコンパイル

Eclipse CDT と MinGW(64bit版)でコンパイルをしてみたくなったので、やってみた。

■確認した環境

AMD Phenom(tm) II X4 955 3.20GHz
Windows Vista Business SP2 64bit

JDK 1.6.0_16  64bit
MinGW(64bit版)(mingw-w64-bin_i686-mingw_20100702_sezero.zip)
Eclipse Classic 3.6.0 64bit(eclipse-SDK-3.6-win32-x86_64.zip)
C/C++ Development Tools 7.0.0.201006141710

  • 間違いの元その1:MinGW は、元から 32bit 版が入っていて(C:\MinGW)、後から 64bit 版を入れた(C:\MinGW64)
    CDT は C:\MinGW にMinGW がインストールされていると、Path に設定されいるかは、関係なく、このディレクトリの GCC を使用してしまう。よって、32bit 版を、C:\MinGW86 にリネームした。
  • 間違いの元その2:環境変数の Path に、MinGW のパスを設定していない。
    CDT は、C:\MinGW にMingGW がインストールされていない場合は、環境変数の Path に設定された、パスから GCC を探して利用する。よって、Windows の「システムプロパティ」-「環境変数」で”Path”に”C:\MinGW64\bin”を追加した。
    GCC のパスは、Eclipse の設定で「C/C++」-「Build」-「Environment」などに設定しても、だめだった。

2010年7月10日土曜日

windows vista 64bit で JOGL 2.x をコンパイル

JOGL 2.x の 64bit 版コンパイルに、なんとか成功したようなので、手順を書いておくことにする。
以下の手順は、Java Binding for the OpenGLR API Wiki(JOGL) の FAQ や How To Build が元になっている。

コンパイル環境
  • Windows Vista 64bit
  • Microsoft Visual C++ 2008 Express Edition SP1
  • Java SDK 1.6.0_16 64bit
  • Ant 1.8.1
  • ANTLR 3.2
  • Git for Windows 1.0.7.2

環境の構築
OS、Visual C++ および Java は、インストール済みとする。
  1. Ant
    Ant は、このページのダウンロードサイトからダウンロードして、解凍し適当なディレクトリへインストールする。
    環境変数 path にAntをインストールした場所の bin ディレクトリを追加。
    コマンドラインで、 ant -version でバージョンが表示されればOK。
  2. ANTLR
    ANTLR は、このページのダウンロードサイトから「Complete ANTLR 3.2 jar; all tools, runtime, etc...」となっているものをダウンロードし、Ant をインストールしたディレクトリの lib ディレクトリの中へコピーする。
  3. Git for Windows
    Git for Windowsは、このページからダウンロードして、インストール

2010年7月5日月曜日

getepg.php で Segmentation fault がいっぱい

最初に気がついたのは、録画予約したはずの番組が、録画されていないことだった。
EPGREC から番組を検索しても、5日後の番組が引っかからない・・・・

はて?と思って、EPGREC の番組表を見てみると、4日後以降マッシロケ・・・
では、手動で番組表を取得してはどうかと getepg.php を実行してみたが。
Segmentation fault がいっぱい表示されてダメっぽい。
epgdump とかも疑って、再インストールしてみたが、状況は変わらず。

受信電波状況が悪いのかと、録画してみることにした。
$ recpt1 --b25 --strip 27 30 test.ts
using B25...
enable B25 strip
pid = 3075
Cannot tune to the specified channel

ぬぉ!? NHK が映らんだと!!