ライブラリのM17Nについての自分向けメモ

自分向けに要点だけメモっとく。
1.9対応かつM17Nでちゃんと動くように作る場合に
あとでこのメモを参照しよう。

  • 基本的に入力も出力もUnicode(UTF-8)を想定する。
  • Encoding#default_internal が設定されている場合はそのエンコーディングで返す
  • 入力については、String#encodingを見る
  • DummyEncodingは文字列として扱えない。
  • ユーザがString#force_encodingしないとならないようでは、M17N対応できたライブラリとは言えない。

ほとんどのライブラリは入出力はUTF-8だけを想定していていいんだけど、
ライブラリの性質上、どうしてもUTF-8以外のエンコーディングを入出力で取り扱わなければならない場合は、入力されたStringのString#encodingを確認したり、Encoding#defualt_internalを確認して、よきに計らうようにするといい。

Encoding#default_internal は、コマンドラインオプションの -Eや、-Uを使うか、マジックコメントに記述することで設定される。
異なるエンコーディングの入出力を想定せざるを得ないライブラリの場合は、ライブラリ自体にはマジックコメントでエンコーディング設定しない方がいいのかもしれない。
なぜなら、それをやってしまうとEncoding#default_internalやEncoding#default_externalを上書きしてしまうからだ。
*1

5/11 追記

気になったので マジックコメント をrequireされる側に書いてみた場合の挙動について確認しました。
マジックコメント に書いても、Encoding#defualt_external が上書きされるわけではなく。
マジックコメント の値は、まず __ENCODING__ に代入されるようです。
そして、 __ENCODING__ には感染性*2はないようです。*3
つまり、ライブラリ自体に magick comment を書いても問題はないわけですね。
むしろ、書くべきだったようです。*4

enc_euc.rb

#-*- encoding: euc-jp -*-
str_euc = 'ほげ'

require_euc.rb

#-*- encoding: utf-8 -*-

# -Eオプションや -Kオプションなしだと、 default_external は US-ASCII
p Encoding.defualt_external #=> #<Encoding:US-ASCII>

# スクリプトエンコーディング(__ENCODING__) は、 マジックコメントで指定したもの。
p __ENCODING__ #=> #<Encoding:UTF-8>

require 'enc_euc'

# require しても、Encoding.default_externalもスクリプトエンコーディングもちゃんと保持されるね。
p Encoding.defualt_external #=> #<Encoding:US-ASCII>
p __ENCODING__ #=> #<Encoding:UTF-8>

自分向けのまとめとしてはこんなところ。
……というか、ぜんぜんまとまってないじゃないか!

M17N恐るべし。
普及したらえらい便利なのだろうけれど、1.9初学者には最大の壁なのかも……

1.9対応したつもりの、手持ちのGemたちも内容確認したほうがいいかも。

*1:この点については、要検証

*2:微妙な表現だけど、自分としては判りやすい

*3:少なくとも、1.9.1-p0では。

*4:参考: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/33647

UstreamSpeaker

Ustで「なんちゃってビデオチャット」ができるツールを作ったよ。

利用環境は、Windows専用ですが
その代わり、Exerbを使って実行ファイルに変換してるので
Rubyが実行できないマシンでも使えるようになってます。

詳しい使い方などは、下記をご覧ください。

UstramSpeaker

特徴

このアプリのおもしろいところは、
配信ユーザがいちいちUstのチャット画面をみなくても
チャット内容が合成音声で再生されるので
ビデオチャットのように、声と声で会話できる」という点です。



どういうことかと言うと…

[Ustのチャット] >> [読み上げアプリ] >> スピーカーから合成音声がでる
>> [配信ユーザに聞こえる] & [配信PCのマイクで集音]
>> [配信ユーザが声で返事をする] & [配信PCのマイクで集音]
>> [Ustの視聴者にも聞こえる]

……と、こんな仕組みです。*1

05.07追記:

要検証ですが、開発環境以外での動作確認がまだでした。
もしかすると、WindowsVistaなどでは「互換モードで実行する」にしておかないと実行できないかもしれません。
開発機(WindowsXP)では、動いたんですけど……

*1:よけいに分かりにくいかもしれないぜ!

続きを読む

続・作りかけの無脳

欲張っていたらいつまでたってもプロトタイプができないので
後に拡張するとして、今回は実装を見送る部分をざっくり決めました.

今回実装を見送るものたち

  • rindaで分散処理する
  • 強化学習
  • 状況に応じて話しわける機能*1

基本的な発話機能だけを作り、
他にも実装を考えていた発話機能については今回見送ります。
必然的に、フレームばかりが無駄に大きくて、その割に頭の悪い無脳に仕上がりそうです……*2

ひとまず「プロトタイプとして動くもの」を作って
後からいろいろ拡張することにしました。
まずは、IRCのインターフェースを積んで
実際に動かしてみようと思います。

動かしてみれば、またいろいろ気がつく箇所も出てくると思うので
それから手直しやら拡張をすればいいかなと。

*1:状況判断部分は、「ゆるく判定する」ものを仮に実装しました

*2:本当に、単純にマルコフ連鎖するだけのお粗末なものです

謎な行為

最近、こんなコードを書きました。

名前空間わけて使いたいものを
モジュールとして定義しとく。

fuga/hoge_util.rb

module Fuga::HogeUtil
  def benri_method
    print "totemo benri!"
  end

  ...

end

使いたいクラスを書いとく。
ここでは、後で使うかもしれないモジュールを
Module#autoload(const, path)で定義しとく。

fuga.rb

class Fuga
  autoload :HogeUtil, 'fuga/hoge_util.rb'

  ...

end

実際に使う場面では、
インスタンスを生成したあとで
Object#extend Mod する。
事前に Module#autoload されているので
Mod が呼ばれたタイミングで Kernel#requireされる

use_case.rb

require 'fuga.rb'

fuga = Fuga.new
fuga.extend HogeUtil
fuga.benri_method #=> "totemo benri!"

実際やってみるとイチイチ Object#extend するのが
面倒だったりする。
最初から クラス定義の中で include Mod しておけばいいのかもしれないけど。
事前になんでも include されていると実際にクラスを使う場面になって、使いもしないモジュールが include されているのもなんだかなぁ…っていう気がしなくもない。


要約すると、個人的に Module#autoload が好きなんだけど。
なんかうまく活用する方法が見つからない。
……っていうことなんだけどね。

今作りかけの無脳

いろいろ迷走しています。

  • 開発言語は ruby
    • 1.8で作って、1.9でも動くようにしてる*1
  • 自然言語解析は n-gram方式を採用*2
  • 基本はマルコフ連鎖で文章生成*4
  • 辞書はDBで保存*5
    • Sqlite3を使うよ
    • Sequelを使うよ*6
  • rindaで分散するよ*7
    • ローカルにあるマシン間で無脳リソースを共有して使うイメージ
  • 強化学習とかさせたい*8
  • 状況判断とかさせたい*9

基本となるフレームをちまちま作っているのですが
作りながらもいろいろ迷走しています。
いろんな要素を取り込もうとしているので迷走しまくりです。

*1:最近は1.9で開発してる

*2:この辺りはできた

*3:この辺りもできた

*4:この辺もできた

*5:辞書が肥大すると、テキストとかYAMLで管理するのも大変なので

*6:いろいろ苦戦してる

*7:この辺りは未着手

*8:苦戦してる

*9:苦戦してる

Ustream音声読み上げアプリ

ずいぶん前に作ったやつだけど、
「コードが汚い」だの、「ライセンスがややこしい」だのと理由をつけてほったらかしてた奴ですが。
先日、作り直しました。

Exerbつかって .exeにしたものと
素のrubyのと二つつくりました。

aqtkを参考にしてみたところ、
どうやらライセンスはGPLになるようだ。*1

  • AquesTalk

独自ライセンス

GPL

不明

Exerb自体はLGPLなんだけど、
生成した .exe は Rubyライセンスになるらしい

んで。
某所で、「そんなこと気にしないで、さっさと公開しる」とか言われたけど
やっぱり気が小さいので、まだどこにも公開していなかったりします。

どんなものかと言いますと。
「Ustのチャット内容を、ゆっくり声(合成音声)で読み上げる」っていう代物。
チャットが読み上げられるもんだから、Ust流している側は
キーボードも画面も見ないで視聴者と会話できるという点が便利です。

しかも。
今回は作り直したついでに、機能をいくつか追加しました。

  • 一度に複数のチャットが入力された場合、非同期で別々の声で再生する
  • 認識する単語を追加可能にした

結局これはどこにアップしたらいいんだろうか。

*1:kakasiGPLなんだね