AqKanji2KoeをPythonから呼び出す (CFFIを使って)


AqKanji2Koe は、漢字かな混じり文のテキストを、AquesTalk用のカナ表記の音声記号列に変換する言語処理のライブラリです。

言語処理ライブラリ AqKanji2Koe

おーすげー と思ったら


評価版は「ナ行、マ行」の音韻がすべて「ヌ」になる制限があります。

評価版ダウンロード

あ、そうだったんだ。 と、今ごろになって気がつきました。

とりあえずPythonから呼び出す方法が判ったのでメモ

RaspberryPiを持っている人はAquesTalk Piにて、-tオプションを付けると同等の機能になるようです

AquesTalk Pi の使い方まとめ N.Yamazaki's blog

CFFI

pythonからCで書かれたDLLを呼び出すには、標準ライブラリのctypesを使う。。。と思ったのですが、あまりに久しぶりすぎて使い方を忘れてしまいました(汗

今回は、新しく*1
開発されたCFFIモジュールを使用します。ctypesよりも記述が簡単になっております。
CFFI ドキュメント

PyPy関連で開発されたようです。
windows版のバイナリはこちらでダウンロードできます

Unofficial Windows Binaries for Python Extension Packages

少しハマったポイント


void * AqKanji2Koe_Create(const char *pathDic, int *pErr);

#int *pErr など、呼び出し側で用意した領域に
#値が戻ってくる場合

pErr=ffi.new("int[1]") #ここが最初判らなかった

#なぜこうなるかは、 pErr[0]=1 とpErr=1の
#結果の違いを考えるとわかりますん

以下 書いてみたコード。

AqKanji2Koeの評価版にて、ZIPファイルを解凍して出来たフォルダ aqk2k_win_eva に以下のスクリプトを記述したファイルを置いて実行します



# -*- coding: utf8 -*-
from cffi import FFI
ffi = FFI()
ffi.cdef("""
void * AqKanji2Koe_Create(const char *pathDic, int *pErr);
void * AqKanji2Koe_Create_Ptr(const void *pSysDic, const void *pUserDic, int *pErr);
void AqKanji2Koe_Release(void *hAqKanji2Koe);
int AqKanji2Koe_ConvertW(void *hAqKanji2Koe, const wchar_t *kanji, wchar_t *wKoe, int nBufKoe);
""")

AqKanji2Koe = ffi.dlopen("AqKanji2Koe.dll")

pathDic=ffi.new("char []","aq_dic")

#int &pErr など、呼び出し側で用意した領域に
#値が戻ってくる場合は、このようにする
pErr=ffi.new("int[1]") #ここが最初判らなかった

#なぜこうなるかは、 pErr[0]=1 とpErr=1の
#結果の違いを考えるとわかりますん

hAqKanji2Koe=AqKanji2Koe.AqKanji2Koe_Create(pathDic, pErr)

nBufKoe=256
txt2read_all=u"""昔、昔、ある所に、お祖父さんと、お婆さんが住んでいました"""

for txt2read in txt2read_all.splitlines():
wKoe=ffi.new("wchar_t [%d]"%nBufKoe)
kanji=ffi.new("wchar_t []",txt2read)
AqKanji2Koe.AqKanji2Koe_ConvertW(hAqKanji2Koe, kanji, wKoe, nBufKoe)

print txt2read
yomi="".join([c for c in wKoe])
print yomi
AqKanji2Koe.AqKanji2Koe_Release(hAqKanji2Koe)

実行サンプル


元の文章
昔、昔、ある所に、お祖父さんと、お婆さんが住んでいました

読み
ヌカ_シ、ヌカ_シ、ア'ルトコロヌ、オジ'ーサント、オバ'ーサンガ/ス'ンデ+イヌ'_シタ。

今回は CFFIモジュールの使い方を憶えた、ということで、ここでおしまい。どっとはらえ。

*1:ctypesよりも新しい、程度の意味