2007/05/28(月)PCastTV2の衛星放送に関するiEPG情報

我が家ではマンション上部のコンバータによってUHF帯に衛星放送が流れてきているという特殊な事情がある。従って、特別なチューナーなしにUHF対応のアナログキャプチャボードで衛星放送が見られたりする。

さて、PC-MV5DX/PCIというキャプチャボードを愛用しているのだが、これの視聴ソフトPCastTV2が、EPGで衛星放送を扱えるようにできていない。PCastTV2はBuffaloブランドのキャプチャ製品共通のソフトであるが、対応機器に衛星チューナー搭載のものがないのが原因である。

そこで今回のミッションは、なんとかしてPCastTV2でUHF33,35チャンネルをNHK BS1,BS2のEPG情報に割り当て、GUIや録画ファイル名に反映させて幸せになるというもの。

[1]PcastTV2のインストール

そもそもPCastTV2はPC-MV5DX/PCIにインストールできるようになっていない。しかし動いてしまえばMV5DXに対応しているようである。従って、インストール時にレジストリをいじってやる。
[HKLM\SYSTEM\ControlSet*(使っているコントロールセット)\Control\DeviceClasses\{65E8773D-8F56-11D0-A3B9-00A0C9223196}##?#PCI#VEN_14F1&DEV_8800&SUBSYS_051E1154&REV_05#4&CF81C54&0&10F0#{65e8773d-8f56-11d0-a3b9-00a0c9223196}#GLOBAL\Device Parameters

]の値
BUFFALO PC-MV5DX/PCI Video Capture



BUFFALO PC-MV52DX/PCI Video Capture

に書き換え、PCastTV2をインストール。
インストール後、文字列を元に戻しPCastTV2を起動。

このままだとPCastTV2がMV5DXを認識していない場合があるので、その場合はPCastTVを立ち上げる必要がある。

さらに録画しても容量0のファイルができる場合はドライバをインストールし直す。ここまでやればたぶんOK。

[2]pcast_iepgloc.datの設定

受信するEPG情報を決めているファイルは、

C:\PROGRAM FILES\BUFFALO\PCastTV_2\EPG\pcast_iepgloc.dat

である(標準のインストール先の場合)。
このファイル中の受信放送エリアの行は、



Lct=東京(東京)

7001=NHK総合<001>,7002=NHK教育<003>, ...



となっている。自分の受信エリアのLctを探し、その下の行を書き換える。

=の前の4桁の数字は、SO-NET TV王国

http://www.so-net.ne.jp/tv/bangumi/

中の放送局コード。
PCastTV2はEPG情報をここ決めうちでダウンロードしているようだ(EPGサイト設定できるけど、リンククリックしたときに開くだけっぽい)。

上記サイトで地域選び、番組表から番組名をクリックしアドレスをみたときに、?st_cd=となっている部分が放送局コードになる。
放送局名はTV王国にあわせる。<>は自分が設定したチャンネル。たとえば、9002=NHK衛星第2<035>と追記してやると、衛星第2の情報がダウンロードされ、PCastTV2のGUIに衛星第2の列が追加される。
[3]でも番組名が出てこないんですが・・・・・・

列が追加され、情報もダウンロードしているのに、なぜか番組タイトルが表示されない。どういうこっちゃ!? と思って調べた。
ダウンロードしたEPG情報は、

C:\PROGRAM FILES\BUFFALO\PCastTV_2\EPG

内の

SEPG.txt(は日付)

に記録される。これがTV王国が提供してる生データか、PCastがパースし直したものかは謎だが、それをさらに加工して表示用のデータ、

EEPG.txt(は日付)

に直している。
調べてみると、先の例でいう衛星第2=放送局コード9002の番組はSEPGの方には記録されているが、EEPGには記録されていない。そこで放送局コードの数字をいじって、PCastがどういう挙動をしているのか確認してみた。放送局リストみたいなものを持っていて、一致しないものを捨てているのかと思いきや、シンプルに、

放送局コードが、

・8999以下->通し

・9000以上->捨て
という挙動であるようだ(8999と9000の境界以外は適当にしか確認していない)。

TV王国のサイトを眺めてみると、9000以上はWOWOWやNHK衛星にしか使われていないようで、地上派オンリーだからそれでいいということらしい。

となってくるとこの判定部分を探せばいいということになる。ついにOllyDbgの出番が来た、それ解析解析~と・・・・・・思ったのだが、使用許諾確認したら逆アセンブル、書き換え禁止となっている。とはいえしゃくに障るので、バイナリ読むのだったら問題ないと考え、それらしい名前のCEpgDll.dllをバイナリエディタで開いてみた。

さて、一文字目を検査して8,9の場合分けだと探しづらい。この際、このコードを書いた人間が一番単純にやっていると考えて、パースしたあと、atoiで数値変換->比較という流れであると想定。

ねらいが正しければ、8999(0x2327)か9000(0x2328)がどこかに見つかるはず。

・・・・・・1カ所あった、28230000が(リトルエンディアン)。あれその前が、0x3Dになってる。3Dってたしか・・・

C・M・P

ここでほぼ確定。アドレス0x2C32からの、3D 28 23 00 00の部分をいじってやればいいっぽい。たとえば、9999(=3D F0 27 00 00)とかに。とはいえ使用許諾があるので書き換えはできないわけで。

Buffalo様何とかしてください。

2007/03/16(金)Ruby関係のPATHが滅茶苦茶

うちのPCにはRubyが3バージョン入っているため良く問題が起きる。

3バージョンとはApollo版とActiveScriptRubyのmswin32版とcygwin版なのだが、これの共存がどうも難しい。スクリプト言語はPATHに支配されるので別バージョンのライブラリを見にいったりしてしまう。

さて今回のトラブルは、諸事情あってmswin32版Rubyを1.8.5に入れ替えたため発生したようだ。入れ替え後、irbを動かそうとしたら、
c:\online\apollo\bin/readline.dll: 127: 指定されたプロシージャが見つかりません。

   - Init_readline (LoadError)

c:\online\apollo\bin/readline.dll       from c:/online/ruby/lib/ruby/1.8/irb/com

pletion.rb:10

        from c:/online/ruby/bin/irb.bat:18:in `require'

        from c:/online/ruby/bin/irb.bat:18
と怒られた。どうやら環境変数$RUBYLIBにapollo版のPATH、c:\online\apollo\binが書いてあるのが駄目らしい。しかし、奇怪なことに先にmswin版のPATH、c:\online\ruby\binを書いてやってもダメ(その場合はruby\binのreadline.dllでプロシージャが見つからないと言われる)。

つまり、環境変数$RUBYLIBに、
C:\ONLINE\RUBY\bin
c:\online\apollo\bin

c:\online\apollo\bin
の場合はダメで、

なら良いらしい。

ところが、RUBYLIBからapollo\binを外したところ、今度はApolloで作ったスクリプトがexerbで固めない限り動かなくなってしまう。

うーん、何も考えずに1.8.5を入れたのが迂闊だったか。

暫定でActiveScriptRubyを1.8.2に戻した。一応gemsも含めて動くようになったので解決。

今後mswin32版のVer Upは注意することにする。危ういバランスの環境はすぐに壊れるということだ。

2006/12/20(水)FULLWIDTH TILDE問題

どこかで聞いたことはあったけど始めて遭遇。

WindowsのShift-JIS <-> UTF-8の変換表が本来の規格と異なるため、アプリ側の変換表で文字化けたりする問題。
VirtualDubのjobsにまとめてファイルを投げるRubyスクリプトを以前書いた。VirtualDubはUTF-8でファイル名を扱うのだが、このとき"~"を含むファイル名に対して、RubyのkconvでSJIS->UTF-8変換をしていたら"~"はWAVE DASHと解釈され\xe3809cに。しかしこれをVirtualDubからWindowsに投げると、"~"(FULLWIDTH TILDE)に戻せない。ということで「ファイルが見つかりません」となり問題が発生。

しかしコードの違いだけならまだしも割り当てられている文字そのものが違うとはまた面倒くさい……

ということで、Windows上の"~"の扱いである\xefbd9e(FULLWIDTH TILDE)に変換しないといけない。とりあえずRubyにはNKFがあるので、

NKF.nkf('-w --cp932', "~")

で変換すれば良し。なお、nkfのオプション指定はパースが厳しいようで、short optionは先に、先後に余計な空白を挟まないようにしないと上手く解釈されなかった(多分)。

今後、Windowsのファイル名をUnicodeで扱う際には念を入れてチェック。他に気をつける場面はなにがあるだろう。ファイル内部の表記はずれるのかな。Winアプリで"~"と表示されているとして、アプリ側がどのコードで保存し、表示でいじってるかとかはファイルの中を見ないと分からない?? 怖いなあ。

2006/08/08(火)AfterEffectsとかPhotoShopとかを自動で

あまり時間がないので雑メモだけ。

FI/FOがあるだけの簡単なテロップを自動制御で大量生産するのが今回の目的。最終的にはPhotoShopをOLEオートメーションでドライブしてpsdを大量に吐かせた後、AfterEffectsはjavascriptの自動制御でフッテージ差し替え->レンダリングを繰り返すことで実現できたようだ。

まずはPhotoShop側から。

PhotoShop/Illustrator/InDesignなんかはOLEオートメーションがしっかり実装されていて、OLEが使える言語からなら色々操作が可能だ。今回はいつも通りRubyでバリバリ.psdを吐かせてみた。

基本スタートはいつものこちら。

http://jp.rubyist.net/magazine/?0003-Win32OLE
ただ、結局の所僕の腕では複雑なアプリケーションのクラス構造やら、引数の見当をつけるのはほとんど不可能に近い。オブジェクトインスペクタならぬ、オブジェクトブラウザで覗いてみたところで、"Option"という引数名に文字列が来てたらもうそこでパンクしてしまう。全ては対象アプリケーションのリファレンスの充実度次第。

photoshopはインストールフォルダのどこを探してもリファレンスらしきものが出てこない。そこで、

http://codezine.jp/a/article.aspx?aid=406
にあるように、英語版AdobeサイトのDownloadページから、

Photoshop 7.0 Scripting plug-in v.1.0.2a

を取ってくる。これに付いてるリファレンスがきっちりしていて使える。これがなかったら何も出来なかった。

AfterEffectsの方は、少なくとも所持している6.0ではOLEオートメーションは効かないようにみえる。スクリプトそのものは動くので、vbsかjsで書くことになる。ちゃんと理解してないのかもしれないが、AfterEffectsのscript部分はレンダリングの制御のみを目標に考えられているようだ。どうもコンポの中身を弄れるようには見えない。だからレンダーオートメーション? 中身はExpressionで弄れるのだろうか?

ともかく、今度は付属のドキュメントが歯抜け過ぎで肝心なことが書いていない。結局以下のサイトに頼った。

http://hpcgi2.nifty.com/Nekomata/nekojyarashi/wiki.cgi?ObjectList01
これ読まなかったらレンダーキューへのつっこみ方もよく分からなかった。感謝。

http://www.openspc2.org/reibun/AfterEffects6.5/
おまけ。でもこっちはドキュメントに書いてある範囲をそんなに出てないから、あんまり役に立たないかなあ。

2006/05/03(水)Perl

久々に触ったけど、Perl難しいよPerl。

Perlのポケットリファレンスどっかいっちゃったので、使ったWebページをメモ。

http://www.rfs.jp/sb/perl/index.html

http://www2u.biglobe.ne.jp/~MAS/perl/ref/index.html

http://www.nwt.jp/document/perlfunc/index.htm

http://pub.cozmixng.org/~the-rwiki/rw-cgi.rb?cmd=view;name=%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8%B8%C0%B8%EC%A4%CE%C8%E6%B3%D3#header-navi
[わからないこと、いやなこと]

・$x と @x が違う変数なのはもちろんいいんだけど、@xの要素にアクセスするときに$x[]なのがちょっと気持ち悪い。

が嫌。なぜここだけ<>?

・あとスカラーで評価されるタイミングがよく分からない。

・破壊的代入ばっか……

・クラス・構造体の実装が無理しすぎに見える。
改めて思う、Rubyは楽ね。

2006/05/03(水)GD::Graphのあれこれ(Perl)

あまり他で書いてないことをいくつか。

GD::Graphの生成画像にイメージマップを貼る


GD::Graph::Mapを使う手もあるがどうも使い勝手が悪い。そこでhotspot()メソッドを使う。
use GD::Graph::points;
my $graph = GD::Graph::points->new(400,300);

@data = (
	['1st', '2nd', '3rd'],
	[1, 2, 3],
);

my $image = $graph->plot(\@data) or die;
my @ret = $graph->get_hotspot(1);
for(my $i = 0; $i < @ret; $i++) &#123;
	print "<area shape=$ret[$i][0] Coords=$ret[$i][1],$ret[$i][4],$ret[$i][2],$ret[$i][3]>\n";
&#125;
こんな感じで。第1引数はデータ系列番号(1始まり)、第2引数はデータ系列中のデータ番号(0始まり)。共に省略可。

ソースをざっと見た限りでは、生成したグラフのタイプによってtop, bottom, left, rightがどの順で帰ってくるか違ってるような気がする。

プログラム作成時にテストした方がよい。
なお、どうでもいい話であるが、このメソッドいつも「ホッツポット」と読んでしまう。なんでだ?

numerical X(x軸を数字として扱う)


GD::Graphは基本では全てのXを見出しとして等価に扱う。

だが、散布グラフや1つの列に2つ以上のデータをプロットする場合など、X座標を数字として扱いたい機会は多い。

GD::Graphのマニュアルにあるとおりこの機能は本来はunsupportedである。従って、ちょっとやり方が複雑。


  1. x_min_value, x_max_value, x_tick_numberの3つを設定する

  2. データ系列が3つ以上の値を含む

  3. x軸のデータが全て数字


この3条件を満たすときに数字として扱ってくれるようだ。
use GD::Graph::points;
my $graph = GD::Graph::points->new(400,300);

@data = (
	[1 ,1, 10],
	[1, 2, 3],
);

$graph->set(
	x_min_value => 0,
	x_max_value => 30,
	x_tick_number => 10,
);

my $image = $graph->plot(\@data) or die;

open(OUT, ">test.png") or die;
binmode OUT;
print OUT $image->png();
close(OUT);
setメソッド中の3行はどれをコメントアウトしても表示がおかしくなると思う。

グラフ座標を画像のピクセル座標に変換


val_to_pixel()メソッドを使う。本来プライベートメソッドであるべきものを呼んでる気がするけども。
use GD::Graph::points;
my $graph = GD::Graph::points->new(400,300);

@data = (
	['1st', '2nd', '3rd'],
	[1, 2, 3],
);

my $image = $graph->plot(\@data) or die;
my $green = $image->colorAllocate(0, 255, 0);

my @p1 = $graph->val_to_pixel(1, 1);
my @p2 = $graph->val_to_pixel(3, 3);
$image->line(@p1, @p2, $green);

open(OUT, ">test.png") or die;
binmode OUT;
print OUT $image->png();
close(OUT);
(1,1)から(3,3)の間に直線を引く。numerical Xにした場合でもちゃんと動くようだ。

なお、普通の解説とかサンプルは下記参考サイトが詳しい。

お、Rubyにラッパーあるね。まだ触って無いけど。
[マニュアル]

http://search.cpan.org/~bwarfield/GDGraph-1.4307/Graph.pm
[サンプル]

http://x68000.q-e-d.net/~68user/webcgi/gd-graph.html

http://www.linkclub.or.jp/~ma3ki/webutil/gdgraph/howtograph.html

2006/02/24(金)Rubyでコンソールから1文字入力

なつかしのC言語だとgetch()あたりで簡単に出来るコンソールからの直接1文字入力。Rubyの標準機能だとどれを使ってもEnterを押されるまで読み込めない。別に我慢すればいいような話なのだが、ちょっと挑戦。

・解決案1(不採用) 添付ライブラリcursesを使う。Winでもunixでも動くには動きそうだが、表示とかが機種依存ぽいので止め。

・解決案2(採用) Win32API+crtdll.dllを使う。もちろんwin32限定だが、その範囲に限れば最も機種依存度低そう。(msvcrt.dllよりもcrtdll.dllの方が汎用性高いという認識で合ってるよね?)

ということで解決案2でGO。

こんなふうに書いてみた。
require 'Win32API'

func_getch = Win32API.new('crtdll.dll', '_getch', 'v', 'i')

str = "Do you like skate? [y/N]\n"
print str

while true do
	x = func_getch.call.chr.downcase
	
	case x
	when 'y'
		#yesの時の処理
		print "Ok!\n"
		break
	when 'n', "\r"
		#noの時の処理(デフォルト)
		print "Terrible!\n"
		break
	when "\C-c"
		#getchでコンソールを奪うと中断出来ないので
		exit
	else
		print str
	end
end
如何にも古い人のコードだが気にしないで欲しい。

Win32API->crtdll.dll経由で_getchを呼び出す。_getchはエコーしないのであとは入力された文字で処理を分けてやるだけ。

意外と簡単に書けたけど…… こんなの使うのかな?

[参考URL]
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/6991

2005/10/27(木)ApolloのPanelでinitializeがオーバーライドできなかった理由

class MyPanel < Phi::Panel
  def initialize
    # ≪処理≫
  end
end

MyPanel.new
というコードを書いたのだが、≪処理≫が実行されない(本来なら処理の前にsuperを書くが、わかりやすくするために削った)。

で、この場合newで呼ばれるのはPhi::Panelのコンストラクタのようで、オーバーライドしたはずのinitializeを通らない。

これはどうやらPhi::Panel上でnewが再定義されている所為らしい。下はGtkの記事だがApolloでも似たようなことをやっているのではないかと推測。再定義したnewはinitializeを呼ばないという解釈で良いと思う。
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/5885

いやちゃんとソース読んで無いので確証はないのだが(読み方すら分からない)。

ということで、
class MyPanel < Phi::Panel
  def MyPanel.new
    # ≪処理≫
  end
end

MyPanel.new
としてやれば願いが叶う。newはクラスオブジェクトのメソッド(こういう言い方でいいんだっけ?)なので、def newではなく、def MyPanel.newと書く。superは省略したが、ちゃんとやるならもちろん返り値の設定までしてやらなきゃいけない。
ret = super
≪処理≫
ret
≪処理≫の中でプロパティいじるような目的がほとんどだと思うので、こんな書き方が定番になるんだろう。initializeと大きく異なるのはこの中でselfを呼ぶとクラスオブジェクトが返ってくることだ。
class B
end

class A < B
  def A.new
    ret = super
    p self
    ret
  end
end

p A.new

--出力--
A
#<A:0x2bb42c8>
つまりこうか。

プロパティを設定するときはsuperの返り値(ここではret)に対して設定してやらなきゃならない。

#追記
newからinitializeを呼んでやった方が汎用性が高い。
OK キャンセル 確認 その他